📄 mp4file.cpp
字号:
{ ProtectWriteOperation("MP4DeleteTrack"); u_int32_t trakIndex = FindTrakAtomIndex(trackId); u_int16_t trackIndex = FindTrackIndex(trackId); MP4Track* pTrack = m_pTracks[trackIndex]; MP4Atom* pTrakAtom = pTrack->GetTrakAtom(); ASSERT(pTrakAtom); MP4Atom* pMoovAtom = FindAtom("moov"); ASSERT(pMoovAtom); RemoveTrackFromIod(trackId); RemoveTrackFromOd(trackId); if (trackId == m_odTrackId) { m_odTrackId = 0; } pMoovAtom->DeleteChildAtom(pTrakAtom); m_trakIds.Delete(trakIndex); m_pTracks.Delete(trackIndex); delete pTrack; delete pTrakAtom;}u_int32_t MP4File::GetNumberOfTracks(const char* type, u_int8_t subType){ if (type == NULL) { return m_pTracks.Size(); } u_int32_t typeSeen = 0; const char* normType = MP4Track::NormalizeTrackType(type); for (u_int32_t i = 0; i < m_pTracks.Size(); i++) { if (!strcmp(normType, m_pTracks[i]->GetType())) { if (subType) { if (normType == MP4_AUDIO_TRACK_TYPE) { if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) { continue; } } else if (normType == MP4_VIDEO_TRACK_TYPE) { if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) { continue; } } // else unknown subtype, ignore it } typeSeen++; } } return typeSeen;}MP4TrackId MP4File::AllocTrackId(){ MP4TrackId trackId = GetIntegerProperty("moov.mvhd.nextTrackId"); if (trackId <= 0xFFFF) { // check that nextTrackid is correct try { FindTrackIndex(trackId); // ERROR, this trackId is in use } catch (MP4Error* e) { // OK, this trackId is not in use, proceed delete e; SetIntegerProperty("moov.mvhd.nextTrackId", trackId + 1); return trackId; } } // we need to search for a track id for (trackId = 1; trackId <= 0xFFFF; trackId++) { try { FindTrackIndex(trackId); // KEEP LOOKING, this trackId is in use } catch (MP4Error* e) { // OK, this trackId is not in use, proceed delete e; return trackId; } } // extreme case where mp4 file has 2^16 tracks in it throw new MP4Error("too many existing tracks", "AddTrack"); return MP4_INVALID_TRACK_ID; // to keep MSVC happy}MP4TrackId MP4File::FindTrackId(u_int16_t trackIndex, const char* type, u_int8_t subType){ if (type == NULL) { return m_pTracks[trackIndex]->GetId(); } u_int32_t typeSeen = 0; const char* normType = MP4Track::NormalizeTrackType(type); for (u_int32_t i = 0; i < m_pTracks.Size(); i++) { if (!strcmp(normType, m_pTracks[i]->GetType())) { if (subType) { if (normType == MP4_AUDIO_TRACK_TYPE) { if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) { continue; } } else if (normType == MP4_VIDEO_TRACK_TYPE) { if (subType != GetTrackEsdsObjectTypeId(m_pTracks[i]->GetId())) { continue; } } // else unknown subtype, ignore it } if (trackIndex == typeSeen) { return m_pTracks[i]->GetId(); } typeSeen++; } } throw new MP4Error("Track index doesn't exist - track %d type %s", "FindTrackId", trackIndex, type); return MP4_INVALID_TRACK_ID; // satisfy MS compiler}u_int16_t MP4File::FindTrackIndex(MP4TrackId trackId){ for (u_int32_t i = 0; i < m_pTracks.Size() && i <= 0xFFFF; i++) { if (m_pTracks[i]->GetId() == trackId) { return (u_int16_t)i; } } throw new MP4Error("Track id %d doesn't exist", "FindTrackIndex", trackId); return (u_int16_t)-1; // satisfy MS compiler}u_int16_t MP4File::FindTrakAtomIndex(MP4TrackId trackId){ if (trackId) { for (u_int32_t i = 0; i < m_trakIds.Size(); i++) { if (m_trakIds[i] == trackId) { return i; } } } throw new MP4Error("Track id %d doesn't exist", "FindTrakAtomIndex", trackId); return (u_int16_t)-1; // satisfy MS compiler}u_int32_t MP4File::GetSampleSize(MP4TrackId trackId, MP4SampleId sampleId){ return m_pTracks[FindTrackIndex(trackId)]->GetSampleSize(sampleId);}u_int32_t MP4File::GetTrackMaxSampleSize(MP4TrackId trackId){ return m_pTracks[FindTrackIndex(trackId)]->GetMaxSampleSize();}MP4SampleId MP4File::GetSampleIdFromTime(MP4TrackId trackId, MP4Timestamp when, bool wantSyncSample){ return m_pTracks[FindTrackIndex(trackId)]-> GetSampleIdFromTime(when, wantSyncSample);}MP4Timestamp MP4File::GetSampleTime( MP4TrackId trackId, MP4SampleId sampleId){ MP4Timestamp timestamp; m_pTracks[FindTrackIndex(trackId)]-> GetSampleTimes(sampleId, ×tamp, NULL); return timestamp;}MP4Duration MP4File::GetSampleDuration( MP4TrackId trackId, MP4SampleId sampleId){ MP4Duration duration; m_pTracks[FindTrackIndex(trackId)]-> GetSampleTimes(sampleId, NULL, &duration); return duration;}MP4Duration MP4File::GetSampleRenderingOffset( MP4TrackId trackId, MP4SampleId sampleId){ return m_pTracks[FindTrackIndex(trackId)]-> GetSampleRenderingOffset(sampleId);}bool MP4File::GetSampleSync(MP4TrackId trackId, MP4SampleId sampleId){ return m_pTracks[FindTrackIndex(trackId)]->IsSyncSample(sampleId);}void MP4File::ReadSample(MP4TrackId trackId, MP4SampleId sampleId, u_int8_t** ppBytes, u_int32_t* pNumBytes, MP4Timestamp* pStartTime, MP4Duration* pDuration, MP4Duration* pRenderingOffset, bool* pIsSyncSample){ m_pTracks[FindTrackIndex(trackId)]-> ReadSample(sampleId, ppBytes, pNumBytes, pStartTime, pDuration, pRenderingOffset, pIsSyncSample);}void MP4File::WriteSample(MP4TrackId trackId, const u_int8_t* pBytes, u_int32_t numBytes, MP4Duration duration, MP4Duration renderingOffset, bool isSyncSample){ ProtectWriteOperation("MP4WriteSample"); m_pTracks[FindTrackIndex(trackId)]-> WriteSample(pBytes, numBytes, duration, renderingOffset, isSyncSample); m_pModificationProperty->SetValue(MP4GetAbsTimestamp());}void MP4File::SetSampleRenderingOffset(MP4TrackId trackId, MP4SampleId sampleId, MP4Duration renderingOffset){ ProtectWriteOperation("MP4SetSampleRenderingOffset"); m_pTracks[FindTrackIndex(trackId)]-> SetSampleRenderingOffset(sampleId, renderingOffset); m_pModificationProperty->SetValue(MP4GetAbsTimestamp());}char* MP4File::MakeTrackName(MP4TrackId trackId, const char* name){ u_int16_t trakIndex = FindTrakAtomIndex(trackId); static char trakName[1024]; if (name == NULL || name[0] == '\0') { snprintf(trakName, sizeof(trakName), "moov.trak[%u]", trakIndex); } else { snprintf(trakName, sizeof(trakName), "moov.trak[%u].%s", trakIndex, name); } return trakName;}u_int64_t MP4File::GetTrackIntegerProperty(MP4TrackId trackId, const char* name){ return GetIntegerProperty(MakeTrackName(trackId, name));}void MP4File::SetTrackIntegerProperty(MP4TrackId trackId, const char* name, int64_t value){ SetIntegerProperty(MakeTrackName(trackId, name), value);}float MP4File::GetTrackFloatProperty(MP4TrackId trackId, const char* name){ return GetFloatProperty(MakeTrackName(trackId, name));}void MP4File::SetTrackFloatProperty(MP4TrackId trackId, const char* name, float value){ SetFloatProperty(MakeTrackName(trackId, name), value);}const char* MP4File::GetTrackStringProperty(MP4TrackId trackId, const char* name){ return GetStringProperty(MakeTrackName(trackId, name));}void MP4File::SetTrackStringProperty(MP4TrackId trackId, const char* name, const char* value){ SetStringProperty(MakeTrackName(trackId, name), value);}void MP4File::GetTrackBytesProperty(MP4TrackId trackId, const char* name, u_int8_t** ppValue, u_int32_t* pValueSize){ GetBytesProperty(MakeTrackName(trackId, name), ppValue, pValueSize);}void MP4File::SetTrackBytesProperty(MP4TrackId trackId, const char* name, const u_int8_t* pValue, u_int32_t valueSize){ SetBytesProperty(MakeTrackName(trackId, name), pValue, valueSize);}// file level convenience functionsMP4Duration MP4File::GetDuration(){ return m_pDurationProperty->GetValue();}void MP4File::SetDuration(MP4Duration value){ m_pDurationProperty->SetValue(value);}u_int32_t MP4File::GetTimeScale(){ return m_pTimeScaleProperty->GetValue();}void MP4File::SetTimeScale(u_int32_t value){ if (value == 0) { throw new MP4Error("invalid value", "SetTimeScale"); } m_pTimeScaleProperty->SetValue(value);}u_int8_t MP4File::GetODProfileLevel(){ return GetIntegerProperty("moov.iods.ODProfileLevelId");}void MP4File::SetODProfileLevel(u_int8_t value){ SetIntegerProperty("moov.iods.ODProfileLevelId", value);}u_int8_t MP4File::GetSceneProfileLevel(){ return GetIntegerProperty("moov.iods.sceneProfileLevelId");}void MP4File::SetSceneProfileLevel(u_int8_t value){ SetIntegerProperty("moov.iods.sceneProfileLevelId", value);}u_int8_t MP4File::GetVideoProfileLevel(){ return GetIntegerProperty("moov.iods.visualProfileLevelId");}void MP4File::SetVideoProfileLevel(u_int8_t value){ SetIntegerProperty("moov.iods.visualProfileLevelId", value);}u_int8_t MP4File::GetAudioProfileLevel(){ return GetIntegerProperty("moov.iods.audioProfileLevelId");}void MP4File::SetAudioProfileLevel(u_int8_t value){ SetIntegerProperty("moov.iods.audioProfileLevelId", value);}u_int8_t MP4File::GetGraphicsProfileLevel(){ return GetIntegerProperty("moov.iods.graphicsProfileLevelId");}void MP4File::SetGraphicsProfileLevel(u_int8_t value){ SetIntegerProperty("moov.iods.graphicsProfileLevelId", value);}const char* MP4File::GetSessionSdp(){ return GetStringProperty("moov.udta.hnti.rtp .sdpText");}void MP4File::SetSessionSdp(const char* sdpString){ AddDescendantAtoms("moov", "udta.hnti.rtp "); SetStringProperty("moov.udta.hnti.rtp .sdpText", sdpString);}void MP4File::AppendSessionSdp(const char* sdpFragment){ const char* oldSdpString = NULL; try { oldSdpString = GetSessionSdp(); } catch (MP4Error* e) { delete e; SetSessionSdp(sdpFragment); return; } char* newSdpString = (char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1); strcpy(newSdpString, oldSdpString); strcat(newSdpString, sdpFragment); SetSessionSdp(newSdpString); MP4Free(newSdpString);}// track level convenience functionsMP4SampleId MP4File::GetTrackNumberOfSamples(MP4TrackId trackId){ return m_pTracks[FindTrackIndex(trackId)]->GetNumberOfSamples();}const char* MP4File::GetTrackType(MP4TrackId trackId){ return m_pTracks[FindTrackIndex(trackId)]->GetType();}u_int32_t MP4File::GetTrackTimeScale(MP4TrackId trackId){ return m_pTracks[FindTrackIndex(trackId)]->GetTimeScale();}void MP4File::SetTrackTimeScale(MP4TrackId trackId, u_int32_t value){ if (value == 0) { throw new MP4Error("invalid value", "SetTrackTimeScale"); } SetTrackIntegerProperty(trackId, "mdia.mdhd.timeScale", value);}MP4Duration MP4File::GetTrackDuration(MP4TrackId trackId){ return GetTrackIntegerProperty(trackId, "mdia.mdhd.duration");}// now GetTrackEsdsObjectTypeIdu_int8_t MP4File::GetTrackAudioType(MP4TrackId trackId){ return GetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.objectTypeId");}u_int8_t MP4File::GetTrackEsdsObjectTypeId(MP4TrackId trackId){ // changed mp4a to * to handle enca case return GetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.*.esds.decConfigDescr.objectTypeId");}u_int8_t MP4File::GetTrackAudioMpeg4Type(MP4TrackId trackId){ // verify that track is an MPEG-4 audio track if (GetTrackEsdsObjectTypeId(trackId) != MP4_MPEG4_AUDIO_TYPE) { return MP4_MPEG4_INVALID_AUDIO_TYPE; } u_int8_t* pEsConfig = NULL; u_int32_t esConfigSize; // The Mpeg4 audio type (AAC, CELP, HXVC, ...)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -