mp4file.cpp

来自「faac-1.25.rar音频编解码器demo」· C++ 代码 · 共 2,476 行 · 第 1/5 页

CPP
2,476
字号
  return trackId;
}

MP4TrackId MP4File::AddVideoTrack(
	u_int32_t timeScale, 
	MP4Duration sampleDuration, 
	u_int16_t width, 
	u_int16_t height, 
	u_int8_t videoType)
{
	MP4TrackId trackId = AddTrack(MP4_VIDEO_TRACK_TYPE, timeScale);

	AddTrackToOd(trackId);

	SetTrackFloatProperty(trackId, "tkhd.width", width);
	SetTrackFloatProperty(trackId, "tkhd.height", height);

	InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0);

	AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4v");

	// stsd is a unique beast in that it has a count of the number 
	// of child atoms that needs to be incremented after we add the mp4v atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
		MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4v.width", width);
	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4v.height", height);

	SetTrackIntegerProperty(trackId, 
				"mdia.minf.stbl.stsd.mp4v.esds.ESID", 
#if 0
				// note - for a file, these values need to 
				// be 0 - wmay - 04/16/2003
				trackId
#else
				0
#endif
				);

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.objectTypeId", 
		videoType);

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.streamType", 
		MP4VisualStreamType);

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsz.sampleSize", sampleDuration);

	m_pTracks[FindTrackIndex(trackId)]->
		SetFixedSampleDuration(sampleDuration);

	return trackId;
}

MP4TrackId MP4File::AddEncVideoTrack(u_int32_t timeScale, 
				     MP4Duration sampleDuration, 
				     u_int16_t width, 
				     u_int16_t height, 
				     u_int8_t videoType,
				     u_int32_t scheme_type,
				     u_int16_t scheme_version, 
				     u_int8_t key_ind_len,
                                     u_int8_t iv_len,
                                     bool selective_enc,
                                     char *kms_uri
                                     )
{
  u_int32_t original_fmt = 0;

  MP4TrackId trackId = AddTrack(MP4_VIDEO_TRACK_TYPE, timeScale);

  AddTrackToOd(trackId);

  SetTrackFloatProperty(trackId, "tkhd.width", width);
  SetTrackFloatProperty(trackId, "tkhd.height", height);

  InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0);

  AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "encv");

  // stsd is a unique beast in that it has a count of the number 
  // of child atoms that needs to be incremented after we add the encv atom
  MP4Integer32Property* pStsdCountProperty;
  FindIntegerProperty(
		      MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		      (MP4Property**)&pStsdCountProperty);
  pStsdCountProperty->IncrementValue();

  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.encv.width", width);
  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.encv.height", height);

  /* set all the ismacryp-specific values */
  // original format is mp4v
  original_fmt = ('m'<<24 | 'p'<<16 | '4'<<8 | 'v');
  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.frma.data-format", 
			  original_fmt);

  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_type", 
			  scheme_type);

  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_version", 
			  scheme_version);
  
  SetTrackStringProperty(trackId,
			 "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI", 
			 kms_uri);
  if (kms_uri != NULL) {
    free(kms_uri);
  }  

  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.selective-encryption", 
			  selective_enc);

  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.key-indicator-length", 
			  key_ind_len);

  SetTrackIntegerProperty(trackId,
			  "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", 
			  iv_len);
  /* end ismacryp */


  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.encv.esds.ESID", 
#if 0
			  // note - for a file, these values need to 
			  // be 0 - wmay - 04/16/2003
			  trackId
#else
			  0
#endif
			  );

  SetTrackIntegerProperty(trackId, 
		  "mdia.minf.stbl.stsd.encv.esds.decConfigDescr.objectTypeId", 
			  videoType);

  SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.encv.esds.decConfigDescr.streamType", 
			  MP4VisualStreamType);

  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsz.sampleSize", sampleDuration);

  m_pTracks[FindTrackIndex(trackId)]->
    SetFixedSampleDuration(sampleDuration);

  return trackId;
}
void  MP4File::SetH263Vendor(
		MP4TrackId trackId,
		u_int32_t vendor)
{
	
	MP4Atom* d263Atom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263"));
	
	if (d263Atom == NULL)
		return;

	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.vendor",
			vendor);

	d263Atom->Rewrite();
	
}

