mp4file.cpp

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

CPP
2,476
字号
{
	char propName[1024];

	snprintf(propName, sizeof(propName), "%s.%s", trefName, "entryCount");
	m_pRootAtom->FindProperty(propName, ppCountProperty);
	ASSERT(*ppCountProperty);

	snprintf(propName, sizeof(propName), "%s.%s", trefName, "entries.trackId");
	m_pRootAtom->FindProperty(propName, ppTrackIdProperty);
	ASSERT(*ppTrackIdProperty);
}

void MP4File::AddTrackReference(const char* trefName, MP4TrackId refTrackId)
{
	MP4Integer32Property* pCountProperty = NULL;
	MP4Integer32Property* pTrackIdProperty = NULL;

	GetTrackReferenceProperties(trefName,
		(MP4Property**)&pCountProperty, 
		(MP4Property**)&pTrackIdProperty);

	pTrackIdProperty->AddValue(refTrackId);
	pCountProperty->IncrementValue();
}

u_int32_t MP4File::FindTrackReference(const char* trefName, 
	MP4TrackId refTrackId)
{
	MP4Integer32Property* pCountProperty = NULL;
	MP4Integer32Property* pTrackIdProperty = NULL;

	GetTrackReferenceProperties(trefName, 
		(MP4Property**)&pCountProperty, 
		(MP4Property**)&pTrackIdProperty);

	for (u_int32_t i = 0; i < pCountProperty->GetValue(); i++) {
		if (refTrackId == pTrackIdProperty->GetValue(i)) {
			return i + 1;	// N.B. 1 not 0 based index
		}
	}
	return 0;
}

void MP4File::RemoveTrackReference(const char* trefName, MP4TrackId refTrackId)
{
	MP4Integer32Property* pCountProperty = NULL;
	MP4Integer32Property* pTrackIdProperty = NULL;

	GetTrackReferenceProperties(trefName,
		(MP4Property**)&pCountProperty, 
		(MP4Property**)&pTrackIdProperty);

	for (u_int32_t i = 0; i < pCountProperty->GetValue(); i++) {
		if (refTrackId == pTrackIdProperty->GetValue(i)) {
			pTrackIdProperty->DeleteValue(i);
			pCountProperty->IncrementValue(-1);
		}
	}
}

void MP4File::AddDataReference(MP4TrackId trackId, const char* url)
{
	MP4Atom* pDrefAtom = 
		FindAtom(MakeTrackName(trackId, "mdia.minf.dinf.dref"));
	ASSERT(pDrefAtom);

	MP4Integer32Property* pCountProperty = NULL;
	pDrefAtom->FindProperty("dref.entryCount", 
		(MP4Property**)&pCountProperty);
	ASSERT(pCountProperty);
	pCountProperty->IncrementValue();

	MP4Atom* pUrlAtom = AddChildAtom(pDrefAtom, "url ");

	if (url && url[0] != '\0') {
		pUrlAtom->SetFlags(pUrlAtom->GetFlags() & 0xFFFFFE);

		MP4StringProperty* pUrlProperty = NULL;
		pUrlAtom->FindProperty("url .location",
			(MP4Property**)&pUrlProperty);
		ASSERT(pUrlProperty);
		pUrlProperty->SetValue(url);
	} else {
		pUrlAtom->SetFlags(pUrlAtom->GetFlags() | 1);
	}
}

MP4TrackId MP4File::AddSystemsTrack(const char* type)
{
	const char* normType = MP4Track::NormalizeTrackType(type); 

	// TBD if user type, fix name to four chars, and warn

	MP4TrackId trackId = AddTrack(type, MP4_MSECS_TIME_SCALE);

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

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

	// 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 mp4s atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
		MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();

	SetTrackIntegerProperty(trackId, 
				"mdia.minf.stbl.stsd.mp4s.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.mp4s.esds.decConfigDescr.objectTypeId", 
		MP4SystemsV1ObjectType);

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.streamType", 
		ConvertTrackTypeToStreamType(normType));

	return trackId;
}

MP4TrackId MP4File::AddODTrack()
{
	// until a demonstrated need emerges
	// we limit ourselves to one object description track
	if (m_odTrackId != MP4_INVALID_TRACK_ID) {
		throw new MP4Error("object description track already exists",
			"AddObjectDescriptionTrack");
	}

	m_odTrackId = AddSystemsTrack(MP4_OD_TRACK_TYPE);

	AddTrackToIod(m_odTrackId);

	AddDescendantAtoms(MakeTrackName(m_odTrackId, NULL), "tref.mpod");

	return m_odTrackId;
}

MP4TrackId MP4File::AddSceneTrack()
{
	MP4TrackId trackId = AddSystemsTrack(MP4_SCENE_TRACK_TYPE);

	AddTrackToIod(trackId);
	AddTrackToOd(trackId);

	return trackId;
}

MP4Atom* MP4File::GetTrakDamrAtom(MP4TrackId trackId)
{
	MP4Atom* amrAtom;
	u_int16_t trackIndex = FindTrackIndex(trackId);
	MP4Track* pTrack = m_pTracks[trackIndex];
	ASSERT(pTrack);
	MP4Atom* pTrakAtom = pTrack->GetTrakAtom();
	ASSERT(pTrakAtom);
	if ((amrAtom = pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd.sawb.damr"))) {
		return amrAtom;
	}
	else if ((amrAtom = pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd.samr.damr"))) {
		return amrAtom;
	}
	return NULL;
}
// NULL terminated list of brands which require the IODS atom
char *brandsWithIods[] = { "mp42",
                           "isom",
                           NULL};

bool MP4File::ShallHaveIods()
{
	u_int32_t compatibleBrandsCount;
        MP4StringProperty *pMajorBrandProperty;
	
	MP4Atom* ftypAtom = m_pRootAtom->FindAtom("ftyp");
	ASSERT(ftypAtom);
	
        // Check the major brand
	ftypAtom->FindProperty(
			"ftyp.majorBrand",
			(MP4Property**)&pMajorBrandProperty);
	ASSERT(pMajorBrandProperty);
        for(u_int32_t j = 0 ; brandsWithIods[j] != NULL ; j++) {
                if (!strcasecmp( ((MP4StringProperty*)pMajorBrandProperty)->GetValue(),
                                 brandsWithIods[j]))
                        return true;
        }

        // Check the compatible brands
	MP4Integer32Property* pCompatibleBrandsCountProperty;
	ftypAtom->FindProperty(
			"ftyp.compatibleBrandsCount",
			(MP4Property**)&pCompatibleBrandsCountProperty);
	ASSERT(pCompatibleBrandsCountProperty);
	
	compatibleBrandsCount  = pCompatibleBrandsCountProperty->GetValue();
	
	MP4TableProperty* pCompatibleBrandsProperty;
	ftypAtom->FindProperty(
			"ftyp.compatibleBrands",
			(MP4Property**)&pCompatibleBrandsProperty);
	
	MP4StringProperty* pBrandProperty = (MP4StringProperty*)pCompatibleBrandsProperty->GetProperty(0);
	ASSERT(pBrandProperty);

        for(u_int32_t i = 0 ; i < compatibleBrandsCount ; i++) {
                for(u_int32_t j = 0 ; brandsWithIods[j] != NULL ; j++) {
                        if (!strcasecmp(pBrandProperty->GetValue(i), brandsWithIods[j]))
                                return true;
                }
        }

	return false;
}

void MP4File::SetAmrVendor(
		MP4TrackId trackId,
		u_int32_t vendor)
{
	
	MP4Atom* damrAtom = GetTrakDamrAtom(trackId);
	
	if (damrAtom == NULL)
		return;
	
	MP4Integer32Property* pVendorProperty = NULL;
	
	damrAtom->FindProperty("damr.vendor",
			(MP4Property**)&pVendorProperty,
			NULL);
	ASSERT(pVendorProperty);
	
	pVendorProperty->SetValue(vendor);
	
	damrAtom->Rewrite();
	
}

void MP4File::SetAmrDecoderVersion(
		MP4TrackId trackId,
		u_int8_t decoderVersion)
{
	MP4Atom* damrAtom = GetTrakDamrAtom(trackId);
	
	if (damrAtom == NULL)
		return;
	
	MP4Integer8Property* pDecoderVersionProperty;
	
	damrAtom->FindProperty("damr.decoderVersion",
			(MP4Property**)&pDecoderVersionProperty,
			NULL);
	ASSERT(pDecoderVersionProperty);
	
	pDecoderVersionProperty->SetValue(decoderVersion);
	
	damrAtom->Rewrite();
}

void MP4File::SetAmrModeSet(
		MP4TrackId trackId,
		u_int16_t modeSet)
{
	MP4Atom* damrAtom = GetTrakDamrAtom(trackId);
	
	if (damrAtom == NULL)
		return;
	
	MP4Integer16Property* pModeSetProperty;
	
	damrAtom->FindProperty("damr.modeSet",
			(MP4Property**)&pModeSetProperty,
			NULL);
	ASSERT(pModeSetProperty);
	
	pModeSetProperty->SetValue(modeSet);
	
	damrAtom->Rewrite();
	
}

MP4TrackId MP4File::AddAmrAudioTrack(
		        u_int32_t timeScale,
			u_int16_t modeSet,
			u_int8_t modeChangePeriod,
			u_int8_t framesPerSample,
			bool isAmrWB)
{
	
	u_int32_t fixedSampleDuration = (timeScale * 20)/1000; // 20mSec/Sample
	
	MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);
	
	AddTrackToOd(trackId);
	
	SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);
	
	InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);
	
	AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), isAmrWB ? "sawb" : "samr");
	
	// 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 mp4a atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
			MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
			(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();
	
	if (isAmrWB) {
		SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.sawb.timeScale", timeScale);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.sawb.damr.modeSet", modeSet);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.sawb.damr.modeChangePeriod", modeChangePeriod);
	
	SetTrackIntegerProperty(trackId,
			"mdia.minf.stbl.stsd.sawb.damr.framesPerSample", framesPerSample);
	
	m_pTracks[FindTrackIndex(trackId)]->
		SetFixedSampleDuration(fixedSampleDuration);
	
	} else {
		SetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.samr.timeScale", timeScale);
		
		SetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.samr.damr.modeSet", modeSet);
		
		SetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.samr.damr.modeChangePeriod", modeChangePeriod);
		
		SetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.samr.damr.framesPerSample", framesPerSample);
	}
	
	m_pTracks[FindTrackIndex(trackId)]->
		SetFixedSampleDuration(fixedSampleDuration);

	return trackId;
}

