mmplugins/lib3gp/impl/src/mp4compose.cpp
changeset 0 40261b775718
child 11 d5f04de580b7
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <3gplibrary/mp4config.h>
       
    17 #include <3gplibrary/mp4lib.h>
       
    18 #include "mp4atom.h"
       
    19 #include "mp4memwrap.h"
       
    20 #include "mp4file.h"
       
    21 #include "mp4compose.h"
       
    22 #include "mp4utils.h"
       
    23 
       
    24 // MACROS
       
    25 // Debug print macro
       
    26 #ifdef _DEBUG
       
    27 #include <e32svr.h>
       
    28 #define PRINT(x) 
       
    29 #else
       
    30 #define PRINT(x)
       
    31 #endif
       
    32 
       
    33 #define STTSMAXENTRYCOUNT  100
       
    34 #define STSZMAXSAMPLECOUNT 100
       
    35 #define STSCMAXENTRYCOUNT    2
       
    36 #define STCOMAXENTRYCOUNT  100
       
    37 #define STSSMAXENTRYCOUNT  100
       
    38 #define SDTPMAXENTRYCOUNT  100
       
    39 
       
    40 
       
    41 extern EXPORT_C MP4Err MP4ComposeOpen(MP4Handle *apihandle,
       
    42                                                    MP4FileName filename,
       
    43                                                    mp4_u32 type)
       
    44 {
       
    45   MP4Err error = MP4_OK;
       
    46   MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
       
    47 
       
    48   if ( filename != NULL )
       
    49       {
       
    50       *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));     
       
    51       if (*handle == NULL)
       
    52           {
       
    53           return MP4_OUT_OF_MEMORY;      
       
    54           }
       
    55       (*handle)->bufferWrite=MP4FALSE;
       
    56       }
       
    57   else
       
    58       {
       
    59       if ( *handle == NULL )
       
    60           {
       
    61           return MP4_ERROR;
       
    62           }
       
    63       }
       
    64   
       
    65   (*handle)->file32Duplicate = NULL;
       
    66   (*handle)->FileHandleFromOutside = EFalse;
       
    67 
       
    68   if(!(*handle)->bufferWrite)
       
    69   {
       
    70 		if (!filename)
       
    71 		    {
       
    72 			error = MP4_FILE_ERROR;
       
    73 		    }
       
    74 		
       
    75 		if ( error == MP4_OK )
       
    76 		    {
       
    77     		if (saveFileName(filename, *handle) < 0)
       
    78 	    		error = MP4_OUT_OF_MEMORY;
       
    79 		    }
       
    80 		
       
    81 		if (error == MP4_OK)
       
    82 		{
       
    83 			if (createTmpFileName(filename, &((*handle)->tmpFileName)) == -1)
       
    84 				error = MP4_OUT_OF_MEMORY;
       
    85 		}
       
    86 		
       
    87 		if (error == MP4_OK)
       
    88 		{
       
    89 			if (initFileWrite(filename, *handle) == -1)
       
    90 				error = MP4_FILE_ERROR;
       
    91 		}
       
    92 		
       
    93 		if (error == MP4_OK)
       
    94 		{
       
    95 			if (initTmpFileWrite((*handle)->tmpFileName, *handle) == -1)
       
    96 				error = MP4_FILE_ERROR;
       
    97 		}
       
    98   }
       
    99 
       
   100   if (error == MP4_OK)
       
   101   {
       
   102     (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE);
       
   103     if ((*handle)->diskWriteBuf == NULL)
       
   104       error = MP4_OUT_OF_MEMORY;
       
   105   }
       
   106 
       
   107   if (error == MP4_OK)
       
   108   {
       
   109     (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
       
   110     if ((*handle)->audioSampleTable == NULL)
       
   111       error = MP4_OUT_OF_MEMORY;
       
   112   }
       
   113 
       
   114   if (error == MP4_OK)
       
   115   {
       
   116     (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   117     if ((*handle)->audioSampleTable->sttsSampleCount == NULL)
       
   118       error = MP4_OUT_OF_MEMORY;
       
   119   }
       
   120 
       
   121   if (error == MP4_OK)
       
   122   {
       
   123     (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   124     if ((*handle)->audioSampleTable->sttsSampleDelta == NULL)
       
   125       error = MP4_OUT_OF_MEMORY;
       
   126   }
       
   127 
       
   128   if (error == MP4_OK)
       
   129   {
       
   130     (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
       
   131     if ((*handle)->audioSampleTable->stszEntrySize == NULL)
       
   132       error = MP4_OUT_OF_MEMORY;
       
   133   }
       
   134 
       
   135   if (error == MP4_OK)
       
   136   {
       
   137     (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   138     if ((*handle)->audioSampleTable->stscFirstChunk == NULL)
       
   139       error = MP4_OUT_OF_MEMORY;
       
   140   }
       
   141 
       
   142   if (error == MP4_OK)
       
   143   {
       
   144     (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   145     if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL)
       
   146       error = MP4_OUT_OF_MEMORY;
       
   147   }
       
   148 
       
   149   if (error == MP4_OK)
       
   150   {
       
   151     (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   152     if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL)
       
   153       error = MP4_OUT_OF_MEMORY;
       
   154   }
       
   155 
       
   156   if (error == MP4_OK)
       
   157   {
       
   158     (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
       
   159     if ((*handle)->audioSampleTable->stcoChunkOffset == NULL)
       
   160       error = MP4_OUT_OF_MEMORY;
       
   161   }
       
   162 
       
   163   if (error == MP4_OK)
       
   164   {
       
   165     (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
       
   166     if ((*handle)->videoSampleTable == NULL)
       
   167       error = MP4_OUT_OF_MEMORY;
       
   168   }
       
   169 
       
   170   if (error == MP4_OK)
       
   171   {
       
   172     (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   173     if ((*handle)->videoSampleTable->sttsSampleCount == NULL)
       
   174       error = MP4_OUT_OF_MEMORY;
       
   175   }
       
   176 
       
   177   if (error == MP4_OK)
       
   178   {
       
   179     (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   180     if ((*handle)->videoSampleTable->sttsSampleDelta == NULL)
       
   181       error = MP4_OUT_OF_MEMORY;
       
   182   }
       
   183 
       
   184   if (error == MP4_OK)
       
   185   {
       
   186     (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
       
   187     if ((*handle)->videoSampleTable->stszEntrySize == NULL)
       
   188       error = MP4_OUT_OF_MEMORY;
       
   189   }
       
   190 
       
   191   if (error == MP4_OK)
       
   192   {
       
   193     (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   194     if ((*handle)->videoSampleTable->stscFirstChunk == NULL)
       
   195       error = MP4_OUT_OF_MEMORY;
       
   196   }
       
   197 
       
   198   if (error == MP4_OK)
       
   199   {
       
   200     (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   201     if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL)
       
   202       error = MP4_OUT_OF_MEMORY;
       
   203   }
       
   204 
       
   205   if (error == MP4_OK)
       
   206   {
       
   207     (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   208     if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL)
       
   209       error = MP4_OUT_OF_MEMORY;
       
   210   }
       
   211 
       
   212   if (error == MP4_OK)
       
   213   {
       
   214     (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
       
   215     if ((*handle)->videoSampleTable->stcoChunkOffset == NULL)
       
   216       error = MP4_OUT_OF_MEMORY;
       
   217   }
       
   218 
       
   219   if (error == MP4_OK)
       
   220   {
       
   221     (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT);
       
   222     if ((*handle)->videoSampleTable->stssSampleNumber == NULL)
       
   223       error = MP4_OUT_OF_MEMORY;
       
   224   }
       
   225   
       
   226   if (error == MP4_OK)
       
   227   {
       
   228     (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT);
       
   229     if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL)
       
   230       error = MP4_OUT_OF_MEMORY;
       
   231   }
       
   232 
       
   233   // register for stblib use 
       
   234   if (error == MP4_OK)
       
   235 	  {
       
   236 	  if (openStdlib() !=  MP4_OK)
       
   237 		  {
       
   238 		  error = MP4_ERROR;
       
   239 		  }
       
   240 	  }
       
   241   
       
   242   if (error != MP4_OK)
       
   243   {
       
   244     if(!(*handle)->bufferWrite)
       
   245     {
       
   246         closeFile(*handle);
       
   247 
       
   248         closeTmpFile(*handle);
       
   249 
       
   250         freeTmpFileName((*handle)->tmpFileName);
       
   251     }
       
   252 
       
   253     if ((*handle)->diskWriteBuf)
       
   254       mp4free((*handle)->diskWriteBuf);
       
   255 
       
   256     if ((*handle)->videoSampleTable)
       
   257     {
       
   258       if ((*handle)->videoSampleTable->stssSampleNumber)
       
   259         mp4free((*handle)->videoSampleTable->stssSampleNumber);
       
   260 
       
   261       if ((*handle)->videoSampleTable->stcoChunkOffset)
       
   262         mp4free((*handle)->videoSampleTable->stcoChunkOffset);
       
   263 
       
   264       if ((*handle)->videoSampleTable->stscSampleDescriptionIndex)
       
   265         mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex);
       
   266 
       
   267       if ((*handle)->videoSampleTable->stscSamplesPerChunk)
       
   268         mp4free((*handle)->videoSampleTable->stscSamplesPerChunk);
       
   269 
       
   270       if ((*handle)->videoSampleTable->stscFirstChunk)
       
   271         mp4free((*handle)->videoSampleTable->stscFirstChunk);
       
   272 
       
   273       if ((*handle)->videoSampleTable->stszEntrySize)
       
   274         mp4free((*handle)->videoSampleTable->stszEntrySize);
       
   275 
       
   276       if ((*handle)->videoSampleTable->sttsSampleCount)
       
   277         mp4free((*handle)->videoSampleTable->sttsSampleCount);
       
   278 
       
   279       if ((*handle)->videoSampleTable->sttsSampleDelta)
       
   280         mp4free((*handle)->videoSampleTable->sttsSampleDelta);
       
   281       
       
   282       if ((*handle)->videoSampleTable->sdtpSampleDependency)
       
   283         mp4free((*handle)->videoSampleTable->sdtpSampleDependency);
       
   284 
       
   285       mp4free((*handle)->videoSampleTable);
       
   286     }
       
   287 
       
   288     if ((*handle)->audioSampleTable)
       
   289     {
       
   290       if ((*handle)->audioSampleTable->stcoChunkOffset)
       
   291         mp4free((*handle)->audioSampleTable->stcoChunkOffset);
       
   292 
       
   293       if ((*handle)->audioSampleTable->stscSampleDescriptionIndex)
       
   294         mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex);
       
   295 
       
   296       if ((*handle)->audioSampleTable->stscSamplesPerChunk)
       
   297         mp4free((*handle)->audioSampleTable->stscSamplesPerChunk);
       
   298 
       
   299       if ((*handle)->audioSampleTable->stscFirstChunk)
       
   300         mp4free((*handle)->audioSampleTable->stscFirstChunk);
       
   301 
       
   302       if ((*handle)->audioSampleTable->stszEntrySize)
       
   303         mp4free((*handle)->audioSampleTable->stszEntrySize);
       
   304 
       
   305       if ((*handle)->audioSampleTable->sttsSampleDelta)
       
   306         mp4free((*handle)->audioSampleTable->sttsSampleDelta);
       
   307 
       
   308       if ((*handle)->audioSampleTable->sttsSampleCount)
       
   309         mp4free((*handle)->audioSampleTable->sttsSampleCount);
       
   310 
       
   311       mp4free((*handle)->audioSampleTable);
       
   312     }
       
   313 
       
   314     if ((*handle)->fileName)
       
   315       mp4free((*handle)->fileName);
       
   316 
       
   317     mp4free(*handle);
       
   318     *handle = NULL;
       
   319 
       
   320     return error;
       
   321   }
       
   322 
       
   323 
       
   324   (*handle)->audioSampleTable->sttsMaxEntryCount  = STTSMAXENTRYCOUNT;
       
   325   (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
       
   326   (*handle)->audioSampleTable->stscMaxEntryCount  = STSCMAXENTRYCOUNT;
       
   327   (*handle)->audioSampleTable->stcoMaxEntryCount  = STCOMAXENTRYCOUNT;
       
   328   (*handle)->audioSampleTable->stcoNeed64Bits     = EFalse;
       
   329   
       
   330   (*handle)->videoSampleTable->sttsMaxEntryCount  = STTSMAXENTRYCOUNT;
       
   331   (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
       
   332   (*handle)->videoSampleTable->stscMaxEntryCount  = STSCMAXENTRYCOUNT;
       
   333   (*handle)->videoSampleTable->stcoMaxEntryCount  = STCOMAXENTRYCOUNT;
       
   334   (*handle)->videoSampleTable->stssMaxEntryCount  = STSSMAXENTRYCOUNT;
       
   335   (*handle)->videoSampleTable->sdtpMaxEntryCount  = SDTPMAXENTRYCOUNT;
       
   336   (*handle)->videoSampleTable->stcoNeed64Bits     = EFalse;
       
   337   
       
   338   (*handle)->type = type;
       
   339 
       
   340   /* Check if a 3GPP2 codec is being used */
       
   341   if ((*handle)->type & MP4_TYPE_QCELP_13K)
       
   342       {
       
   343       (*handle)->generate3G2 = MP4TRUE;
       
   344       }
       
   345 
       
   346   return MP4_OK;
       
   347 }
       
   348 
       
   349 extern EXPORT_C MP4Err MP4ComposeOpenToBuffer(MP4Handle *apihandle,
       
   350                                                    mp4_u32 type,
       
   351                                                    mp4_u8* composeBuffer, 
       
   352                                                    mp4_u32 *composedSize)
       
   353 {
       
   354   MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
       
   355 
       
   356   *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));
       
   357   if (*handle == NULL)              
       
   358     return MP4_OUT_OF_MEMORY;
       
   359 
       
   360   (*handle)->file32Duplicate = NULL;
       
   361   (*handle)->bufferWrite=MP4TRUE;
       
   362   (*handle)->FileHandleFromOutside = EFalse;
       
   363 
       
   364   if(composeBuffer == NULL)
       
   365 	{
       
   366 	return MP4_NO_OUTPUT_BUFFER; //This is to indicate that compose buffer has not been initialized
       
   367 	}
       
   368 
       
   369   (*handle)->composeBuffer=composeBuffer;
       
   370   (*handle)->composedSize=composedSize;
       
   371 
       
   372   return MP4ComposeOpen( apihandle, NULL, type );
       
   373 }
       
   374 
       
   375 extern EXPORT_C MP4Err MP4ComposeOpenFileHandle(MP4Handle *apihandle, 
       
   376                                                              RFile *composedfile, 
       
   377                                                              TDriveNumber metadataTempDrive, 
       
   378                                                              mp4_u32 type)
       
   379 {
       
   380   MP4Err err;
       
   381   RFile64 *f64 = new RFile64;
       
   382   if (f64 == NULL)
       
   383   {
       
   384     return MP4_OUT_OF_MEMORY;
       
   385   }
       
   386   if  (f64->Duplicate(*composedfile) != KErrNone)
       
   387   {
       
   388     delete f64;
       
   389     return MP4_ERROR;
       
   390   }
       
   391   err = MP4ComposeOpenFileHandle64(apihandle, f64, metadataTempDrive, type);
       
   392   if (err == MP4_OK)
       
   393   {    
       
   394     MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
       
   395     (*handle)->file32Duplicate = (void*)f64;
       
   396   }
       
   397   return err;
       
   398 }
       
   399 
       
   400 
       
   401 
       
   402 extern EXPORT_C MP4Err MP4ComposeOpenFileHandle64(MP4Handle *apihandle, 
       
   403                                                              RFile64 *composedfile, 
       
   404                                                              TDriveNumber metadataTempDrive, 
       
   405                                                              mp4_u32 type)
       
   406 {
       
   407   MP4Err error = MP4_OK;
       
   408   MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
       
   409 
       
   410   *handle = (MP4HandleImp)mp4malloc(sizeof(MP4HandleStruct));     
       
   411   if (*handle == NULL)
       
   412       {
       
   413       return MP4_OUT_OF_MEMORY;      
       
   414       }
       
   415   (*handle)->bufferWrite=MP4FALSE;
       
   416   (*handle)->file32Duplicate = NULL;
       
   417   // since file handle we can´t use temporary file for mediadata safely.
       
   418   (*handle)->flags |= MP4_FLAG_METADATALAST;
       
   419   (*handle)->FileHandleFromOutside = ETrue;
       
   420   (*handle)->fileHandleDrive = metadataTempDrive;
       
   421 
       
   422   RFs   *fs;
       
   423   fs = new(RFs);
       
   424   (*handle)->fs = (void *)fs;
       
   425   if (fs == NULL)
       
   426     error = MP4_FILE_ERROR;
       
   427   
       
   428   if (error == MP4_OK)
       
   429     {
       
   430     if (fs->Connect() != KErrNone)
       
   431         error = MP4_FILE_ERROR;
       
   432     }
       
   433 
       
   434   if (error == MP4_OK)
       
   435     {
       
   436     (*handle)->rfile = (void *)composedfile;
       
   437     if (composedfile == NULL)
       
   438         error = MP4_FILE_ERROR;
       
   439     
       
   440     (*handle)->file = (*handle)->rfile;    
       
   441     
       
   442     TRAPD(traperror, (*handle)->filewriter = CFileWriter::NewL( *composedfile ));
       
   443     if ( traperror != KErrNone )
       
   444         {
       
   445         error = MP4_FILE_ERROR;
       
   446         }
       
   447     }
       
   448 	
       
   449   if (error == MP4_OK)
       
   450   {
       
   451     (*handle)->diskWriteBuf = (mp4_u8 *)mp4malloc(WRITEBUFSIZE);
       
   452     if ((*handle)->diskWriteBuf == NULL)
       
   453       error = MP4_OUT_OF_MEMORY;
       
   454   }
       
   455 
       
   456   if (error == MP4_OK)
       
   457   {
       
   458     (*handle)->audioSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
       
   459     if ((*handle)->audioSampleTable == NULL)
       
   460       error = MP4_OUT_OF_MEMORY;
       
   461   }
       
   462 
       
   463   if (error == MP4_OK)
       
   464   {
       
   465     (*handle)->audioSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   466     if ((*handle)->audioSampleTable->sttsSampleCount == NULL)
       
   467       error = MP4_OUT_OF_MEMORY;
       
   468   }
       
   469 
       
   470   if (error == MP4_OK)
       
   471   {
       
   472     (*handle)->audioSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   473     if ((*handle)->audioSampleTable->sttsSampleDelta == NULL)
       
   474       error = MP4_OUT_OF_MEMORY;
       
   475   }
       
   476 
       
   477   if (error == MP4_OK)
       
   478   {
       
   479     (*handle)->audioSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
       
   480     if ((*handle)->audioSampleTable->stszEntrySize == NULL)
       
   481       error = MP4_OUT_OF_MEMORY;
       
   482   }
       
   483 
       
   484   if (error == MP4_OK)
       
   485   {
       
   486     (*handle)->audioSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   487     if ((*handle)->audioSampleTable->stscFirstChunk == NULL)
       
   488       error = MP4_OUT_OF_MEMORY;
       
   489   }
       
   490 
       
   491   if (error == MP4_OK)
       
   492   {
       
   493     (*handle)->audioSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   494     if ((*handle)->audioSampleTable->stscSamplesPerChunk == NULL)
       
   495       error = MP4_OUT_OF_MEMORY;
       
   496   }
       
   497 
       
   498   if (error == MP4_OK)
       
   499   {
       
   500     (*handle)->audioSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   501     if ((*handle)->audioSampleTable->stscSampleDescriptionIndex == NULL)
       
   502       error = MP4_OUT_OF_MEMORY;
       
   503   }
       
   504 
       
   505   if (error == MP4_OK)
       
   506   {
       
   507     (*handle)->audioSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
       
   508     if ((*handle)->audioSampleTable->stcoChunkOffset == NULL)
       
   509       error = MP4_OUT_OF_MEMORY;
       
   510   }
       
   511 
       
   512   if (error == MP4_OK)
       
   513   {
       
   514     (*handle)->videoSampleTable = (sampleTable *)mp4malloc(sizeof(sampleTable));
       
   515     if ((*handle)->videoSampleTable == NULL)
       
   516       error = MP4_OUT_OF_MEMORY;
       
   517   }
       
   518 
       
   519   if (error == MP4_OK)
       
   520   {
       
   521     (*handle)->videoSampleTable->sttsSampleCount = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   522     if ((*handle)->videoSampleTable->sttsSampleCount == NULL)
       
   523       error = MP4_OUT_OF_MEMORY;
       
   524   }
       
   525 
       
   526   if (error == MP4_OK)
       
   527   {
       
   528     (*handle)->videoSampleTable->sttsSampleDelta = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STTSMAXENTRYCOUNT);
       
   529     if ((*handle)->videoSampleTable->sttsSampleDelta == NULL)
       
   530       error = MP4_OUT_OF_MEMORY;
       
   531   }
       
   532 
       
   533   if (error == MP4_OK)
       
   534   {
       
   535     (*handle)->videoSampleTable->stszEntrySize = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSZMAXSAMPLECOUNT);
       
   536     if ((*handle)->videoSampleTable->stszEntrySize == NULL)
       
   537       error = MP4_OUT_OF_MEMORY;
       
   538   }
       
   539 
       
   540   if (error == MP4_OK)
       
   541   {
       
   542     (*handle)->videoSampleTable->stscFirstChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   543     if ((*handle)->videoSampleTable->stscFirstChunk == NULL)
       
   544       error = MP4_OUT_OF_MEMORY;
       
   545   }
       
   546 
       
   547   if (error == MP4_OK)
       
   548   {
       
   549     (*handle)->videoSampleTable->stscSamplesPerChunk = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   550     if ((*handle)->videoSampleTable->stscSamplesPerChunk == NULL)
       
   551       error = MP4_OUT_OF_MEMORY;
       
   552   }
       
   553 
       
   554   if (error == MP4_OK)
       
   555   {
       
   556     (*handle)->videoSampleTable->stscSampleDescriptionIndex = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSCMAXENTRYCOUNT);
       
   557     if ((*handle)->videoSampleTable->stscSampleDescriptionIndex == NULL)
       
   558       error = MP4_OUT_OF_MEMORY;
       
   559   }
       
   560 
       
   561   if (error == MP4_OK)
       
   562   {
       
   563     (*handle)->videoSampleTable->stcoChunkOffset = (mp4_u64 *)mp4malloc(sizeof(mp4_u64) * STCOMAXENTRYCOUNT);
       
   564     if ((*handle)->videoSampleTable->stcoChunkOffset == NULL)
       
   565       error = MP4_OUT_OF_MEMORY;
       
   566   }
       
   567 
       
   568   if (error == MP4_OK)
       
   569   {
       
   570     (*handle)->videoSampleTable->stssSampleNumber = (mp4_u32 *)mp4malloc(sizeof(mp4_u32) * STSSMAXENTRYCOUNT);
       
   571     if ((*handle)->videoSampleTable->stssSampleNumber == NULL)
       
   572       error = MP4_OUT_OF_MEMORY;
       
   573   }
       
   574   
       
   575   if (error == MP4_OK)
       
   576   {
       
   577     (*handle)->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)mp4malloc(sizeof(mp4_u8) * SDTPMAXENTRYCOUNT);
       
   578     if ((*handle)->videoSampleTable->sdtpSampleDependency == NULL)
       
   579       error = MP4_OUT_OF_MEMORY;
       
   580   }
       
   581 
       
   582   // register for stblib use 
       
   583   if (error == MP4_OK)
       
   584 	  {
       
   585 	  if (openStdlib() !=  MP4_OK)
       
   586 		  {
       
   587 		  error = MP4_ERROR;
       
   588 		  }
       
   589 	  }
       
   590   
       
   591   if (error != MP4_OK)
       
   592   {
       
   593     if(!(*handle)->bufferWrite)
       
   594     {
       
   595         closeFile(*handle);
       
   596     }
       
   597 
       
   598     if ((*handle)->diskWriteBuf)
       
   599       mp4free((*handle)->diskWriteBuf);
       
   600 
       
   601     if ((*handle)->videoSampleTable)
       
   602     {
       
   603       if ((*handle)->videoSampleTable->stssSampleNumber)
       
   604         mp4free((*handle)->videoSampleTable->stssSampleNumber);
       
   605 
       
   606       if ((*handle)->videoSampleTable->stcoChunkOffset)
       
   607         mp4free((*handle)->videoSampleTable->stcoChunkOffset);
       
   608 
       
   609       if ((*handle)->videoSampleTable->stscSampleDescriptionIndex)
       
   610         mp4free((*handle)->videoSampleTable->stscSampleDescriptionIndex);
       
   611 
       
   612       if ((*handle)->videoSampleTable->stscSamplesPerChunk)
       
   613         mp4free((*handle)->videoSampleTable->stscSamplesPerChunk);
       
   614 
       
   615       if ((*handle)->videoSampleTable->stscFirstChunk)
       
   616         mp4free((*handle)->videoSampleTable->stscFirstChunk);
       
   617 
       
   618       if ((*handle)->videoSampleTable->stszEntrySize)
       
   619         mp4free((*handle)->videoSampleTable->stszEntrySize);
       
   620 
       
   621       if ((*handle)->videoSampleTable->sttsSampleCount)
       
   622         mp4free((*handle)->videoSampleTable->sttsSampleCount);
       
   623 
       
   624       if ((*handle)->videoSampleTable->sttsSampleDelta)
       
   625         mp4free((*handle)->videoSampleTable->sttsSampleDelta);
       
   626       
       
   627       if ((*handle)->videoSampleTable->sdtpSampleDependency)
       
   628         mp4free((*handle)->videoSampleTable->sdtpSampleDependency);
       
   629 
       
   630       mp4free((*handle)->videoSampleTable);
       
   631     }
       
   632 
       
   633     if ((*handle)->audioSampleTable)
       
   634     {
       
   635       if ((*handle)->audioSampleTable->stcoChunkOffset)
       
   636         mp4free((*handle)->audioSampleTable->stcoChunkOffset);
       
   637 
       
   638       if ((*handle)->audioSampleTable->stscSampleDescriptionIndex)
       
   639         mp4free((*handle)->audioSampleTable->stscSampleDescriptionIndex);
       
   640 
       
   641       if ((*handle)->audioSampleTable->stscSamplesPerChunk)
       
   642         mp4free((*handle)->audioSampleTable->stscSamplesPerChunk);
       
   643 
       
   644       if ((*handle)->audioSampleTable->stscFirstChunk)
       
   645         mp4free((*handle)->audioSampleTable->stscFirstChunk);
       
   646 
       
   647       if ((*handle)->audioSampleTable->stszEntrySize)
       
   648         mp4free((*handle)->audioSampleTable->stszEntrySize);
       
   649 
       
   650       if ((*handle)->audioSampleTable->sttsSampleDelta)
       
   651         mp4free((*handle)->audioSampleTable->sttsSampleDelta);
       
   652 
       
   653       if ((*handle)->audioSampleTable->sttsSampleCount)
       
   654         mp4free((*handle)->audioSampleTable->sttsSampleCount);
       
   655 
       
   656       mp4free((*handle)->audioSampleTable);
       
   657     }
       
   658 
       
   659     if ((*handle)->fileName)
       
   660       mp4free((*handle)->fileName);
       
   661 
       
   662     mp4free(*handle);
       
   663     *handle = NULL;
       
   664 
       
   665     return error;
       
   666   }
       
   667 
       
   668   (*handle)->audioSampleTable->sttsMaxEntryCount  = STTSMAXENTRYCOUNT;
       
   669   (*handle)->audioSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
       
   670   (*handle)->audioSampleTable->stscMaxEntryCount  = STSCMAXENTRYCOUNT;
       
   671   (*handle)->audioSampleTable->stcoMaxEntryCount  = STCOMAXENTRYCOUNT;
       
   672   (*handle)->audioSampleTable->stcoNeed64Bits     = EFalse;
       
   673 
       
   674   (*handle)->videoSampleTable->sttsMaxEntryCount  = STTSMAXENTRYCOUNT;
       
   675   (*handle)->videoSampleTable->stszMaxSampleCount = STSZMAXSAMPLECOUNT;
       
   676   (*handle)->videoSampleTable->stscMaxEntryCount  = STSCMAXENTRYCOUNT;
       
   677   (*handle)->videoSampleTable->stcoMaxEntryCount  = STCOMAXENTRYCOUNT;
       
   678   (*handle)->videoSampleTable->stssMaxEntryCount  = STSSMAXENTRYCOUNT;
       
   679   (*handle)->videoSampleTable->sdtpMaxEntryCount  = SDTPMAXENTRYCOUNT;
       
   680   (*handle)->videoSampleTable->stcoNeed64Bits     = EFalse;
       
   681 
       
   682   (*handle)->type = type;
       
   683 
       
   684   /* Check if a 3GPP2 codec is being used */
       
   685   if ((*handle)->type & MP4_TYPE_QCELP_13K)
       
   686       {
       
   687       (*handle)->generate3G2 = MP4TRUE;
       
   688       }
       
   689   
       
   690   return MP4_OK;
       
   691 }
       
   692 
       
   693 extern EXPORT_C MP4Err MP4ComposeClose(MP4Handle apihandle)
       
   694 {
       
   695   PRINT((_L("e_composeclose 1")));
       
   696 
       
   697   mp4_i32  error;
       
   698   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
   699 
       
   700   if (!handle)
       
   701     return MP4_ERROR;
       
   702   
       
   703   PRINT((_L("e_composeclose_writedatatofile 1")));
       
   704 
       
   705   error = writeDataToFile(handle);
       
   706 
       
   707   PRINT((_L("e_composeclose_writedatatofile 0")));
       
   708 
       
   709   if(handle->bufferWrite && handle->composedSize)
       
   710   {
       
   711 	   *(handle->composedSize)=handle->bytesProgressed;
       
   712   }
       
   713 
       
   714   PRINT((_L("e_composeclose_free_decspecinfos 1")));
       
   715   if (handle->videoDecSpecificInfo)
       
   716     mp4free(handle->videoDecSpecificInfo);
       
   717 
       
   718   if (handle->audioDecSpecificInfo)
       
   719     mp4free(handle->audioDecSpecificInfo);
       
   720   
       
   721   PRINT((_L("e_composeclose_free_decspecinfos 0")));
       
   722   PRINT((_L("e_composeclose_free_audiosampletables 1")));
       
   723   
       
   724   if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleCount)
       
   725     mp4free(handle->audioSampleTable->sttsSampleCount);
       
   726 
       
   727   if (handle->audioSampleTable && handle->audioSampleTable->sttsSampleDelta)
       
   728     mp4free(handle->audioSampleTable->sttsSampleDelta);
       
   729 
       
   730   if (handle->audioSampleTable && handle->audioSampleTable->stszEntrySize)
       
   731     mp4free(handle->audioSampleTable->stszEntrySize);
       
   732 
       
   733   if (handle->audioSampleTable && handle->audioSampleTable->stscFirstChunk)
       
   734     mp4free(handle->audioSampleTable->stscFirstChunk);
       
   735 
       
   736   if (handle->audioSampleTable && handle->audioSampleTable->stscSamplesPerChunk)
       
   737     mp4free(handle->audioSampleTable->stscSamplesPerChunk);
       
   738 
       
   739   if (handle->audioSampleTable && handle->audioSampleTable->stscSampleDescriptionIndex)
       
   740     mp4free(handle->audioSampleTable->stscSampleDescriptionIndex);
       
   741 
       
   742   if (handle->audioSampleTable && handle->audioSampleTable->stcoChunkOffset)
       
   743     mp4free(handle->audioSampleTable->stcoChunkOffset);
       
   744 
       
   745   if (handle->audioSampleTable)
       
   746     mp4free(handle->audioSampleTable);
       
   747   PRINT((_L("e_composeclose_free_audiosampletables 0")));
       
   748   PRINT((_L("e_composeclose_free_videosampletables 1")));
       
   749 
       
   750   if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleCount)
       
   751     mp4free(handle->videoSampleTable->sttsSampleCount);
       
   752 
       
   753   if (handle->videoSampleTable && handle->videoSampleTable->sttsSampleDelta)
       
   754     mp4free(handle->videoSampleTable->sttsSampleDelta);
       
   755 
       
   756   if (handle->videoSampleTable && handle->videoSampleTable->stszEntrySize)
       
   757     mp4free(handle->videoSampleTable->stszEntrySize);
       
   758 
       
   759   if (handle->videoSampleTable && handle->videoSampleTable->stscFirstChunk)
       
   760     mp4free(handle->videoSampleTable->stscFirstChunk);
       
   761 
       
   762   if (handle->videoSampleTable && handle->videoSampleTable->stscSamplesPerChunk)
       
   763     mp4free(handle->videoSampleTable->stscSamplesPerChunk);
       
   764 
       
   765   if (handle->videoSampleTable && handle->videoSampleTable->stscSampleDescriptionIndex)
       
   766     mp4free(handle->videoSampleTable->stscSampleDescriptionIndex);
       
   767 
       
   768   if (handle->videoSampleTable && handle->videoSampleTable->stcoChunkOffset)
       
   769     mp4free(handle->videoSampleTable->stcoChunkOffset);
       
   770 
       
   771   if (handle->videoSampleTable && handle->videoSampleTable->stssSampleNumber)
       
   772     mp4free(handle->videoSampleTable->stssSampleNumber);
       
   773   
       
   774   if (handle->videoSampleTable && handle->videoSampleTable->sdtpSampleDependency)
       
   775     mp4free(handle->videoSampleTable->sdtpSampleDependency);
       
   776 
       
   777   if (handle->videoSampleTable)
       
   778     mp4free(handle->videoSampleTable);
       
   779   PRINT((_L("e_composeclose_free_videosampletables 0")));  
       
   780   PRINT((_L("e_composeclose_free_dskbuf_and_udta 1")));
       
   781   if (handle->diskWriteBuf)
       
   782     mp4free(handle->diskWriteBuf);
       
   783 
       
   784   if (handle->moovUDTA)
       
   785       {
       
   786       if ( handle->moovUDTA->contentdata )
       
   787           {
       
   788           mp4free(handle->moovUDTA->contentdata);
       
   789           }
       
   790       mp4free(handle->moovUDTA);
       
   791       }
       
   792   if (handle->audioUDTA)
       
   793       {
       
   794       if ( handle->audioUDTA->contentdata )
       
   795           {
       
   796           mp4free(handle->audioUDTA->contentdata);
       
   797           }
       
   798       mp4free(handle->audioUDTA);
       
   799       }
       
   800   if (handle->videoUDTA)
       
   801       {
       
   802       if ( handle->videoUDTA->contentdata )
       
   803           {
       
   804           mp4free(handle->videoUDTA->contentdata);
       
   805           }
       
   806       mp4free(handle->videoUDTA);
       
   807       }
       
   808   PRINT((_L("e_composeclose_free_dskbuf_and_udta 0")));
       
   809 
       
   810   if (!(handle->flags & MP4_FLAG_METADATALAST))
       
   811   {
       
   812     if (handle->tmpfile)
       
   813     {
       
   814       PRINT((_L("e_composeclose_close_temp_files 1")));
       
   815       closeTmpFile(handle);
       
   816       PRINT((_L("e_composeclose_close_temp_files 0")));
       
   817       PRINT((_L("e_composeclose_del_temp_files 1")));      
       
   818       deleteTmpFile(handle);
       
   819       PRINT((_L("e_composeclose_del_temp_files 0")));
       
   820     }
       
   821   }
       
   822 
       
   823   PRINT((_L("e_composeclose_free_temp_filename 1")));
       
   824   freeTmpFileName(handle->tmpFileName);
       
   825   PRINT((_L("e_composeclose_free_temp_filename 0")));
       
   826 
       
   827   if (handle->flags & MP4_FLAG_LONGCLIP)
       
   828   {
       
   829   	PRINT((_L("e_composeclose_close_metadata_files 1")));
       
   830     closeMetaDataFiles(handle);
       
   831     PRINT((_L("e_composeclose_close_metadata_files 0")));
       
   832 	PRINT((_L("e_composeclose_del_metadata_files 1")));
       
   833     if (deleteMetaDataFiles(handle) < 0)
       
   834       error = -1;
       
   835     PRINT((_L("e_composeclose_del_metadata_files 0")));
       
   836   }
       
   837 
       
   838   PRINT((_L("e_composeclose_free_filename 1")));
       
   839   if (handle->fileName)
       
   840     mp4free(handle->fileName);
       
   841   PRINT((_L("e_composeclose_free_filename 0")));
       
   842 
       
   843   PRINT((_L("e_composeclose_close_file 1")));
       
   844   if (handle->file)
       
   845     closeFile(handle);
       
   846   PRINT((_L("e_composeclose_close_file 0")));
       
   847 
       
   848   PRINT((_L("e_composeclose_close_std_lib 1")));
       
   849   closeStdlib();
       
   850   PRINT((_L("e_composeclose_close_std_lib 0")));
       
   851 
       
   852   if (handle->file32Duplicate)
       
   853       ((RFile64*)handle->file32Duplicate)->Close();
       
   854   
       
   855   PRINT((_L("e_composeclose_free_handle 1")));
       
   856   if (handle)
       
   857     {
       
   858     mp4free(handle);
       
   859     handle = NULL;
       
   860     }
       
   861   PRINT((_L("e_composeclose_free_handle 0")));  
       
   862 
       
   863   if (error)
       
   864     return MP4_METADATA_ERROR;
       
   865   
       
   866   PRINT((_L("e_composeclose 0")));
       
   867   return MP4_OK;
       
   868 }
       
   869 
       
   870 extern EXPORT_C MP4Err MP4ComposeAddVideoDescription(MP4Handle apihandle,
       
   871                                                                   mp4_u32 timescale,
       
   872                                                                   mp4_u16 width,
       
   873                                                                   mp4_u16 height,
       
   874                                                                   mp4_u32 maxbitrate,
       
   875                                                                   mp4_u32 avgbitrate)
       
   876 {
       
   877   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
   878 
       
   879   if (timescale)
       
   880     handle->videoTimeScale = timescale;
       
   881   else
       
   882     return MP4_ERROR;
       
   883 
       
   884   handle->videoWidth = width;
       
   885   handle->videoHeight = height;
       
   886   handle->videoMaxBitrate = maxbitrate;
       
   887   handle->videoAvgBitrate = avgbitrate;
       
   888 
       
   889   if ( handle->type & (MP4_TYPE_H263_PROFILE_0 | MP4_TYPE_H263_PROFILE_3) )
       
   890       {
       
   891       // default H.263 level is 10; it may be overwritten by MP4ComposeWriteVideoDecoderSpecificInfo
       
   892       handle->videoLevel = 10;
       
   893       }
       
   894 
       
   895   /* Write FTYP and media data size & type if meta data flag is set */
       
   896   if (handle->flags & MP4_FLAG_METADATALAST)
       
   897   {
       
   898     if (handle->ftypWritten != MP4TRUE)
       
   899     {
       
   900       if (writeFTYPAndMDATToFile(handle) < 0)
       
   901         return MP4_ERROR;
       
   902     }
       
   903   }
       
   904 
       
   905   return MP4_OK;
       
   906 }
       
   907 
       
   908 extern EXPORT_C MP4Err MP4ComposeAddAudioDescription(MP4Handle apihandle,
       
   909                                                                   mp4_u32 timescale,
       
   910                                                                   mp4_u8 audioFramesPerSample,
       
   911                                                                   mp4_u16 modeSet)
       
   912 {
       
   913   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
   914   
       
   915   PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale=%d, AudioFrames=%d, ModeSet=%d "), timescale, audioFramesPerSample, modeSet));  
       
   916   if (timescale)
       
   917   {
       
   918     if (timescale > (mp4_u32)0xffff)
       
   919     	{
       
   920       	return MP4_ERROR;    	
       
   921     	}
       
   922     handle->audioTimeScale = timescale;
       
   923     PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription in. TimeScale set to = %d"), handle->audioTimeScale ));  
       
   924   }
       
   925   else
       
   926     return MP4_ERROR;
       
   927 
       
   928 
       
   929   if ((handle->type & MP4_TYPE_AMR_NB) ||
       
   930       (handle->type & MP4_TYPE_AMR_WB)) /* Audio is AMR */
       
   931   {
       
   932     if (audioFramesPerSample)
       
   933       handle->audioFramesPerSample = audioFramesPerSample;
       
   934     else
       
   935       return MP4_ERROR;
       
   936 
       
   937     if (modeSet)
       
   938       handle->audioModeSet = modeSet;
       
   939     else
       
   940       return MP4_ERROR;
       
   941   }
       
   942   else if (handle->type & MP4_TYPE_QCELP_13K) /* Audio is QCELP 13K */
       
   943   {
       
   944     if (audioFramesPerSample)
       
   945       handle->audioFramesPerSample = audioFramesPerSample;
       
   946     else
       
   947       return MP4_ERROR;
       
   948   }
       
   949   else /* MPEG AAC audio */
       
   950   {
       
   951     handle->audioFramesPerSample = 1;
       
   952   }
       
   953 
       
   954   /* Write FTYP and media data size & type if meta data flag is set */
       
   955   if (handle->flags & MP4_FLAG_METADATALAST)
       
   956   {
       
   957     if (handle->ftypWritten != MP4TRUE)
       
   958     {
       
   959       if (writeFTYPAndMDATToFile(handle) < 0)
       
   960         return MP4_ERROR;
       
   961     }
       
   962   }
       
   963   
       
   964   PRINT((_L("3GPMP4Lib::MP4ComposeAddAudioDescription out")));  
       
   965   return MP4_OK;
       
   966 }
       
   967 
       
   968 extern EXPORT_C MP4Err MP4ComposeWriteVideoFrame(MP4Handle apihandle,
       
   969                                                               mp4_u8 *buffer,
       
   970                                                               mp4_u32 framesize,
       
   971                                                               mp4_u32 duration,
       
   972                                                               mp4_bool keyframe)
       
   973 {
       
   974   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
   975   PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame in")));
       
   976   if (handle->videoTimeScale == 0)
       
   977     return MP4_TIMESCALE_NOT_SET;
       
   978 
       
   979   if (framesize == 0)
       
   980     return MP4_ERROR;
       
   981 
       
   982   handle->videoDuration += duration;
       
   983   handle->videoSampleNum++;
       
   984 
       
   985   if (updateVideoMetaData(handle, framesize, duration, keyframe) < 0)
       
   986     return MP4_ERROR;
       
   987 
       
   988   if (handle->flags & MP4_FLAG_METADATALAST)
       
   989   {
       
   990     if (writeFile(handle, buffer, framesize) < 0)
       
   991       return MP4_ERROR;
       
   992 
       
   993     handle->mediaDataBytes += framesize;
       
   994   }
       
   995   else
       
   996   {
       
   997     if (writeTmpFile(handle, buffer, framesize) < 0)
       
   998       return MP4_ERROR;
       
   999   }
       
  1000 
       
  1001   PRINT((_L("3GPMP4Lib::MP4ComposeWriteVideoFrame out")));
       
  1002   return MP4_OK;
       
  1003 }
       
  1004 
       
  1005 extern EXPORT_C MP4Err MP4ComposeWriteAudioFrames(MP4Handle apihandle,
       
  1006                                                                mp4_u8 *buffer,
       
  1007                                                                mp4_u32 bytestowrite,
       
  1008                                                                mp4_u32 numberofframes,
       
  1009                                                                mp4_u32 duration)
       
  1010 {
       
  1011   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1012   PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames in")));
       
  1013 
       
  1014   if ( handle->audioTimeScale == 0)	
       
  1015   	  {
       
  1016   	  PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Error 14 - AudioTimeScale is 0")));
       
  1017       return MP4_TIMESCALE_NOT_SET;
       
  1018 	  }
       
  1019 	  
       
  1020   PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames Audio Timescale ok")));	  
       
  1021 
       
  1022   if (bytestowrite == 0)
       
  1023     return MP4_ERROR;
       
  1024 
       
  1025   handle->audioDuration += duration;
       
  1026   handle->audioFrameCount += numberofframes;
       
  1027   handle->audioMediaDataSize += bytestowrite;
       
  1028 
       
  1029   PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames updating audio metadata")));	  
       
  1030   
       
  1031   if (updateAudioMetaData(handle, bytestowrite, duration) < 0)
       
  1032     return MP4_ERROR;
       
  1033 
       
  1034   if (handle->flags & MP4_FLAG_METADATALAST)
       
  1035   {
       
  1036 	PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to file")));	    
       
  1037     if (writeFile(handle, buffer, bytestowrite) < 0)
       
  1038       return MP4_ERROR;
       
  1039 
       
  1040     handle->mediaDataBytes += bytestowrite;
       
  1041   }
       
  1042   else
       
  1043   {
       
  1044 	PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames writing to temp file")));	      
       
  1045     if (writeTmpFile(handle, buffer, bytestowrite) < 0)
       
  1046       return MP4_ERROR;
       
  1047   }
       
  1048   
       
  1049   PRINT((_L("3GPMP4Lib::MP4ComposeWriteAudioFrames out")));
       
  1050   return MP4_OK;
       
  1051 }
       
  1052 
       
  1053 extern EXPORT_C MP4Err MP4ComposeWriteVideoDecoderSpecificInfo(MP4Handle apihandle,
       
  1054                                                                             mp4_u8 *info,
       
  1055                                                                             mp4_u32 infosize)
       
  1056 {
       
  1057   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1058 
       
  1059   if ( (handle->type & MP4_TYPE_MPEG4_VIDEO) || containsAvcVideo( handle->type ) )
       
  1060       {
       
  1061       if ((handle->videoDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL)
       
  1062         return MP4_ERROR;
       
  1063 
       
  1064       mp4memcpy(handle->videoDecSpecificInfo, info, infosize);
       
  1065       handle->videoDecSpecificInfoSize = infosize;
       
  1066       }
       
  1067   else
       
  1068       {
       
  1069       // H.263, save level only
       
  1070       if ( *info >= 10 && *info < 100 )
       
  1071           {
       
  1072           handle->videoLevel = *info;
       
  1073           }
       
  1074       }
       
  1075   return MP4_OK;
       
  1076 }
       
  1077 
       
  1078 extern EXPORT_C MP4Err MP4ComposeWriteAudioDecoderSpecificInfo(MP4Handle apihandle,
       
  1079                                                                             mp4_u8 *info,
       
  1080                                                                             mp4_u32 infosize)
       
  1081 {
       
  1082   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1083 
       
  1084   if ((handle->audioDecSpecificInfo = (mp4_u8 *)mp4malloc(infosize)) == NULL)
       
  1085     return MP4_ERROR;
       
  1086 
       
  1087   mp4memcpy(handle->audioDecSpecificInfo, info, infosize);
       
  1088   handle->audioDecSpecificInfoSize = infosize;
       
  1089 
       
  1090   return MP4_OK;
       
  1091 }
       
  1092 
       
  1093 extern EXPORT_C MP4Err MP4ComposeSetFlags(MP4Handle apihandle,
       
  1094                                                        mp4_u32 flags)
       
  1095 {
       
  1096   MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1097   handle->flags |= flags;
       
  1098 
       
  1099   if (handle->flags & MP4_FLAG_METADATALAST)
       
  1100   {
       
  1101     if (handle->tmpfile)
       
  1102     {
       
  1103       closeTmpFile(handle);
       
  1104       deleteTmpFile(handle);
       
  1105     }
       
  1106   }
       
  1107 
       
  1108   if (handle->flags & MP4_FLAG_LONGCLIP)
       
  1109   {
       
  1110     // Open temporary files
       
  1111     MP4Err error = MP4_OK;
       
  1112     error = initMetaDataFiles(handle);
       
  1113     if ( error == MP4_OUT_OF_MEMORY )
       
  1114 	    {
       
  1115 	    return MP4_OUT_OF_MEMORY;
       
  1116 	    }
       
  1117  	else if ( error != MP4_OK )
       
  1118 	 	{
       
  1119 		return MP4_ERROR;
       
  1120 	 	}
       
  1121   }
       
  1122 
       
  1123   handle->generate3G2 = MP4FALSE;
       
  1124   handle->generateMP4 = MP4FALSE;   
       
  1125 
       
  1126   if (handle->flags & MP4_FLAG_GENERATE_3G2) // 3G2
       
  1127   {
       
  1128     // Generate 3G2 file.
       
  1129     handle->generate3G2 = MP4TRUE;
       
  1130     handle->generateMP4 = MP4FALSE;      
       
  1131   }
       
  1132   else if ( handle->flags & MP4_FLAG_GENERATE_MP4 ) // MP4
       
  1133 	  {
       
  1134 	  // if at least ONE audio/video codec is specified
       
  1135 	  if (handle->type != MP4_TYPE_NONE)
       
  1136 		  {
       
  1137 	      /* Check if a 3GPP2 codec is being used */
       
  1138 	      if ( handle->type & MP4_TYPE_QCELP_13K )
       
  1139 	    	  {
       
  1140 	    	  handle->generate3G2 = MP4TRUE;
       
  1141 	    	  handle->generateMP4 = MP4FALSE;   
       
  1142 	    	  }
       
  1143 	      else 
       
  1144 	    	  {
       
  1145 			  // types other than MPEG-4 AUDIO & VIDEO  
       
  1146 			  mp4_u32 type = handle->type >> 2;	
       
  1147 		  
       
  1148 			  // Check if a MPEG4 codec is being used
       
  1149 			  if (type == MP4_TYPE_NONE)
       
  1150 				  {
       
  1151 				  // if ONLY MPEG4 Video and/or Audio codec is used, generate MP4 file.
       
  1152 				  handle->generateMP4 = MP4TRUE;      
       
  1153 				  handle->generate3G2 = MP4FALSE;
       
  1154 				  }	  
       
  1155 			  else
       
  1156 				  {
       
  1157 				  // ignoring both MPEG-4 audio and video, check again if only AVC codecs are 
       
  1158 				  // used
       
  1159 				  type <<= 2;			  
       
  1160 				  if ( isAvcVideo(type) )
       
  1161 					  {
       
  1162 					  // generate MP4 file
       
  1163 					  handle->generateMP4 = MP4TRUE;      
       
  1164 					  handle->generate3G2 = MP4FALSE;
       
  1165 					  }
       
  1166 				  }
       
  1167 	    	  }
       
  1168 		  }
       
  1169 	  }
       
  1170   else // 3GP
       
  1171   {
       
  1172       /* Check if a 3GPP2 codec is being used */
       
  1173       if ( handle->type & MP4_TYPE_QCELP_13K )
       
  1174       {
       
  1175         handle->generate3G2 = MP4TRUE;
       
  1176         handle->generateMP4 = MP4FALSE;   
       
  1177       }
       
  1178       // use defaults -> 3GP
       
  1179   }
       
  1180 
       
  1181   if ( (handle->flags & MP4_FLAG_LARGEFILEBUFFER) && !(handle->bufferWrite) )
       
  1182       {
       
  1183       TInt bufferSizeError = KErrNone;
       
  1184       bufferSizeError = handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeLarge, apihandle );
       
  1185       if ( bufferSizeError == KErrNoMemory )
       
  1186       	{
       
  1187       	return MP4_OUT_OF_MEMORY;
       
  1188       	}
       
  1189 	  else if ( bufferSizeError != KErrNone )
       
  1190         {
       
  1191         return MP4_ERROR;
       
  1192         }
       
  1193       }
       
  1194   return MP4_OK;
       
  1195 }
       
  1196 
       
  1197 extern EXPORT_C MP4Err MP4ComposeSetQCELPStorageMode(MP4Handle apihandle, mp4_u8 qcelpStorageMode)
       
  1198 {
       
  1199     MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1200 
       
  1201     if (qcelpStorageMode)
       
  1202       handle->qcelpStoredAsMPEGAudio = MP4TRUE;
       
  1203     else
       
  1204       handle->qcelpStoredAsMPEGAudio = MP4FALSE;
       
  1205 
       
  1206     return MP4_OK;
       
  1207 
       
  1208 }
       
  1209 
       
  1210 extern EXPORT_C MP4Err MP4ComposeSetVideoClipProperties(MP4Handle apihandle, const TVideoClipProperties& aVideoClipProperties)
       
  1211 {
       
  1212     MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1213 
       
  1214     if ( !handle )
       
  1215     {
       
  1216         return MP4_ERROR;
       
  1217     }
       
  1218     else
       
  1219     {
       
  1220         if ( aVideoClipProperties.iH263Level )
       
  1221         {
       
  1222             handle->videoLevel = aVideoClipProperties.iH263Level;
       
  1223         }
       
  1224         return MP4_OK;
       
  1225     }
       
  1226 }
       
  1227 
       
  1228 extern EXPORT_C MP4Err MP4ComposeSetUserDataAtom(MP4Handle apihandle, 
       
  1229                                                             mp4_u8& udtaLocation,
       
  1230                                                             mp4_u8* buffer,
       
  1231                                                             mp4_u32& bufferSize )
       
  1232     {
       
  1233     userDataAtom* udta = NULL;
       
  1234     MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1235 
       
  1236     if (!handle)
       
  1237         return MP4_ERROR;
       
  1238 
       
  1239     if ( buffer == NULL )
       
  1240         {
       
  1241         return MP4_ERROR;
       
  1242         }
       
  1243     if ( !bufferSize )
       
  1244         {
       
  1245         return MP4_ERROR;
       
  1246         }
       
  1247 
       
  1248     // Check which UDTA atom to use
       
  1249     switch ( udtaLocation )
       
  1250         {
       
  1251         case MP4_UDTA_MOOV:
       
  1252             {
       
  1253             if ( handle->moovUDTA == NULL )
       
  1254                 {
       
  1255                 handle->moovUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
       
  1256                 }
       
  1257             udta = handle->moovUDTA;
       
  1258             break;
       
  1259             }
       
  1260         case MP4_UDTA_VIDEOTRAK:
       
  1261             {
       
  1262             if ( handle->videoUDTA == NULL )
       
  1263                 {
       
  1264                 handle->videoUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
       
  1265                 }
       
  1266             udta = handle->videoUDTA;
       
  1267             break;
       
  1268             }
       
  1269         case MP4_UDTA_AUDIOTRAK:
       
  1270             {
       
  1271             if ( handle->audioUDTA == NULL )
       
  1272                 {
       
  1273                 handle->audioUDTA = (userDataAtom *)mp4malloc(sizeof(userDataAtom));
       
  1274                 }
       
  1275             udta = handle->audioUDTA;
       
  1276             break;
       
  1277             }
       
  1278        default:
       
  1279             {
       
  1280             return MP4_INVALID_TYPE;
       
  1281             }
       
  1282         }
       
  1283         
       
  1284     if ( udta == NULL )
       
  1285         {
       
  1286         return MP4_OUT_OF_MEMORY;
       
  1287         }
       
  1288 
       
  1289     // CHECK if there is old data in UDTA
       
  1290     if ( udta->contentdata && udta->atomcontentsize )
       
  1291         {
       
  1292         mp4_u8* temp;
       
  1293         if ((temp = (mp4_u8 *)mp4malloc(bufferSize + udta->atomcontentsize)) == NULL)
       
  1294             {
       
  1295             return MP4_OUT_OF_MEMORY;
       
  1296             }
       
  1297         mp4memcpy(temp, udta->contentdata, udta->atomcontentsize);
       
  1298         mp4memcpy(temp+udta->atomcontentsize, buffer, bufferSize);
       
  1299         mp4free(udta->contentdata);
       
  1300         udta->contentdata = temp;
       
  1301         udta->atomcontentsize += bufferSize;
       
  1302         }
       
  1303     else
       
  1304         {
       
  1305         if ((udta->contentdata = (mp4_u8 *)mp4malloc(bufferSize)) == NULL)
       
  1306             return MP4_OUT_OF_MEMORY;        
       
  1307         // Copy data from buffer to atom contentdata        
       
  1308         mp4memcpy(udta->contentdata, buffer, bufferSize);                
       
  1309         udta->atomcontentsize = bufferSize;
       
  1310         }
       
  1311 
       
  1312     return MP4_OK;
       
  1313     }
       
  1314 
       
  1315 extern EXPORT_C MP4Err MP4SetCustomFileBufferSizes( MP4Handle apihandle, 
       
  1316                                                                mp4_u32 mediaWriteBufferSize,
       
  1317                                                                mp4_u32 writeBufferMaxCount,
       
  1318                                                                mp4_u32 readBufferSize )
       
  1319     {
       
  1320     MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1321 
       
  1322     if (!handle)
       
  1323         return MP4_ERROR;
       
  1324     
       
  1325     // Read Buffer size
       
  1326     if ( (readBufferSize) && 
       
  1327          (readBufferSize != handle->readBufferSize) )
       
  1328         {
       
  1329         handle->readBufferSize = readBufferSize;
       
  1330         if (handle->diskReadBuf)
       
  1331             {
       
  1332             mp4free(handle->diskReadBuf);
       
  1333             if ((handle->diskReadBuf = (mp4_u8 *)mp4malloc(handle->readBufferSize)) == NULL)
       
  1334                 {
       
  1335                 return MP4_OUT_OF_MEMORY;
       
  1336                 }
       
  1337             }
       
  1338         }
       
  1339         
       
  1340     // Media Write buffer size
       
  1341     if ( (mediaWriteBufferSize) &&  
       
  1342          (mediaWriteBufferSize != handle->mediaWriteBufferSize) &&
       
  1343          (!(handle->bufferWrite)) )
       
  1344         {
       
  1345         handle->mediaWriteBufferSize = mediaWriteBufferSize;
       
  1346         if ( (handle->filewriter) )
       
  1347           {
       
  1348           if ( handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeCustom, apihandle ) < 0 )
       
  1349               {
       
  1350               return MP4_ERROR;
       
  1351               }
       
  1352           }
       
  1353         }
       
  1354         
       
  1355     // Write Buffer Max Count change
       
  1356     if ( (writeBufferMaxCount) &&  
       
  1357          (writeBufferMaxCount != handle->writeBufferMaxCount) &&
       
  1358          !(handle->bufferWrite) )
       
  1359         {
       
  1360         if ( writeBufferMaxCount >= 6 ) // min number of buffers is 4, +1 for soft limit, +1 for hardlimit = 6
       
  1361             {
       
  1362             handle->writeBufferMaxCount = writeBufferMaxCount;
       
  1363             if ( (handle->filewriter) )
       
  1364               {
       
  1365               handle->filewriter->SetOutputBufferCount( apihandle );
       
  1366               }
       
  1367             }
       
  1368         else
       
  1369             {
       
  1370             return MP4_ERROR;
       
  1371             }
       
  1372         }
       
  1373     return MP4_OK;
       
  1374     }
       
  1375 
       
  1376 extern EXPORT_C MP4Err MP4ComposeWriteNextVideoFrameDependencies(MP4Handle apihandle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy)
       
  1377 {
       
  1378 	MP4HandleImp handle = (MP4HandleImp)apihandle;
       
  1379 	
       
  1380 	if( (aDependsOn > 2) || (aIsDependentOn > 2) || (aHasRedundancy > 2) )
       
  1381 	{
       
  1382 		return MP4_ERROR;
       
  1383 	}
       
  1384 	
       
  1385 	if (updateVideoDependencyMetaData(handle, aDependsOn, aIsDependentOn, aHasRedundancy) < 0)
       
  1386 	{
       
  1387 		return MP4_ERROR;
       
  1388 	}
       
  1389 	
       
  1390 	return MP4_OK;
       
  1391 }
       
  1392 
       
  1393 extern EXPORT_C MP4Err MP4ComposeSetTempFileRemoverObserver(
       
  1394                                         MP4Handle *apihandle,
       
  1395                                         M3GPMP4LibAsyncTempFileRemoverObserver *aObserver)
       
  1396 {
       
  1397   PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver in")));
       
  1398 
       
  1399   MP4Err error = MP4_OK;
       
  1400   MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
       
  1401 
       
  1402   if ( handle != NULL && *handle != NULL )
       
  1403       {
       
  1404       (*handle)->tempFileRemoverObserver = aObserver;
       
  1405       }
       
  1406   else
       
  1407       {
       
  1408       error = MP4_ERROR;
       
  1409       }
       
  1410 
       
  1411 
       
  1412   PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver out error=%d"), error));
       
  1413   return error;
       
  1414 }
       
  1415 // End of File