void MP4File::SetH263DecoderVersion(
		MP4TrackId trackId,
		u_int8_t decoderVersion)
{
	MP4Atom* d263Atom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263"));
	
	if (d263Atom == NULL) {
		return;
	}
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.decoderVersion",
			decoderVersion);

	d263Atom->Rewrite();
}

void MP4File::SetH263Bitrates(
	MP4TrackId trackId,
	u_int32_t avgBitrate,
	u_int32_t maxBitrate)
{
	MP4Atom* bitrAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr"));

	if (bitrAtom == NULL) {
		VERBOSE_ERROR(m_verbosity, WARNING("Could not find bitr atom!"));
		return;
	}

	SetTrackIntegerProperty(trackId, 
			"mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", 
			avgBitrate);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate",
			maxBitrate);

	bitrAtom->Rewrite();

}

MP4TrackId MP4File::AddH263VideoTrack(
		u_int32_t timeScale,
		MP4Duration sampleDuration,
		u_int16_t width,
		u_int16_t height,
		u_int8_t h263Level,
		u_int8_t h263Profile,
		u_int32_t avgBitrate,
		u_int32_t maxBitrate)

{
	MP4TrackId trackId = AddTrack(MP4_VIDEO_TRACK_TYPE, timeScale);
	
	AddTrackToOd(trackId);
	
	SetTrackFloatProperty(trackId, "tkhd.width", width);
	SetTrackFloatProperty(trackId, "tkhd.height", height);
	
	InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0);
	
	AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "s263");
	
	// stsd is a unique beast in that it has a count of the number
	// of child atoms that needs to be incremented after we add the mp4v atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
			MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
			(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.width", width);
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.height", height);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.h263Level", h263Level);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.h263Profile", h263Profile);

	// Add the bitr atom
	AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263"), 
			"bitr");

	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", avgBitrate);

	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate", maxBitrate);
	
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsz.sampleSize", sampleDuration);
	
	m_pTracks[FindTrackIndex(trackId)]->
		SetFixedSampleDuration(sampleDuration);
	
	return trackId;

}

MP4TrackId MP4File::AddHintTrack(MP4TrackId refTrackId)
{
	// validate reference track id
	FindTrackIndex(refTrackId);

	MP4TrackId trackId = 
		AddTrack(MP4_HINT_TRACK_TYPE, GetTrackTimeScale(refTrackId));

	InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "hmhd", 0);

	AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "rtp ");

	// stsd is a unique beast in that it has a count of the number 
	// of child atoms that needs to be incremented after we add the rtp atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
		MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.rtp .tims.timeScale", 
		GetTrackTimeScale(trackId));

	AddDescendantAtoms(MakeTrackName(trackId, NULL), "tref.hint");

	AddTrackReference(MakeTrackName(trackId, "tref.hint"), refTrackId);

	AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hnti.sdp ");

	AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hinf");

	return trackId;
}

void MP4File::DeleteTrack(MP4TrackId trackId)
{
	ProtectWriteOperation("MP4DeleteTrack");

	u_int32_t trakIndex = FindTrakAtomIndex(trackId);
	u_int16_t trackIndex = FindTrackIndex(trackId);
	MP4Track* pTrack = m_pTracks[trackIndex];

	MP4Atom* pTrakAtom = pTrack->GetTrakAtom();
	ASSERT(pTrakAtom);

	MP4Atom* pMoovAtom = FindAtom("moov");
	ASSERT(pMoovAtom);

	RemoveTrackFromIod(trackId, ShallHaveIods());
	RemoveTrackFromOd(trackId);

	if (trackId == m_odTrackId) {
		m_odTrackId = 0;
	}

	pMoovAtom->DeleteChildAtom(pTrakAtom);

	m_trakIds.Delete(trakIndex);

	m_pTracks.Delete(trackIndex);

	delete pTrack;
	delete pTrakAtom;
}

u_int32_t MP4File::GetNumberOfTracks(const char* type, u_int8_t subType)
{
	if (type == NULL) {
		return m_pTracks.Size();
	} 

	u_int32_t typeSeen = 0;
	const char* normType = MP4Track::NormalizeTrackType(type);

	for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
		if (!strcmp(normType, m_pTracks[i]->GetType())) {
			if (subType) {
				if (normType == MP4_AUDIO_TRACK_TYPE) {
					if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
						continue;
					}
				} else if (normType == MP4_VIDEO_TRACK_TYPE) {
					if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
						continue;
					}
				} 
				// else unknown subtype, ignore it
			}
			typeSeen++;
		}
	}
	return typeSeen;
}

MP4TrackId MP4File::AllocTrackId()
{
	MP4TrackId trackId = 
		GetIntegerProperty("moov.mvhd.nextTrackId");

	if (trackId <= 0xFFFF) {
		// check that nextTrackid is correct
		try {
			FindTrackIndex(trackId);
			// ERROR, this trackId is in use
		}
		catch (MP4Error* e) {
			// OK, this trackId is not in use, proceed
			delete e;
			SetIntegerProperty("moov.mvhd.nextTrackId", trackId + 1);
			return trackId;
		}
	}

	// we need to search for a track id
	for (trackId = 1; trackId <= 0xFFFF; trackId++) {
		try {
			FindTrackIndex(trackId);
			// KEEP LOOKING, this trackId is in use
		}
		catch (MP4Error* e) {
			// OK, this trackId is not in use, proceed
			delete e;
			return trackId;
		}
	}

	// extreme case where mp4 file has 2^16 tracks in it
	throw new MP4Error("too many existing tracks", "AddTrack");
	return MP4_INVALID_TRACK_ID;		// to keep MSVC happy
}

MP4TrackId MP4File::FindTrackId(u_int16_t trackIndex, 
				const char* type, u_int8_t subType)
{
  if (type == NULL) {
    return m_pTracks[trackIndex]->GetId();
  } 

  u_int32_t typeSeen = 0;
  const char* normType = MP4Track::NormalizeTrackType(type);

  for (u_int32_t i = 0; i < m_pTracks.Size(); i++) {
    if (!strcmp(normType, m_pTracks[i]->GetType())) {
      if (subType) {
	if (normType == MP4_AUDIO_TRACK_TYPE) {
	  if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
	    continue;
	  }
	} else if (normType == MP4_VIDEO_TRACK_TYPE) {
	  if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) {
	    continue;
	  }
	} 
	// else unknown subtype, ignore it
      }

      if (trackIndex == typeSeen) {
	return m_pTracks[i]->GetId();
      }

      typeSeen++;
    }
  }

  throw new MP4Error("Track index doesn't exist - track %d type %s", 
		     "FindTrackId", 
		     trackIndex, type); 
  return MP4_INVALID_TRACK_ID; // satisfy MS compiler
}

u_int16_t MP4File::FindTrackIndex(MP4TrackId trackId)
{
	for (u_int32_t i = 0; i < m_pTracks.Size() && i <= 0xFFFF; i++) {
		if (m_pTracks[i]->GetId() == trackId) {
			return (u_int16_t)i;
		}
	}
	
	throw new MP4Error("Track id %d doesn't exist", "FindTrackIndex", trackId); 
	return (u_int16_t)-1; // satisfy MS compiler
}

u_int16_t MP4File::FindTrakAtomIndex(MP4TrackId trackId)
{
	if (trackId) {
		for (u_int32_t i = 0; i < m_trakIds.Size(); i++) {
			if (m_trakIds[i] == trackId) {
				return i;
			}
		}
	}

	throw new MP4Error("Track id %d doesn't exist", "FindTrakAtomIndex",
			   trackId); 
	return (u_int16_t)-1; // satisfy MS compiler
}

u_int32_t MP4File::GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId)
{
	return m_pTracks[FindTrackIndex(trackId)]->GetSampleSize(sampleId);
}

u_int32_t MP4File::GetTrackMaxSampleSize(MP4TrackId trackId)
{
	return m_pTracks[FindTrackIndex(trackId)]->GetMaxSampleSize();
}

MP4SampleId MP4File::GetSampleIdFromTime(MP4TrackId trackId, 
	MP4Timestamp when, bool wantSyncSample)
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?