📄 mp4file.cpp
字号:
pInteger32Property->SetValue(timeScale ? timeScale : 1000);
// now have enough to create MP4Track object
MP4Track* pTrack = NULL;
if (!strcmp(normType, MP4_HINT_TRACK_TYPE)) {
pTrack = new MP4RtpHintTrack(this, pTrakAtom);
} else {
pTrack = new MP4Track(this, pTrakAtom);
}
m_pTracks.Add(pTrack);
// mark non-hint tracks as enabled
if (strcmp(normType, MP4_HINT_TRACK_TYPE)) {
SetTrackIntegerProperty(trackId, "tkhd.flags", 1);
}
// mark track as contained in this file
// LATER will provide option for external data references
AddDataReference(trackId, NULL);
return trackId;
}
void MP4File::AddTrackToIod(MP4TrackId trackId)
{
MP4DescriptorProperty* pDescriptorProperty = NULL;
m_pRootAtom->FindProperty("moov.iods.esIds",
(MP4Property**)&pDescriptorProperty);
ASSERT(pDescriptorProperty);
MP4Descriptor* pDescriptor =
pDescriptorProperty->AddDescriptor(MP4ESIDIncDescrTag);
ASSERT(pDescriptor);
MP4Integer32Property* pIdProperty = NULL;
pDescriptor->FindProperty("id",
(MP4Property**)&pIdProperty);
ASSERT(pIdProperty);
pIdProperty->SetValue(trackId);
}
void MP4File::RemoveTrackFromIod(MP4TrackId trackId)
{
MP4DescriptorProperty* pDescriptorProperty = NULL;
m_pRootAtom->FindProperty("moov.iods.esIds",
(MP4Property**)&pDescriptorProperty);
ASSERT(pDescriptorProperty);
for (u_int32_t i = 0; i < pDescriptorProperty->GetCount(); i++) {
static char name[32];
snprintf(name, sizeof(name), "esIds[%u].id", i);
MP4Integer32Property* pIdProperty = NULL;
pDescriptorProperty->FindProperty(name,
(MP4Property**)&pIdProperty);
ASSERT(pIdProperty);
if (pIdProperty->GetValue() == trackId) {
pDescriptorProperty->DeleteDescriptor(i);
break;
}
}
}
void MP4File::AddTrackToOd(MP4TrackId trackId)
{
if (!m_odTrackId) {
return;
}
AddTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);
}
void MP4File::RemoveTrackFromOd(MP4TrackId trackId)
{
if (!m_odTrackId) {
return;
}
RemoveTrackReference(MakeTrackName(m_odTrackId, "tref.mpod"), trackId);
}
void MP4File::GetTrackReferenceProperties(const char* trefName,
MP4Property** ppCountProperty, MP4Property** ppTrackIdProperty)
{
char propName[1024];
snprintf(propName, sizeof(propName), "%s.%s", trefName, "entryCount");
m_pRootAtom->FindProperty(propName, ppCountProperty);
ASSERT(*ppCountProperty);
snprintf(propName, sizeof(propName), "%s.%s", trefName, "entries.trackId");
m_pRootAtom->FindProperty(propName, ppTrackIdProperty);
ASSERT(*ppTrackIdProperty);
}
void MP4File::AddTrackReference(const char* trefName, MP4TrackId refTrackId)
{
MP4Integer32Property* pCountProperty = NULL;
MP4Integer32Property* pTrackIdProperty = NULL;
GetTrackReferenceProperties(trefName,
(MP4Property**)&pCountProperty,
(MP4Property**)&pTrackIdProperty);
pTrackIdProperty->AddValue(refTrackId);
pCountProperty->IncrementValue();
}
u_int32_t MP4File::FindTrackReference(const char* trefName,
MP4TrackId refTrackId)
{
MP4Integer32Property* pCountProperty = NULL;
MP4Integer32Property* pTrackIdProperty = NULL;
GetTrackReferenceProperties(trefName,
(MP4Property**)&pCountProperty,
(MP4Property**)&pTrackIdProperty);
for (u_int32_t i = 0; i < pCountProperty->GetValue(); i++) {
if (refTrackId == pTrackIdProperty->GetValue(i)) {
return i + 1; // N.B. 1 not 0 based index
}
}
return 0;
}
void MP4File::RemoveTrackReference(const char* trefName, MP4TrackId refTrackId)
{
MP4Integer32Property* pCountProperty = NULL;
MP4Integer32Property* pTrackIdProperty = NULL;
GetTrackReferenceProperties(trefName,
(MP4Property**)&pCountProperty,
(MP4Property**)&pTrackIdProperty);
for (u_int32_t i = 0; i < pCountProperty->GetValue(); i++) {
if (refTrackId == pTrackIdProperty->GetValue(i)) {
pTrackIdProperty->DeleteValue(i);
pCountProperty->IncrementValue(-1);
}
}
}
void MP4File::AddDataReference(MP4TrackId trackId, const char* url)
{
MP4Atom* pDrefAtom =
FindAtom(MakeTrackName(trackId, "mdia.minf.dinf.dref"));
ASSERT(pDrefAtom);
MP4Integer32Property* pCountProperty = NULL;
pDrefAtom->FindProperty("dref.entryCount",
(MP4Property**)&pCountProperty);
ASSERT(pCountProperty);
pCountProperty->IncrementValue();
MP4Atom* pUrlAtom = AddChildAtom(pDrefAtom, "url ");
if (url && url[0] != '\0') {
pUrlAtom->SetFlags(pUrlAtom->GetFlags() & 0xFFFFFE);
MP4StringProperty* pUrlProperty = NULL;
pUrlAtom->FindProperty("url .location",
(MP4Property**)&pUrlProperty);
ASSERT(pUrlProperty);
pUrlProperty->SetValue(url);
} else {
pUrlAtom->SetFlags(pUrlAtom->GetFlags() | 1);
}
}
MP4TrackId MP4File::AddSystemsTrack(const char* type)
{
const char* normType = MP4Track::NormalizeTrackType(type);
// TBD if user type, fix name to four chars, and warn
MP4TrackId trackId = AddTrack(type, MP4_MSECS_TIME_SCALE);
InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0);
AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4s");
// 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 mp4s atom
MP4Integer32Property* pStsdCountProperty;
FindIntegerProperty(
MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
(MP4Property**)&pStsdCountProperty);
pStsdCountProperty->IncrementValue();
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4s.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.mp4s.esds.decConfigDescr.objectTypeId",
MP4SystemsV1ObjectType);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.streamType",
ConvertTrackTypeToStreamType(normType));
return trackId;
}
MP4TrackId MP4File::AddODTrack()
{
// until a demonstrated need emerges
// we limit ourselves to one object description track
if (m_odTrackId != MP4_INVALID_TRACK_ID) {
throw new MP4Error("object description track already exists",
"AddObjectDescriptionTrack");
}
m_odTrackId = AddSystemsTrack(MP4_OD_TRACK_TYPE);
AddTrackToIod(m_odTrackId);
AddDescendantAtoms(MakeTrackName(m_odTrackId, NULL), "tref.mpod");
return m_odTrackId;
}
MP4TrackId MP4File::AddSceneTrack()
{
MP4TrackId trackId = AddSystemsTrack(MP4_SCENE_TRACK_TYPE);
AddTrackToIod(trackId);
AddTrackToOd(trackId);
return trackId;
}
MP4TrackId MP4File::AddAudioTrack(
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int8_t audioType)
{
MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);
AddTrackToOd(trackId);
SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);
InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);
AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4a");
// 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 mp4a atom
MP4Integer32Property* pStsdCountProperty;
FindIntegerProperty(
MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
(MP4Property**)&pStsdCountProperty);
pStsdCountProperty->IncrementValue();
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4a.timeScale", timeScale);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4a.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.mp4a.esds.decConfigDescr.objectTypeId",
audioType);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4a.esds.decConfigDescr.streamType",
MP4AudioStreamType);
m_pTracks[FindTrackIndex(trackId)]->
SetFixedSampleDuration(sampleDuration);
return trackId;
}
MP4TrackId MP4File::AddEncAudioTrack(u_int32_t timeScale,
MP4Duration sampleDuration,
u_int8_t audioType)
{
MP4TrackId trackId = AddTrack(MP4_AUDIO_TRACK_TYPE, timeScale);
AddTrackToOd(trackId);
SetTrackFloatProperty(trackId, "tkhd.volume", 1.0);
InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "smhd", 0);
AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "enca");
// 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 enca atom
MP4Integer32Property* pStsdCountProperty;
FindIntegerProperty(
MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"),
(MP4Property**)&pStsdCountProperty);
pStsdCountProperty->IncrementValue();
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.enca.timeScale", timeScale);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.enca.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.enca.esds.decConfigDescr.objectTypeId",
audioType);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.enca.esds.decConfigDescr.streamType",
MP4AudioStreamType);
m_pTracks[FindTrackIndex(trackId)]->
SetFixedSampleDuration(sampleDuration);
return trackId;
}
MP4TrackId MP4File::AddVideoTrack(
u_int32_t timeScale,
MP4Duration sampleDuration,
u_int16_t width,
u_int16_t height,
u_int8_t videoType)
{
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"), "mp4v");
// 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.mp4v.width", width);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4v.height", height);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4v.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.mp4v.esds.decConfigDescr.objectTypeId",
videoType);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsd.mp4v.esds.decConfigDescr.streamType",
MP4VisualStreamType);
SetTrackIntegerProperty(trackId,
"mdia.minf.stbl.stsz.sampleSize", sampleDuration);
m_pTracks[FindTrackIndex(trackId)]->
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)
{
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);
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -