📄 mp4file.cpp
字号:
}MP4Track* MP4File::GetTrack(MP4TrackId trackId){ return m_pTracks[FindTrackIndex(trackId)];}MP4Atom* MP4File::FindAtom(const char* name){ MP4Atom* pAtom = NULL; if (!name || !strcmp(name, "")) { pAtom = m_pRootAtom; } else { pAtom = m_pRootAtom->FindAtom(name); } return pAtom;}MP4Atom* MP4File::AddChildAtom( const char* parentName, const char* childName){ return AddChildAtom(FindAtom(parentName), childName);}MP4Atom* MP4File::AddChildAtom( MP4Atom* pParentAtom, const char* childName){ return InsertChildAtom(pParentAtom, childName, pParentAtom->GetNumberOfChildAtoms());}MP4Atom* MP4File::InsertChildAtom( const char* parentName, const char* childName, u_int32_t index){ return InsertChildAtom(FindAtom(parentName), childName, index); }MP4Atom* MP4File::InsertChildAtom( MP4Atom* pParentAtom, const char* childName, u_int32_t index){ MP4Atom* pChildAtom = MP4Atom::CreateAtom(childName); ASSERT(pParentAtom); pParentAtom->InsertChildAtom(pChildAtom, index); pChildAtom->Generate(); return pChildAtom;}MP4Atom* MP4File::AddDescendantAtoms( const char* ancestorName, const char* descendantNames){ return AddDescendantAtoms(FindAtom(ancestorName), descendantNames);}MP4Atom* MP4File::AddDescendantAtoms( MP4Atom* pAncestorAtom, const char* descendantNames){ ASSERT(pAncestorAtom); MP4Atom* pParentAtom = pAncestorAtom; MP4Atom* pChildAtom = NULL; while (true) { char* childName = MP4NameFirst(descendantNames); if (childName == NULL) { break; } descendantNames = MP4NameAfterFirst(descendantNames); pChildAtom = pParentAtom->FindChildAtom(childName); if (pChildAtom == NULL) { pChildAtom = AddChildAtom(pParentAtom, childName); } pParentAtom = pChildAtom; MP4Free(childName); } return pChildAtom;}bool MP4File::FindProperty(const char* name, MP4Property** ppProperty, u_int32_t* pIndex){ if (pIndex) { *pIndex = 0; // set the default answer for index } return m_pRootAtom->FindProperty(name, ppProperty, pIndex);}void MP4File::FindIntegerProperty(const char* name, MP4Property** ppProperty, u_int32_t* pIndex){ if (!FindProperty(name, ppProperty, pIndex)) { throw new MP4Error("no such property - %s", "MP4File::FindIntegerProperty", name); } switch ((*ppProperty)->GetType()) { case Integer8Property: case Integer16Property: case Integer24Property: case Integer32Property: case Integer64Property: break; default: throw new MP4Error("type mismatch - property %s type %d", "MP4File::FindIntegerProperty", name, (*ppProperty)->GetType()); }}u_int64_t MP4File::GetIntegerProperty(const char* name){ MP4Property* pProperty; u_int32_t index; FindIntegerProperty(name, &pProperty, &index); return ((MP4IntegerProperty*)pProperty)->GetValue(index);}void MP4File::SetIntegerProperty(const char* name, u_int64_t value){ ProtectWriteOperation("SetIntegerProperty"); MP4Property* pProperty = NULL; u_int32_t index = 0; FindIntegerProperty(name, &pProperty, &index); ((MP4IntegerProperty*)pProperty)->SetValue(value, index);}void MP4File::FindFloatProperty(const char* name, MP4Property** ppProperty, u_int32_t* pIndex){ if (!FindProperty(name, ppProperty, pIndex)) { throw new MP4Error("no such property - %s", "MP4File::FindFloatProperty", name); } if ((*ppProperty)->GetType() != Float32Property) { throw new MP4Error("type mismatch - property %s type %d", "MP4File::FindFloatProperty", name, (*ppProperty)->GetType()); }}float MP4File::GetFloatProperty(const char* name){ MP4Property* pProperty; u_int32_t index; FindFloatProperty(name, &pProperty, &index); return ((MP4Float32Property*)pProperty)->GetValue(index);}void MP4File::SetFloatProperty(const char* name, float value){ ProtectWriteOperation("SetFloatProperty"); MP4Property* pProperty; u_int32_t index; FindFloatProperty(name, &pProperty, &index); ((MP4Float32Property*)pProperty)->SetValue(value, index);}void MP4File::FindStringProperty(const char* name, MP4Property** ppProperty, u_int32_t* pIndex){ if (!FindProperty(name, ppProperty, pIndex)) { throw new MP4Error("no such property - %s", "MP4File::FindStringProperty", name); } if ((*ppProperty)->GetType() != StringProperty) { throw new MP4Error("type mismatch - property %s type %d", "MP4File::FindStringProperty", name, (*ppProperty)->GetType()); }}const char* MP4File::GetStringProperty(const char* name){ MP4Property* pProperty; u_int32_t index; FindStringProperty(name, &pProperty, &index); return ((MP4StringProperty*)pProperty)->GetValue(index);}void MP4File::SetStringProperty(const char* name, const char* value){ ProtectWriteOperation("SetStringProperty"); MP4Property* pProperty; u_int32_t index; FindStringProperty(name, &pProperty, &index); ((MP4StringProperty*)pProperty)->SetValue(value, index);}void MP4File::FindBytesProperty(const char* name, MP4Property** ppProperty, u_int32_t* pIndex){ if (!FindProperty(name, ppProperty, pIndex)) { throw new MP4Error("no such property %s", "MP4File::FindBytesProperty", name); } if ((*ppProperty)->GetType() != BytesProperty) { throw new MP4Error("type mismatch - property %s - type %d", "MP4File::FindBytesProperty", name, (*ppProperty)->GetType()); }}void MP4File::GetBytesProperty(const char* name, u_int8_t** ppValue, u_int32_t* pValueSize){ MP4Property* pProperty; u_int32_t index; FindBytesProperty(name, &pProperty, &index); ((MP4BytesProperty*)pProperty)->GetValue(ppValue, pValueSize, index);}void MP4File::SetBytesProperty(const char* name, const u_int8_t* pValue, u_int32_t valueSize){ ProtectWriteOperation("SetBytesProperty"); MP4Property* pProperty; u_int32_t index; FindBytesProperty(name, &pProperty, &index); ((MP4BytesProperty*)pProperty)->SetValue(pValue, valueSize, index);}// track functionsMP4TrackId MP4File::AddTrack(const char* type, u_int32_t timeScale){ ProtectWriteOperation("AddTrack"); // create and add new trak atom MP4Atom* pTrakAtom = AddChildAtom("moov", "trak"); // allocate a new track id MP4TrackId trackId = AllocTrackId(); m_trakIds.Add(trackId); // set track id MP4Integer32Property* pInteger32Property = NULL; pTrakAtom->FindProperty( "trak.tkhd.trackId", (MP4Property**)&pInteger32Property); ASSERT(pInteger32Property); pInteger32Property->SetValue(trackId); // set track type const char* normType = MP4Track::NormalizeTrackType(type); // sanity check for user defined types if (strlen(normType) > 4) { VERBOSE_WARNING(m_verbosity, printf("AddTrack: type truncated to four characters\n")); // StringProperty::SetValue() will do the actual truncation } MP4StringProperty* pStringProperty = NULL; pTrakAtom->FindProperty( "trak.mdia.hdlr.handlerType", (MP4Property**)&pStringProperty); ASSERT(pStringProperty); pStringProperty->SetValue(normType); // set track time scale pInteger32Property = NULL; 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; m_pRootAtom->FindProperty("moov.iods.esIds", (MP4Property**)&pDescriptorProperty); ASSERT(pDescriptorProperty); MP4Descriptor* pDescriptor = pDescriptorProperty->AddDescriptor(MP4ESIDIncDescrTag); ASSERT(pDescriptor); MP4Integer32Property* pIdProperty = NULL; pDescriptor->FindProperty("id", (MP4Property**)&pIdProperty); ASSERT(pIdProperty); pIdProperty->SetValue(trackId);}void MP4File::RemoveTrackFromIod(MP4TrackId trackId){ MP4DescriptorProperty* pDescriptorProperty = NULL; m_pRootAtom->FindProperty("moov.iods.esIds", (MP4Property**)&pDescriptorProperty); ASSERT(pDescriptorProperty); 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; pDescriptorProperty->FindProperty(name, (MP4Property**)&pIdProperty); ASSERT(pIdProperty); if (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"); 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", trackId); 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;}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", trackId); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -