📄 mp4file.cpp
字号:
SetFixedSampleDuration(sampleDuration); return trackId;}MP4TrackId MP4File::AddEncVideoTrack(u_int32_t timeScale, MP4Duration sampleDuration, u_int16_t width, u_int16_t height, u_int8_t videoType, 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_VIDEO_TRACK_TYPE, timeScale); AddTrackToOd(trackId); SetTrackFloatProperty(trackId, "tkhd.width", width); SetTrackFloatProperty(trackId, "tkhd.height", height); InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0); AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "encv"); // 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 encv atom MP4Integer32Property* pStsdCountProperty; FindIntegerProperty( MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"), (MP4Property**)&pStsdCountProperty); pStsdCountProperty->IncrementValue(); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.width", width); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.height", height); /* set all the ismacryp-specific values */ // original format is mp4v original_fmt = ('m'<<24 | 'p'<<16 | '4'<<8 | 'v'); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.frma.data-format", original_fmt); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_type", scheme_type); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schm.scheme_version", scheme_version); SetTrackStringProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI", kms_uri); if (kms_uri != NULL) { free(kms_uri); } SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.selective-encryption", selective_enc); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.key-indicator-length", key_ind_len); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", iv_len); /* end ismacryp */ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.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.encv.esds.decConfigDescr.objectTypeId", videoType); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.encv.esds.decConfigDescr.streamType", MP4VisualStreamType); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsz.sampleSize", sampleDuration); m_pTracks[FindTrackIndex(trackId)]-> SetFixedSampleDuration(sampleDuration); return trackId;}void MP4File::SetH263Vendor( MP4TrackId trackId, u_int32_t vendor){ MP4Atom* d263Atom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263")); if (d263Atom == NULL) return; SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.vendor", vendor); d263Atom->Rewrite(); }void MP4File::SetH263DecoderVersion( MP4TrackId trackId, u_int8_t decoderVersion){ MP4Atom* d263Atom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263")); if (d263Atom == NULL) { return; } SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.decoderVersion", decoderVersion); d263Atom->Rewrite();}void MP4File::SetH263Bitrates( MP4TrackId trackId, u_int32_t avgBitrate, u_int32_t maxBitrate){ MP4Atom* bitrAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr")); if (bitrAtom == NULL) { VERBOSE_ERROR(m_verbosity, WARNING("Could not find bitr atom!")); return; } SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", avgBitrate); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate", maxBitrate); bitrAtom->Rewrite();}MP4TrackId MP4File::AddH263VideoTrack( u_int32_t timeScale, MP4Duration sampleDuration, u_int16_t width, u_int16_t height, u_int8_t h263Level, u_int8_t h263Profile, u_int32_t avgBitrate, u_int32_t maxBitrate){ MP4TrackId trackId = AddTrack(MP4_VIDEO_TRACK_TYPE, timeScale); AddTrackToOd(trackId); SetTrackFloatProperty(trackId, "tkhd.width", width); SetTrackFloatProperty(trackId, "tkhd.height", height); InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "vmhd", 0); AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "s263"); // 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 mp4v atom MP4Integer32Property* pStsdCountProperty; FindIntegerProperty( MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"), (MP4Property**)&pStsdCountProperty); pStsdCountProperty->IncrementValue(); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.width", width); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.height", height); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.h263Level", h263Level); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.h263Profile", h263Profile); // Add the bitr atom AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.s263.d263"), "bitr"); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", avgBitrate); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate", maxBitrate); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsz.sampleSize", sampleDuration); m_pTracks[FindTrackIndex(trackId)]-> SetFixedSampleDuration(sampleDuration); return trackId;}MP4TrackId MP4File::AddHintTrack(MP4TrackId refTrackId){ // validate reference track id FindTrackIndex(refTrackId); MP4TrackId trackId = AddTrack(MP4_HINT_TRACK_TYPE, GetTrackTimeScale(refTrackId)); InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "hmhd", 0); AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "rtp "); // 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 rtp atom MP4Integer32Property* pStsdCountProperty; FindIntegerProperty( MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"), (MP4Property**)&pStsdCountProperty); pStsdCountProperty->IncrementValue(); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.rtp .tims.timeScale", GetTrackTimeScale(trackId)); AddDescendantAtoms(MakeTrackName(trackId, NULL), "tref.hint"); AddTrackReference(MakeTrackName(trackId, "tref.hint"), refTrackId); AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hnti.sdp "); AddDescendantAtoms(MakeTrackName(trackId, NULL), "udta.hinf"); return trackId;}void MP4File::DeleteTrack(MP4TrackId trackId){ 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, ShallHaveIods()); 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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -