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