shithub: aacdec

Download patch

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		dmackie@cisco.com
- */
-
-#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		dmackie@cisco.com
+ */
+
+#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 &quot;.\\&quot; /nologo /W3 /O2 /Ob1 /Oy /D &quot;WIN32&quot; /D &quot;NDEBUG&quot; /D &quot;_WINDOWS&quot; /GF /FD /EHsc /MT /GS /Gy /YX&quot;StdAfx.h&quot; /Fp&quot;.\ST_Release/libmp4v2_st60.pch&quot; /Fo&quot;.\ST_Release/&quot; /Fd&quot;.\ST_Release/&quot; /Gd"
+					MSOriginalAdditionalOptions=""/>
+			</Tool>
 			<Tool
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLibrarianTool"
 				OutputFile=".\ST_Release\libmp4v2_st60.lib"
-				SuppressStartupBanner="TRUE"/>
+				SuppressStartupBanner="TRUE"
+				AdditionalOptions="">
+				<IntelOptions
+					AllOptions="/OUT:&quot;.\ST_Release\libmp4v2_st60.lib&quot; /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 &quot;.\\&quot; /Z7 /nologo /W3 /Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /Gm /EHsc /RTC1 /MTd /YX&quot;StdAfx.h&quot; /Fp&quot;.\ST_Debug/libmp4v2_st60.pch&quot; /Fo&quot;.\ST_Debug/&quot; /Fd&quot;.\ST_Debug/&quot; /Gd"
+					MSOriginalAdditionalOptions=""/>
+			</Tool>
 			<Tool
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLibrarianTool"
 				OutputFile=".\ST_Debug\libmp4v2_st60.lib"
-				SuppressStartupBanner="TRUE"/>
+				SuppressStartupBanner="TRUE"
+				AdditionalOptions="">
+				<IntelOptions
+					AllOptions="/OUT:&quot;.\ST_Debug\libmp4v2_st60.lib&quot; /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 &quot;../include&quot; /I &quot;../common/mp4v2&quot; /I &quot;../common/faad&quot; /ZI /nologo /W3 /Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_CONSOLE&quot; /D &quot;_MBCS&quot; /Gm /EHsc /RTC1 /MTd /YX&quot;StdAfx.h&quot; /Fp&quot;.\Debug/faad.pch&quot; /Fo&quot;.\Debug/&quot; /Fd&quot;.\Debug/&quot; /Gd"
+					MSOriginalAdditionalOptions=""/>
+			</Tool>
 			<Tool
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/MACHINE:I386"
+				AdditionalOptions="/MACHINE:I386 &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot;"
 				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:&quot;.\Debug/faad.exe&quot; /INCREMENTAL ws2_32.lib odbc32.lib odbccp32.lib /DEBUG /PDB:&quot;.\Debug/faad.pdb&quot; /SUBSYSTEM:CONSOLE /TLBID:1 /MACHINE:I386 &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; 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 &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Debug\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Debug\libmp4v2_st60.lib&quot;"/>
+			</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 &quot;../include&quot; /I &quot;../common/mp4v2&quot; /I &quot;../common/faad&quot; /nologo /W3 /O2 /Og /Ob1 /Oy /D &quot;WIN32&quot; /D &quot;NDEBUG&quot; /D &quot;_CONSOLE&quot; /D &quot;_MBCS&quot; /GF /FD /EHsc /MT /GS /Gy /YX&quot;StdAfx.h&quot; /Fp&quot;.\Release/faad.pch&quot; /Fo&quot;.\Release/&quot; /Fd&quot;.\Release/&quot; /Gd"
+					MSOriginalAdditionalOptions=""/>
+			</Tool>
 			<Tool
 				Name="VCCustomBuildTool"/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/MACHINE:I386"
+				AdditionalOptions="/MACHINE:I386 &quot;e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib&quot;"
 				AdditionalDependencies="ws2_32.lib"
 				OutputFile=".\Release/faad.exe"
 				LinkIncremental="1"
 				SuppressStartupBanner="TRUE"
-				SubSystem="1"/>
+				SubSystem="1">
+				<IntelOptions
+					AllOptions="/NOLOGO /OUT:&quot;.\Release/faad.exe&quot; /INCREMENTAL:NO ws2_32.lib /SUBSYSTEM:CONSOLE /TLBID:1 /MACHINE:I386 &quot;e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib&quot; 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 &quot;e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib&quot; &quot;e:\aac\cvsroot\faad2\libfaad\Release\libfaad.lib&quot; &quot;e:\aac\cvsroot\faad2\common\mp4v2\ST_Release\libmp4v2_st60.lib&quot;"/>
+			</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 */