mp4file.cpp
来自「faac-1.25.rar音频编解码器demo」· C++ 代码 · 共 2,476 行 · 第 1/5 页
CPP
2,476 行
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 functions
MP4Duration 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 functions
MP4SampleId 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 GetTrackEsdsObjectTypeId
u_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, ...)
// is the first 5 bits of the ES configuration
GetTrackESConfiguration(trackId, &pEsConfig, &esConfigSize);
if (esConfigSize < 1) {
return MP4_MPEG4_INVALID_AUDIO_TYPE;
}
u_int8_t mpeg4Type = (pEsConfig[0] >> 3);
free(pEsConfig);
return mpeg4Type;
}
// replaced with GetTrackEsdsObjectTypeId
u_int8_t MP4File::GetTrackVideoType(MP4TrackId trackId)
{
return GetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.objectTypeId");
}
MP4Duration MP4File::GetTrackFixedSampleDuration(MP4TrackId trackId)
{
return m_pTracks[FindTrackIndex(trackId)]->GetFixedSampleDuration();
}
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;
}
// true if media track encrypted according to ismacryp
bool MP4File::IsIsmaCrypMediaTrack(MP4TrackId trackId)
{
if (GetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.*.sinf.frma.data-format")
!= (u_int64_t)-1) {
return true;
}
return false;
}
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) {
usedPa
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?