📄 mp4file.cpp
字号:
ASSERT(pStringProperty); pStringProperty->SetValue(normType); // set track time scale pInteger32Property = NULL; (void)pTrakAtom->FindProperty("trak.mdia.mdhd.timeScale", (MP4Property**)&pInteger32Property); ASSERT(pInteger32Property); pInteger32Property->SetValue(timeScale ? timeScale : 1000); // now have enough to create MP4Track object MP4Track* pTrack = NULL; if (!strcmp(normType, MP4_HINT_TRACK_TYPE)) { pTrack = new MP4RtpHintTrack(this, pTrakAtom); } else { pTrack = new MP4Track(this, pTrakAtom); } m_pTracks.Add(pTrack); // mark non-hint tracks as enabled if (strcmp(normType, MP4_HINT_TRACK_TYPE)) { SetTrackIntegerProperty(trackId, "tkhd.flags", 1); } // mark track as contained in this file // LATER will provide option for external data references AddDataReference(trackId, NULL); return trackId;}void MP4File::AddTrackToIod(MP4TrackId trackId){ MP4DescriptorProperty* pDescriptorProperty = NULL; (void)m_pRootAtom->FindProperty("moov.iods.esIds", (MP4Property**)&pDescriptorProperty); ASSERT(pDescriptorProperty); MP4Descriptor* pDescriptor = pDescriptorProperty->AddDescriptor(MP4ESIDIncDescrTag); ASSERT(pDescriptor); MP4Integer32Property* pIdProperty = NULL; (void)pDescriptor->FindProperty("id", (MP4Property**)&pIdProperty); ASSERT(pIdProperty); pIdProperty->SetValue(trackId);} void MP4File::RemoveTrackFromIod(MP4TrackId trackId, bool shallHaveIods){ MP4DescriptorProperty* pDescriptorProperty = NULL; if (!m_pRootAtom->FindProperty("moov.iods.esIds", (MP4Property**)&pDescriptorProperty)) return;#if 0 // we may not have iods if (shallHaveIods) { ASSERT(pDescriptorProperty); } else { if (!pDescriptorProperty) { return; } }#else if (pDescriptorProperty == NULL) { return; }#endif for (u_int32_t i = 0; i < pDescriptorProperty->GetCount(); i++) { /* static */char name[32]; snprintf(name, sizeof(name), "esIds[%u].id", i); MP4Integer32Property* pIdProperty = NULL; (void)pDescriptorProperty->FindProperty(name, (MP4Property**)&pIdProperty); // wmay ASSERT(pIdProperty); if (pIdProperty != NULL && pIdProperty->GetValue() == trackId) { pDescriptorProperty->DeleteDescriptor(i); break; } }}void MP4File::AddTrackToOd(MP4TrackId trackId){ if (!m_odTrackId) { return; } AddTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);}void MP4File::RemoveTrackFromOd(MP4TrackId trackId){ if (!m_odTrackId) { return; } RemoveTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);}void MP4File::GetTrackReferenceProperties(const char* trefName, MP4Property** ppCountProperty, MP4Property** ppTrackIdProperty){ char propName[1024]; snprintf(propName, sizeof(propName), "%s.%s", trefName, "entryCount"); (void)m_pRootAtom->FindProperty(propName, ppCountProperty); ASSERT(*ppCountProperty); snprintf(propName, sizeof(propName), "%s.%s", trefName, "entries.trackId"); (void)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; (void)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; (void)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 = MP4NormalizeTrackType(type, m_verbosity); // TBD if user type, fix name to four chars, and warn MP4TrackId trackId = AddTrack(type, MP4_MSECS_TIME_SCALE); (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0); (void)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); (void)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;}// NULL terminated list of brands which require the IODS atomchar *brandsWithIods[] = { "mp42", "isom", NULL};bool MP4File::ShallHaveIods(){ u_int32_t compatibleBrandsCount; MP4StringProperty *pMajorBrandProperty; MP4Atom* ftypAtom = m_pRootAtom->FindAtom("ftyp"); if (ftypAtom == NULL) return false; // Check the major brand (void)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; (void)ftypAtom->FindProperty( "ftyp.compatibleBrandsCount", (MP4Property**)&pCompatibleBrandsCountProperty); ASSERT(pCompatibleBrandsCountProperty); compatibleBrandsCount = pCompatibleBrandsCountProperty->GetValue(); MP4TableProperty* pCompatibleBrandsProperty; (void)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){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.vendor", vendor);}void MP4File::SetAmrDecoderVersion( MP4TrackId trackId, u_int8_t decoderVersion){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.decoderVersion", decoderVersion);}void MP4File::SetAmrModeSet( MP4TrackId trackId, u_int16_t modeSet){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.modeSet", modeSet);}uint16_t MP4File::GetAmrModeSet(MP4TrackId trackId){ return GetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.modeSet");}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); (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0); (void)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(); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.timeScale", timeScale); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.modeSet", modeSet); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.damr.modeChangePeriod", modeChangePeriod); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.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); (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0); (void)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, const char *kms_uri, bool use_ismacryp ){ u_int32_t original_fmt = 0; MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale); AddTrackToOd(trackId); SetTrackFloatProperty(trackId, "tkhd.volume", 1.0); (void)InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0); (void)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 if (use_ismacryp) { original_fmt = ATOMID("mp4a"); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.enca.sinf.frma.data-format", original_fmt); (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf"), "schm"); (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf"), "schi"); (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf.schi"), "iKMS"); (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.enca.sinf.schi"), "iSFM"); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.enca.sinf.schm.scheme_type", scheme_type); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.enca.sinf.schm.scheme_version",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -