📄 mp4file.cpp
字号:
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); 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 */ if (kms_uri != NULL) { free(kms_uri); } 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); return trackId;}MP4TrackId MP4File::AddH264VideoTrack( u_int32_t timeScale, MP4Duration sampleDuration, u_int16_t width, u_int16_t height, uint8_t AVCProfileIndication, uint8_t profile_compat, uint8_t AVCLevelIndication, uint8_t sampleLenFieldSizeMinusOne){ MP4TrackId trackId = AddVideoTrackDefault(timeScale, sampleDuration, width, height, "avc1"); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.width", width); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.height", height); /* shouldn't need this AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1"), "avcC"); */ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.avcC.AVCProfileIndication", AVCProfileIndication); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.avcC.profile_compatibility", profile_compat); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.avcC.AVCLevelIndication", AVCLevelIndication); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.avc1.avcC.lengthSizeMinusOne", sampleLenFieldSizeMinusOne); return trackId;}bool MP4File::AddH264SequenceParameterSet (MP4TrackId trackId, const uint8_t *pSequence, uint16_t sequenceLen){ MP4Atom *avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1.avcC")); MP4BitfieldProperty *pCount; MP4Integer16Property *pLength; MP4BytesProperty *pUnit; if ((avcCAtom->FindProperty("avcC.numOfSequenceParameterSets", (MP4Property **)&pCount) == false) || (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetLength", (MP4Property **)&pLength) == false) || (avcCAtom->FindProperty("avcC.sequenceEntries.sequenceParameterSetNALUnit", (MP4Property **)&pUnit) == false)) { VERBOSE_ERROR(m_verbosity, WARNING("Could not find avcC properties")); return false; } uint32_t count = pCount->GetValue(); if (count > 0) { // see if we already exist for (uint32_t index = 0; index < count; index++) { if (pLength->GetValue(index) == sequenceLen) { uint8_t *seq; uint32_t seqlen; pUnit->GetValue(&seq, &seqlen, index); if (memcmp(seq, pSequence, sequenceLen) == 0) { free(seq); return true; } free(seq); } } } pLength->AddValue(sequenceLen); pUnit->AddValue(pSequence, sequenceLen); pCount->IncrementValue(); return true;}bool MP4File::AddH264PictureParameterSet (MP4TrackId trackId, const uint8_t *pPict, uint16_t pictLen){ MP4Atom *avcCAtom = FindAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd.avc1.avcC")); MP4Integer8Property *pCount; MP4Integer16Property *pLength; MP4BytesProperty *pUnit; if ((avcCAtom->FindProperty("avcC.numOfPictureParameterSets", (MP4Property **)&pCount) == false) || (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetLength", (MP4Property **)&pLength) == false) || (avcCAtom->FindProperty("avcC.pictureEntries.pictureParameterSetNALUnit", (MP4Property **)&pUnit) == false)) { VERBOSE_ERROR(m_verbosity, WARNING("Could not find avcC picture table properties")); return false; } uint32_t count = pCount->GetValue(); if (count > 0) { // see if we already exist for (uint32_t index = 0; index < count; index++) { if (pLength->GetValue(index) == pictLen) { uint8_t *seq; uint32_t seqlen; pUnit->GetValue(&seq, &seqlen, index); if (memcmp(seq, pPict, pictLen) == 0) { VERBOSE_WRITE(m_verbosity, fprintf(stderr, "picture matches %d\n", index)); free(seq); return true; } free(seq); } } } pLength->AddValue(pictLen); pUnit->AddValue(pPict, pictLen); pCount->IncrementValue(); VERBOSE_WRITE(m_verbosity, fprintf(stderr, "new picture added %d\n", pCount->GetValue())); return true;}void MP4File::SetH263Vendor( MP4TrackId trackId, u_int32_t vendor){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.vendor", vendor);}void MP4File::SetH263DecoderVersion( MP4TrackId trackId, u_int8_t decoderVersion){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.decoderVersion", decoderVersion);}void MP4File::SetH263Bitrates( MP4TrackId trackId, u_int32_t avgBitrate, u_int32_t maxBitrate){ SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.avgBitrate", avgBitrate); SetTrackIntegerProperty(trackId, "mdia.minf.stbl.stsd.s263.d263.bitr.maxBitrate", maxBitrate);}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 = AddVideoTrackDefault(timeScale, sampleDuration, width, height, "s263"); 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); 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 = MP4NormalizeTrackType(type, m_verbosity); 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 } __except (EXCEPTION_EXECUTE_HANDLER) { // 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 } __except (EXCEPTION_EXECUTE_HANDLER) { // 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"); RaiseException(1, 0, 0, NULL); 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 = MP4NormalizeTrackType(type, m_verbosity); 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++; } }#ifdef SIMON_CHANGED RaiseException(1, 0, 0, NULL);#else throw new MP4Error("Track index doesn't exist - track %d type %s", "FindTrackId", trackIndex, type); #endif 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; } }#ifdef SIMON_CHANGED printf("\n[%s] %s - %d", "FindTrackIndex", "Track id %d doesn't exist", trackId); RaiseException(1, 0, 0, NULL);#else throw new MP4Error("Track id %d doesn't exist", "FindTrackIndex", trackId); #endif 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_trakId
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -