diff -r 000000000000 -r 40261b775718 mmplugins/lib3gp/impl/src/mp4compose.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmplugins/lib3gp/impl/src/mp4compose.cpp Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,1415 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include <3gplibrary/mp4config.h> +#include <3gplibrary/mp4lib.h> +#include "mp4atom.h" +#include "mp4memwrap.h" +#include "mp4file.h" +#include "mp4compose.h" +#include "mp4utils.h" + +// MACROS +// Debug print macro +#ifdef _DEBUG +#include +#define PRINT(x) +#else +#define PRINT(x) +#endif + +#define STTSMAXENTRYCOUNT 100 +#define STSZMAXSAMPLECOUNT 100 +#define STSCMAXENTRYCOUNT 2 +#define STCOMAXENTRYCOUNT 100 +#define STSSMAXENTRYCOUNT 100 +#define SDTPMAXENTRYCOUNT 100 + + +extern EXPORT_C MP4Err MP4ComposeOpen(MP4Handle *apihandle, + MP4FileName filename, + mp4_u32 type) +{ + MP4Err error = MP4_OK; + MP4HandleImp* handle = (MP4HandleStruct **)apihandle; + + if ( filename != NULL ) + { + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct)); + if (*handle == NULL) + { + return MP4_OUT_OF_MEMORY; + } + (*handle)->bufferWrite=MP4FALSE; + } + else + { + if ( *handle == NULL ) + { + return MP4_ERROR; + } + } + + (*handle)->file32Duplicate = NULL; + (*handle)->FileHandleFromOutside = EFalse; + + if(!(*handle)->bufferWrite) + { + if (!filename) + { + error = MP4_FILE_ERROR; + } + + if ( error == MP4_OK ) + { + if (saveFileName(filename, *handle) < 0) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + if (createTmpFileName(filename, &((*handle)->tmpFileName)) == -1) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + if (initFileWrite(filename, *handle) == -1) + error = MP4_FILE_ERROR; + } + + if (error == MP4_OK) + { + if (initTmpFileWrite((*handle)->tmpFileName, *handle) == -1) + error = MP4_FILE_ERROR; + } + } + + if (error == MP4_OK) + { + (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE); + if ((*handle)->diskWriteBuf == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable)); + if ((*handle)->audioSampleTable == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->sttsSampleCount == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->sttsSampleDelta == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT); + if ((*handle)->audioSampleTable->stszEntrySize == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscFirstChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stcoChunkOffset == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable)); + if ((*handle)->videoSampleTable == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sttsSampleCount == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sttsSampleDelta == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT); + if ((*handle)->videoSampleTable->stszEntrySize == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscFirstChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stcoChunkOffset == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stssSampleNumber == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL) + error = MP4_OUT_OF_MEMORY; + } + + // register for stblib use + if (error == MP4_OK) + { + if (openStdlib() != MP4_OK) + { + error = MP4_ERROR; + } + } + + if (error != MP4_OK) + { + if(!(*handle)->bufferWrite) + { + closeFile(*handle); + + closeTmpFile(*handle); + + freeTmpFileName((*handle)->tmpFileName); + } + + if ((*handle)->diskWriteBuf) + mp4free((*handle)->diskWriteBuf); + + if ((*handle)->videoSampleTable) + { + if ((*handle)->videoSampleTable->stssSampleNumber) + mp4free((*handle)->videoSampleTable->stssSampleNumber); + + if ((*handle)->videoSampleTable->stcoChunkOffset) + mp4free((*handle)->videoSampleTable->stcoChunkOffset); + + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex) + mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex); + + if ((*handle)->videoSampleTable->stscSamplesPerChunk) + mp4free((*handle)->videoSampleTable->stscSamplesPerChunk); + + if ((*handle)->videoSampleTable->stscFirstChunk) + mp4free((*handle)->videoSampleTable->stscFirstChunk); + + if ((*handle)->videoSampleTable->stszEntrySize) + mp4free((*handle)->videoSampleTable->stszEntrySize); + + if ((*handle)->videoSampleTable->sttsSampleCount) + mp4free((*handle)->videoSampleTable->sttsSampleCount); + + if ((*handle)->videoSampleTable->sttsSampleDelta) + mp4free((*handle)->videoSampleTable->sttsSampleDelta); + + if ((*handle)->videoSampleTable->sdtpSampleDependency) + mp4free((*handle)->videoSampleTable->sdtpSampleDependency); + + mp4free((*handle)->videoSampleTable); + } + + if ((*handle)->audioSampleTable) + { + if ((*handle)->audioSampleTable->stcoChunkOffset) + mp4free((*handle)->audioSampleTable->stcoChunkOffset); + + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex) + mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex); + + if ((*handle)->audioSampleTable->stscSamplesPerChunk) + mp4free((*handle)->audioSampleTable->stscSamplesPerChunk); + + if ((*handle)->audioSampleTable->stscFirstChunk) + mp4free((*handle)->audioSampleTable->stscFirstChunk); + + if ((*handle)->audioSampleTable->stszEntrySize) + mp4free((*handle)->audioSampleTable->stszEntrySize); + + if ((*handle)->audioSampleTable->sttsSampleDelta) + mp4free((*handle)->audioSampleTable->sttsSampleDelta); + + if ((*handle)->audioSampleTable->sttsSampleCount) + mp4free((*handle)->audioSampleTable->sttsSampleCount); + + mp4free((*handle)->audioSampleTable); + } + + if ((*handle)->fileName) + mp4free((*handle)->fileName); + + mp4free(*handle); + *handle = NULL; + + return error; + } + + + (*handle)->audioSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT; + (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT; + (*handle)->audioSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT; + (*handle)->audioSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT; + (*handle)->audioSampleTable->stcoNeed64Bits = EFalse; + + (*handle)->videoSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT; + (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT; + (*handle)->videoSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT; + (*handle)->videoSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT; + (*handle)->videoSampleTable->stssMaxEntryCount = STSSMAXENTRYCOUNT; + (*handle)->videoSampleTable->sdtpMaxEntryCount = SDTPMAXENTRYCOUNT; + (*handle)->videoSampleTable->stcoNeed64Bits = EFalse; + + (*handle)->type = type; + + /* Check if a 3GPP2 codec is being used */ + if ((*handle)->type & MP4_TYPE_QCELP_13K) + { + (*handle)->generate3G2 = MP4TRUE; + } + + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeOpenToBuffer(MP4Handle *apihandle, + mp4_u32 type, + mp4_u8* composeBuffer, + mp4_u32 *composedSize) +{ + MP4HandleImp* handle = (MP4HandleStruct **)apihandle; + + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct)); + if (*handle == NULL) + return MP4_OUT_OF_MEMORY; + + (*handle)->file32Duplicate = NULL; + (*handle)->bufferWrite=MP4TRUE; + (*handle)->FileHandleFromOutside = EFalse; + + if(composeBuffer == NULL) + { + return MP4_NO_OUTPUT_BUFFER; //This is to indicate that compose buffer has not been initialized + } + + (*handle)->composeBuffer=composeBuffer; + (*handle)->composedSize=composedSize; + + return MP4ComposeOpen( apihandle, NULL, type ); +} + +extern EXPORT_C MP4Err MP4ComposeOpenFileHandle(MP4Handle *apihandle, + RFile *composedfile, + TDriveNumber metadataTempDrive, + mp4_u32 type) +{ + MP4Err err; + RFile64 *f64 = new RFile64; + if (f64 == NULL) + { + return MP4_OUT_OF_MEMORY; + } + if (f64->Duplicate(*composedfile) != KErrNone) + { + delete f64; + return MP4_ERROR; + } + err = MP4ComposeOpenFileHandle64(apihandle, f64, metadataTempDrive, type); + if (err == MP4_OK) + { + MP4HandleImp* handle = (MP4HandleStruct **)apihandle; + (*handle)->file32Duplicate = (void*)f64; + } + return err; +} + + + +extern EXPORT_C MP4Err MP4ComposeOpenFileHandle64(MP4Handle *apihandle, + RFile64 *composedfile, + TDriveNumber metadataTempDrive, + mp4_u32 type) +{ + MP4Err error = MP4_OK; + MP4HandleImp* handle = (MP4HandleStruct **)apihandle; + + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct)); + if (*handle == NULL) + { + return MP4_OUT_OF_MEMORY; + } + (*handle)->bufferWrite=MP4FALSE; + (*handle)->file32Duplicate = NULL; + // since file handle we canīt use temporary file for mediadata safely. + (*handle)->flags |= MP4_FLAG_METADATALAST; + (*handle)->FileHandleFromOutside = ETrue; + (*handle)->fileHandleDrive = metadataTempDrive; + + RFs *fs; + fs = new(RFs); + (*handle)->fs = (void *)fs; + if (fs == NULL) + error = MP4_FILE_ERROR; + + if (error == MP4_OK) + { + if (fs->Connect() != KErrNone) + error = MP4_FILE_ERROR; + } + + if (error == MP4_OK) + { + (*handle)->rfile = (void *)composedfile; + if (composedfile == NULL) + error = MP4_FILE_ERROR; + + (*handle)->file = (*handle)->rfile; + + TRAPD(traperror, (*handle)->filewriter = CFileWriter::NewL( *composedfile )); + if ( traperror != KErrNone ) + { + error = MP4_FILE_ERROR; + } + } + + if (error == MP4_OK) + { + (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE); + if ((*handle)->diskWriteBuf == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable)); + if ((*handle)->audioSampleTable == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->sttsSampleCount == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->sttsSampleDelta == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT); + if ((*handle)->audioSampleTable->stszEntrySize == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscFirstChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT); + if ((*handle)->audioSampleTable->stcoChunkOffset == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable)); + if ((*handle)->videoSampleTable == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sttsSampleCount == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sttsSampleDelta == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT); + if ((*handle)->videoSampleTable->stszEntrySize == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscFirstChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stcoChunkOffset == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->stssSampleNumber == NULL) + error = MP4_OUT_OF_MEMORY; + } + + if (error == MP4_OK) + { + (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT); + if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL) + error = MP4_OUT_OF_MEMORY; + } + + // register for stblib use + if (error == MP4_OK) + { + if (openStdlib() != MP4_OK) + { + error = MP4_ERROR; + } + } + + if (error != MP4_OK) + { + if(!(*handle)->bufferWrite) + { + closeFile(*handle); + } + + if ((*handle)->diskWriteBuf) + mp4free((*handle)->diskWriteBuf); + + if ((*handle)->videoSampleTable) + { + if ((*handle)->videoSampleTable->stssSampleNumber) + mp4free((*handle)->videoSampleTable->stssSampleNumber); + + if ((*handle)->videoSampleTable->stcoChunkOffset) + mp4free((*handle)->videoSampleTable->stcoChunkOffset); + + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex) + mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex); + + if ((*handle)->videoSampleTable->stscSamplesPerChunk) + mp4free((*handle)->videoSampleTable->stscSamplesPerChunk); + + if ((*handle)->videoSampleTable->stscFirstChunk) + mp4free((*handle)->videoSampleTable->stscFirstChunk); + + if ((*handle)->videoSampleTable->stszEntrySize) + mp4free((*handle)->videoSampleTable->stszEntrySize); + + if ((*handle)->videoSampleTable->sttsSampleCount) + mp4free((*handle)->videoSampleTable->sttsSampleCount); + + if ((*handle)->videoSampleTable->sttsSampleDelta) + mp4free((*handle)->videoSampleTable->sttsSampleDelta); + + if ((*handle)->videoSampleTable->sdtpSampleDependency) + mp4free((*handle)->videoSampleTable->sdtpSampleDependency); + + mp4free((*handle)->videoSampleTable); + } + + if ((*handle)->audioSampleTable) + { + if ((*handle)->audioSampleTable->stcoChunkOffset) + mp4free((*handle)->audioSampleTable->stcoChunkOffset); + + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex) + mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex); + + if ((*handle)->audioSampleTable->stscSamplesPerChunk) + mp4free((*handle)->audioSampleTable->stscSamplesPerChunk); + + if ((*handle)->audioSampleTable->stscFirstChunk) + mp4free((*handle)->audioSampleTable->stscFirstChunk); + + if ((*handle)->audioSampleTable->stszEntrySize) + mp4free((*handle)->audioSampleTable->stszEntrySize); + + if ((*handle)->audioSampleTable->sttsSampleDelta) + mp4free((*handle)->audioSampleTable->sttsSampleDelta); + + if ((*handle)->audioSampleTable->sttsSampleCount) + mp4free((*handle)->audioSampleTable->sttsSampleCount); + + mp4free((*handle)->audioSampleTable); + } + + if ((*handle)->fileName) + mp4free((*handle)->fileName); + + mp4free(*handle); + *handle = NULL; + + return error; + } + + (*handle)->audioSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT; + (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT; + (*handle)->audioSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT; + (*handle)->audioSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT; + (*handle)->audioSampleTable->stcoNeed64Bits = EFalse; + + (*handle)->videoSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT; + (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT; + (*handle)->videoSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT; + (*handle)->videoSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT; + (*handle)->videoSampleTable->stssMaxEntryCount = STSSMAXENTRYCOUNT; + (*handle)->videoSampleTable->sdtpMaxEntryCount = SDTPMAXENTRYCOUNT; + (*handle)->videoSampleTable->stcoNeed64Bits = EFalse; + + (*handle)->type = type; + + /* Check if a 3GPP2 codec is being used */ + if ((*handle)->type & MP4_TYPE_QCELP_13K) + { + (*handle)->generate3G2 = MP4TRUE; + } + + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeClose(MP4Handle apihandle) +{ + PRINT((_L("e_composeclose 1"))); + + mp4_i32 error; + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if (!handle) + return MP4_ERROR; + + PRINT((_L("e_composeclose_writedatatofile 1"))); + + error = writeDataToFile(handle); + + PRINT((_L("e_composeclose_writedatatofile 0"))); + + if(handle->bufferWrite && handle->composedSize) + { + *(handle->composedSize)=handle->bytesProgressed; + } + + PRINT((_L("e_composeclose_free_decspecinfos 1"))); + if (handle->videoDecSpecificInfo) + mp4free(handle->videoDecSpecificInfo); + + if (handle->audioDecSpecificInfo) + mp4free(handle->audioDecSpecificInfo); + + PRINT((_L("e_composeclose_free_decspecinfos 0"))); + PRINT((_L("e_composeclose_free_audiosampletables 1"))); + + if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleCount) + mp4free(handle->audioSampleTable->sttsSampleCount); + + if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleDelta) + mp4free(handle->audioSampleTable->sttsSampleDelta); + + if (handle->audioSampleTable && handle->audioSampleTable->stszEntrySize) + mp4free(handle->audioSampleTable->stszEntrySize); + + if (handle->audioSampleTable && handle->audioSampleTable->stscFirstChunk) + mp4free(handle->audioSampleTable->stscFirstChunk); + + if (handle->audioSampleTable && handle->audioSampleTable->stscSamplesPerChunk) + mp4free(handle->audioSampleTable->stscSamplesPerChunk); + + if (handle->audioSampleTable && handle->audioSampleTable->stscSampleDescriptionIndex) + mp4free(handle->audioSampleTable->stscSampleDescriptionIndex); + + if (handle->audioSampleTable && handle->audioSampleTable->stcoChunkOffset) + mp4free(handle->audioSampleTable->stcoChunkOffset); + + if (handle->audioSampleTable) + mp4free(handle->audioSampleTable); + PRINT((_L("e_composeclose_free_audiosampletables 0"))); + PRINT((_L("e_composeclose_free_videosampletables 1"))); + + if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleCount) + mp4free(handle->videoSampleTable->sttsSampleCount); + + if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleDelta) + mp4free(handle->videoSampleTable->sttsSampleDelta); + + if (handle->videoSampleTable && handle->videoSampleTable->stszEntrySize) + mp4free(handle->videoSampleTable->stszEntrySize); + + if (handle->videoSampleTable && handle->videoSampleTable->stscFirstChunk) + mp4free(handle->videoSampleTable->stscFirstChunk); + + if (handle->videoSampleTable && handle->videoSampleTable->stscSamplesPerChunk) + mp4free(handle->videoSampleTable->stscSamplesPerChunk); + + if (handle->videoSampleTable && handle->videoSampleTable->stscSampleDescriptionIndex) + mp4free(handle->videoSampleTable->stscSampleDescriptionIndex); + + if (handle->videoSampleTable && handle->videoSampleTable->stcoChunkOffset) + mp4free(handle->videoSampleTable->stcoChunkOffset); + + if (handle->videoSampleTable && handle->videoSampleTable->stssSampleNumber) + mp4free(handle->videoSampleTable->stssSampleNumber); + + if (handle->videoSampleTable && handle->videoSampleTable->sdtpSampleDependency) + mp4free(handle->videoSampleTable->sdtpSampleDependency); + + if (handle->videoSampleTable) + mp4free(handle->videoSampleTable); + PRINT((_L("e_composeclose_free_videosampletables 0"))); + PRINT((_L("e_composeclose_free_dskbuf_and_udta 1"))); + if (handle->diskWriteBuf) + mp4free(handle->diskWriteBuf); + + if (handle->moovUDTA) + { + if ( handle->moovUDTA->contentdata ) + { + mp4free(handle->moovUDTA->contentdata); + } + mp4free(handle->moovUDTA); + } + if (handle->audioUDTA) + { + if ( handle->audioUDTA->contentdata ) + { + mp4free(handle->audioUDTA->contentdata); + } + mp4free(handle->audioUDTA); + } + if (handle->videoUDTA) + { + if ( handle->videoUDTA->contentdata ) + { + mp4free(handle->videoUDTA->contentdata); + } + mp4free(handle->videoUDTA); + } + PRINT((_L("e_composeclose_free_dskbuf_and_udta 0"))); + + if (!(handle->flags & MP4_FLAG_METADATALAST)) + { + if (handle->tmpfile) + { + PRINT((_L("e_composeclose_close_temp_files 1"))); + closeTmpFile(handle); + PRINT((_L("e_composeclose_close_temp_files 0"))); + PRINT((_L("e_composeclose_del_temp_files 1"))); + deleteTmpFile(handle); + PRINT((_L("e_composeclose_del_temp_files 0"))); + } + } + + PRINT((_L("e_composeclose_free_temp_filename 1"))); + freeTmpFileName(handle->tmpFileName); + PRINT((_L("e_composeclose_free_temp_filename 0"))); + + if (handle->flags & MP4_FLAG_LONGCLIP) + { + PRINT((_L("e_composeclose_close_metadata_files 1"))); + closeMetaDataFiles(handle); + PRINT((_L("e_composeclose_close_metadata_files 0"))); + PRINT((_L("e_composeclose_del_metadata_files 1"))); + if (deleteMetaDataFiles(handle) < 0) + error = -1; + PRINT((_L("e_composeclose_del_metadata_files 0"))); + } + + PRINT((_L("e_composeclose_free_filename 1"))); + if (handle->fileName) + mp4free(handle->fileName); + PRINT((_L("e_composeclose_free_filename 0"))); + + PRINT((_L("e_composeclose_close_file 1"))); + if (handle->file) + closeFile(handle); + PRINT((_L("e_composeclose_close_file 0"))); + + PRINT((_L("e_composeclose_close_std_lib 1"))); + closeStdlib(); + PRINT((_L("e_composeclose_close_std_lib 0"))); + + if (handle->file32Duplicate) + ((RFile64*)handle->file32Duplicate)->Close(); + + PRINT((_L("e_composeclose_free_handle 1"))); + if (handle) + { + mp4free(handle); + handle = NULL; + } + PRINT((_L("e_composeclose_free_handle 0"))); + + if (error) + return MP4_METADATA_ERROR; + + PRINT((_L("e_composeclose 0"))); + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeAddVideoDescription(MP4Handle apihandle, + mp4_u32 timescale, + mp4_u16 width, + mp4_u16 height, + mp4_u32 maxbitrate, + mp4_u32 avgbitrate) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if (timescale) + handle->videoTimeScale = timescale; + else + return MP4_ERROR; + + handle->videoWidth = width; + handle->videoHeight = height; + handle->videoMaxBitrate = maxbitrate; + handle->videoAvgBitrate = avgbitrate; + + if ( handle->type & (MP4_TYPE_H263_PROFILE_0 | MP4_TYPE_H263_PROFILE_3) ) + { + // default H.263 level is 10; it may be overwritten by MP4ComposeWriteVideoDecoderSpecificInfo + handle->videoLevel = 10; + } + + /* Write FTYP and media data size & type if meta data flag is set */ + if (handle->flags & MP4_FLAG_METADATALAST) + { + if (handle->ftypWritten != MP4TRUE) + { + if (writeFTYPAndMDATToFile(handle) < 0) + return MP4_ERROR; + } + } + + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeAddAudioDescription(MP4Handle apihandle, + mp4_u32 timescale, + mp4_u8 audioFramesPerSample, + mp4_u16 modeSet) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale=%d, AudioFrames=%d, ModeSet=%d "), timescale, audioFramesPerSample, modeSet)); + if (timescale) + { + if (timescale > (mp4_u32)0xffff) + { + return MP4_ERROR; + } + handle->audioTimeScale = timescale; + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale set to = %d"), handle->audioTimeScale )); + } + else + return MP4_ERROR; + + + if ((handle->type & MP4_TYPE_AMR_NB) || + (handle->type & MP4_TYPE_AMR_WB)) /* Audio is AMR */ + { + if (audioFramesPerSample) + handle->audioFramesPerSample = audioFramesPerSample; + else + return MP4_ERROR; + + if (modeSet) + handle->audioModeSet = modeSet; + else + return MP4_ERROR; + } + else if (handle->type & MP4_TYPE_QCELP_13K) /* Audio is QCELP 13K */ + { + if (audioFramesPerSample) + handle->audioFramesPerSample = audioFramesPerSample; + else + return MP4_ERROR; + } + else /* MPEG AAC audio */ + { + handle->audioFramesPerSample = 1; + } + + /* Write FTYP and media data size & type if meta data flag is set */ + if (handle->flags & MP4_FLAG_METADATALAST) + { + if (handle->ftypWritten != MP4TRUE) + { + if (writeFTYPAndMDATToFile(handle) < 0) + return MP4_ERROR; + } + } + + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription out"))); + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeWriteVideoFrame(MP4Handle apihandle, + mp4_u8 *buffer, + mp4_u32 framesize, + mp4_u32 duration, + mp4_bool keyframe) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame in"))); + if (handle->videoTimeScale == 0) + return MP4_TIMESCALE_NOT_SET; + + if (framesize == 0) + return MP4_ERROR; + + handle->videoDuration += duration; + handle->videoSampleNum++; + + if (updateVideoMetaData(handle, framesize, duration, keyframe) < 0) + return MP4_ERROR; + + if (handle->flags & MP4_FLAG_METADATALAST) + { + if (writeFile(handle, buffer, framesize) < 0) + return MP4_ERROR; + + handle->mediaDataBytes += framesize; + } + else + { + if (writeTmpFile(handle, buffer, framesize) < 0) + return MP4_ERROR; + } + + PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame out"))); + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeWriteAudioFrames(MP4Handle apihandle, + mp4_u8 *buffer, + mp4_u32 bytestowrite, + mp4_u32 numberofframes, + mp4_u32 duration) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames in"))); + + if ( handle->audioTimeScale == 0) + { + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Error 14 - AudioTimeScale is 0"))); + return MP4_TIMESCALE_NOT_SET; + } + + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Audio Timescale ok"))); + + if (bytestowrite == 0) + return MP4_ERROR; + + handle->audioDuration += duration; + handle->audioFrameCount += numberofframes; + handle->audioMediaDataSize += bytestowrite; + + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames updating audio metadata"))); + + if (updateAudioMetaData(handle, bytestowrite, duration) < 0) + return MP4_ERROR; + + if (handle->flags & MP4_FLAG_METADATALAST) + { + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to file"))); + if (writeFile(handle, buffer, bytestowrite) < 0) + return MP4_ERROR; + + handle->mediaDataBytes += bytestowrite; + } + else + { + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to temp file"))); + if (writeTmpFile(handle, buffer, bytestowrite) < 0) + return MP4_ERROR; + } + + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames out"))); + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeWriteVideoDecoderSpecificInfo(MP4Handle apihandle, + mp4_u8 *info, + mp4_u32 infosize) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if ( (handle->type & MP4_TYPE_MPEG4_VIDEO) || containsAvcVideo( handle->type ) ) + { + if ((handle->videoDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL) + return MP4_ERROR; + + mp4memcpy(handle->videoDecSpecificInfo, info, infosize); + handle->videoDecSpecificInfoSize = infosize; + } + else + { + // H.263, save level only + if ( *info >= 10 && *info < 100 ) + { + handle->videoLevel = *info; + } + } + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeWriteAudioDecoderSpecificInfo(MP4Handle apihandle, + mp4_u8 *info, + mp4_u32 infosize) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if ((handle->audioDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL) + return MP4_ERROR; + + mp4memcpy(handle->audioDecSpecificInfo, info, infosize); + handle->audioDecSpecificInfoSize = infosize; + + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeSetFlags(MP4Handle apihandle, + mp4_u32 flags) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + handle->flags |= flags; + + if (handle->flags & MP4_FLAG_METADATALAST) + { + if (handle->tmpfile) + { + closeTmpFile(handle); + deleteTmpFile(handle); + } + } + + if (handle->flags & MP4_FLAG_LONGCLIP) + { + // Open temporary files + MP4Err error = MP4_OK; + error = initMetaDataFiles(handle); + if ( error == MP4_OUT_OF_MEMORY ) + { + return MP4_OUT_OF_MEMORY; + } + else if ( error != MP4_OK ) + { + return MP4_ERROR; + } + } + + handle->generate3G2 = MP4FALSE; + handle->generateMP4 = MP4FALSE; + + if (handle->flags & MP4_FLAG_GENERATE_3G2) // 3G2 + { + // Generate 3G2 file. + handle->generate3G2 = MP4TRUE; + handle->generateMP4 = MP4FALSE; + } + else if ( handle->flags & MP4_FLAG_GENERATE_MP4 ) // MP4 + { + // if at least ONE audio/video codec is specified + if (handle->type != MP4_TYPE_NONE) + { + /* Check if a 3GPP2 codec is being used */ + if ( handle->type & MP4_TYPE_QCELP_13K ) + { + handle->generate3G2 = MP4TRUE; + handle->generateMP4 = MP4FALSE; + } + else + { + // types other than MPEG-4 AUDIO & VIDEO + mp4_u32 type = handle->type >> 2; + + // Check if a MPEG4 codec is being used + if (type == MP4_TYPE_NONE) + { + // if ONLY MPEG4 Video and/or Audio codec is used, generate MP4 file. + handle->generateMP4 = MP4TRUE; + handle->generate3G2 = MP4FALSE; + } + else + { + // ignoring both MPEG-4 audio and video, check again if only AVC codecs are + // used + type <<= 2; + if ( isAvcVideo(type) ) + { + // generate MP4 file + handle->generateMP4 = MP4TRUE; + handle->generate3G2 = MP4FALSE; + } + } + } + } + } + else // 3GP + { + /* Check if a 3GPP2 codec is being used */ + if ( handle->type & MP4_TYPE_QCELP_13K ) + { + handle->generate3G2 = MP4TRUE; + handle->generateMP4 = MP4FALSE; + } + // use defaults -> 3GP + } + + if ( (handle->flags & MP4_FLAG_LARGEFILEBUFFER) && !(handle->bufferWrite) ) + { + TInt bufferSizeError = KErrNone; + bufferSizeError = handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeLarge, apihandle ); + if ( bufferSizeError == KErrNoMemory ) + { + return MP4_OUT_OF_MEMORY; + } + else if ( bufferSizeError != KErrNone ) + { + return MP4_ERROR; + } + } + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeSetQCELPStorageMode(MP4Handle apihandle, mp4_u8 qcelpStorageMode) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if (qcelpStorageMode) + handle->qcelpStoredAsMPEGAudio = MP4TRUE; + else + handle->qcelpStoredAsMPEGAudio = MP4FALSE; + + return MP4_OK; + +} + +extern EXPORT_C MP4Err MP4ComposeSetVideoClipProperties(MP4Handle apihandle, const TVideoClipProperties& aVideoClipProperties) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if ( !handle ) + { + return MP4_ERROR; + } + else + { + if ( aVideoClipProperties.iH263Level ) + { + handle->videoLevel = aVideoClipProperties.iH263Level; + } + return MP4_OK; + } +} + +extern EXPORT_C MP4Err MP4ComposeSetUserDataAtom(MP4Handle apihandle, + mp4_u8& udtaLocation, + mp4_u8* buffer, + mp4_u32& bufferSize ) + { + userDataAtom* udta = NULL; + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if (!handle) + return MP4_ERROR; + + if ( buffer == NULL ) + { + return MP4_ERROR; + } + if ( !bufferSize ) + { + return MP4_ERROR; + } + + // Check which UDTA atom to use + switch ( udtaLocation ) + { + case MP4_UDTA_MOOV: + { + if ( handle->moovUDTA == NULL ) + { + handle->moovUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom)); + } + udta = handle->moovUDTA; + break; + } + case MP4_UDTA_VIDEOTRAK: + { + if ( handle->videoUDTA == NULL ) + { + handle->videoUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom)); + } + udta = handle->videoUDTA; + break; + } + case MP4_UDTA_AUDIOTRAK: + { + if ( handle->audioUDTA == NULL ) + { + handle->audioUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom)); + } + udta = handle->audioUDTA; + break; + } + default: + { + return MP4_INVALID_TYPE; + } + } + + if ( udta == NULL ) + { + return MP4_OUT_OF_MEMORY; + } + + // CHECK if there is old data in UDTA + if ( udta->contentdata && udta->atomcontentsize ) + { + mp4_u8* temp; + if ((temp = (mp4_u8 *)mp4malloc(bufferSize + udta->atomcontentsize)) == NULL) + { + return MP4_OUT_OF_MEMORY; + } + mp4memcpy(temp, udta->contentdata, udta->atomcontentsize); + mp4memcpy(temp+udta->atomcontentsize, buffer, bufferSize); + mp4free(udta->contentdata); + udta->contentdata = temp; + udta->atomcontentsize += bufferSize; + } + else + { + if ((udta->contentdata = (mp4_u8 *)mp4malloc(bufferSize)) == NULL) + return MP4_OUT_OF_MEMORY; + // Copy data from buffer to atom contentdata + mp4memcpy(udta->contentdata, buffer, bufferSize); + udta->atomcontentsize = bufferSize; + } + + return MP4_OK; + } + +extern EXPORT_C MP4Err MP4SetCustomFileBufferSizes( MP4Handle apihandle, + mp4_u32 mediaWriteBufferSize, + mp4_u32 writeBufferMaxCount, + mp4_u32 readBufferSize ) + { + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if (!handle) + return MP4_ERROR; + + // Read Buffer size + if ( (readBufferSize) && + (readBufferSize != handle->readBufferSize) ) + { + handle->readBufferSize = readBufferSize; + if (handle->diskReadBuf) + { + mp4free(handle->diskReadBuf); + if ((handle->diskReadBuf = (mp4_u8 *)mp4malloc(handle->readBufferSize)) == NULL) + { + return MP4_OUT_OF_MEMORY; + } + } + } + + // Media Write buffer size + if ( (mediaWriteBufferSize) && + (mediaWriteBufferSize != handle->mediaWriteBufferSize) && + (!(handle->bufferWrite)) ) + { + handle->mediaWriteBufferSize = mediaWriteBufferSize; + if ( (handle->filewriter) ) + { + if ( handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeCustom, apihandle ) < 0 ) + { + return MP4_ERROR; + } + } + } + + // Write Buffer Max Count change + if ( (writeBufferMaxCount) && + (writeBufferMaxCount != handle->writeBufferMaxCount) && + !(handle->bufferWrite) ) + { + if ( writeBufferMaxCount >= 6 ) // min number of buffers is 4, +1 for soft limit, +1 for hardlimit = 6 + { + handle->writeBufferMaxCount = writeBufferMaxCount; + if ( (handle->filewriter) ) + { + handle->filewriter->SetOutputBufferCount( apihandle ); + } + } + else + { + return MP4_ERROR; + } + } + return MP4_OK; + } + +extern EXPORT_C MP4Err MP4ComposeWriteNextVideoFrameDependencies(MP4Handle apihandle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy) +{ + MP4HandleImp handle = (MP4HandleImp)apihandle; + + if( (aDependsOn > 2) || (aIsDependentOn > 2) || (aHasRedundancy > 2) ) + { + return MP4_ERROR; + } + + if (updateVideoDependencyMetaData(handle, aDependsOn, aIsDependentOn, aHasRedundancy) < 0) + { + return MP4_ERROR; + } + + return MP4_OK; +} + +extern EXPORT_C MP4Err MP4ComposeSetTempFileRemoverObserver( + MP4Handle *apihandle, + M3GPMP4LibAsyncTempFileRemoverObserver *aObserver) +{ + PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver in"))); + + MP4Err error = MP4_OK; + MP4HandleImp* handle = (MP4HandleStruct **)apihandle; + + if ( handle != NULL && *handle != NULL ) + { + (*handle)->tempFileRemoverObserver = aObserver; + } + else + { + error = MP4_ERROR; + } + + + PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver out error=%d"), error)); + return error; +} +// End of File