MP4TrackId MP4File::AddAudioTrack(
	u_int32_t timeScale, 
	MP4Duration sampleDuration, 
	u_int8_t audioType)
{
	MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);

	AddTrackToOd(trackId);

	SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

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

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

	// 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 mp4a atom
	MP4Integer32Property* pStsdCountProperty;
	FindIntegerProperty(
		MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		(MP4Property**)&pStsdCountProperty);
	pStsdCountProperty->IncrementValue();

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4a.timeScale", timeScale);

	SetTrackIntegerProperty(trackId, 
				"mdia.minf.stbl.stsd.mp4a.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.mp4a.esds.decConfigDescr.objectTypeId", 
		audioType);

	SetTrackIntegerProperty(trackId, 
		"mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.streamType", 
		MP4AudioStreamType);

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

	return trackId;
}

MP4TrackId MP4File::AddEncAudioTrack(u_int32_t timeScale, 
				     MP4Duration sampleDuration, 
				     u_int8_t audioType,
				     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_AUDIO_TRACK_TYPE, timeScale);

  AddTrackToOd(trackId);

  SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);

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

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

  // 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 enca atom
  MP4Integer32Property* pStsdCountProperty;
  FindIntegerProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
		      (MP4Property**)&pStsdCountProperty);
  pStsdCountProperty->IncrementValue();


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

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

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

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

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

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

  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.enca.timeScale", timeScale);

  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.enca.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.enca.esds.decConfigDescr.objectTypeId", 
			  audioType);

  SetTrackIntegerProperty(trackId, 
			  "mdia.minf.stbl.stsd.enca.esds.decConfigDescr.streamType", 
			  MP4AudioStreamType);

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

⌨️ 快捷键说明

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