📄 mp4file.cpp
字号:
ASSERT(pFreeAtom); pFreeAtom->SetFile(this); int64_t size = m_orgFileSize - (m_fileSize + 8); if (size < 0) size = 0; pFreeAtom->SetSize(size); pFreeAtom->Write(); delete pFreeAtom; }}MP4Duration MP4File::UpdateDuration(MP4Duration duration){ MP4Duration currentDuration = GetDuration(); if (duration > currentDuration) { SetDuration(duration); return duration; } return currentDuration;}void MP4File::Dump(FILE* pDumpFile, bool dumpImplicits){ if (pDumpFile == NULL) { pDumpFile = stdout; } fprintf(pDumpFile, "Dumping %s meta-information...\n", m_fileName); m_pRootAtom->Dump(pDumpFile, 0, dumpImplicits);}void MP4File::Close(){ if (m_mode == 'w') { SetIntegerProperty("moov.mvhd.modificationTime", MP4GetAbsTimestamp()); FinishWrite(); } fclose(m_pFile); m_pFile = NULL;}const char* MP4File::TempFileName(){ // there are so many attempts in libc to get this right // that for portablity reasons, it's best just to roll our own#ifndef _WIN32 static char tempFileName[64]; u_int32_t i; for (i = getpid(); i < 0xFFFFFFFF; i++) { sprintf(tempFileName, "./tmp%u.mp4", i); if (access(tempFileName, F_OK) != 0) { break; } } if (i == 0xFFFFFFFF) { throw new MP4Error("can't create temporary file", "TempFileName"); }#else static char tempFileName[MAX_PATH + 3]; GetTempFileName(".", // dir. for temp. files "mp4", // temp. filename prefix 0, // create unique name tempFileName); // buffer for name #endif return tempFileName;}void MP4File::Rename(const char* oldFileName, const char* newFileName){ int rc;#ifdef _WIN32 rc = remove(newFileName); if (rc == 0) { rc = rename(oldFileName, newFileName); }#else rc = rename(oldFileName, newFileName);#endif if (rc != 0) { throw new MP4Error(errno, "can't overwrite existing file", "Rename"); }}void MP4File::ProtectWriteOperation(char* where){ if (m_mode == 'r') { throw new MP4Error("operation not permitted in read mode", where); }}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, bool shallHaveIods){ MP4DescriptorProperty* pDescriptorProperty = NULL; m_pRootAtom->FindProperty("moov.iods.esIds", (MP4Property**)&pDescriptorProperty); if (shallHaveIods) { ASSERT(pDescriptorProperty); } else { if (!pDescriptorProperty) { return; } } 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -