os/mm/mmplugins/lib3gp/impl/src/mp4compose.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	
  1316 extern EXPORT_C MP4Err MP4SetCustomFileBufferSizes( MP4Handle apihandle, 
  1317                                                                mp4_u32 mediaWriteBufferSize,
  1318                                                                mp4_u32 writeBufferMaxCount,
  1319                                                                mp4_u32 readBufferSize )
  1320     {
  1321     MP4HandleImp handle = (MP4HandleImp)apihandle;
  1322 
  1323     if (!handle)
  1324         return MP4_ERROR;
  1325     
  1326     // If no specific file size is given we try to use an 'optimal' buffer size.
  1327     if (readBufferSize == 0)
  1328     	{
  1329     	readBufferSize = RecommendedBufferSize(handle);
  1330 		}
  1331 
  1332 	if (readBufferSize > handle->readBufferSize)
  1333         {
  1334         handle->readBufferSize = readBufferSize;
  1335         if (handle->diskReadBuf)
  1336             {
  1337             mp4free(handle->diskReadBuf);
  1338             handle->diskReadBuf = NULL;
  1339             if ((handle->diskReadBuf = (mp4_u8 *)mp4malloc(handle->readBufferSize)) == NULL)
  1340                 {
  1341                 return MP4_OUT_OF_MEMORY;
  1342                 }
  1343             }
  1344         }
  1345         
  1346     // Media Write buffer size
  1347     if ( (mediaWriteBufferSize) &&  
  1348          (mediaWriteBufferSize != handle->mediaWriteBufferSize) &&
  1349          (!(handle->bufferWrite)) )
  1350         {
  1351         handle->mediaWriteBufferSize = mediaWriteBufferSize;
  1352         if ( (handle->filewriter) )
  1353           {
  1354           if ( handle->filewriter->SetOutputBufferSize( CFileWriter::EBufferSizeCustom, apihandle ) < 0 )
  1355               {
  1356               return MP4_ERROR;
  1357               }
  1358           }
  1359         }
  1360         
  1361     // Write Buffer Max Count change
  1362     if ( (writeBufferMaxCount) &&  
  1363          (writeBufferMaxCount != handle->writeBufferMaxCount) &&
  1364          !(handle->bufferWrite) )
  1365         {
  1366         if ( writeBufferMaxCount >= 6 ) // min number of buffers is 4, +1 for soft limit, +1 for hardlimit = 6
  1367             {
  1368             handle->writeBufferMaxCount = writeBufferMaxCount;
  1369             if ( (handle->filewriter) )
  1370               {
  1371               handle->filewriter->SetOutputBufferCount( apihandle );
  1372               }
  1373             }
  1374         else
  1375             {
  1376             return MP4_ERROR;
  1377             }
  1378         }
  1379     return MP4_OK;
  1380     }
  1381 
  1382 extern EXPORT_C MP4Err MP4ComposeWriteNextVideoFrameDependencies(MP4Handle apihandle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy)
  1383 {
  1384 	MP4HandleImp handle = (MP4HandleImp)apihandle;
  1385 	
  1386 	if( (aDependsOn > 2) || (aIsDependentOn > 2) || (aHasRedundancy > 2) )
  1387 	{
  1388 		return MP4_ERROR;
  1389 	}
  1390 	
  1391 	if (updateVideoDependencyMetaData(handle, aDependsOn, aIsDependentOn, aHasRedundancy) < 0)
  1392 	{
  1393 		return MP4_ERROR;
  1394 	}
  1395 	
  1396 	return MP4_OK;
  1397 }
  1398 
  1399 extern EXPORT_C MP4Err MP4ComposeSetTempFileRemoverObserver(
  1400                                         MP4Handle *apihandle,
  1401                                         M3GPMP4LibAsyncTempFileRemoverObserver *aObserver)
  1402 {
  1403   PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver in")));
  1404 
  1405   MP4Err error = MP4_OK;
  1406   MP4HandleImp* handle = (MP4HandleStruct **)apihandle;
  1407 
  1408   if ( handle != NULL && *handle != NULL )
  1409       {
  1410       (*handle)->tempFileRemoverObserver = aObserver;
  1411       }
  1412   else
  1413       {
  1414       error = MP4_ERROR;
  1415       }
  1416 
  1417 
  1418   PRINT((_L("3GPMP4Lib::MP4ComposeSetTempFileRemoverObserver out error=%d"), error));
  1419   return error;
  1420 }
  1421 // End of File