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 + -
显示快捷键?