📄 mp4file.cpp
字号:
float MP4File::GetTrackVideoFrameRate(MP4TrackId trackId){ MP4SampleId numSamples = GetTrackNumberOfSamples(trackId); u_int64_t msDuration = ConvertFromTrackDuration(trackId, GetTrackDuration(trackId), MP4_MSECS_TIME_SCALE); if (msDuration == 0) { return 0.0; } return ((double)numSamples / UINT64_TO_DOUBLE(msDuration)) * MP4_MSECS_TIME_SCALE;}void MP4File::GetTrackESConfiguration(MP4TrackId trackId, u_int8_t** ppConfig, u_int32_t* pConfigSize){ GetTrackBytesProperty(trackId, "mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo[0].info", ppConfig, pConfigSize);}void MP4File::SetTrackESConfiguration(MP4TrackId trackId, const u_int8_t* pConfig, u_int32_t configSize){ // get a handle on the track decoder config descriptor MP4DescriptorProperty* pConfigDescrProperty = NULL; FindProperty(MakeTrackName(trackId, "mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo"), (MP4Property**)&pConfigDescrProperty); if (pConfigDescrProperty == NULL) { // probably trackId refers to a hint track throw new MP4Error("no such property", "MP4SetTrackESConfiguration"); } // lookup the property to store the configuration MP4BytesProperty* pInfoProperty = NULL; pConfigDescrProperty->FindProperty("decSpecificInfo[0].info", (MP4Property**)&pInfoProperty); // configuration being set for the first time if (pInfoProperty == NULL) { // need to create a new descriptor to hold it MP4Descriptor* pConfigDescr = pConfigDescrProperty->AddDescriptor(MP4DecSpecificDescrTag); pConfigDescr->Generate(); pConfigDescrProperty->FindProperty( "decSpecificInfo[0].info", (MP4Property**)&pInfoProperty); ASSERT(pInfoProperty); } // set the value pInfoProperty->SetValue(pConfig, configSize);}const char* MP4File::GetHintTrackSdp(MP4TrackId hintTrackId){ return GetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText");}void MP4File::SetHintTrackSdp(MP4TrackId hintTrackId, const char* sdpString){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4SetHintTrackSdp"); } AddDescendantAtoms( MakeTrackName(hintTrackId, NULL), "udta.hnti.sdp "); SetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText", sdpString);}void MP4File::AppendHintTrackSdp(MP4TrackId hintTrackId, const char* sdpFragment){ const char* oldSdpString = NULL; try { oldSdpString = GetHintTrackSdp(hintTrackId); } catch (MP4Error* e) { delete e; SetHintTrackSdp(hintTrackId, sdpFragment); return; } char* newSdpString = (char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1); strcpy(newSdpString, oldSdpString); strcat(newSdpString, sdpFragment); SetHintTrackSdp(hintTrackId, newSdpString); MP4Free(newSdpString);}void MP4File::GetHintTrackRtpPayload( MP4TrackId hintTrackId, char** ppPayloadName, u_int8_t* pPayloadNumber, u_int16_t* pMaxPayloadSize, char **ppEncodingParams){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetHintTrackRtpPayload"); } ((MP4RtpHintTrack*)pTrack)->GetPayload( ppPayloadName, pPayloadNumber, pMaxPayloadSize, ppEncodingParams);}void MP4File::SetHintTrackRtpPayload(MP4TrackId hintTrackId, const char* payloadName, u_int8_t* pPayloadNumber, u_int16_t maxPayloadSize, const char *encoding_params, bool include_rtp_map, bool include_mpeg4_esid){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4SetHintTrackRtpPayload"); } u_int8_t payloadNumber; if (pPayloadNumber && *pPayloadNumber != MP4_SET_DYNAMIC_PAYLOAD) { payloadNumber = *pPayloadNumber; } else { payloadNumber = AllocRtpPayloadNumber(); if (pPayloadNumber) { *pPayloadNumber = payloadNumber; } } ((MP4RtpHintTrack*)pTrack)->SetPayload( payloadName, payloadNumber, maxPayloadSize, encoding_params, include_rtp_map, include_mpeg4_esid);}u_int8_t MP4File::AllocRtpPayloadNumber(){ MP4Integer32Array usedPayloads; u_int32_t i; // collect rtp payload numbers in use by existing tracks for (i = 0; i < m_pTracks.Size(); i++) { MP4Atom* pTrakAtom = m_pTracks[i]->GetTrakAtom(); MP4Integer32Property* pPayloadProperty = NULL; pTrakAtom->FindProperty("trak.udta.hinf.payt.payloadNumber", (MP4Property**)&pPayloadProperty); if (pPayloadProperty) { usedPayloads.Add(pPayloadProperty->GetValue()); } } // search dynamic payload range for an available slot u_int8_t payload; for (payload = 96; payload < 128; payload++) { for (i = 0; i < usedPayloads.Size(); i++) { if (payload == usedPayloads[i]) { break; } } if (i == usedPayloads.Size()) { break; } } if (payload >= 128) { throw new MP4Error("no more available rtp payload numbers", "AllocRtpPayloadNumber"); } return payload;}MP4TrackId MP4File::GetHintTrackReferenceTrackId( MP4TrackId hintTrackId){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetHintTrackReferenceTrackId"); } MP4Track* pRefTrack = ((MP4RtpHintTrack*)pTrack)->GetRefTrack(); if (pRefTrack == NULL) { return MP4_INVALID_TRACK_ID; } return pRefTrack->GetId();}void MP4File::ReadRtpHint( MP4TrackId hintTrackId, MP4SampleId hintSampleId, u_int16_t* pNumPackets){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4ReadRtpHint"); } ((MP4RtpHintTrack*)pTrack)-> ReadHint(hintSampleId, pNumPackets);}u_int16_t MP4File::GetRtpHintNumberOfPackets( MP4TrackId hintTrackId){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetRtpHintNumberOfPackets"); } return ((MP4RtpHintTrack*)pTrack)->GetHintNumberOfPackets();}int8_t MP4File::GetRtpPacketBFrame( MP4TrackId hintTrackId, u_int16_t packetIndex){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetRtpHintBFrame"); } return ((MP4RtpHintTrack*)pTrack)->GetPacketBFrame(packetIndex);}int32_t MP4File::GetRtpPacketTransmitOffset( MP4TrackId hintTrackId, u_int16_t packetIndex){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetRtpPacketTransmitOffset"); } return ((MP4RtpHintTrack*)pTrack)->GetPacketTransmitOffset(packetIndex);}void MP4File::ReadRtpPacket( MP4TrackId hintTrackId, u_int16_t packetIndex, u_int8_t** ppBytes, u_int32_t* pNumBytes, u_int32_t ssrc, bool includeHeader, bool includePayload){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4ReadPacket"); } ((MP4RtpHintTrack*)pTrack)->ReadPacket( packetIndex, ppBytes, pNumBytes, ssrc, includeHeader, includePayload);}MP4Timestamp MP4File::GetRtpTimestampStart( MP4TrackId hintTrackId){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4GetRtpTimestampStart"); } return ((MP4RtpHintTrack*)pTrack)->GetRtpTimestampStart();}void MP4File::SetRtpTimestampStart( MP4TrackId hintTrackId, MP4Timestamp rtpStart){ MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4SetRtpTimestampStart"); } ((MP4RtpHintTrack*)pTrack)->SetRtpTimestampStart(rtpStart);}void MP4File::AddRtpHint(MP4TrackId hintTrackId, bool isBframe, u_int32_t timestampOffset){ ProtectWriteOperation("MP4AddRtpHint"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4AddRtpHint"); } ((MP4RtpHintTrack*)pTrack)->AddHint(isBframe, timestampOffset);}void MP4File::AddRtpPacket( MP4TrackId hintTrackId, bool setMbit, int32_t transmitOffset){ ProtectWriteOperation("MP4AddRtpPacket"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4AddRtpPacket"); } ((MP4RtpHintTrack*)pTrack)->AddPacket(setMbit, transmitOffset);}void MP4File::AddRtpImmediateData(MP4TrackId hintTrackId, const u_int8_t* pBytes, u_int32_t numBytes){ ProtectWriteOperation("MP4AddRtpImmediateData"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4AddRtpImmediateData"); } ((MP4RtpHintTrack*)pTrack)->AddImmediateData(pBytes, numBytes);}void MP4File::AddRtpSampleData(MP4TrackId hintTrackId, MP4SampleId sampleId, u_int32_t dataOffset, u_int32_t dataLength){ ProtectWriteOperation("MP4AddRtpSampleData"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4AddRtpSampleData"); } ((MP4RtpHintTrack*)pTrack)->AddSampleData( sampleId, dataOffset, dataLength);}void MP4File::AddRtpESConfigurationPacket(MP4TrackId hintTrackId){ ProtectWriteOperation("MP4AddRtpESConfigurationPacket"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4AddRtpESConfigurationPacket"); } ((MP4RtpHintTrack*)pTrack)->AddESConfigurationPacket();}void MP4File::WriteRtpHint(MP4TrackId hintTrackId, MP4Duration duration, bool isSyncSample){ ProtectWriteOperation("MP4WriteRtpHint"); MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)]; if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) { throw new MP4Error("track is not a hint track", "MP4WriteRtpHint"); } ((MP4RtpHintTrack*)pTrack)->WriteHint(duration, isSyncSample);}u_int64_t MP4File::ConvertFromMovieDuration( MP4Duration duration, u_int32_t timeScale){ return MP4ConvertTime((u_int64_t)duration, GetTimeScale(), timeScale);}u_int64_t MP4File::ConvertFromTrackTimestamp( MP4TrackId trackId, MP4Timestamp timeStamp, u_int32_t timeScale){ return MP4ConvertTime((u_int64_t)timeStamp, GetTrackTimeScale(trackId), timeScale);}MP4Timestamp MP4File::ConvertToTrackTimestamp( MP4TrackId trackId, u_int64_t timeStamp, u_int32_t timeScale){ return (MP4Timestamp)MP4ConvertTime(timeStamp, timeScale, GetTrackTimeScale(trackId));}u_int64_t MP4File::ConvertFromTrackDuration( MP4TrackId trackId, MP4Duration duration, u_int32_t timeScale){ return MP4ConvertTime((u_int64_t)duration, GetTrackTimeScale(trackId), timeScale);}MP4Duration MP4File::ConvertToTrackDuration( MP4TrackId trackId, u_int64_t duration, u_int32_t timeScale){ return (MP4Duration)MP4ConvertTime(duration, timeScale, GetTrackTimeScale(trackId));}u_int8_t MP4File::ConvertTrackTypeToStreamType(const char* trackType){ u_int8_t streamType; if (!strcmp(trackType, MP4_OD_TRACK_TYPE)) { streamType = MP4ObjectDescriptionStreamType; } else if (!strcmp(trackType, MP4_SCENE_TRACK_TYPE)) { streamType = MP4SceneDescriptionStreamType; } else if (!strcmp(trackType, MP4_CLOCK_TRACK_TYPE)) { streamType = MP4ClockReferenceStreamType; } else if (!strcmp(trackType, MP4_MPEG7_TRACK_TYPE)) { streamType = MP4Mpeg7StreamType; } else if (!strcmp(trackType, MP4_OCI_TRACK_TYPE)) { streamType = MP4OCIStreamType; } else if (!strcmp(trackType, MP4_IPMP_TRACK_TYPE)) { streamType = MP4IPMPStreamType; } else if (!strcmp(trackType, MP4_MPEGJ_TRACK_TYPE)) { streamType = MP4MPEGJStreamType; } else { streamType = MP4UserPrivateStreamType; } return streamType;}// edit listchar* MP4File::MakeTrackEditName( MP4TrackId trackId, MP4EditId editId, const char* name){ char* trakName = MakeTrackName(trackId, NULL); static char editName[1024]; snprintf(editName, sizeof(editName), "%s.edts.elst.entries[%u].%s", trakName, editId - 1, name); return editName;}MP4EditId MP4File::AddTrackEdit( MP4TrackId trackId, MP4EditId editId){ ProtectWriteOperation("AddTrackEdit"); return m_pTracks[FindTrackIndex(trackId)]->AddEdit(editId);}void MP4File::DeleteTrackEdit( MP4TrackId trackId, MP4EditId editId){ ProtectWriteOperation("DeleteTrackEdit"); m_pTracks[FindTrackIndex(trackId)]->DeleteEdit(editId);}u_int32_t MP4File::GetTrackNumberOfEdits( MP4TrackId trackId){ return GetTrackIntegerProperty(trackId, "edts.elst.entryCount");}MP4Duration MP4File::GetTrackEditTotalDuration( MP4TrackId trackId, MP4EditId editId){ return m_pTracks[FindTrackIndex(trackId)]->GetEditTotalDuration(editId);}MP4Timestamp MP4File::GetTrackEditStart( MP4TrackId trackId, MP4EditId editId){ return m_pTracks[FindTrackIndex(trackId)]->GetEditStart(editId);}MP4Timestamp MP4File::GetTrackEditMediaStart( MP4TrackId trackId, MP4EditId editId){ return GetIntegerProperty( MakeTrackEditName(trackId, editId, "mediaTime"));}void MP4File::SetTrackEditMediaStart( MP4TrackId trackId, MP4EditId editId, MP4Timestamp startTime){ SetIntegerProperty( MakeTrackEditName(trackId, editId, "mediaTime"), startTime);}MP4Duration MP4File::GetTrackEditDuration( MP4TrackId trackId, MP4EditId editId){ return GetIntegerProperty( MakeTrackEditName(trackId, editId, "segmentDuration"));}void MP4File::SetTrackEditDuration( MP4TrackId trackId, MP4EditId editId, MP4Duration duration){ SetIntegerProperty( MakeTrackEditName(trackId, editId, "segmentDuration"), duration);}bool MP4File::GetTrackEditDwell( MP4TrackId trackId, MP4EditId editId){ return (GetIntegerProperty( MakeTrackEditName(trackId, editId, "mediaRate")) == 0);}void MP4File::SetTrackEditDwell( MP4TrackId trackId, MP4EditId editId, bool dwell){ SetIntegerProperty( MakeTrackEditName(trackId, editId, "mediaRate"), (dwell ? 0 : 1));}MP4SampleId MP4File::GetSampleIdFromEditTime( MP4TrackId trackId, MP4Timestamp when, MP4Timestamp* pStartTime, MP4Duration* pDuration){ return m_pTracks[FindTrackIndex(trackId)]->GetSampleIdFromEditTime( when, pStartTime, pDuration);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -