📄 isma.cpp
字号:
printf("Scene data URL = \042%s\042\n", urlBuf));
MP4Descriptor* pSceneEsd =
CreateESD(
pEsProperty,
201, // esid
MP4SystemsV2ObjectType,
MP4SceneDescriptionStreamType,
numBytes, // bufferSize
numBytes * 8, // bitrate
BifsV2Config,
sizeof(BifsV2Config),
urlBuf);
MP4Free(sceneCmdBase64);
sceneCmdBase64 = NULL;
MP4Free(urlBuf);
urlBuf = NULL;
MP4Free(pBytes);
pBytes = NULL;
// Video
MP4Descriptor* pVideoEsd =
CreateESD(
pEsProperty,
20, // esid
MP4_MPEG4_VIDEO_TYPE,
MP4VisualStreamType,
videoBitrate / 8, // bufferSize
videoBitrate,
videoConfig,
videoConfigLength,
NULL);
// Audio
MP4Descriptor* pAudioEsd =
CreateESD(
pEsProperty,
10, // esid
MP4_MPEG4_AUDIO_TYPE,
MP4AudioStreamType,
audioBitrate / 8, // bufferSize
audioBitrate,
audioConfig,
audioConfigLength,
NULL);
// OD
// Glop to make infrastructure happy
MP4DescriptorProperty* pAudioEsdProperty =
new MP4DescriptorProperty();
pAudioEsdProperty->AppendDescriptor(pAudioEsd);
MP4DescriptorProperty* pVideoEsdProperty =
new MP4DescriptorProperty();
pVideoEsdProperty->AppendDescriptor(pVideoEsd);
CreateIsmaODUpdateCommandForStream(
pAudioEsdProperty,
pVideoEsdProperty,
&pBytes,
&numBytes);
// TBD cleanup temporary descriptor properties
VERBOSE_ISMA(GetVerbosity(),
printf("OD data =\n"); MP4HexDump(pBytes, numBytes));
char* odCmdBase64 = MP4ToBase64(pBytes, numBytes);
urlBuf = (char*)MP4Malloc(strlen(odCmdBase64) + 64);
sprintf(urlBuf,
"data:application/mpeg4-od-au;base64,%s",
odCmdBase64);
VERBOSE_ISMA(GetVerbosity(),
printf("OD data URL = \042%s\042\n", urlBuf));
MP4Descriptor* pOdEsd =
CreateESD(
pEsProperty,
101,
MP4SystemsV1ObjectType,
MP4ObjectDescriptionStreamType,
numBytes, // bufferSize
numBytes * 8, // bitrate
NULL, // config
0, // configLength
urlBuf);
MP4Free(odCmdBase64);
odCmdBase64 = NULL;
MP4Free(pBytes);
pBytes = NULL;
MP4Free(urlBuf);
urlBuf = NULL;
// finally get the whole thing written to a memory
pIod->WriteToMemory(this, ppIodBytes, pIodNumBytes);
delete pIod;
VERBOSE_ISMA(GetVerbosity(),
printf("IOD data =\n"); MP4HexDump(*ppIodBytes, *pIodNumBytes));
}
MP4Descriptor* MP4File::CreateESD(
MP4DescriptorProperty* pEsProperty,
u_int32_t esid,
u_int8_t objectType,
u_int8_t streamType,
u_int32_t bufferSize,
u_int32_t bitrate,
u_int8_t* pConfig,
u_int32_t configLength,
char* url)
{
MP4IntegerProperty* pInt;
MP4StringProperty* pString;
MP4BytesProperty* pBytes;
MP4Descriptor* pEsd =
pEsProperty->AddDescriptor(MP4ESDescrTag);
pEsd->Generate();
pEsd->FindProperty("ESID",
(MP4Property**)&pInt);
pInt->SetValue(esid);
pEsd->FindProperty("decConfigDescr.objectTypeId",
(MP4Property**)&pInt);
pInt->SetValue(objectType);
pEsd->FindProperty("decConfigDescr.streamType",
(MP4Property**)&pInt);
pInt->SetValue(streamType);
pEsd->FindProperty("decConfigDescr.bufferSizeDB",
(MP4Property**)&pInt);
pInt->SetValue(bufferSize);
pEsd->FindProperty("decConfigDescr.maxBitrate",
(MP4Property**)&pInt);
pInt->SetValue(bitrate);
pEsd->FindProperty("decConfigDescr.avgBitrate",
(MP4Property**)&pInt);
pInt->SetValue(bitrate);
MP4DescriptorProperty* pConfigDescrProperty;
pEsd->FindProperty("decConfigDescr.decSpecificInfo",
(MP4Property**)&pConfigDescrProperty);
MP4Descriptor* pConfigDescr =
pConfigDescrProperty->AddDescriptor(MP4DecSpecificDescrTag);
pConfigDescr->Generate();
pConfigDescrProperty->FindProperty("decSpecificInfo[0].info",
(MP4Property**)&pBytes);
pBytes->SetValue(pConfig, configLength);
pEsd->FindProperty("slConfigDescr.predefined",
(MP4Property**)&pInt);
pInt->SetValue(1);
if (url) {
pEsd->FindProperty("URLFlag",
(MP4Property**)&pInt);
pInt->SetValue(1);
pEsd->FindProperty("URL",
(MP4Property**)&pString);
pString->SetValue(url);
}
return pEsd;
}
void MP4File::CreateIsmaODUpdateCommandFromFileForFile(
MP4TrackId odTrackId,
MP4TrackId audioTrackId,
MP4TrackId videoTrackId,
u_int8_t** ppBytes,
u_int64_t* pNumBytes)
{
MP4Descriptor* pCommand = CreateODCommand(MP4ODUpdateODCommandTag);
pCommand->Generate();
for (u_int8_t i = 0; i < 2; i++) {
MP4TrackId trackId;
u_int16_t odId;
if (i == 0) {
trackId = audioTrackId;
odId = 10;
} else {
trackId = videoTrackId;
odId = 20;
}
if (trackId == MP4_INVALID_TRACK_ID) {
continue;
}
MP4DescriptorProperty* pOdDescrProperty =
(MP4DescriptorProperty*)(pCommand->GetProperty(0));
pOdDescrProperty->SetTags(MP4FileODescrTag);
MP4Descriptor* pOd =
pOdDescrProperty->AddDescriptor(MP4FileODescrTag);
pOd->Generate();
MP4BitfieldProperty* pOdIdProperty = NULL;
pOd->FindProperty("objectDescriptorId",
(MP4Property**)&pOdIdProperty);
pOdIdProperty->SetValue(odId);
MP4DescriptorProperty* pEsIdsDescriptorProperty = NULL;
pOd->FindProperty("esIds",
(MP4Property**)&pEsIdsDescriptorProperty);
ASSERT(pEsIdsDescriptorProperty);
pEsIdsDescriptorProperty->SetTags(MP4ESIDRefDescrTag);
MP4Descriptor *pRefDescriptor =
pEsIdsDescriptorProperty->AddDescriptor(MP4ESIDRefDescrTag);
pRefDescriptor->Generate();
MP4Integer16Property* pRefIndexProperty = NULL;
pRefDescriptor->FindProperty("refIndex",
(MP4Property**)&pRefIndexProperty);
ASSERT(pRefIndexProperty);
u_int32_t mpodIndex = FindTrackReference(
MakeTrackName(odTrackId, "tref.mpod"), trackId);
ASSERT(mpodIndex != 0);
pRefIndexProperty->SetValue(mpodIndex);
}
pCommand->WriteToMemory(this, ppBytes, pNumBytes);
delete pCommand;
}
void MP4File::CreateIsmaODUpdateCommandFromFileForStream(
MP4TrackId audioTrackId,
MP4TrackId videoTrackId,
u_int8_t** ppBytes,
u_int64_t* pNumBytes)
{
MP4DescriptorProperty* pAudioEsd = NULL;
MP4Integer8Property* pAudioSLConfig = NULL;
MP4DescriptorProperty* pVideoEsd = NULL;
MP4Integer8Property* pVideoSLConfig = NULL;
if (audioTrackId != MP4_INVALID_TRACK_ID) {
MP4Atom* pEsdsAtom =
FindAtom(MakeTrackName(audioTrackId,
"mdia.minf.stbl.stsd.mp4a.esds"));
ASSERT(pEsdsAtom);
pAudioEsd = (MP4DescriptorProperty*)(pEsdsAtom->GetProperty(2));
// SL config needs to change from 2 (file) to 1 (null)
pAudioEsd->FindProperty("slConfigDescr.predefined",
(MP4Property**)&pAudioSLConfig);
ASSERT(pAudioSLConfig);
pAudioSLConfig->SetValue(1);
}
if (videoTrackId != MP4_INVALID_TRACK_ID) {
MP4Atom* pEsdsAtom =
FindAtom(MakeTrackName(videoTrackId,
"mdia.minf.stbl.stsd.mp4v.esds"));
ASSERT(pEsdsAtom);
pVideoEsd = (MP4DescriptorProperty*)(pEsdsAtom->GetProperty(2));
// SL config needs to change from 2 (file) to 1 (null)
pVideoEsd->FindProperty("slConfigDescr.predefined",
(MP4Property**)&pVideoSLConfig);
ASSERT(pVideoSLConfig);
pVideoSLConfig->SetValue(1);
}
CreateIsmaODUpdateCommandForStream(
pAudioEsd, pVideoEsd, ppBytes, pNumBytes);
// return SL config values to 2 (file)
if (pAudioSLConfig) {
pAudioSLConfig->SetValue(2);
}
if (pVideoSLConfig) {
pVideoSLConfig->SetValue(2);
}
}
void MP4File::CreateIsmaODUpdateCommandForStream(
MP4DescriptorProperty* pAudioEsdProperty,
MP4DescriptorProperty* pVideoEsdProperty,
u_int8_t** ppBytes,
u_int64_t* pNumBytes)
{
MP4Descriptor* pAudioOd = NULL;
MP4Descriptor* pVideoOd = NULL;
MP4Descriptor* pCommand =
CreateODCommand(MP4ODUpdateODCommandTag);
pCommand->Generate();
for (u_int8_t i = 0; i < 2; i++) {
u_int16_t odId;
MP4DescriptorProperty* pEsdProperty = NULL;
if (i == 0) {
odId = 10;
pEsdProperty = pAudioEsdProperty;
} else {
odId = 20;
pEsdProperty = pVideoEsdProperty;
}
if (pEsdProperty == NULL) {
continue;
}
MP4DescriptorProperty* pOdDescrProperty =
(MP4DescriptorProperty*)(pCommand->GetProperty(0));
pOdDescrProperty->SetTags(MP4ODescrTag);
MP4Descriptor* pOd =
pOdDescrProperty->AddDescriptor(MP4ODescrTag);
pOd->Generate();
if (i == 0) {
pAudioOd = pOd;
} else {
pVideoOd = pOd;
}
MP4BitfieldProperty* pOdIdProperty = NULL;
pOd->FindProperty("objectDescriptorId",
(MP4Property**)&pOdIdProperty);
pOdIdProperty->SetValue(odId);
delete (MP4DescriptorProperty*)pOd->GetProperty(4);
pOd->SetProperty(4, pEsdProperty);
}
// serialize OD command
pCommand->WriteToMemory(this, ppBytes, pNumBytes);
// detach from esd descriptor params
if (pAudioOd) {
pAudioOd->SetProperty(4, NULL);
}
if (pVideoOd) {
pVideoOd->SetProperty(4, NULL);
}
// then destroy
delete pCommand;
}
void MP4File::CreateIsmaSceneCommand(
bool hasAudio,
bool hasVideo,
u_int8_t** ppBytes,
u_int64_t* pNumBytes)
{
// from ISMA 1.0 Tech Spec Appendix E
static u_int8_t bifsAudioOnly[] = {
0xC0, 0x10, 0x12,
0x81, 0x30, 0x2A, 0x05, 0x7C
};
static u_int8_t bifsVideoOnly[] = {
0xC0, 0x10, 0x12,
0x61, 0x04, 0x88, 0x50, 0x45, 0x05, 0x3F, 0x00
};
static u_int8_t bifsAudioVideo[] = {
0xC0, 0x10, 0x12,
0x81, 0x30, 0x2A, 0x05, 0x72,
0x61, 0x04, 0x88, 0x50, 0x45, 0x05, 0x3F, 0x00
};
if (hasAudio && hasVideo) {
*pNumBytes = sizeof(bifsAudioVideo);
*ppBytes = (u_int8_t*)MP4Malloc(*pNumBytes);
memcpy(*ppBytes, bifsAudioVideo, sizeof(bifsAudioVideo));
} else if (hasAudio) {
*pNumBytes = sizeof(bifsAudioOnly);
*ppBytes = (u_int8_t*)MP4Malloc(*pNumBytes);
memcpy(*ppBytes, bifsAudioOnly, sizeof(bifsAudioOnly));
} else if (hasVideo) {
*pNumBytes = sizeof(bifsVideoOnly);
*ppBytes = (u_int8_t*)MP4Malloc(*pNumBytes);
memcpy(*ppBytes, bifsVideoOnly, sizeof(bifsVideoOnly));
} else {
*pNumBytes = 0;
*ppBytes = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -