1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmplugins/lib3gp/impl/src/mp4compose.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1421 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <3gplibrary/mp4config.h>
1.20 +#include <3gplibrary/mp4lib.h>
1.21 +#include "mp4atom.h"
1.22 +#include "mp4memwrap.h"
1.23 +#include "mp4file.h"
1.24 +#include "mp4compose.h"
1.25 +#include "mp4utils.h"
1.26 +
1.27 +// MACROS
1.28 +// Debug print macro
1.29 +#ifdef _DEBUG
1.30 +#include <e32svr.h>
1.31 +#define PRINT(x)
1.32 +#else
1.33 +#define PRINT(x)
1.34 +#endif
1.35 +
1.36 +#define STTSMAXENTRYCOUNT 100
1.37 +#define STSZMAXSAMPLECOUNT 100
1.38 +#define STSCMAXENTRYCOUNT 2
1.39 +#define STCOMAXENTRYCOUNT 100
1.40 +#define STSSMAXENTRYCOUNT 100
1.41 +#define SDTPMAXENTRYCOUNT 100
1.42 +
1.43 +
1.44 +extern EXPORT_C MP4Err MP4ComposeOpen(MP4Handle *apihandle,
1.45 + MP4FileName filename,
1.46 + mp4_u32 type)
1.47 +{
1.48 + MP4Err error = MP4_OK;
1.49 + MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
1.50 +
1.51 + if ( filename != NULL )
1.52 + {
1.53 + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
1.54 + if (*handle == NULL)
1.55 + {
1.56 + return MP4_OUT_OF_MEMORY;
1.57 + }
1.58 + (*handle)->bufferWrite=MP4FALSE;
1.59 + }
1.60 + else
1.61 + {
1.62 + if ( *handle == NULL )
1.63 + {
1.64 + return MP4_ERROR;
1.65 + }
1.66 + }
1.67 +
1.68 + (*handle)->file32Duplicate = NULL;
1.69 + (*handle)->FileHandleFromOutside = EFalse;
1.70 +
1.71 + if(!(*handle)->bufferWrite)
1.72 + {
1.73 + if (!filename)
1.74 + {
1.75 + error = MP4_FILE_ERROR;
1.76 + }
1.77 +
1.78 + if ( error == MP4_OK )
1.79 + {
1.80 + if (saveFileName(filename, *handle) < 0)
1.81 + error = MP4_OUT_OF_MEMORY;
1.82 + }
1.83 +
1.84 + if (error == MP4_OK)
1.85 + {
1.86 + if (createTmpFileName(filename, &((*handle)->tmpFileName)) == -1)
1.87 + error = MP4_OUT_OF_MEMORY;
1.88 + }
1.89 +
1.90 + if (error == MP4_OK)
1.91 + {
1.92 + if (initFileWrite(filename, *handle) == -1)
1.93 + error = MP4_FILE_ERROR;
1.94 + }
1.95 +
1.96 + if (error == MP4_OK)
1.97 + {
1.98 + if (initTmpFileWrite((*handle)->tmpFileName, *handle) == -1)
1.99 + error = MP4_FILE_ERROR;
1.100 + }
1.101 + }
1.102 +
1.103 + if (error == MP4_OK)
1.104 + {
1.105 + (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE);
1.106 + if ((*handle)->diskWriteBuf == NULL)
1.107 + error = MP4_OUT_OF_MEMORY;
1.108 + }
1.109 +
1.110 + if (error == MP4_OK)
1.111 + {
1.112 + (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
1.113 + if ((*handle)->audioSampleTable == NULL)
1.114 + error = MP4_OUT_OF_MEMORY;
1.115 + }
1.116 +
1.117 + if (error == MP4_OK)
1.118 + {
1.119 + (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.120 + if ((*handle)->audioSampleTable->sttsSampleCount == NULL)
1.121 + error = MP4_OUT_OF_MEMORY;
1.122 + }
1.123 +
1.124 + if (error == MP4_OK)
1.125 + {
1.126 + (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.127 + if ((*handle)->audioSampleTable->sttsSampleDelta == NULL)
1.128 + error = MP4_OUT_OF_MEMORY;
1.129 + }
1.130 +
1.131 + if (error == MP4_OK)
1.132 + {
1.133 + (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
1.134 + if ((*handle)->audioSampleTable->stszEntrySize == NULL)
1.135 + error = MP4_OUT_OF_MEMORY;
1.136 + }
1.137 +
1.138 + if (error == MP4_OK)
1.139 + {
1.140 + (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.141 + if ((*handle)->audioSampleTable->stscFirstChunk == NULL)
1.142 + error = MP4_OUT_OF_MEMORY;
1.143 + }
1.144 +
1.145 + if (error == MP4_OK)
1.146 + {
1.147 + (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.148 + if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL)
1.149 + error = MP4_OUT_OF_MEMORY;
1.150 + }
1.151 +
1.152 + if (error == MP4_OK)
1.153 + {
1.154 + (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.155 + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL)
1.156 + error = MP4_OUT_OF_MEMORY;
1.157 + }
1.158 +
1.159 + if (error == MP4_OK)
1.160 + {
1.161 + (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
1.162 + if ((*handle)->audioSampleTable->stcoChunkOffset == NULL)
1.163 + error = MP4_OUT_OF_MEMORY;
1.164 + }
1.165 +
1.166 + if (error == MP4_OK)
1.167 + {
1.168 + (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
1.169 + if ((*handle)->videoSampleTable == NULL)
1.170 + error = MP4_OUT_OF_MEMORY;
1.171 + }
1.172 +
1.173 + if (error == MP4_OK)
1.174 + {
1.175 + (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.176 + if ((*handle)->videoSampleTable->sttsSampleCount == NULL)
1.177 + error = MP4_OUT_OF_MEMORY;
1.178 + }
1.179 +
1.180 + if (error == MP4_OK)
1.181 + {
1.182 + (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.183 + if ((*handle)->videoSampleTable->sttsSampleDelta == NULL)
1.184 + error = MP4_OUT_OF_MEMORY;
1.185 + }
1.186 +
1.187 + if (error == MP4_OK)
1.188 + {
1.189 + (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
1.190 + if ((*handle)->videoSampleTable->stszEntrySize == NULL)
1.191 + error = MP4_OUT_OF_MEMORY;
1.192 + }
1.193 +
1.194 + if (error == MP4_OK)
1.195 + {
1.196 + (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.197 + if ((*handle)->videoSampleTable->stscFirstChunk == NULL)
1.198 + error = MP4_OUT_OF_MEMORY;
1.199 + }
1.200 +
1.201 + if (error == MP4_OK)
1.202 + {
1.203 + (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.204 + if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL)
1.205 + error = MP4_OUT_OF_MEMORY;
1.206 + }
1.207 +
1.208 + if (error == MP4_OK)
1.209 + {
1.210 + (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.211 + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL)
1.212 + error = MP4_OUT_OF_MEMORY;
1.213 + }
1.214 +
1.215 + if (error == MP4_OK)
1.216 + {
1.217 + (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
1.218 + if ((*handle)->videoSampleTable->stcoChunkOffset == NULL)
1.219 + error = MP4_OUT_OF_MEMORY;
1.220 + }
1.221 +
1.222 + if (error == MP4_OK)
1.223 + {
1.224 + (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT);
1.225 + if ((*handle)->videoSampleTable->stssSampleNumber == NULL)
1.226 + error = MP4_OUT_OF_MEMORY;
1.227 + }
1.228 +
1.229 + if (error == MP4_OK)
1.230 + {
1.231 + (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT);
1.232 + if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL)
1.233 + error = MP4_OUT_OF_MEMORY;
1.234 + }
1.235 +
1.236 + // register for stblib use
1.237 + if (error == MP4_OK)
1.238 + {
1.239 + if (openStdlib() != MP4_OK)
1.240 + {
1.241 + error = MP4_ERROR;
1.242 + }
1.243 + }
1.244 +
1.245 + if (error != MP4_OK)
1.246 + {
1.247 + if(!(*handle)->bufferWrite)
1.248 + {
1.249 + closeFile(*handle);
1.250 +
1.251 + closeTmpFile(*handle);
1.252 +
1.253 + freeTmpFileName((*handle)->tmpFileName);
1.254 + }
1.255 +
1.256 + if ((*handle)->diskWriteBuf)
1.257 + mp4free((*handle)->diskWriteBuf);
1.258 +
1.259 + if ((*handle)->videoSampleTable)
1.260 + {
1.261 + if ((*handle)->videoSampleTable->stssSampleNumber)
1.262 + mp4free((*handle)->videoSampleTable->stssSampleNumber);
1.263 +
1.264 + if ((*handle)->videoSampleTable->stcoChunkOffset)
1.265 + mp4free((*handle)->videoSampleTable->stcoChunkOffset);
1.266 +
1.267 + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex)
1.268 + mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex);
1.269 +
1.270 + if ((*handle)->videoSampleTable->stscSamplesPerChunk)
1.271 + mp4free((*handle)->videoSampleTable->stscSamplesPerChunk);
1.272 +
1.273 + if ((*handle)->videoSampleTable->stscFirstChunk)
1.274 + mp4free((*handle)->videoSampleTable->stscFirstChunk);
1.275 +
1.276 + if ((*handle)->videoSampleTable->stszEntrySize)
1.277 + mp4free((*handle)->videoSampleTable->stszEntrySize);
1.278 +
1.279 + if ((*handle)->videoSampleTable->sttsSampleCount)
1.280 + mp4free((*handle)->videoSampleTable->sttsSampleCount);
1.281 +
1.282 + if ((*handle)->videoSampleTable->sttsSampleDelta)
1.283 + mp4free((*handle)->videoSampleTable->sttsSampleDelta);
1.284 +
1.285 + if ((*handle)->videoSampleTable->sdtpSampleDependency)
1.286 + mp4free((*handle)->videoSampleTable->sdtpSampleDependency);
1.287 +
1.288 + mp4free((*handle)->videoSampleTable);
1.289 + }
1.290 +
1.291 + if ((*handle)->audioSampleTable)
1.292 + {
1.293 + if ((*handle)->audioSampleTable->stcoChunkOffset)
1.294 + mp4free((*handle)->audioSampleTable->stcoChunkOffset);
1.295 +
1.296 + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex)
1.297 + mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex);
1.298 +
1.299 + if ((*handle)->audioSampleTable->stscSamplesPerChunk)
1.300 + mp4free((*handle)->audioSampleTable->stscSamplesPerChunk);
1.301 +
1.302 + if ((*handle)->audioSampleTable->stscFirstChunk)
1.303 + mp4free((*handle)->audioSampleTable->stscFirstChunk);
1.304 +
1.305 + if ((*handle)->audioSampleTable->stszEntrySize)
1.306 + mp4free((*handle)->audioSampleTable->stszEntrySize);
1.307 +
1.308 + if ((*handle)->audioSampleTable->sttsSampleDelta)
1.309 + mp4free((*handle)->audioSampleTable->sttsSampleDelta);
1.310 +
1.311 + if ((*handle)->audioSampleTable->sttsSampleCount)
1.312 + mp4free((*handle)->audioSampleTable->sttsSampleCount);
1.313 +
1.314 + mp4free((*handle)->audioSampleTable);
1.315 + }
1.316 +
1.317 + if ((*handle)->fileName)
1.318 + mp4free((*handle)->fileName);
1.319 +
1.320 + mp4free(*handle);
1.321 + *handle = NULL;
1.322 +
1.323 + return error;
1.324 + }
1.325 +
1.326 +
1.327 + (*handle)->audioSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT;
1.328 + (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
1.329 + (*handle)->audioSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT;
1.330 + (*handle)->audioSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT;
1.331 + (*handle)->audioSampleTable->stcoNeed64Bits = EFalse;
1.332 +
1.333 + (*handle)->videoSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT;
1.334 + (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
1.335 + (*handle)->videoSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT;
1.336 + (*handle)->videoSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT;
1.337 + (*handle)->videoSampleTable->stssMaxEntryCount = STSSMAXENTRYCOUNT;
1.338 + (*handle)->videoSampleTable->sdtpMaxEntryCount = SDTPMAXENTRYCOUNT;
1.339 + (*handle)->videoSampleTable->stcoNeed64Bits = EFalse;
1.340 +
1.341 + (*handle)->type = type;
1.342 +
1.343 + /* Check if a 3GPP2 codec is being used */
1.344 + if ((*handle)->type & MP4_TYPE_QCELP_13K)
1.345 + {
1.346 + (*handle)->generate3G2 = MP4TRUE;
1.347 + }
1.348 +
1.349 + return MP4_OK;
1.350 +}
1.351 +
1.352 +extern EXPORT_C MP4Err MP4ComposeOpenToBuffer(MP4Handle *apihandle,
1.353 + mp4_u32 type,
1.354 + mp4_u8* composeBuffer,
1.355 + mp4_u32 *composedSize)
1.356 +{
1.357 + MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
1.358 +
1.359 + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
1.360 + if (*handle == NULL)
1.361 + return MP4_OUT_OF_MEMORY;
1.362 +
1.363 + (*handle)->file32Duplicate = NULL;
1.364 + (*handle)->bufferWrite=MP4TRUE;
1.365 + (*handle)->FileHandleFromOutside = EFalse;
1.366 +
1.367 + if(composeBuffer == NULL)
1.368 + {
1.369 + return MP4_NO_OUTPUT_BUFFER; //This is to indicate that compose buffer has not been initialized
1.370 + }
1.371 +
1.372 + (*handle)->composeBuffer=composeBuffer;
1.373 + (*handle)->composedSize=composedSize;
1.374 +
1.375 + return MP4ComposeOpen( apihandle, NULL, type );
1.376 +}
1.377 +
1.378 +extern EXPORT_C MP4Err MP4ComposeOpenFileHandle(MP4Handle *apihandle,
1.379 + RFile *composedfile,
1.380 + TDriveNumber metadataTempDrive,
1.381 + mp4_u32 type)
1.382 +{
1.383 + MP4Err err;
1.384 + RFile64 *f64 = new RFile64;
1.385 + if (f64 == NULL)
1.386 + {
1.387 + return MP4_OUT_OF_MEMORY;
1.388 + }
1.389 + if (f64->Duplicate(*composedfile) != KErrNone)
1.390 + {
1.391 + delete f64;
1.392 + return MP4_ERROR;
1.393 + }
1.394 + err = MP4ComposeOpenFileHandle64(apihandle, f64, metadataTempDrive, type);
1.395 + if (err == MP4_OK)
1.396 + {
1.397 + MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
1.398 + (*handle)->file32Duplicate = (void*)f64;
1.399 + }
1.400 + return err;
1.401 +}
1.402 +
1.403 +
1.404 +
1.405 +extern EXPORT_C MP4Err MP4ComposeOpenFileHandle64(MP4Handle *apihandle,
1.406 + RFile64 *composedfile,
1.407 + TDriveNumber metadataTempDrive,
1.408 + mp4_u32 type)
1.409 +{
1.410 + MP4Err error = MP4_OK;
1.411 + MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
1.412 +
1.413 + *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
1.414 + if (*handle == NULL)
1.415 + {
1.416 + return MP4_OUT_OF_MEMORY;
1.417 + }
1.418 + (*handle)->bufferWrite=MP4FALSE;
1.419 + (*handle)->file32Duplicate = NULL;
1.420 + // since file handle we canīt use temporary file for mediadata safely.
1.421 + (*handle)->flags |= MP4_FLAG_METADATALAST;
1.422 + (*handle)->FileHandleFromOutside = ETrue;
1.423 + (*handle)->fileHandleDrive = metadataTempDrive;
1.424 +
1.425 + RFs *fs;
1.426 + fs = new(RFs);
1.427 + (*handle)->fs = (void *)fs;
1.428 + if (fs == NULL)
1.429 + error = MP4_FILE_ERROR;
1.430 +
1.431 + if (error == MP4_OK)
1.432 + {
1.433 + if (fs->Connect() != KErrNone)
1.434 + error = MP4_FILE_ERROR;
1.435 + }
1.436 +
1.437 + if (error == MP4_OK)
1.438 + {
1.439 + (*handle)->rfile = (void *)composedfile;
1.440 + if (composedfile == NULL)
1.441 + error = MP4_FILE_ERROR;
1.442 +
1.443 + (*handle)->file = (*handle)->rfile;
1.444 +
1.445 + TRAPD(traperror, (*handle)->filewriter = CFileWriter::NewL( *composedfile ));
1.446 + if ( traperror != KErrNone )
1.447 + {
1.448 + error = MP4_FILE_ERROR;
1.449 + }
1.450 + }
1.451 +
1.452 + if (error == MP4_OK)
1.453 + {
1.454 + (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE);
1.455 + if ((*handle)->diskWriteBuf == NULL)
1.456 + error = MP4_OUT_OF_MEMORY;
1.457 + }
1.458 +
1.459 + if (error == MP4_OK)
1.460 + {
1.461 + (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
1.462 + if ((*handle)->audioSampleTable == NULL)
1.463 + error = MP4_OUT_OF_MEMORY;
1.464 + }
1.465 +
1.466 + if (error == MP4_OK)
1.467 + {
1.468 + (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.469 + if ((*handle)->audioSampleTable->sttsSampleCount == NULL)
1.470 + error = MP4_OUT_OF_MEMORY;
1.471 + }
1.472 +
1.473 + if (error == MP4_OK)
1.474 + {
1.475 + (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.476 + if ((*handle)->audioSampleTable->sttsSampleDelta == NULL)
1.477 + error = MP4_OUT_OF_MEMORY;
1.478 + }
1.479 +
1.480 + if (error == MP4_OK)
1.481 + {
1.482 + (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
1.483 + if ((*handle)->audioSampleTable->stszEntrySize == NULL)
1.484 + error = MP4_OUT_OF_MEMORY;
1.485 + }
1.486 +
1.487 + if (error == MP4_OK)
1.488 + {
1.489 + (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.490 + if ((*handle)->audioSampleTable->stscFirstChunk == NULL)
1.491 + error = MP4_OUT_OF_MEMORY;
1.492 + }
1.493 +
1.494 + if (error == MP4_OK)
1.495 + {
1.496 + (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.497 + if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL)
1.498 + error = MP4_OUT_OF_MEMORY;
1.499 + }
1.500 +
1.501 + if (error == MP4_OK)
1.502 + {
1.503 + (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.504 + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL)
1.505 + error = MP4_OUT_OF_MEMORY;
1.506 + }
1.507 +
1.508 + if (error == MP4_OK)
1.509 + {
1.510 + (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
1.511 + if ((*handle)->audioSampleTable->stcoChunkOffset == NULL)
1.512 + error = MP4_OUT_OF_MEMORY;
1.513 + }
1.514 +
1.515 + if (error == MP4_OK)
1.516 + {
1.517 + (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
1.518 + if ((*handle)->videoSampleTable == NULL)
1.519 + error = MP4_OUT_OF_MEMORY;
1.520 + }
1.521 +
1.522 + if (error == MP4_OK)
1.523 + {
1.524 + (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.525 + if ((*handle)->videoSampleTable->sttsSampleCount == NULL)
1.526 + error = MP4_OUT_OF_MEMORY;
1.527 + }
1.528 +
1.529 + if (error == MP4_OK)
1.530 + {
1.531 + (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
1.532 + if ((*handle)->videoSampleTable->sttsSampleDelta == NULL)
1.533 + error = MP4_OUT_OF_MEMORY;
1.534 + }
1.535 +
1.536 + if (error == MP4_OK)
1.537 + {
1.538 + (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
1.539 + if ((*handle)->videoSampleTable->stszEntrySize == NULL)
1.540 + error = MP4_OUT_OF_MEMORY;
1.541 + }
1.542 +
1.543 + if (error == MP4_OK)
1.544 + {
1.545 + (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.546 + if ((*handle)->videoSampleTable->stscFirstChunk == NULL)
1.547 + error = MP4_OUT_OF_MEMORY;
1.548 + }
1.549 +
1.550 + if (error == MP4_OK)
1.551 + {
1.552 + (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.553 + if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL)
1.554 + error = MP4_OUT_OF_MEMORY;
1.555 + }
1.556 +
1.557 + if (error == MP4_OK)
1.558 + {
1.559 + (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
1.560 + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL)
1.561 + error = MP4_OUT_OF_MEMORY;
1.562 + }
1.563 +
1.564 + if (error == MP4_OK)
1.565 + {
1.566 + (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
1.567 + if ((*handle)->videoSampleTable->stcoChunkOffset == NULL)
1.568 + error = MP4_OUT_OF_MEMORY;
1.569 + }
1.570 +
1.571 + if (error == MP4_OK)
1.572 + {
1.573 + (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT);
1.574 + if ((*handle)->videoSampleTable->stssSampleNumber == NULL)
1.575 + error = MP4_OUT_OF_MEMORY;
1.576 + }
1.577 +
1.578 + if (error == MP4_OK)
1.579 + {
1.580 + (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT);
1.581 + if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL)
1.582 + error = MP4_OUT_OF_MEMORY;
1.583 + }
1.584 +
1.585 + // register for stblib use
1.586 + if (error == MP4_OK)
1.587 + {
1.588 + if (openStdlib() != MP4_OK)
1.589 + {
1.590 + error = MP4_ERROR;
1.591 + }
1.592 + }
1.593 +
1.594 + if (error != MP4_OK)
1.595 + {
1.596 + if(!(*handle)->bufferWrite)
1.597 + {
1.598 + closeFile(*handle);
1.599 + }
1.600 +
1.601 + if ((*handle)->diskWriteBuf)
1.602 + mp4free((*handle)->diskWriteBuf);
1.603 +
1.604 + if ((*handle)->videoSampleTable)
1.605 + {
1.606 + if ((*handle)->videoSampleTable->stssSampleNumber)
1.607 + mp4free((*handle)->videoSampleTable->stssSampleNumber);
1.608 +
1.609 + if ((*handle)->videoSampleTable->stcoChunkOffset)
1.610 + mp4free((*handle)->videoSampleTable->stcoChunkOffset);
1.611 +
1.612 + if ((*handle)->videoSampleTable->stscSampleDescriptionIndex)
1.613 + mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex);
1.614 +
1.615 + if ((*handle)->videoSampleTable->stscSamplesPerChunk)
1.616 + mp4free((*handle)->videoSampleTable->stscSamplesPerChunk);
1.617 +
1.618 + if ((*handle)->videoSampleTable->stscFirstChunk)
1.619 + mp4free((*handle)->videoSampleTable->stscFirstChunk);
1.620 +
1.621 + if ((*handle)->videoSampleTable->stszEntrySize)
1.622 + mp4free((*handle)->videoSampleTable->stszEntrySize);
1.623 +
1.624 + if ((*handle)->videoSampleTable->sttsSampleCount)
1.625 + mp4free((*handle)->videoSampleTable->sttsSampleCount);
1.626 +
1.627 + if ((*handle)->videoSampleTable->sttsSampleDelta)
1.628 + mp4free((*handle)->videoSampleTable->sttsSampleDelta);
1.629 +
1.630 + if ((*handle)->videoSampleTable->sdtpSampleDependency)
1.631 + mp4free((*handle)->videoSampleTable->sdtpSampleDependency);
1.632 +
1.633 + mp4free((*handle)->videoSampleTable);
1.634 + }
1.635 +
1.636 + if ((*handle)->audioSampleTable)
1.637 + {
1.638 + if ((*handle)->audioSampleTable->stcoChunkOffset)
1.639 + mp4free((*handle)->audioSampleTable->stcoChunkOffset);
1.640 +
1.641 + if ((*handle)->audioSampleTable->stscSampleDescriptionIndex)
1.642 + mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex);
1.643 +
1.644 + if ((*handle)->audioSampleTable->stscSamplesPerChunk)
1.645 + mp4free((*handle)->audioSampleTable->stscSamplesPerChunk);
1.646 +
1.647 + if ((*handle)->audioSampleTable->stscFirstChunk)
1.648 + mp4free((*handle)->audioSampleTable->stscFirstChunk);
1.649 +
1.650 + if ((*handle)->audioSampleTable->stszEntrySize)
1.651 + mp4free((*handle)->audioSampleTable->stszEntrySize);
1.652 +
1.653 + if ((*handle)->audioSampleTable->sttsSampleDelta)
1.654 + mp4free((*handle)->audioSampleTable->sttsSampleDelta);
1.655 +
1.656 + if ((*handle)->audioSampleTable->sttsSampleCount)
1.657 + mp4free((*handle)->audioSampleTable->sttsSampleCount);
1.658 +
1.659 + mp4free((*handle)->audioSampleTable);
1.660 + }
1.661 +
1.662 + if ((*handle)->fileName)
1.663 + mp4free((*handle)->fileName);
1.664 +
1.665 + mp4free(*handle);
1.666 + *handle = NULL;
1.667 +
1.668 + return error;
1.669 + }
1.670 +
1.671 + (*handle)->audioSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT;
1.672 + (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
1.673 + (*handle)->audioSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT;
1.674 + (*handle)->audioSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT;
1.675 + (*handle)->audioSampleTable->stcoNeed64Bits = EFalse;
1.676 +
1.677 + (*handle)->videoSampleTable->sttsMaxEntryCount = STTSMAXENTRYCOUNT;
1.678 + (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
1.679 + (*handle)->videoSampleTable->stscMaxEntryCount = STSCMAXENTRYCOUNT;
1.680 + (*handle)->videoSampleTable->stcoMaxEntryCount = STCOMAXENTRYCOUNT;
1.681 + (*handle)->videoSampleTable->stssMaxEntryCount = STSSMAXENTRYCOUNT;
1.682 + (*handle)->videoSampleTable->sdtpMaxEntryCount = SDTPMAXENTRYCOUNT;
1.683 + (*handle)->videoSampleTable->stcoNeed64Bits = EFalse;
1.684 +
1.685 + (*handle)->type = type;
1.686 +
1.687 + /* Check if a 3GPP2 codec is being used */
1.688 + if ((*handle)->type & MP4_TYPE_QCELP_13K)
1.689 + {
1.690 + (*handle)->generate3G2 = MP4TRUE;
1.691 + }
1.692 +
1.693 + return MP4_OK;
1.694 +}
1.695 +
1.696 +extern EXPORT_C MP4Err MP4ComposeClose(MP4Handle apihandle)
1.697 +{
1.698 + PRINT((_L("e_composeclose 1")));
1.699 +
1.700 + mp4_i32 error;
1.701 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.702 +
1.703 + if (!handle)
1.704 + return MP4_ERROR;
1.705 +
1.706 + PRINT((_L("e_composeclose_writedatatofile 1")));
1.707 +
1.708 + error = writeDataToFile(handle);
1.709 +
1.710 + PRINT((_L("e_composeclose_writedatatofile 0")));
1.711 +
1.712 + if(handle->bufferWrite && handle->composedSize)
1.713 + {
1.714 + *(handle->composedSize)=handle->bytesProgressed;
1.715 + }
1.716 +
1.717 + PRINT((_L("e_composeclose_free_decspecinfos 1")));
1.718 + if (handle->videoDecSpecificInfo)
1.719 + mp4free(handle->videoDecSpecificInfo);
1.720 +
1.721 + if (handle->audioDecSpecificInfo)
1.722 + mp4free(handle->audioDecSpecificInfo);
1.723 +
1.724 + PRINT((_L("e_composeclose_free_decspecinfos 0")));
1.725 + PRINT((_L("e_composeclose_free_audiosampletables 1")));
1.726 +
1.727 + if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleCount)
1.728 + mp4free(handle->audioSampleTable->sttsSampleCount);
1.729 +
1.730 + if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleDelta)
1.731 + mp4free(handle->audioSampleTable->sttsSampleDelta);
1.732 +
1.733 + if (handle->audioSampleTable && handle->audioSampleTable->stszEntrySize)
1.734 + mp4free(handle->audioSampleTable->stszEntrySize);
1.735 +
1.736 + if (handle->audioSampleTable && handle->audioSampleTable->stscFirstChunk)
1.737 + mp4free(handle->audioSampleTable->stscFirstChunk);
1.738 +
1.739 + if (handle->audioSampleTable && handle->audioSampleTable->stscSamplesPerChunk)
1.740 + mp4free(handle->audioSampleTable->stscSamplesPerChunk);
1.741 +
1.742 + if (handle->audioSampleTable && handle->audioSampleTable->stscSampleDescriptionIndex)
1.743 + mp4free(handle->audioSampleTable->stscSampleDescriptionIndex);
1.744 +
1.745 + if (handle->audioSampleTable && handle->audioSampleTable->stcoChunkOffset)
1.746 + mp4free(handle->audioSampleTable->stcoChunkOffset);
1.747 +
1.748 + if (handle->audioSampleTable)
1.749 + mp4free(handle->audioSampleTable);
1.750 + PRINT((_L("e_composeclose_free_audiosampletables 0")));
1.751 + PRINT((_L("e_composeclose_free_videosampletables 1")));
1.752 +
1.753 + if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleCount)
1.754 + mp4free(handle->videoSampleTable->sttsSampleCount);
1.755 +
1.756 + if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleDelta)
1.757 + mp4free(handle->videoSampleTable->sttsSampleDelta);
1.758 +
1.759 + if (handle->videoSampleTable && handle->videoSampleTable->stszEntrySize)
1.760 + mp4free(handle->videoSampleTable->stszEntrySize);
1.761 +
1.762 + if (handle->videoSampleTable && handle->videoSampleTable->stscFirstChunk)
1.763 + mp4free(handle->videoSampleTable->stscFirstChunk);
1.764 +
1.765 + if (handle->videoSampleTable && handle->videoSampleTable->stscSamplesPerChunk)
1.766 + mp4free(handle->videoSampleTable->stscSamplesPerChunk);
1.767 +
1.768 + if (handle->videoSampleTable && handle->videoSampleTable->stscSampleDescriptionIndex)
1.769 + mp4free(handle->videoSampleTable->stscSampleDescriptionIndex);
1.770 +
1.771 + if (handle->videoSampleTable && handle->videoSampleTable->stcoChunkOffset)
1.772 + mp4free(handle->videoSampleTable->stcoChunkOffset);
1.773 +
1.774 + if (handle->videoSampleTable && handle->videoSampleTable->stssSampleNumber)
1.775 + mp4free(handle->videoSampleTable->stssSampleNumber);
1.776 +
1.777 + if (handle->videoSampleTable && handle->videoSampleTable->sdtpSampleDependency)
1.778 + mp4free(handle->videoSampleTable->sdtpSampleDependency);
1.779 +
1.780 + if (handle->videoSampleTable)
1.781 + mp4free(handle->videoSampleTable);
1.782 + PRINT((_L("e_composeclose_free_videosampletables 0")));
1.783 + PRINT((_L("e_composeclose_free_dskbuf_and_udta 1")));
1.784 + if (handle->diskWriteBuf)
1.785 + mp4free(handle->diskWriteBuf);
1.786 +
1.787 + if (handle->moovUDTA)
1.788 + {
1.789 + if ( handle->moovUDTA->contentdata )
1.790 + {
1.791 + mp4free(handle->moovUDTA->contentdata);
1.792 + }
1.793 + mp4free(handle->moovUDTA);
1.794 + }
1.795 + if (handle->audioUDTA)
1.796 + {
1.797 + if ( handle->audioUDTA->contentdata )
1.798 + {
1.799 + mp4free(handle->audioUDTA->contentdata);
1.800 + }
1.801 + mp4free(handle->audioUDTA);
1.802 + }
1.803 + if (handle->videoUDTA)
1.804 + {
1.805 + if ( handle->videoUDTA->contentdata )
1.806 + {
1.807 + mp4free(handle->videoUDTA->contentdata);
1.808 + }
1.809 + mp4free(handle->videoUDTA);
1.810 + }
1.811 + PRINT((_L("e_composeclose_free_dskbuf_and_udta 0")));
1.812 +
1.813 + if (!(handle->flags & MP4_FLAG_METADATALAST))
1.814 + {
1.815 + if (handle->tmpfile)
1.816 + {
1.817 + PRINT((_L("e_composeclose_close_temp_files 1")));
1.818 + closeTmpFile(handle);
1.819 + PRINT((_L("e_composeclose_close_temp_files 0")));
1.820 + PRINT((_L("e_composeclose_del_temp_files 1")));
1.821 + deleteTmpFile(handle);
1.822 + PRINT((_L("e_composeclose_del_temp_files 0")));
1.823 + }
1.824 + }
1.825 +
1.826 + PRINT((_L("e_composeclose_free_temp_filename 1")));
1.827 + freeTmpFileName(handle->tmpFileName);
1.828 + PRINT((_L("e_composeclose_free_temp_filename 0")));
1.829 +
1.830 + if (handle->flags & MP4_FLAG_LONGCLIP)
1.831 + {
1.832 + PRINT((_L("e_composeclose_close_metadata_files 1")));
1.833 + closeMetaDataFiles(handle);
1.834 + PRINT((_L("e_composeclose_close_metadata_files 0")));
1.835 + PRINT((_L("e_composeclose_del_metadata_files 1")));
1.836 + if (deleteMetaDataFiles(handle) < 0)
1.837 + error = -1;
1.838 + PRINT((_L("e_composeclose_del_metadata_files 0")));
1.839 + }
1.840 +
1.841 + PRINT((_L("e_composeclose_free_filename 1")));
1.842 + if (handle->fileName)
1.843 + mp4free(handle->fileName);
1.844 + PRINT((_L("e_composeclose_free_filename 0")));
1.845 +
1.846 + PRINT((_L("e_composeclose_close_file 1")));
1.847 + if (handle->file)
1.848 + closeFile(handle);
1.849 + PRINT((_L("e_composeclose_close_file 0")));
1.850 +
1.851 + PRINT((_L("e_composeclose_close_std_lib 1")));
1.852 + closeStdlib();
1.853 + PRINT((_L("e_composeclose_close_std_lib 0")));
1.854 +
1.855 + if (handle->file32Duplicate)
1.856 + ((RFile64*)handle->file32Duplicate)->Close();
1.857 +
1.858 + PRINT((_L("e_composeclose_free_handle 1")));
1.859 + if (handle)
1.860 + {
1.861 + mp4free(handle);
1.862 + handle = NULL;
1.863 + }
1.864 + PRINT((_L("e_composeclose_free_handle 0")));
1.865 +
1.866 + if (error)
1.867 + return MP4_METADATA_ERROR;
1.868 +
1.869 + PRINT((_L("e_composeclose 0")));
1.870 + return MP4_OK;
1.871 +}
1.872 +
1.873 +extern EXPORT_C MP4Err MP4ComposeAddVideoDescription(MP4Handle apihandle,
1.874 + mp4_u32 timescale,
1.875 + mp4_u16 width,
1.876 + mp4_u16 height,
1.877 + mp4_u32 maxbitrate,
1.878 + mp4_u32 avgbitrate)
1.879 +{
1.880 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.881 +
1.882 + if (timescale)
1.883 + handle->videoTimeScale = timescale;
1.884 + else
1.885 + return MP4_ERROR;
1.886 +
1.887 + handle->videoWidth = width;
1.888 + handle->videoHeight = height;
1.889 + handle->videoMaxBitrate = maxbitrate;
1.890 + handle->videoAvgBitrate = avgbitrate;
1.891 +
1.892 + if ( handle->type & (MP4_TYPE_H263_PROFILE_0 | MP4_TYPE_H263_PROFILE_3) )
1.893 + {
1.894 + // default H.263 level is 10; it may be overwritten by MP4ComposeWriteVideoDecoderSpecificInfo
1.895 + handle->videoLevel = 10;
1.896 + }
1.897 +
1.898 + /* Write FTYP and media data size & type if meta data flag is set */
1.899 + if (handle->flags & MP4_FLAG_METADATALAST)
1.900 + {
1.901 + if (handle->ftypWritten != MP4TRUE)
1.902 + {
1.903 + if (writeFTYPAndMDATToFile(handle) < 0)
1.904 + return MP4_ERROR;
1.905 + }
1.906 + }
1.907 +
1.908 + return MP4_OK;
1.909 +}
1.910 +
1.911 +extern EXPORT_C MP4Err MP4ComposeAddAudioDescription(MP4Handle apihandle,
1.912 + mp4_u32 timescale,
1.913 + mp4_u8 audioFramesPerSample,
1.914 + mp4_u16 modeSet)
1.915 +{
1.916 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.917 +
1.918 + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale=%d, AudioFrames=%d, ModeSet=%d "), timescale, audioFramesPerSample, modeSet));
1.919 + if (timescale)
1.920 + {
1.921 + if (timescale > (mp4_u32)0xffff)
1.922 + {
1.923 + return MP4_ERROR;
1.924 + }
1.925 + handle->audioTimeScale = timescale;
1.926 + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale set to = %d"), handle->audioTimeScale ));
1.927 + }
1.928 + else
1.929 + return MP4_ERROR;
1.930 +
1.931 +
1.932 + if ((handle->type & MP4_TYPE_AMR_NB) ||
1.933 + (handle->type & MP4_TYPE_AMR_WB)) /* Audio is AMR */
1.934 + {
1.935 + if (audioFramesPerSample)
1.936 + handle->audioFramesPerSample = audioFramesPerSample;
1.937 + else
1.938 + return MP4_ERROR;
1.939 +
1.940 + if (modeSet)
1.941 + handle->audioModeSet = modeSet;
1.942 + else
1.943 + return MP4_ERROR;
1.944 + }
1.945 + else if (handle->type & MP4_TYPE_QCELP_13K) /* Audio is QCELP 13K */
1.946 + {
1.947 + if (audioFramesPerSample)
1.948 + handle->audioFramesPerSample = audioFramesPerSample;
1.949 + else
1.950 + return MP4_ERROR;
1.951 + }
1.952 + else /* MPEG AAC audio */
1.953 + {
1.954 + handle->audioFramesPerSample = 1;
1.955 + }
1.956 +
1.957 + /* Write FTYP and media data size & type if meta data flag is set */
1.958 + if (handle->flags & MP4_FLAG_METADATALAST)
1.959 + {
1.960 + if (handle->ftypWritten != MP4TRUE)
1.961 + {
1.962 + if (writeFTYPAndMDATToFile(handle) < 0)
1.963 + return MP4_ERROR;
1.964 + }
1.965 + }
1.966 +
1.967 + PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription out")));
1.968 + return MP4_OK;
1.969 +}
1.970 +
1.971 +extern EXPORT_C MP4Err MP4ComposeWriteVideoFrame(MP4Handle apihandle,
1.972 + mp4_u8 *buffer,
1.973 + mp4_u32 framesize,
1.974 + mp4_u32 duration,
1.975 + mp4_bool keyframe)
1.976 +{
1.977 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.978 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame in")));
1.979 + if (handle->videoTimeScale == 0)
1.980 + return MP4_TIMESCALE_NOT_SET;
1.981 +
1.982 + if (framesize == 0)
1.983 + return MP4_ERROR;
1.984 +
1.985 + handle->videoDuration += duration;
1.986 + handle->videoSampleNum++;
1.987 +
1.988 + if (updateVideoMetaData(handle, framesize, duration, keyframe) < 0)
1.989 + return MP4_ERROR;
1.990 +
1.991 + if (handle->flags & MP4_FLAG_METADATALAST)
1.992 + {
1.993 + if (writeFile(handle, buffer, framesize) < 0)
1.994 + return MP4_ERROR;
1.995 +
1.996 + handle->mediaDataBytes += framesize;
1.997 + }
1.998 + else
1.999 + {
1.1000 + if (writeTmpFile(handle, buffer, framesize) < 0)
1.1001 + return MP4_ERROR;
1.1002 + }
1.1003 +
1.1004 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame out")));
1.1005 + return MP4_OK;
1.1006 +}
1.1007 +
1.1008 +extern EXPORT_C MP4Err MP4ComposeWriteAudioFrames(MP4Handle apihandle,
1.1009 + mp4_u8 *buffer,
1.1010 + mp4_u32 bytestowrite,
1.1011 + mp4_u32 numberofframes,
1.1012 + mp4_u32 duration)
1.1013 +{
1.1014 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1015 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames in")));
1.1016 +
1.1017 + if ( handle->audioTimeScale == 0)
1.1018 + {
1.1019 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Error 14 - AudioTimeScale is 0")));
1.1020 + return MP4_TIMESCALE_NOT_SET;
1.1021 + }
1.1022 +
1.1023 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Audio Timescale ok")));
1.1024 +
1.1025 + if (bytestowrite == 0)
1.1026 + return MP4_ERROR;
1.1027 +
1.1028 + handle->audioDuration += duration;
1.1029 + handle->audioFrameCount += numberofframes;
1.1030 + handle->audioMediaDataSize += bytestowrite;
1.1031 +
1.1032 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames updating audio metadata")));
1.1033 +
1.1034 + if (updateAudioMetaData(handle, bytestowrite, duration) < 0)
1.1035 + return MP4_ERROR;
1.1036 +
1.1037 + if (handle->flags & MP4_FLAG_METADATALAST)
1.1038 + {
1.1039 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to file")));
1.1040 + if (writeFile(handle, buffer, bytestowrite) < 0)
1.1041 + return MP4_ERROR;
1.1042 +
1.1043 + handle->mediaDataBytes += bytestowrite;
1.1044 + }
1.1045 + else
1.1046 + {
1.1047 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to temp file")));
1.1048 + if (writeTmpFile(handle, buffer, bytestowrite) < 0)
1.1049 + return MP4_ERROR;
1.1050 + }
1.1051 +
1.1052 + PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames out")));
1.1053 + return MP4_OK;
1.1054 +}
1.1055 +
1.1056 +extern EXPORT_C MP4Err MP4ComposeWriteVideoDecoderSpecificInfo(MP4Handle apihandle,
1.1057 + mp4_u8 *info,
1.1058 + mp4_u32 infosize)
1.1059 +{
1.1060 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1061 +
1.1062 + if ( (handle->type & MP4_TYPE_MPEG4_VIDEO) || containsAvcVideo( handle->type ) )
1.1063 + {
1.1064 + if ((handle->videoDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL)
1.1065 + return MP4_ERROR;
1.1066 +
1.1067 + mp4memcpy(handle->videoDecSpecificInfo, info, infosize);
1.1068 + handle->videoDecSpecificInfoSize = infosize;
1.1069 + }
1.1070 + else
1.1071 + {
1.1072 + // H.263, save level only
1.1073 + if ( *info >= 10 && *info < 100 )
1.1074 + {
1.1075 + handle->videoLevel = *info;
1.1076 + }
1.1077 + }
1.1078 + return MP4_OK;
1.1079 +}
1.1080 +
1.1081 +extern EXPORT_C MP4Err MP4ComposeWriteAudioDecoderSpecificInfo(MP4Handle apihandle,
1.1082 + mp4_u8 *info,
1.1083 + mp4_u32 infosize)
1.1084 +{
1.1085 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1086 +
1.1087 + if ((handle->audioDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL)
1.1088 + return MP4_ERROR;
1.1089 +
1.1090 + mp4memcpy(handle->audioDecSpecificInfo, info, infosize);
1.1091 + handle->audioDecSpecificInfoSize = infosize;
1.1092 +
1.1093 + return MP4_OK;
1.1094 +}
1.1095 +
1.1096 +extern EXPORT_C MP4Err MP4ComposeSetFlags(MP4Handle apihandle,
1.1097 + mp4_u32 flags)
1.1098 +{
1.1099 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1100 + handle->flags |= flags;
1.1101 +
1.1102 + if (handle->flags & MP4_FLAG_METADATALAST)
1.1103 + {
1.1104 + if (handle->tmpfile)
1.1105 + {
1.1106 + closeTmpFile(handle);
1.1107 + deleteTmpFile(handle);
1.1108 + }
1.1109 + }
1.1110 +
1.1111 + if (handle->flags & MP4_FLAG_LONGCLIP)
1.1112 + {
1.1113 + // Open temporary files
1.1114 + MP4Err error = MP4_OK;
1.1115 + error = initMetaDataFiles(handle);
1.1116 + if ( error == MP4_OUT_OF_MEMORY )
1.1117 + {
1.1118 + return MP4_OUT_OF_MEMORY;
1.1119 + }
1.1120 + else if ( error != MP4_OK )
1.1121 + {
1.1122 + return MP4_ERROR;
1.1123 + }
1.1124 + }
1.1125 +
1.1126 + handle->generate3G2 = MP4FALSE;
1.1127 + handle->generateMP4 = MP4FALSE;
1.1128 +
1.1129 + if (handle->flags & MP4_FLAG_GENERATE_3G2) // 3G2
1.1130 + {
1.1131 + // Generate 3G2 file.
1.1132 + handle->generate3G2 = MP4TRUE;
1.1133 + handle->generateMP4 = MP4FALSE;
1.1134 + }
1.1135 + else if ( handle->flags & MP4_FLAG_GENERATE_MP4 ) // MP4
1.1136 + {
1.1137 + // if at least ONE audio/video codec is specified
1.1138 + if (handle->type != MP4_TYPE_NONE)
1.1139 + {
1.1140 + /* Check if a 3GPP2 codec is being used */
1.1141 + if ( handle->type & MP4_TYPE_QCELP_13K )
1.1142 + {
1.1143 + handle->generate3G2 = MP4TRUE;
1.1144 + handle->generateMP4 = MP4FALSE;
1.1145 + }
1.1146 + else
1.1147 + {
1.1148 + // types other than MPEG-4 AUDIO & VIDEO
1.1149 + mp4_u32 type = handle->type >> 2;
1.1150 +
1.1151 + // Check if a MPEG4 codec is being used
1.1152 + if (type == MP4_TYPE_NONE)
1.1153 + {
1.1154 + // if ONLY MPEG4 Video and/or Audio codec is used, generate MP4 file.
1.1155 + handle->generateMP4 = MP4TRUE;
1.1156 + handle->generate3G2 = MP4FALSE;
1.1157 + }
1.1158 + else
1.1159 + {
1.1160 + // ignoring both MPEG-4 audio and video, check again if only AVC codecs are
1.1161 + // used
1.1162 + type <<= 2;
1.1163 + if ( isAvcVideo(type) )
1.1164 + {
1.1165 + // generate MP4 file
1.1166 + handle->generateMP4 = MP4TRUE;
1.1167 + handle->generate3G2 = MP4FALSE;
1.1168 + }
1.1169 + }
1.1170 + }
1.1171 + }
1.1172 + }
1.1173 + else // 3GP
1.1174 + {
1.1175 + /* Check if a 3GPP2 codec is being used */
1.1176 + if ( handle->type & MP4_TYPE_QCELP_13K )
1.1177 + {
1.1178 + handle->generate3G2 = MP4TRUE;
1.1179 + handle->generateMP4 = MP4FALSE;
1.1180 + }
1.1181 + // use defaults -> 3GP
1.1182 + }
1.1183 +
1.1184 + if ( (handle->flags & MP4_FLAG_LARGEFILEBUFFER) && !(handle->bufferWrite) )
1.1185 + {
1.1186 + TInt bufferSizeError = KErrNone;
1.1187 + bufferSizeError = handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeLarge, apihandle );
1.1188 + if ( bufferSizeError == KErrNoMemory )
1.1189 + {
1.1190 + return MP4_OUT_OF_MEMORY;
1.1191 + }
1.1192 + else if ( bufferSizeError != KErrNone )
1.1193 + {
1.1194 + return MP4_ERROR;
1.1195 + }
1.1196 + }
1.1197 + return MP4_OK;
1.1198 +}
1.1199 +
1.1200 +extern EXPORT_C MP4Err MP4ComposeSetQCELPStorageMode(MP4Handle apihandle, mp4_u8 qcelpStorageMode)
1.1201 +{
1.1202 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1203 +
1.1204 + if (qcelpStorageMode)
1.1205 + handle->qcelpStoredAsMPEGAudio = MP4TRUE;
1.1206 + else
1.1207 + handle->qcelpStoredAsMPEGAudio = MP4FALSE;
1.1208 +
1.1209 + return MP4_OK;
1.1210 +
1.1211 +}
1.1212 +
1.1213 +extern EXPORT_C MP4Err MP4ComposeSetVideoClipProperties(MP4Handle apihandle, const TVideoClipProperties& aVideoClipProperties)
1.1214 +{
1.1215 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1216 +
1.1217 + if ( !handle )
1.1218 + {
1.1219 + return MP4_ERROR;
1.1220 + }
1.1221 + else
1.1222 + {
1.1223 + if ( aVideoClipProperties.iH263Level )
1.1224 + {
1.1225 + handle->videoLevel = aVideoClipProperties.iH263Level;
1.1226 + }
1.1227 + return MP4_OK;
1.1228 + }
1.1229 +}
1.1230 +
1.1231 +extern EXPORT_C MP4Err MP4ComposeSetUserDataAtom(MP4Handle apihandle,
1.1232 + mp4_u8& udtaLocation,
1.1233 + mp4_u8* buffer,
1.1234 + mp4_u32& bufferSize )
1.1235 + {
1.1236 + userDataAtom* udta = NULL;
1.1237 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1238 +
1.1239 + if (!handle)
1.1240 + return MP4_ERROR;
1.1241 +
1.1242 + if ( buffer == NULL )
1.1243 + {
1.1244 + return MP4_ERROR;
1.1245 + }
1.1246 + if ( !bufferSize )
1.1247 + {
1.1248 + return MP4_ERROR;
1.1249 + }
1.1250 +
1.1251 + // Check which UDTA atom to use
1.1252 + switch ( udtaLocation )
1.1253 + {
1.1254 + case MP4_UDTA_MOOV:
1.1255 + {
1.1256 + if ( handle->moovUDTA == NULL )
1.1257 + {
1.1258 + handle->moovUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
1.1259 + }
1.1260 + udta = handle->moovUDTA;
1.1261 + break;
1.1262 + }
1.1263 + case MP4_UDTA_VIDEOTRAK:
1.1264 + {
1.1265 + if ( handle->videoUDTA == NULL )
1.1266 + {
1.1267 + handle->videoUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
1.1268 + }
1.1269 + udta = handle->videoUDTA;
1.1270 + break;
1.1271 + }
1.1272 + case MP4_UDTA_AUDIOTRAK:
1.1273 + {
1.1274 + if ( handle->audioUDTA == NULL )
1.1275 + {
1.1276 + handle->audioUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
1.1277 + }
1.1278 + udta = handle->audioUDTA;
1.1279 + break;
1.1280 + }
1.1281 + default:
1.1282 + {
1.1283 + return MP4_INVALID_TYPE;
1.1284 + }
1.1285 + }
1.1286 +
1.1287 + if ( udta == NULL )
1.1288 + {
1.1289 + return MP4_OUT_OF_MEMORY;
1.1290 + }
1.1291 +
1.1292 + // CHECK if there is old data in UDTA
1.1293 + if ( udta->contentdata && udta->atomcontentsize )
1.1294 + {
1.1295 + mp4_u8* temp;
1.1296 + if ((temp = (mp4_u8 *)mp4malloc(bufferSize + udta->atomcontentsize)) == NULL)
1.1297 + {
1.1298 + return MP4_OUT_OF_MEMORY;
1.1299 + }
1.1300 + mp4memcpy(temp, udta->contentdata, udta->atomcontentsize);
1.1301 + mp4memcpy(temp+udta->atomcontentsize, buffer, bufferSize);
1.1302 + mp4free(udta->contentdata);
1.1303 + udta->contentdata = temp;
1.1304 + udta->atomcontentsize += bufferSize;
1.1305 + }
1.1306 + else
1.1307 + {
1.1308 + if ((udta->contentdata = (mp4_u8 *)mp4malloc(bufferSize)) == NULL)
1.1309 + return MP4_OUT_OF_MEMORY;
1.1310 + // Copy data from buffer to atom contentdata
1.1311 + mp4memcpy(udta->contentdata, buffer, bufferSize);
1.1312 + udta->atomcontentsize = bufferSize;
1.1313 + }
1.1314 +
1.1315 + return MP4_OK;
1.1316 + }
1.1317 +
1.1318 +
1.1319 +extern EXPORT_C MP4Err MP4SetCustomFileBufferSizes( MP4Handle apihandle,
1.1320 + mp4_u32 mediaWriteBufferSize,
1.1321 + mp4_u32 writeBufferMaxCount,
1.1322 + mp4_u32 readBufferSize )
1.1323 + {
1.1324 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1325 +
1.1326 + if (!handle)
1.1327 + return MP4_ERROR;
1.1328 +
1.1329 + // If no specific file size is given we try to use an 'optimal' buffer size.
1.1330 + if (readBufferSize == 0)
1.1331 + {
1.1332 + readBufferSize = RecommendedBufferSize(handle);
1.1333 + }
1.1334 +
1.1335 + if (readBufferSize > handle->readBufferSize)
1.1336 + {
1.1337 + handle->readBufferSize = readBufferSize;
1.1338 + if (handle->diskReadBuf)
1.1339 + {
1.1340 + mp4free(handle->diskReadBuf);
1.1341 + handle->diskReadBuf = NULL;
1.1342 + if ((handle->diskReadBuf = (mp4_u8 *)mp4malloc(handle->readBufferSize)) == NULL)
1.1343 + {
1.1344 + return MP4_OUT_OF_MEMORY;
1.1345 + }
1.1346 + }
1.1347 + }
1.1348 +
1.1349 + // Media Write buffer size
1.1350 + if ( (mediaWriteBufferSize) &&
1.1351 + (mediaWriteBufferSize != handle->mediaWriteBufferSize) &&
1.1352 + (!(handle->bufferWrite)) )
1.1353 + {
1.1354 + handle->mediaWriteBufferSize = mediaWriteBufferSize;
1.1355 + if ( (handle->filewriter) )
1.1356 + {
1.1357 + if ( handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeCustom, apihandle ) < 0 )
1.1358 + {
1.1359 + return MP4_ERROR;
1.1360 + }
1.1361 + }
1.1362 + }
1.1363 +
1.1364 + // Write Buffer Max Count change
1.1365 + if ( (writeBufferMaxCount) &&
1.1366 + (writeBufferMaxCount != handle->writeBufferMaxCount) &&
1.1367 + !(handle->bufferWrite) )
1.1368 + {
1.1369 + if ( writeBufferMaxCount >= 6 ) // min number of buffers is 4, +1 for soft limit, +1 for hardlimit = 6
1.1370 + {
1.1371 + handle->writeBufferMaxCount = writeBufferMaxCount;
1.1372 + if ( (handle->filewriter) )
1.1373 + {
1.1374 + handle->filewriter->SetOutputBufferCount( apihandle );
1.1375 + }
1.1376 + }
1.1377 + else
1.1378 + {
1.1379 + return MP4_ERROR;
1.1380 + }
1.1381 + }
1.1382 + return MP4_OK;
1.1383 + }
1.1384 +
1.1385 +extern EXPORT_C MP4Err MP4ComposeWriteNextVideoFrameDependencies(MP4Handle apihandle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy)
1.1386 +{
1.1387 + MP4HandleImp handle = (MP4HandleImp)apihandle;
1.1388 +
1.1389 + if( (aDependsOn > 2) || (aIsDependentOn > 2) || (aHasRedundancy > 2) )
1.1390 + {
1.1391 + return MP4_ERROR;
1.1392 + }
1.1393 +
1.1394 + if (updateVideoDependencyMetaData(handle, aDependsOn, aIsDependentOn, aHasRedundancy) < 0)
1.1395 + {
1.1396 + return MP4_ERROR;
1.1397 + }
1.1398 +
1.1399 + return MP4_OK;
1.1400 +}
1.1401 +
1.1402 +extern EXPORT_C MP4Err MP4ComposeSetTempFileRemoverObserver(
1.1403 + MP4Handle *apihandle,
1.1404 + M3GPMP4LibAsyncTempFileRemoverObserver *aObserver)
1.1405 +{
1.1406 + PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver in")));
1.1407 +
1.1408 + MP4Err error = MP4_OK;
1.1409 + MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
1.1410 +
1.1411 + if ( handle != NULL && *handle != NULL )
1.1412 + {
1.1413 + (*handle)->tempFileRemoverObserver = aObserver;
1.1414 + }
1.1415 + else
1.1416 + {
1.1417 + error = MP4_ERROR;
1.1418 + }
1.1419 +
1.1420 +
1.1421 + PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver out error=%d"), error));
1.1422 + return error;
1.1423 +}
1.1424 +// End of File