--- /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 <e32svr.h>
+#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