ref: 46ee73267fc46d0f0f229ab8aff4262e554c86f6
parent: 99a01ee867743997e40318c6456af79fdc77dea0
author: menno <menno>
date: Tue Dec 10 14:45:36 EST 2002
Updates for DRM
--- a/common/mp4v2/atom_stdp.cpp
+++ b/common/mp4v2/atom_stdp.cpp
@@ -41,9 +41,9 @@
void MP4StdpAtom::Read()
{
// table entry count computed from atom size
- ((MP4Integer32Property*)m_pProperties[0])->SetReadOnly(false);
- ((MP4Integer32Property*)m_pProperties[0])->SetValue((m_size - 4) / 2);
- ((MP4Integer32Property*)m_pProperties[0])->SetReadOnly(true);
+ ((MP4Integer32Property*)m_pProperties[2])->SetReadOnly(false);
+ ((MP4Integer32Property*)m_pProperties[2])->SetValue((m_size - 4) / 2);
+ ((MP4Integer32Property*)m_pProperties[2])->SetReadOnly(true);
MP4Atom::Read();
}
--- a/common/mp4v2/isma.cpp
+++ b/common/mp4v2/isma.cpp
@@ -1,825 +1,827 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is MPEG4IP.
- *
- * The Initial Developer of the Original Code is Cisco Systems Inc.
- * Portions created by Cisco Systems Inc. are
- * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
- *
- * Contributor(s):
- * Dave Mackie [email protected]
- */
-
-#include "mp4common.h"
-
-static u_int8_t BifsV2Config[3] = {
- 0x00, 0x00, 0x60 // IsCommandStream = 1, PixelMetric = 1
-};
-
-void MP4File::MakeIsmaCompliant(bool addIsmaComplianceSdp)
-{
- ProtectWriteOperation("MP4MakeIsmaCompliant");
-
- if (m_useIsma) {
- // already done
- return;
- }
- m_useIsma = true;
-
- // find first audio and/or video tracks
-
- MP4TrackId audioTrackId = MP4_INVALID_TRACK_ID;
- try {
- audioTrackId = FindTrackId(0, MP4_AUDIO_TRACK_TYPE);
- }
- catch (MP4Error* e) {
- delete e;
- }
-
- MP4TrackId videoTrackId = MP4_INVALID_TRACK_ID;
- try {
- videoTrackId = FindTrackId(0, MP4_VIDEO_TRACK_TYPE);
- }
- catch (MP4Error* e) {
- delete e;
- }
-
- u_int64_t fileMsDuration =
- ConvertFromMovieDuration(GetDuration(), MP4_MSECS_TIME_SCALE);
-
- // delete any existing OD track
- if (m_odTrackId != MP4_INVALID_TRACK_ID) {
- DeleteTrack(m_odTrackId);
- }
-
- AddODTrack();
- SetODProfileLevel(0xFF);
-
- if (audioTrackId != MP4_INVALID_TRACK_ID) {
- AddTrackToOd(audioTrackId);
- }
-
- if (videoTrackId != MP4_INVALID_TRACK_ID) {
- AddTrackToOd(videoTrackId);
- }
-
- // delete any existing scene track
- MP4TrackId sceneTrackId = MP4_INVALID_TRACK_ID;
- try {
- sceneTrackId = FindTrackId(0, MP4_SCENE_TRACK_TYPE);
- }
- catch (MP4Error *e) {
- delete e;
- }
- if (sceneTrackId != MP4_INVALID_TRACK_ID) {
- DeleteTrack(sceneTrackId);
- }
-
- // add scene track
- sceneTrackId = AddSceneTrack();
- SetSceneProfileLevel(0xFF);
- SetGraphicsProfileLevel(0xFF);
- SetTrackIntegerProperty(sceneTrackId,
- "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId",
- MP4SystemsV2ObjectType);
-
- SetTrackESConfiguration(sceneTrackId,
- BifsV2Config, sizeof(BifsV2Config));
-
- u_int8_t* pBytes = NULL;
- u_int64_t numBytes = 0;
-
- // write OD Update Command
- CreateIsmaODUpdateCommandFromFileForFile(
- m_odTrackId,
- audioTrackId,
- videoTrackId,
- &pBytes,
- &numBytes);
-
- WriteSample(m_odTrackId, pBytes, numBytes, fileMsDuration);
-
- MP4Free(pBytes);
- pBytes = NULL;
-
- // write BIFS Scene Replace Command
- CreateIsmaSceneCommand(
- MP4_IS_VALID_TRACK_ID(audioTrackId),
- MP4_IS_VALID_TRACK_ID(videoTrackId),
- &pBytes,
- &numBytes);
-
- WriteSample(sceneTrackId, pBytes, numBytes, fileMsDuration);
-
- MP4Free(pBytes);
- pBytes = NULL;
-
- // add session level sdp
- CreateIsmaIodFromFile(
- m_odTrackId,
- sceneTrackId,
- audioTrackId,
- videoTrackId,
- &pBytes,
- &numBytes);
-
- char* iodBase64 = MP4ToBase64(pBytes, numBytes);
-
- char* sdpBuf = (char*)MP4Calloc(strlen(iodBase64) + 256);
-
- if (addIsmaComplianceSdp) {
- strcpy(sdpBuf, "a=isma-compliance:1,1.0,1\015\012");
- }
-
- sprintf(&sdpBuf[strlen(sdpBuf)],
- "a=mpeg4-iod: \042data:application/mpeg4-iod;base64,%s\042\015\012",
- iodBase64);
-
- SetSessionSdp(sdpBuf);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("IOD SDP = %s\n", sdpBuf));
-
- MP4Free(iodBase64);
- iodBase64 = NULL;
- MP4Free(pBytes);
- pBytes = NULL;
- MP4Free(sdpBuf);
- sdpBuf = NULL;
-}
-
-static void CloneIntegerProperty(
- MP4Descriptor* pDest,
- MP4DescriptorProperty* pSrc,
- const char* name)
-{
- MP4IntegerProperty* pGetProperty;
- MP4IntegerProperty* pSetProperty;
-
- pSrc->FindProperty(name, (MP4Property**)&pGetProperty);
- pDest->FindProperty(name, (MP4Property**)&pSetProperty);
-
- pSetProperty->SetValue(pGetProperty->GetValue());
-}
-
-void MP4File::CreateIsmaIodFromFile(
- MP4TrackId odTrackId,
- MP4TrackId sceneTrackId,
- MP4TrackId audioTrackId,
- MP4TrackId videoTrackId,
- u_int8_t** ppBytes,
- u_int64_t* pNumBytes)
-{
- MP4Descriptor* pIod = new MP4IODescriptor();
- pIod->SetTag(MP4IODescrTag);
- pIod->Generate();
-
- MP4Atom* pIodsAtom = FindAtom("moov.iods");
- ASSERT(pIodsAtom);
- MP4DescriptorProperty* pSrcIod =
- (MP4DescriptorProperty*)pIodsAtom->GetProperty(2);
-
- CloneIntegerProperty(pIod, pSrcIod, "objectDescriptorId");
- CloneIntegerProperty(pIod, pSrcIod, "ODProfileLevelId");
- CloneIntegerProperty(pIod, pSrcIod, "sceneProfileLevelId");
- CloneIntegerProperty(pIod, pSrcIod, "audioProfileLevelId");
- CloneIntegerProperty(pIod, pSrcIod, "visualProfileLevelId");
- CloneIntegerProperty(pIod, pSrcIod, "graphicsProfileLevelId");
-
- // mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag
- MP4DescriptorProperty* pEsProperty;
- pIod->FindProperty("esIds", (MP4Property**)&pEsProperty);
- pEsProperty->SetTags(MP4ESDescrTag);
-
- MP4IntegerProperty* pSetProperty;
-
- // OD
- MP4Descriptor* pOdEsd =
- pEsProperty->AddDescriptor(MP4ESDescrTag);
- pOdEsd->Generate();
-
- pOdEsd->FindProperty("ESID",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(m_odTrackId);
-
- pOdEsd->FindProperty("URLFlag",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(1);
-
- u_int8_t* pBytes;
- u_int64_t numBytes;
-
- CreateIsmaODUpdateCommandFromFileForStream(
- audioTrackId,
- videoTrackId,
- &pBytes,
- &numBytes);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("OD data =\n"); MP4HexDump(pBytes, numBytes));
-
- char* odCmdBase64 = MP4ToBase64(pBytes, numBytes);
-
- char* urlBuf = (char*)MP4Malloc(strlen(odCmdBase64) + 64);
-
- sprintf(urlBuf,
- "data:application/mpeg4-od-au;base64,%s",
- odCmdBase64);
-
- MP4StringProperty* pUrlProperty;
- pOdEsd->FindProperty("URL",
- (MP4Property**)&pUrlProperty);
- pUrlProperty->SetValue(urlBuf);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("OD data URL = \042%s\042\n", urlBuf));
-
- MP4Free(odCmdBase64);
- odCmdBase64 = NULL;
- MP4Free(pBytes);
- pBytes = NULL;
- MP4Free(urlBuf);
- urlBuf = NULL;
-
- MP4DescriptorProperty* pSrcDcd = NULL;
-
- // HACK temporarily point to scene decoder config
- FindProperty(MakeTrackName(odTrackId,
- "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
- (MP4Property**)&pSrcDcd);
- ASSERT(pSrcDcd);
- MP4Property* pOrgOdEsdProperty =
- pOdEsd->GetProperty(8);
- pOdEsd->SetProperty(8, pSrcDcd);
-
- // bufferSizeDB needs to be set appropriately
- MP4BitfieldProperty* pBufferSizeProperty = NULL;
- pOdEsd->FindProperty("decConfigDescr.bufferSizeDB",
- (MP4Property**)&pBufferSizeProperty);
- ASSERT(pBufferSizeProperty);
- pBufferSizeProperty->SetValue(numBytes);
-
- // SL config needs to change from 2 (file) to 1 (null)
- pOdEsd->FindProperty("slConfigDescr.predefined",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(1);
-
-
- // Scene
- MP4Descriptor* pSceneEsd =
- pEsProperty->AddDescriptor(MP4ESDescrTag);
- pSceneEsd->Generate();
-
- pSceneEsd->FindProperty("ESID",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(sceneTrackId);
-
- pSceneEsd->FindProperty("URLFlag",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(1);
-
- CreateIsmaSceneCommand(
- MP4_IS_VALID_TRACK_ID(audioTrackId),
- MP4_IS_VALID_TRACK_ID(videoTrackId),
- &pBytes,
- &numBytes);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("Scene data =\n"); MP4HexDump(pBytes, numBytes));
-
- char *sceneCmdBase64 = MP4ToBase64(pBytes, numBytes);
-
- urlBuf = (char*)MP4Malloc(strlen(sceneCmdBase64) + 64);
- sprintf(urlBuf,
- "data:application/mpeg4-bifs-au;base64,%s",
- sceneCmdBase64);
-
- pSceneEsd->FindProperty("URL",
- (MP4Property**)&pUrlProperty);
- pUrlProperty->SetValue(urlBuf);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("Scene data URL = \042%s\042\n", urlBuf));
-
- MP4Free(sceneCmdBase64);
- sceneCmdBase64 = NULL;
- MP4Free(urlBuf);
- urlBuf = NULL;
- MP4Free(pBytes);
- pBytes = NULL;
-
- // HACK temporarily point to scene decoder config
- FindProperty(MakeTrackName(sceneTrackId,
- "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
- (MP4Property**)&pSrcDcd);
- ASSERT(pSrcDcd);
- MP4Property* pOrgSceneEsdProperty =
- pSceneEsd->GetProperty(8);
- pSceneEsd->SetProperty(8, pSrcDcd);
-
- // bufferSizeDB needs to be set
- pBufferSizeProperty = NULL;
- pSceneEsd->FindProperty("decConfigDescr.bufferSizeDB",
- (MP4Property**)&pBufferSizeProperty);
- ASSERT(pBufferSizeProperty);
- pBufferSizeProperty->SetValue(numBytes);
-
- // SL config needs to change from 2 (file) to 1 (null)
- pSceneEsd->FindProperty("slConfigDescr.predefined",
- (MP4Property**)&pSetProperty);
- pSetProperty->SetValue(1);
-
-
- // finally get the whole thing written to a memory
- pIod->WriteToMemory(this, ppBytes, pNumBytes);
-
-
- // now carefully replace esd properties before destroying
- pOdEsd->SetProperty(8, pOrgOdEsdProperty);
- pSceneEsd->SetProperty(8, pOrgSceneEsdProperty);
-
- delete pIod;
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("IOD data =\n"); MP4HexDump(*ppBytes, *pNumBytes));
-}
-
-void MP4File::CreateIsmaIodFromParams(
- u_int8_t videoProfile,
- u_int32_t videoBitrate,
- u_int8_t* videoConfig,
- u_int32_t videoConfigLength,
- u_int8_t audioProfile,
- u_int32_t audioBitrate,
- u_int8_t* audioConfig,
- u_int32_t audioConfigLength,
- u_int8_t** ppIodBytes,
- u_int64_t* pIodNumBytes)
-{
- MP4IntegerProperty* pInt;
- u_int8_t* pBytes = NULL;
- u_int64_t numBytes;
-
- // Create the IOD
- MP4Descriptor* pIod = new MP4IODescriptor();
- pIod->SetTag(MP4IODescrTag);
- pIod->Generate();
-
- // Set audio and video profileLevels
- pIod->FindProperty("audioProfileLevelId",
- (MP4Property**)&pInt);
- pInt->SetValue(audioProfile);
-
- pIod->FindProperty("visualProfileLevelId",
- (MP4Property**)&pInt);
- pInt->SetValue(videoProfile);
-
- // Mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag
- MP4DescriptorProperty* pEsProperty;
- pIod->FindProperty("esIds", (MP4Property**)&pEsProperty);
- pEsProperty->SetTags(MP4ESDescrTag);
-
- // Add ES Descriptors
-
- // Scene
- CreateIsmaSceneCommand(
- (audioProfile != 0xFF),
- (videoProfile != 0xFF),
- &pBytes,
- &numBytes);
-
- VERBOSE_ISMA(GetVerbosity(),
- printf("Scene data =\n"); MP4HexDump(pBytes, numBytes));
-
- char* sceneCmdBase64 = MP4ToBase64(pBytes, numBytes);
-
- char* urlBuf =
- (char*)MP4Malloc(strlen(sceneCmdBase64) + 64);
- sprintf(urlBuf,
- "data:application/mpeg4-bifs-au;base64,%s",
- sceneCmdBase64);
-
- VERBOSE_ISMA(GetVerbosity(),
- 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, 0x6D, 0xC0
- };
- static u_int8_t bifsVideoOnly[] = {
- 0xC0, 0x10, 0x12,
- 0x61, 0x04,
- 0x1F, 0xC0, 0x00, 0x00,
- 0x1F, 0xC0, 0x00, 0x00,
- 0x44, 0x28, 0x22, 0x82, 0x9F, 0x80
- };
- static u_int8_t bifsAudioVideo[] = {
- 0xC0, 0x10, 0x12,
- 0x81, 0x30, 0x2A, 0x05, 0x6D, 0x26,
- 0x10, 0x41, 0xFC, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
- 0x04, 0x42, 0x82, 0x28, 0x29, 0xF8
- };
-
- 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;
- }
-}
-
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is MPEG4IP.
+ *
+ * The Initial Developer of the Original Code is Cisco Systems Inc.
+ * Portions created by Cisco Systems Inc. are
+ * Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dave Mackie [email protected]
+ */
+
+#include "mp4common.h"
+
+static u_int8_t BifsV2Config[3] = {
+ 0x00, 0x00, 0x60 // IsCommandStream = 1, PixelMetric = 1
+};
+
+void MP4File::MakeIsmaCompliant(bool addIsmaComplianceSdp)
+{
+ ProtectWriteOperation("MP4MakeIsmaCompliant");
+
+ if (m_useIsma) {
+ // already done
+ return;
+ }
+ m_useIsma = true;
+
+ // find first audio and/or video tracks
+
+ MP4TrackId audioTrackId = MP4_INVALID_TRACK_ID;
+ try {
+ audioTrackId = FindTrackId(0, MP4_AUDIO_TRACK_TYPE);
+ }
+ catch (MP4Error* e) {
+ delete e;
+ }
+
+ MP4TrackId videoTrackId = MP4_INVALID_TRACK_ID;
+ try {
+ videoTrackId = FindTrackId(0, MP4_VIDEO_TRACK_TYPE);
+ }
+ catch (MP4Error* e) {
+ delete e;
+ }
+
+ u_int64_t fileMsDuration =
+ ConvertFromMovieDuration(GetDuration(), MP4_MSECS_TIME_SCALE);
+
+ // delete any existing OD track
+ if (m_odTrackId != MP4_INVALID_TRACK_ID) {
+ DeleteTrack(m_odTrackId);
+ }
+
+ AddODTrack();
+ SetODProfileLevel(0xFF);
+
+ if (audioTrackId != MP4_INVALID_TRACK_ID) {
+ AddTrackToOd(audioTrackId);
+ }
+
+ if (videoTrackId != MP4_INVALID_TRACK_ID) {
+ AddTrackToOd(videoTrackId);
+ }
+
+ // delete any existing scene track
+ MP4TrackId sceneTrackId = MP4_INVALID_TRACK_ID;
+ try {
+ sceneTrackId = FindTrackId(0, MP4_SCENE_TRACK_TYPE);
+ }
+ catch (MP4Error *e) {
+ delete e;
+ }
+ if (sceneTrackId != MP4_INVALID_TRACK_ID) {
+ DeleteTrack(sceneTrackId);
+ }
+
+ // add scene track
+ sceneTrackId = AddSceneTrack();
+ SetSceneProfileLevel(0xFF);
+ SetGraphicsProfileLevel(0xFF);
+ SetTrackIntegerProperty(sceneTrackId,
+ "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId",
+ MP4SystemsV2ObjectType);
+
+ SetTrackESConfiguration(sceneTrackId,
+ BifsV2Config, sizeof(BifsV2Config));
+
+ u_int8_t* pBytes = NULL;
+ u_int64_t numBytes = 0;
+
+ // write OD Update Command
+ CreateIsmaODUpdateCommandFromFileForFile(
+ m_odTrackId,
+ audioTrackId,
+ videoTrackId,
+ &pBytes,
+ &numBytes);
+
+ WriteSample(m_odTrackId, pBytes, numBytes, fileMsDuration);
+
+ MP4Free(pBytes);
+ pBytes = NULL;
+
+ // write BIFS Scene Replace Command
+ CreateIsmaSceneCommand(
+ MP4_IS_VALID_TRACK_ID(audioTrackId),
+ MP4_IS_VALID_TRACK_ID(videoTrackId),
+ &pBytes,
+ &numBytes);
+
+ WriteSample(sceneTrackId, pBytes, numBytes, fileMsDuration);
+
+ MP4Free(pBytes);
+ pBytes = NULL;
+
+ // add session level sdp
+ CreateIsmaIodFromFile(
+ m_odTrackId,
+ sceneTrackId,
+ audioTrackId,
+ videoTrackId,
+ &pBytes,
+ &numBytes);
+
+ char* iodBase64 = MP4ToBase64(pBytes, numBytes);
+
+ char* sdpBuf = (char*)MP4Calloc(strlen(iodBase64) + 256);
+
+ if (addIsmaComplianceSdp) {
+ strcpy(sdpBuf, "a=isma-compliance:1,1.0,1\015\012");
+ }
+
+ sprintf(&sdpBuf[strlen(sdpBuf)],
+ "a=mpeg4-iod: \042data:application/mpeg4-iod;base64,%s\042\015\012",
+ iodBase64);
+
+ SetSessionSdp(sdpBuf);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("IOD SDP = %s\n", sdpBuf));
+
+ MP4Free(iodBase64);
+ iodBase64 = NULL;
+ MP4Free(pBytes);
+ pBytes = NULL;
+ MP4Free(sdpBuf);
+ sdpBuf = NULL;
+}
+
+static void CloneIntegerProperty(
+ MP4Descriptor* pDest,
+ MP4DescriptorProperty* pSrc,
+ const char* name)
+{
+ MP4IntegerProperty* pGetProperty;
+ MP4IntegerProperty* pSetProperty;
+
+ pSrc->FindProperty(name, (MP4Property**)&pGetProperty);
+ pDest->FindProperty(name, (MP4Property**)&pSetProperty);
+
+ pSetProperty->SetValue(pGetProperty->GetValue());
+}
+
+void MP4File::CreateIsmaIodFromFile(
+ MP4TrackId odTrackId,
+ MP4TrackId sceneTrackId,
+ MP4TrackId audioTrackId,
+ MP4TrackId videoTrackId,
+ u_int8_t** ppBytes,
+ u_int64_t* pNumBytes)
+{
+ MP4Descriptor* pIod = new MP4IODescriptor();
+ pIod->SetTag(MP4IODescrTag);
+ pIod->Generate();
+
+ MP4Atom* pIodsAtom = FindAtom("moov.iods");
+ ASSERT(pIodsAtom);
+ MP4DescriptorProperty* pSrcIod =
+ (MP4DescriptorProperty*)pIodsAtom->GetProperty(2);
+
+ CloneIntegerProperty(pIod, pSrcIod, "objectDescriptorId");
+ CloneIntegerProperty(pIod, pSrcIod, "ODProfileLevelId");
+ CloneIntegerProperty(pIod, pSrcIod, "sceneProfileLevelId");
+ CloneIntegerProperty(pIod, pSrcIod, "audioProfileLevelId");
+ CloneIntegerProperty(pIod, pSrcIod, "visualProfileLevelId");
+ CloneIntegerProperty(pIod, pSrcIod, "graphicsProfileLevelId");
+
+ // mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag
+ MP4DescriptorProperty* pEsProperty;
+ pIod->FindProperty("esIds", (MP4Property**)&pEsProperty);
+ pEsProperty->SetTags(MP4ESDescrTag);
+
+ MP4IntegerProperty* pSetProperty;
+
+ // OD
+ MP4Descriptor* pOdEsd =
+ pEsProperty->AddDescriptor(MP4ESDescrTag);
+ pOdEsd->Generate();
+
+ pOdEsd->FindProperty("ESID",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(m_odTrackId);
+
+ pOdEsd->FindProperty("URLFlag",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(1);
+
+ u_int8_t* pBytes;
+ u_int64_t numBytes;
+
+ CreateIsmaODUpdateCommandFromFileForStream(
+ audioTrackId,
+ videoTrackId,
+ &pBytes,
+ &numBytes);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("OD data =\n"); MP4HexDump(pBytes, numBytes));
+
+ char* odCmdBase64 = MP4ToBase64(pBytes, numBytes);
+
+ char* urlBuf = (char*)MP4Malloc(strlen(odCmdBase64) + 64);
+
+ sprintf(urlBuf,
+ "data:application/mpeg4-od-au;base64,%s",
+ odCmdBase64);
+
+ MP4StringProperty* pUrlProperty;
+ pOdEsd->FindProperty("URL",
+ (MP4Property**)&pUrlProperty);
+ pUrlProperty->SetValue(urlBuf);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("OD data URL = \042%s\042\n", urlBuf));
+
+ MP4Free(odCmdBase64);
+ odCmdBase64 = NULL;
+ MP4Free(pBytes);
+ pBytes = NULL;
+ MP4Free(urlBuf);
+ urlBuf = NULL;
+
+ MP4DescriptorProperty* pSrcDcd = NULL;
+
+ // HACK temporarily point to scene decoder config
+ FindProperty(MakeTrackName(odTrackId,
+ "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
+ (MP4Property**)&pSrcDcd);
+ ASSERT(pSrcDcd);
+ MP4Property* pOrgOdEsdProperty =
+ pOdEsd->GetProperty(8);
+ pOdEsd->SetProperty(8, pSrcDcd);
+
+ // bufferSizeDB needs to be set appropriately
+ MP4BitfieldProperty* pBufferSizeProperty = NULL;
+ pOdEsd->FindProperty("decConfigDescr.bufferSizeDB",
+ (MP4Property**)&pBufferSizeProperty);
+ ASSERT(pBufferSizeProperty);
+ pBufferSizeProperty->SetValue(numBytes);
+
+ // SL config needs to change from 2 (file) to 1 (null)
+ pOdEsd->FindProperty("slConfigDescr.predefined",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(1);
+
+
+ // Scene
+ MP4Descriptor* pSceneEsd =
+ pEsProperty->AddDescriptor(MP4ESDescrTag);
+ pSceneEsd->Generate();
+
+ pSceneEsd->FindProperty("ESID",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(sceneTrackId);
+
+ pSceneEsd->FindProperty("URLFlag",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(1);
+
+ CreateIsmaSceneCommand(
+ MP4_IS_VALID_TRACK_ID(audioTrackId),
+ MP4_IS_VALID_TRACK_ID(videoTrackId),
+ &pBytes,
+ &numBytes);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("Scene data =\n"); MP4HexDump(pBytes, numBytes));
+
+ char *sceneCmdBase64 = MP4ToBase64(pBytes, numBytes);
+
+ urlBuf = (char*)MP4Malloc(strlen(sceneCmdBase64) + 64);
+ sprintf(urlBuf,
+ "data:application/mpeg4-bifs-au;base64,%s",
+ sceneCmdBase64);
+
+ pSceneEsd->FindProperty("URL",
+ (MP4Property**)&pUrlProperty);
+ pUrlProperty->SetValue(urlBuf);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("Scene data URL = \042%s\042\n", urlBuf));
+
+ MP4Free(sceneCmdBase64);
+ sceneCmdBase64 = NULL;
+ MP4Free(urlBuf);
+ urlBuf = NULL;
+ MP4Free(pBytes);
+ pBytes = NULL;
+
+ // HACK temporarily point to scene decoder config
+ FindProperty(MakeTrackName(sceneTrackId,
+ "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr"),
+ (MP4Property**)&pSrcDcd);
+ ASSERT(pSrcDcd);
+ MP4Property* pOrgSceneEsdProperty =
+ pSceneEsd->GetProperty(8);
+ pSceneEsd->SetProperty(8, pSrcDcd);
+
+ // bufferSizeDB needs to be set
+ pBufferSizeProperty = NULL;
+ pSceneEsd->FindProperty("decConfigDescr.bufferSizeDB",
+ (MP4Property**)&pBufferSizeProperty);
+ ASSERT(pBufferSizeProperty);
+ pBufferSizeProperty->SetValue(numBytes);
+
+ // SL config needs to change from 2 (file) to 1 (null)
+ pSceneEsd->FindProperty("slConfigDescr.predefined",
+ (MP4Property**)&pSetProperty);
+ pSetProperty->SetValue(1);
+
+
+ // finally get the whole thing written to a memory
+ pIod->WriteToMemory(this, ppBytes, pNumBytes);
+
+
+ // now carefully replace esd properties before destroying
+ pOdEsd->SetProperty(8, pOrgOdEsdProperty);
+ pSceneEsd->SetProperty(8, pOrgSceneEsdProperty);
+
+ delete pIod;
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("IOD data =\n"); MP4HexDump(*ppBytes, *pNumBytes));
+}
+
+void MP4File::CreateIsmaIodFromParams(
+ u_int8_t videoProfile,
+ u_int32_t videoBitrate,
+ u_int8_t* videoConfig,
+ u_int32_t videoConfigLength,
+ u_int8_t audioProfile,
+ u_int32_t audioBitrate,
+ u_int8_t* audioConfig,
+ u_int32_t audioConfigLength,
+ u_int8_t** ppIodBytes,
+ u_int64_t* pIodNumBytes)
+{
+ MP4IntegerProperty* pInt;
+ u_int8_t* pBytes = NULL;
+ u_int64_t numBytes;
+
+ // Create the IOD
+ MP4Descriptor* pIod = new MP4IODescriptor();
+ pIod->SetTag(MP4IODescrTag);
+ pIod->Generate();
+
+ // Set audio and video profileLevels
+ pIod->FindProperty("audioProfileLevelId",
+ (MP4Property**)&pInt);
+ pInt->SetValue(audioProfile);
+
+ pIod->FindProperty("visualProfileLevelId",
+ (MP4Property**)&pInt);
+ pInt->SetValue(videoProfile);
+
+ // Mutate esIds from MP4ESIDIncDescrTag to MP4ESDescrTag
+ MP4DescriptorProperty* pEsProperty;
+ pIod->FindProperty("esIds", (MP4Property**)&pEsProperty);
+ pEsProperty->SetTags(MP4ESDescrTag);
+
+ // Add ES Descriptors
+
+ // Scene
+ CreateIsmaSceneCommand(
+ (audioProfile != 0xFF),
+ (videoProfile != 0xFF),
+ &pBytes,
+ &numBytes);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ printf("Scene data =\n"); MP4HexDump(pBytes, numBytes));
+
+ char* sceneCmdBase64 = MP4ToBase64(pBytes, numBytes);
+
+ char* urlBuf =
+ (char*)MP4Malloc(strlen(sceneCmdBase64) + 64);
+ sprintf(urlBuf,
+ "data:application/mpeg4-bifs-au;base64,%s",
+ sceneCmdBase64);
+
+ VERBOSE_ISMA(GetVerbosity(),
+ 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;
+
+ // OD
+
+ // Video
+ MP4DescriptorProperty* pVideoEsdProperty =
+ new MP4DescriptorProperty();
+ pVideoEsdProperty->SetTags(MP4ESDescrTag);
+
+ /* MP4Descriptor* pVideoEsd = */
+ CreateESD(
+ pVideoEsdProperty,
+ 20, // esid
+ MP4_MPEG4_VIDEO_TYPE,
+ MP4VisualStreamType,
+ videoBitrate / 8, // bufferSize
+ videoBitrate,
+ videoConfig,
+ videoConfigLength,
+ NULL);
+
+ // Audio
+ MP4DescriptorProperty* pAudioEsdProperty =
+ new MP4DescriptorProperty();
+ pAudioEsdProperty->SetTags(MP4ESDescrTag);
+
+ /* MP4Descriptor* pAudioEsd = */
+ CreateESD(
+ pAudioEsdProperty,
+ 10, // esid
+ MP4_MPEG4_AUDIO_TYPE,
+ MP4AudioStreamType,
+ audioBitrate / 8, // bufferSize
+ audioBitrate,
+ audioConfig,
+ audioConfigLength,
+ NULL);
+
+ CreateIsmaODUpdateCommandForStream(
+ pAudioEsdProperty,
+ pVideoEsdProperty,
+ &pBytes,
+ &numBytes);
+
+ // cleanup temporary descriptor properties
+ delete pAudioEsdProperty;
+ delete pVideoEsdProperty;
+
+ 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, 0x6D, 0xC0
+ };
+ static u_int8_t bifsVideoOnly[] = {
+ 0xC0, 0x10, 0x12,
+ 0x61, 0x04,
+ 0x1F, 0xC0, 0x00, 0x00,
+ 0x1F, 0xC0, 0x00, 0x00,
+ 0x44, 0x28, 0x22, 0x82, 0x9F, 0x80
+ };
+ static u_int8_t bifsAudioVideo[] = {
+ 0xC0, 0x10, 0x12,
+ 0x81, 0x30, 0x2A, 0x05, 0x6D, 0x26,
+ 0x10, 0x41, 0xFC, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
+ 0x04, 0x42, 0x82, 0x28, 0x29, 0xF8
+ };
+
+ 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;
+ }
+}
+
--- a/common/mp4v2/libmp4v2_st60.vcproj
+++ b/common/mp4v2/libmp4v2_st60.vcproj
@@ -3,6 +3,7 @@
ProjectType="Visual C++"
Version="7.00"
Name="libmp4v2_st"
+ ProjectGUID="{0842E354-7635-4B5D-8709-9A373ED27DCA}"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -32,13 +33,30 @@
ProgramDataBaseFileName=".\ST_Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
- CompileAs="0"/>
+ CompileAs="0"
+ AdditionalOptions="">
+ <IntelOptions
+ Optimization="2"
+ InlineFuncExpansion="1"
+ OmitFramePtrs="1"
+ StringPooling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="1"
+ FunctionLevelLinking="1"
+ AllOptions="/c /I ".\\" /nologo /W3 /O2 /Ob1 /Oy /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /GF /FD /EHsc /MT /GS /Gy /YX"StdAfx.h" /Fp".\ST_Release/libmp4v2_st60.pch" /Fo".\ST_Release/" /Fd".\ST_Release/" /Gd"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\ST_Release\libmp4v2_st60.lib"
- SuppressStartupBanner="TRUE"/>
+ SuppressStartupBanner="TRUE"
+ AdditionalOptions="">
+ <IntelOptions
+ AllOptions="/OUT:".\ST_Release\libmp4v2_st60.lib" /NOLOGO"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -74,13 +92,27 @@
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="1"
- CompileAs="0"/>
+ CompileAs="0"
+ AdditionalOptions="">
+ <IntelOptions
+ Optimization="0"
+ MinimalRebuild="1"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ AllOptions="/c /I ".\\" /Z7 /nologo /W3 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Gm /EHsc /RTC1 /MTd /YX"StdAfx.h" /Fp".\ST_Debug/libmp4v2_st60.pch" /Fo".\ST_Debug/" /Fd".\ST_Debug/" /Gd"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\ST_Debug\libmp4v2_st60.lib"
- SuppressStartupBanner="TRUE"/>
+ SuppressStartupBanner="TRUE"
+ AdditionalOptions="">
+ <IntelOptions
+ AllOptions="/OUT:".\ST_Debug\libmp4v2_st60.lib" /NOLOGO"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -94,6 +126,8 @@
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
+ <IntelOptions
+ CompilerName="1"/>
</Configuration>
</Configurations>
<Files>
@@ -101,323 +135,218 @@
Name="source"
Filter=".c, .cpp">
<File
- RelativePath=".\atom_co64.cpp">
- </File>
+ RelativePath=".\atom_co64.cpp"/>
<File
- RelativePath=".\atom_cprt.cpp">
- </File>
+ RelativePath=".\atom_cprt.cpp"/>
<File
- RelativePath=".\atom_ctts.cpp">
- </File>
+ RelativePath=".\atom_ctts.cpp"/>
<File
- RelativePath=".\atom_dimm.cpp">
- </File>
+ RelativePath=".\atom_dimm.cpp"/>
<File
- RelativePath=".\atom_dinf.cpp">
- </File>
+ RelativePath=".\atom_dinf.cpp"/>
<File
- RelativePath=".\atom_dmax.cpp">
- </File>
+ RelativePath=".\atom_dmax.cpp"/>
<File
- RelativePath=".\atom_dmed.cpp">
- </File>
+ RelativePath=".\atom_dmed.cpp"/>
<File
- RelativePath=".\atom_dref.cpp">
- </File>
+ RelativePath=".\atom_dref.cpp"/>
<File
- RelativePath=".\atom_drep.cpp">
- </File>
+ RelativePath=".\atom_drep.cpp"/>
<File
- RelativePath=".\atom_edts.cpp">
- </File>
+ RelativePath=".\atom_edts.cpp"/>
<File
- RelativePath=".\atom_elst.cpp">
- </File>
+ RelativePath=".\atom_elst.cpp"/>
<File
- RelativePath=".\atom_esds.cpp">
- </File>
+ RelativePath=".\atom_esds.cpp"/>
<File
- RelativePath=".\atom_free.cpp">
- </File>
+ RelativePath=".\atom_free.cpp"/>
<File
- RelativePath=".\atom_ftyp.cpp">
- </File>
+ RelativePath=".\atom_ftyp.cpp"/>
<File
- RelativePath=".\atom_hdlr.cpp">
- </File>
+ RelativePath=".\atom_hdlr.cpp"/>
<File
- RelativePath=".\atom_hinf.cpp">
- </File>
+ RelativePath=".\atom_hinf.cpp"/>
<File
- RelativePath=".\atom_hmhd.cpp">
- </File>
+ RelativePath=".\atom_hmhd.cpp"/>
<File
- RelativePath=".\atom_hnti.cpp">
- </File>
+ RelativePath=".\atom_hnti.cpp"/>
<File
- RelativePath=".\atom_iods.cpp">
- </File>
+ RelativePath=".\atom_iods.cpp"/>
<File
- RelativePath=".\atom_maxr.cpp">
- </File>
+ RelativePath=".\atom_maxr.cpp"/>
<File
- RelativePath=".\atom_mdat.cpp">
- </File>
+ RelativePath=".\atom_mdat.cpp"/>
<File
- RelativePath=".\atom_mdhd.cpp">
- </File>
+ RelativePath=".\atom_mdhd.cpp"/>
<File
- RelativePath=".\atom_mdia.cpp">
- </File>
+ RelativePath=".\atom_mdia.cpp"/>
<File
- RelativePath=".\atom_mfhd.cpp">
- </File>
+ RelativePath=".\atom_mfhd.cpp"/>
<File
- RelativePath=".\atom_minf.cpp">
- </File>
+ RelativePath=".\atom_minf.cpp"/>
<File
- RelativePath=".\atom_moof.cpp">
- </File>
+ RelativePath=".\atom_moof.cpp"/>
<File
- RelativePath=".\atom_moov.cpp">
- </File>
+ RelativePath=".\atom_moov.cpp"/>
<File
- RelativePath=".\atom_mp4a.cpp">
- </File>
+ RelativePath=".\atom_mp4a.cpp"/>
<File
- RelativePath=".\atom_mp4s.cpp">
- </File>
+ RelativePath=".\atom_mp4s.cpp"/>
<File
- RelativePath=".\atom_mp4v.cpp">
- </File>
+ RelativePath=".\atom_mp4v.cpp"/>
<File
- RelativePath=".\atom_mvex.cpp">
- </File>
+ RelativePath=".\atom_mvex.cpp"/>
<File
- RelativePath=".\atom_mvhd.cpp">
- </File>
+ RelativePath=".\atom_mvhd.cpp"/>
<File
- RelativePath=".\atom_nmhd.cpp">
- </File>
+ RelativePath=".\atom_nmhd.cpp"/>
<File
- RelativePath=".\atom_nump.cpp">
- </File>
+ RelativePath=".\atom_nump.cpp"/>
<File
- RelativePath=".\atom_payt.cpp">
- </File>
+ RelativePath=".\atom_payt.cpp"/>
<File
- RelativePath=".\atom_pmax.cpp">
- </File>
+ RelativePath=".\atom_pmax.cpp"/>
<File
- RelativePath=".\atom_root.cpp">
- </File>
+ RelativePath=".\atom_root.cpp"/>
<File
- RelativePath=".\atom_rtp.cpp">
- </File>
+ RelativePath=".\atom_rtp.cpp"/>
<File
- RelativePath=".\atom_sdp.cpp">
- </File>
+ RelativePath=".\atom_sdp.cpp"/>
<File
- RelativePath=".\atom_smhd.cpp">
- </File>
+ RelativePath=".\atom_smhd.cpp"/>
<File
- RelativePath=".\atom_snro.cpp">
- </File>
+ RelativePath=".\atom_snro.cpp"/>
<File
- RelativePath=".\atom_stbl.cpp">
- </File>
+ RelativePath=".\atom_stbl.cpp"/>
<File
- RelativePath=".\atom_stco.cpp">
- </File>
+ RelativePath=".\atom_stco.cpp"/>
<File
- RelativePath=".\atom_stdp.cpp">
- </File>
+ RelativePath=".\atom_stdp.cpp"/>
<File
- RelativePath=".\atom_stsc.cpp">
- </File>
+ RelativePath=".\atom_stsc.cpp"/>
<File
- RelativePath=".\atom_stsd.cpp">
- </File>
+ RelativePath=".\atom_stsd.cpp"/>
<File
- RelativePath=".\atom_stsh.cpp">
- </File>
+ RelativePath=".\atom_stsh.cpp"/>
<File
- RelativePath=".\atom_stss.cpp">
- </File>
+ RelativePath=".\atom_stss.cpp"/>
<File
- RelativePath=".\atom_stsz.cpp">
- </File>
+ RelativePath=".\atom_stsz.cpp"/>
<File
- RelativePath=".\atom_stts.cpp">
- </File>
+ RelativePath=".\atom_stts.cpp"/>
<File
- RelativePath=".\atom_tfhd.cpp">
- </File>
+ RelativePath=".\atom_tfhd.cpp"/>
<File
- RelativePath=".\atom_tims.cpp">
- </File>
+ RelativePath=".\atom_tims.cpp"/>
<File
- RelativePath=".\atom_tkhd.cpp">
- </File>
+ RelativePath=".\atom_tkhd.cpp"/>
<File
- RelativePath=".\atom_tmax.cpp">
- </File>
+ RelativePath=".\atom_tmax.cpp"/>
<File
- RelativePath=".\atom_tmin.cpp">
- </File>
+ RelativePath=".\atom_tmin.cpp"/>
<File
- RelativePath=".\atom_tpyl.cpp">
- </File>
+ RelativePath=".\atom_tpyl.cpp"/>
<File
- RelativePath=".\atom_traf.cpp">
- </File>
+ RelativePath=".\atom_traf.cpp"/>
<File
- RelativePath=".\atom_trak.cpp">
- </File>
+ RelativePath=".\atom_trak.cpp"/>
<File
- RelativePath=".\atom_tref.cpp">
- </File>
+ RelativePath=".\atom_tref.cpp"/>
<File
- RelativePath=".\atom_treftype.cpp">
- </File>
+ RelativePath=".\atom_treftype.cpp"/>
<File
- RelativePath=".\atom_trex.cpp">
- </File>
+ RelativePath=".\atom_trex.cpp"/>
<File
- RelativePath=".\atom_trpy.cpp">
- </File>
+ RelativePath=".\atom_trpy.cpp"/>
<File
- RelativePath=".\atom_trun.cpp">
- </File>
+ RelativePath=".\atom_trun.cpp"/>
<File
- RelativePath=".\atom_tsro.cpp">
- </File>
+ RelativePath=".\atom_tsro.cpp"/>
<File
- RelativePath=".\atom_udta.cpp">
- </File>
+ RelativePath=".\atom_udta.cpp"/>
<File
- RelativePath=".\atom_url.cpp">
- </File>
+ RelativePath=".\atom_url.cpp"/>
<File
- RelativePath=".\atom_urn.cpp">
- </File>
+ RelativePath=".\atom_urn.cpp"/>
<File
- RelativePath=".\atom_vmhd.cpp">
- </File>
+ RelativePath=".\atom_vmhd.cpp"/>
<File
- RelativePath=".\descriptors.cpp">
- </File>
+ RelativePath=".\descriptors.cpp"/>
<File
- RelativePath=".\isma.cpp">
- </File>
+ RelativePath=".\isma.cpp"/>
<File
- RelativePath=".\mp4.cpp">
- </File>
+ RelativePath=".\mp4.cpp"/>
<File
- RelativePath=".\mp4atom.cpp">
- </File>
+ RelativePath=".\mp4atom.cpp"/>
<File
- RelativePath=".\mp4container.cpp">
- </File>
+ RelativePath=".\mp4container.cpp"/>
<File
- RelativePath=".\mp4descriptor.cpp">
- </File>
+ RelativePath=".\mp4descriptor.cpp"/>
<File
- RelativePath=".\mp4file.cpp">
- </File>
+ RelativePath=".\mp4file.cpp"/>
<File
- RelativePath=".\mp4file_io.cpp">
- </File>
+ RelativePath=".\mp4file_io.cpp"/>
<File
- RelativePath=".\mp4property.cpp">
- </File>
+ RelativePath=".\mp4property.cpp"/>
<File
- RelativePath=".\mp4track.cpp">
- </File>
+ RelativePath=".\mp4track.cpp"/>
<File
- RelativePath=".\mp4util.cpp">
- </File>
+ RelativePath=".\mp4util.cpp"/>
<File
- RelativePath=".\need_for_win32.c">
- </File>
+ RelativePath=".\need_for_win32.c"/>
<File
- RelativePath=".\ocidescriptors.cpp">
- </File>
+ RelativePath=".\ocidescriptors.cpp"/>
<File
- RelativePath=".\odcommands.cpp">
- </File>
+ RelativePath=".\odcommands.cpp"/>
<File
- RelativePath=".\qosqualifiers.cpp">
- </File>
+ RelativePath=".\qosqualifiers.cpp"/>
<File
- RelativePath=".\rtphint.cpp">
- </File>
+ RelativePath=".\rtphint.cpp"/>
</Filter>
<Filter
Name="include"
Filter=".h">
<File
- RelativePath=".\atoms.h">
- </File>
+ RelativePath=".\atoms.h"/>
<File
- RelativePath=".\descriptors.h">
- </File>
+ RelativePath=".\descriptors.h"/>
<File
- RelativePath=".\mp4.h">
- </File>
+ RelativePath=".\mp4.h"/>
<File
- RelativePath=".\mp4array.h">
- </File>
+ RelativePath=".\mp4array.h"/>
<File
- RelativePath=".\mp4atom.h">
- </File>
+ RelativePath=".\mp4atom.h"/>
<File
- RelativePath=".\mp4common.h">
- </File>
+ RelativePath=".\mp4common.h"/>
<File
- RelativePath=".\mp4container.h">
- </File>
+ RelativePath=".\mp4container.h"/>
<File
- RelativePath=".\mp4descriptor.h">
- </File>
+ RelativePath=".\mp4descriptor.h"/>
<File
- RelativePath=".\mp4file.h">
- </File>
+ RelativePath=".\mp4file.h"/>
<File
- RelativePath=".\mp4property.h">
- </File>
+ RelativePath=".\mp4property.h"/>
<File
- RelativePath=".\mp4track.h">
- </File>
+ RelativePath=".\mp4track.h"/>
<File
- RelativePath=".\mp4util.h">
- </File>
+ RelativePath=".\mp4util.h"/>
<File
- RelativePath=".\mpeg4ip.h">
- </File>
+ RelativePath=".\mpeg4ip.h"/>
<File
- RelativePath=".\ocidescriptors.h">
- </File>
+ RelativePath=".\ocidescriptors.h"/>
<File
- RelativePath=".\odcommands.h">
- </File>
+ RelativePath=".\odcommands.h"/>
<File
- RelativePath=".\qosqualifiers.h">
- </File>
+ RelativePath=".\qosqualifiers.h"/>
<File
- RelativePath=".\rtphint.h">
- </File>
+ RelativePath=".\rtphint.h"/>
<File
- RelativePath=".\systems.h">
- </File>
+ RelativePath=".\systems.h"/>
<File
- RelativePath=".\win32_ver.h">
- </File>
+ RelativePath=".\win32_ver.h"/>
</Filter>
<File
- RelativePath=".\mp4info.cpp">
- </File>
+ RelativePath=".\mp4info.cpp"/>
</Files>
- <Globals>
- </Globals>
+ <Globals/>
</VisualStudioProject>
--- a/common/mp4v2/mp4atom.cpp
+++ b/common/mp4v2/mp4atom.cpp
@@ -278,15 +278,16 @@
u_int64_t dataSize = pFile->ReadUInt32();
+ char type[5];
+ pFile->ReadBytes((u_int8_t*)&type[0], 4);
+ type[4] = '\0';
+
+ // extended size
if (dataSize == 1) {
dataSize = pFile->ReadUInt64();
hdrSize += 8;
}
- char type[5];
- pFile->ReadBytes((u_int8_t*)&type[0], 4);
- type[4] = '\0';
-
// extended type
if (ATOMID(type) == ATOMID("uuid")) {
pFile->ReadBytes(extendedType, sizeof(extendedType));
@@ -612,11 +613,13 @@
m_start = m_pFile->GetPosition();
if (use64) {
m_pFile->WriteUInt32(1);
- m_pFile->WriteUInt64(0);
} else {
m_pFile->WriteUInt32(0);
}
m_pFile->WriteBytes((u_int8_t*)&m_type[0], 4);
+ if (use64) {
+ m_pFile->WriteUInt64(0);
+ }
if (ATOMID(m_type) == ATOMID("uuid")) {
m_pFile->WriteBytes(m_extendedType, sizeof(m_extendedType));
}
@@ -627,7 +630,7 @@
m_end = m_pFile->GetPosition();
m_size = (m_end - m_start);
if (use64) {
- m_pFile->SetPosition(m_start + 4);
+ m_pFile->SetPosition(m_start + 8);
m_pFile->WriteUInt64(m_size);
} else {
ASSERT(m_size <= (u_int64_t)0xFFFFFFFF);
--- a/common/mp4v2/systems.h
+++ b/common/mp4v2/systems.h
@@ -28,6 +28,8 @@
#define HAVE_SOCKLEN_T
#include <win32_ver.h>
#else
+#undef PACKAGE
+#undef VERSION
#include <config.h>
#endif
@@ -197,7 +199,7 @@
#ifdef sun
#include <limits.h>
#define u_int8_t uint8_t
-#define u_int16_t uint8_t
+#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#define __STRING(expr) #expr
@@ -227,6 +229,7 @@
#define MALLOC_STRUCTURE(a) ((a *)malloc(sizeof(a)))
+#define CHECK_AND_FREE(a) if ((a) != NULL) { free((a)); (a) = NULL;}
#ifndef HAVE_GLIB_H
typedef char gchar;
typedef unsigned char guchar;
--- a/common/mp4v2/win32_ver.h
+++ b/common/mp4v2/win32_ver.h
@@ -1,2 +1,2 @@
#define PACKAGE "mpeg4ip"
-#define VERSION "0.9.5"
+#define VERSION "0.9.6.4"
--- a/configure.in
+++ b/configure.in
@@ -1,13 +1,11 @@
AC_INIT()
AM_INIT_AUTOMAKE(faad,2.0)
-AC_PROG_CC
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
dnl Checks for programs.
AC_PROG_CXX
-AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
@@ -15,19 +13,50 @@
AC_PROG_MAKE_SET
AC_PROG_RANLIB
+AM_CONFIG_HEADER(config.h)
+
+
dnl Checks for header files required for mp4.h
+AC_HEADER_STDC
AC_CHECK_HEADERS(stdint.h inttypes.h)
+AC_CHECK_HEADERS(mathf.h)
+AC_CHECK_HEADERS(float.h)
+AC_CHECK_FUNCS(strchr memcpy)
-dnl Checks for sndfile library.
-AC_CHECK_LIB(sndfile, sf_perror, have_sndfile_lib=yes)
-AC_CHECK_HEADER(sndfile.h, have_sndfile_hdr=yes)
+AC_C_INLINE
+AC_C_BIGENDIAN
-if test x$have_sndfile_lib != xyes -o x$have_sndfile_hdr != xyes; then
-AC_MSG_ERROR([
- *** FAAD requires libsndfile to be installed first.
- *** A copy of it is included in common/libsndfile.
- ])
+AC_DEFUN(MY_CHECK_TYPEDEF_FROM_INCLUDE,
+[
+ AC_MSG_CHECKING([for $1])
+ AC_TRY_COMPILE([$2],
+ [$1;],
+ libfaad_ok=yes, libfaad_ok=no)
+ if test $libfaad_ok = yes; then
+ AC_DEFINE($3)
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
fi
+])
+
+
+MY_CHECK_TYPEDEF_FROM_INCLUDE([float32_t temp],
+ [#include <sys/types.h>,
+ #include <sys/float.h>], [HAVE_FLOAT32_T])
+
+AC_CHECK_FUNCS(strsep)
+
+MY_CHECK_TYPEDEF_FROM_INCLUDE([in_port_t temp],
+ [#include <sys/types.h>
+ #include <netinet/in.h>], [HAVE_IN_PORT_T])
+MY_CHECK_TYPEDEF_FROM_INCLUDE([socklen_t temp],
+ [#include <sys/types.h>
+ #include <sys/socket.h>], HAVE_SOCKLEN_T)
+MY_CHECK_TYPEDEF_FROM_INCLUDE([fpos_t foo; foo.__pos = 0;],
+ [#include <stdio.h>],
+ [HAVE_FPOS_T_POS])
+
AC_OUTPUT_COMMANDS(,[cd common/mp4v2; aclocal -I .; autoheader; libtoolize --automake; automake --add-missing; autoconf; cd -])
--- a/frontend/Makefile.am
+++ b/frontend/Makefile.am
@@ -2,8 +2,6 @@
faad_SOURCES = main.c audio.c
-CXXFLAGS = -O2
-CFLAGS = -O2 -D_FILE_OFFSET_BITS=64
+CFLAGS = -O2
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/common/mp4v2
-LDFLAGS =
-LDADD = $(top_builddir)/libfaad/libfaad.la $(top_builddir)/common/mp4v2/libmp4v2.la -lm -lsndfile
+LDADD = $(top_builddir)/libfaad/libfaad.la
--- a/frontend/faad.vcproj
+++ b/frontend/faad.vcproj
@@ -33,12 +33,21 @@
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
- CompileAs="0"/>
+ CompileAs="0"
+ AdditionalOptions="">
+ <IntelOptions
+ Optimization="0"
+ MinimalRebuild="1"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ AllOptions="/c /I "../include" /I "../common/mp4v2" /I "../common/faad" /ZI /nologo /W3 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MTd /YX"StdAfx.h" /Fp".\Debug/faad.pch" /Fo".\Debug/" /Fd".\Debug/" /Gd"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
+ AdditionalOptions="/MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib""
AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib"
OutputFile=".\Debug/faad.exe"
LinkIncremental="2"
@@ -45,7 +54,11 @@
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/faad.pdb"
- SubSystem="1"/>
+ SubSystem="1">
+ <IntelOptions
+ AllOptions="/NOLOGO /OUT:".\Debug/faad.exe" /INCREMENTAL ws2_32.lib odbc32.lib odbccp32.lib /DEBUG /PDB:".\Debug/faad.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
+ MSOriginalAdditionalOptions="/MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib""/>
+ </Tool>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/faad.tlb"/>
@@ -63,6 +76,8 @@
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
+ <IntelOptions
+ CompilerName="1"/>
</Configuration>
<Configuration
Name="Release|Win32"
@@ -82,7 +97,7 @@
AdditionalIncludeDirectories="../include,../common/mp4v2,../common/faad"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
- RuntimeLibrary="4"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/faad.pch"
@@ -91,17 +106,34 @@
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
- CompileAs="0"/>
+ CompileAs="0"
+ AdditionalOptions="">
+ <IntelOptions
+ Optimization="2"
+ GlobalOptimizations="1"
+ InlineFuncExpansion="1"
+ OmitFramePtrs="1"
+ StringPooling="1"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="1"
+ FunctionLevelLinking="1"
+ AllOptions="/c /I "../include" /I "../common/mp4v2" /I "../common/faad" /nologo /W3 /O2 /Og /Ob1 /Oy /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /FD /EHsc /MT /GS /Gy /YX"StdAfx.h" /Fp".\Release/faad.pch" /Fo".\Release/" /Fd".\Release/" /Gd"
+ MSOriginalAdditionalOptions=""/>
+ </Tool>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
+ AdditionalOptions="/MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib""
AdditionalDependencies="ws2_32.lib"
OutputFile=".\Release/faad.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
- SubSystem="1"/>
+ SubSystem="1">
+ <IntelOptions
+ AllOptions="/NOLOGO /OUT:".\Release/faad.exe" /INCREMENTAL:NO ws2_32.lib /SUBSYSTEM:CONSOLE /TLBID:1 /MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"
+ MSOriginalAdditionalOptions="/MACHINE:I386 "e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib" "e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib" "e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib""/>
+ </Tool>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/faad.tlb"/>
@@ -119,6 +151,8 @@
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
+ <IntelOptions
+ CompilerName="0"/>
</Configuration>
</Configurations>
<Files>
@@ -126,41 +160,30 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
- RelativePath=".\audio.c">
- </File>
+ RelativePath=".\audio.c"/>
<File
- RelativePath="..\common\faad\getopt.c">
- </File>
+ RelativePath="..\common\faad\getopt.c"/>
<File
- RelativePath=".\main.c">
- </File>
+ RelativePath=".\main.c"/>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
- RelativePath=".\audio.h">
- </File>
+ RelativePath=".\audio.h"/>
<File
- RelativePath="..\include\faad.h">
- </File>
+ RelativePath="..\include\faad.h"/>
<File
- RelativePath="..\common\faad\getopt.h">
- </File>
+ RelativePath="..\common\faad\getopt.h"/>
<File
- RelativePath="..\common\mp4v2\mp4.h">
- </File>
+ RelativePath="..\common\mp4v2\mp4.h"/>
<File
- RelativePath="..\common\mp4v2\mpeg4ip.h">
- </File>
+ RelativePath="..\common\mp4v2\mpeg4ip.h"/>
<File
- RelativePath="..\common\mp4v2\systems.h">
- </File>
+ RelativePath="..\common\mp4v2\systems.h"/>
<File
- RelativePath="..\common\mp4v2\win32_ver.h">
- </File>
+ RelativePath="..\common\mp4v2\win32_ver.h"/>
</Filter>
</Files>
- <Globals>
- </Globals>
+ <Globals/>
</VisualStudioProject>
--- a/include/faad.h
+++ b/include/faad.h
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: faad.h,v 1.16 2002/11/01 11:19:35 menno Exp $
+** $Id: faad.h,v 1.17 2002/12/10 19:45:35 menno Exp $
**/
#ifndef __AACDEC_H__
@@ -107,6 +107,10 @@
char FAADAPI faacDecInit2(faacDecHandle hDecoder, unsigned char *pBuffer,
unsigned long SizeOfDecoderSpecificInfo,
unsigned long *samplerate, unsigned char *channels);
+
+/* Init the library for DRM */
+char FAADAPI faacDecInitDRM(faacDecHandle hDecoder, unsigned long samplerate,
+ unsigned char channels);
void FAADAPI faacDecClose(faacDecHandle hDecoder);
--- a/libfaad/bits.c
+++ b/libfaad/bits.c
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: bits.c,v 1.17 2002/11/28 18:48:29 menno Exp $
+** $Id: bits.c,v 1.18 2002/12/10 19:45:35 menno Exp $
**/
#include "common.h"
@@ -76,6 +76,26 @@
return (8 - remainder);
}
return 0;
+}
+
+/* rewind to beginning */
+void faad_rewindbits(bitfile *ld)
+{
+ uint32_t tmp;
+
+ tmp = ld->start[0];
+#ifndef ARCH_IS_BIG_ENDIAN
+ BSWAP(tmp);
+#endif
+ ld->bufa = tmp;
+
+ tmp = ld->start[1];
+#ifndef ARCH_IS_BIG_ENDIAN
+ BSWAP(tmp);
+#endif
+ ld->bufb = tmp;
+ ld->bits_left = 32;
+ ld->tail = &ld->start[2];
}
uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
--- a/libfaad/bits.h
+++ b/libfaad/bits.h
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: bits.h,v 1.14 2002/11/28 18:48:29 menno Exp $
+** $Id: bits.h,v 1.15 2002/12/10 19:45:35 menno Exp $
**/
#ifndef __BITS_H__
@@ -70,6 +70,7 @@
uint32_t bits_in_buffer);
uint8_t faad_byte_align(bitfile *ld);
uint32_t faad_get_processed_bits(bitfile *ld);
+void faad_rewindbits(bitfile *ld);
uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
DEBUGDEC);
--- a/libfaad/common.h
+++ b/libfaad/common.h
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: common.h,v 1.27 2002/12/05 19:28:22 menno Exp $
+** $Id: common.h,v 1.28 2002/12/10 19:45:35 menno Exp $
**/
#ifndef __COMMON_H__
@@ -156,6 +156,10 @@
# endif
#endif
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define ARCH_IS_BIG_ENDIAN
#endif
/* FIXED_POINT doesn't work with MAIN and SSR yet */
--- a/libfaad/syntax.c
+++ b/libfaad/syntax.c
@@ -16,7 +16,7 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: syntax.c,v 1.35 2002/12/10 14:53:15 menno Exp $
+** $Id: syntax.c,v 1.36 2002/12/10 19:45:36 menno Exp $
**/
/*
@@ -451,6 +451,35 @@
return elements;
}
+
+#ifdef DRM
+static uint8_t faad_check_CRC(bitfile *ld)
+{
+ uint16_t len = faad_get_processed_bits(ld) - 8;
+ uint8_t CRC;
+ uint16_t r=255; /* Initialize to all ones */
+
+ /* CRC polynome used x^8 + x^4 + x^3 + x^2 +1 */
+#define GPOLY 0435
+
+ faad_rewindbits(ld);
+
+ CRC = ~faad_getbits(ld, 8
+ DEBUGVAR(1,999,"faad_check_CRC(): CRC")); /* CRC is stored inverted */
+
+ for (; len>0; len--)
+ {
+ r = ( (r << 1) ^ (( ( faad_get1bit(ld
+ DEBUGVAR(1,998,"")) & 1) ^ ((r >> 7) & 1)) * GPOLY )) & 0xFF;
+ }
+ if (r != CRC)
+ {
+ return 8;
+ } else {
+ return 0;
+ }
+}
+#endif
/* Table 4.4.4 and */
/* Table 4.4.9 */