os/mm/mmplugins/lib3gp/impl/src/compose.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <3gplibrary/mp4config.h>
sl@0
    17
#include <3gplibrary/mp4lib.h>
sl@0
    18
#include "mp4atom.h"
sl@0
    19
#include "mp4memwrap.h"
sl@0
    20
#include "mp4file.h"
sl@0
    21
#include "mp4endian.h"
sl@0
    22
#include "mp4compose.h"
sl@0
    23
#include "mp4currenttime.h"
sl@0
    24
#include "mp4utils.h"
sl@0
    25
sl@0
    26
#define MP4_INT_MAX		KMaxTInt32	
sl@0
    27
#define MDAT_HEADER_SIZE 16
sl@0
    28
sl@0
    29
// MACROS
sl@0
    30
// Debug print macro
sl@0
    31
#ifdef _DEBUG
sl@0
    32
#include <e32svr.h>
sl@0
    33
#define PRINT(x)
sl@0
    34
#else
sl@0
    35
#define PRINT(x)
sl@0
    36
#endif
sl@0
    37
sl@0
    38
sl@0
    39
inline void updateChunkOffset(sampleTable *st, mp4_i32 index, mp4_i64 value) 
sl@0
    40
{
sl@0
    41
  if (value > MP4_INT_MAX) 
sl@0
    42
    st->stcoNeed64Bits = ETrue; 
sl@0
    43
  
sl@0
    44
  st->stcoChunkOffset[index] = value;
sl@0
    45
}
sl@0
    46
sl@0
    47
/* must be called after determineAudioTrakMetaDataSize and determineVideoTrakMetaDataSize */
sl@0
    48
size_t mvhdAtomSize(MP4HandleImp handle)
sl@0
    49
{
sl@0
    50
  if (handle->videoDuration > MP4_INT_MAX || handle->audioDuration > MP4_INT_MAX)
sl@0
    51
  {
sl@0
    52
    return 120;
sl@0
    53
  }
sl@0
    54
  else
sl@0
    55
  {
sl@0
    56
    return 108;
sl@0
    57
  }
sl@0
    58
}
sl@0
    59
sl@0
    60
sl@0
    61
sl@0
    62
/* helper functions */
sl@0
    63
mp4_i32 formatMdatHeader(mp4_u8 *buffer, mp4_i64 size);
sl@0
    64
sl@0
    65
/*
sl@0
    66
 * Function:
sl@0
    67
 *
sl@0
    68
 *   mp4_i32 updateVideoMetaData(MP4HandleImp handle,
sl@0
    69
 *                               mp4_u32 size,
sl@0
    70
 *                               mp4_u32 duration)
sl@0
    71
 *
sl@0
    72
 * Description:
sl@0
    73
 *
sl@0
    74
 *   This function updates sample table atom data.
sl@0
    75
 *
sl@0
    76
 *   One call of this function will generate one chunk in the MP4 file.
sl@0
    77
 *
sl@0
    78
 * Parameters:
sl@0
    79
 *
sl@0
    80
 *   handle    MP4 library handle
sl@0
    81
 *   size      Size of video frame to insert
sl@0
    82
 *   duration  Duration of the video frame (in media timescale)
sl@0
    83
 *
sl@0
    84
 * Return value:
sl@0
    85
 *
sl@0
    86
 *   0         Success
sl@0
    87
 *   -1        Error
sl@0
    88
 *
sl@0
    89
 */
sl@0
    90
mp4_i32 updateVideoMetaData(MP4HandleImp handle, mp4_u32 size, mp4_u32 duration, mp4_bool keyframe)
sl@0
    91
{
sl@0
    92
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
    93
  {
sl@0
    94
    if (handle->metaDataBlocks == BLOCK_LIMIT)
sl@0
    95
    {
sl@0
    96
      /* Write metadata to temporary files */
sl@0
    97
sl@0
    98
      if (writeMetaDataTmp(handle) < 0)
sl@0
    99
        return -1;
sl@0
   100
    }
sl@0
   101
sl@0
   102
    handle->metaDataBlocks++;
sl@0
   103
  }
sl@0
   104
sl@0
   105
  handle->videoSampleTable->currentChunk++;
sl@0
   106
sl@0
   107
  if (updateDecodingTimeToSample(handle, handle->videoSampleTable, duration) < 0)
sl@0
   108
    return -1;
sl@0
   109
sl@0
   110
  if (updateSampleSize(handle, handle->videoSampleTable, size) < 0)
sl@0
   111
    return -1;
sl@0
   112
sl@0
   113
  if (updateSampleToChunk(handle->videoSampleTable) < 0)
sl@0
   114
    return -1;
sl@0
   115
sl@0
   116
  if (updateChunkOffset(handle, handle->videoSampleTable) < 0)
sl@0
   117
    return -1;
sl@0
   118
sl@0
   119
  if (keyframe)
sl@0
   120
    if (updateSyncSample(handle, handle->videoSampleTable) < 0)
sl@0
   121
      return -1;
sl@0
   122
sl@0
   123
  return 0;
sl@0
   124
}
sl@0
   125
sl@0
   126
sl@0
   127
/*
sl@0
   128
 * Function:
sl@0
   129
 *
sl@0
   130
 *   mp4_i32 updateAudioMetaData(MP4HandleImp handle,
sl@0
   131
 *                               mp4_u32 size,
sl@0
   132
 *                               mp4_u32 numberofframes)
sl@0
   133
 *
sl@0
   134
 * Description:
sl@0
   135
 *
sl@0
   136
 *   This function updates sample table atom data.
sl@0
   137
 *
sl@0
   138
 *   One call of this function will generate one chunk in the MP4 file.
sl@0
   139
 *
sl@0
   140
 * Parameters:
sl@0
   141
 *
sl@0
   142
 *   handle          MP4 library handle
sl@0
   143
 *   size            Size of video frame to insert
sl@0
   144
 *   duration        Duration of audio frames (in timescale,
sl@0
   145
 *                   see MP4ComposeAddAudioDescription)
sl@0
   146
 *
sl@0
   147
 * Return value:
sl@0
   148
 *
sl@0
   149
 *   0         Success
sl@0
   150
 *   -1        Error
sl@0
   151
 *
sl@0
   152
 */
sl@0
   153
mp4_i32 updateAudioMetaData(MP4HandleImp handle, mp4_u32 size, mp4_u32 duration)
sl@0
   154
{
sl@0
   155
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
   156
  {
sl@0
   157
    if (handle->metaDataBlocks == BLOCK_LIMIT)
sl@0
   158
    {
sl@0
   159
      /* Write metadata to temporary files */
sl@0
   160
sl@0
   161
      if (writeMetaDataTmp(handle) < 0)
sl@0
   162
        return -1;
sl@0
   163
    }
sl@0
   164
sl@0
   165
    handle->metaDataBlocks++;
sl@0
   166
  }
sl@0
   167
sl@0
   168
  handle->audioSampleTable->currentChunk++;
sl@0
   169
sl@0
   170
  if (updateDecodingTimeToSample(handle, handle->audioSampleTable, duration) < 0)
sl@0
   171
    return -1;
sl@0
   172
sl@0
   173
  if (updateSampleSize(handle, handle->audioSampleTable, size) < 0)
sl@0
   174
    return -1;
sl@0
   175
sl@0
   176
  if (updateSampleToChunk(handle->audioSampleTable) < 0)
sl@0
   177
    return -1;
sl@0
   178
sl@0
   179
  if (updateChunkOffset(handle, handle->audioSampleTable) < 0)
sl@0
   180
    return -1;
sl@0
   181
sl@0
   182
  return 0;
sl@0
   183
}
sl@0
   184
sl@0
   185
sl@0
   186
/*
sl@0
   187
 * Function:
sl@0
   188
 *
sl@0
   189
 *   mp4_i32 writeFTYPAndMDATToFile(MP4HandleImp handle)
sl@0
   190
 *
sl@0
   191
 * Description:
sl@0
   192
 *
sl@0
   193
 *   This function writes FTYP box to a file. In addition, it writes MDAT box
sl@0
   194
 *   size and type to a file. The function is used when meta data is put to
sl@0
   195
 *   the end of file.
sl@0
   196
 *
sl@0
   197
 * Parameters:
sl@0
   198
 *
sl@0
   199
 *   handle     MP4 library handle
sl@0
   200
 *
sl@0
   201
 * Return value:
sl@0
   202
 *
sl@0
   203
 *   0          Success
sl@0
   204
 *   -1         Error
sl@0
   205
 *
sl@0
   206
 */
sl@0
   207
mp4_i32 writeFTYPAndMDATToFile(MP4HandleImp handle)
sl@0
   208
{
sl@0
   209
  mp4_u8  buf[32];
sl@0
   210
  mp4_u32 i = 0;
sl@0
   211
sl@0
   212
sl@0
   213
  if (writeFTYP(handle) < 0)
sl@0
   214
    return -1;
sl@0
   215
sl@0
   216
  handle->ftypWritten = MP4TRUE;
sl@0
   217
sl@0
   218
sl@0
   219
  i = formatMdatHeader(buf, (mp4_u32)0);
sl@0
   220
  if (writeFile(handle, buf, i) < 0)
sl@0
   221
    return -1;
sl@0
   222
sl@0
   223
  return 0;
sl@0
   224
}
sl@0
   225
sl@0
   226
sl@0
   227
/*
sl@0
   228
 * Function:
sl@0
   229
 *
sl@0
   230
 *   mp4_i32 writeDataToFile(MP4HandleImp handle)
sl@0
   231
 *
sl@0
   232
 * Description:
sl@0
   233
 *
sl@0
   234
 *   This function writes meta and media data to a file.
sl@0
   235
 *
sl@0
   236
 * Parameters:
sl@0
   237
 *
sl@0
   238
 *   handle     MP4 library handle
sl@0
   239
 *
sl@0
   240
 * Return value:
sl@0
   241
 *
sl@0
   242
 *   0          Success
sl@0
   243
 *   -1         Error
sl@0
   244
 *
sl@0
   245
 */
sl@0
   246
mp4_i32 writeDataToFile(MP4HandleImp handle)
sl@0
   247
{
sl@0
   248
  PRINT((_L("e_writedatatofile 1")));
sl@0
   249
  mp4_u32   metaDataSize = 0;
sl@0
   250
  trakSize  *audioTrackSize;
sl@0
   251
  trakSize  *videoTrackSize;
sl@0
   252
  mp4_bool  haveAudio = MP4FALSE;
sl@0
   253
  mp4_bool  haveVideo = MP4FALSE;
sl@0
   254
  mp4_u8 ftypdelta = 0;
sl@0
   255
sl@0
   256
sl@0
   257
  if ((handle->type & MP4_TYPE_AMR_NB) ||
sl@0
   258
      (handle->type & MP4_TYPE_AMR_WB) ||
sl@0
   259
       (handle->type & MP4_TYPE_QCELP_13K) ||     
sl@0
   260
      (handle->type & MP4_TYPE_MPEG4_AUDIO))
sl@0
   261
    haveAudio = MP4TRUE;
sl@0
   262
sl@0
   263
  if ((handle->type & MP4_TYPE_H263_PROFILE_0) ||
sl@0
   264
      (handle->type & MP4_TYPE_H263_PROFILE_3) ||
sl@0
   265
      (handle->type & MP4_TYPE_MPEG4_VIDEO) ||
sl@0
   266
	  containsAvcVideo( handle->type ) )
sl@0
   267
    haveVideo = MP4TRUE;
sl@0
   268
sl@0
   269
  if ((handle->generate3G2 && !(handle->type &  MP4_TYPE_QCELP_13K)) ||
sl@0
   270
       (!handle->generate3G2 && !(handle->type &  MP4_TYPE_AMR_WB)))
sl@0
   271
     ftypdelta = 4; /* one more additional compatible brand */
sl@0
   272
  else
sl@0
   273
     ftypdelta = 0;
sl@0
   274
  
sl@0
   275
  if( containsAvcVideo( handle->type ) )
sl@0
   276
  {
sl@0
   277
    ftypdelta += 4;
sl@0
   278
  }  
sl@0
   279
sl@0
   280
  PRINT((_L("e_writedatatofile_alloc_audiotrk 1")));
sl@0
   281
  audioTrackSize = (trakSize *)mp4malloc(sizeof(trakSize));
sl@0
   282
  if (audioTrackSize == NULL)
sl@0
   283
    return -1;
sl@0
   284
  PRINT((_L("e_writedatatofile_alloc_audiotrk 0")));    
sl@0
   285
	
sl@0
   286
  PRINT((_L("e_writedatatofile_alloc_videotrk 1")));  
sl@0
   287
  videoTrackSize = (trakSize *)mp4malloc(sizeof(trakSize));
sl@0
   288
  if (videoTrackSize == NULL)
sl@0
   289
  {
sl@0
   290
    mp4free(audioTrackSize);
sl@0
   291
sl@0
   292
    return -1;
sl@0
   293
  }
sl@0
   294
  PRINT((_L("e_writedatatofile_alloc_videotrk 0")));  
sl@0
   295
sl@0
   296
  if (haveAudio)
sl@0
   297
  {
sl@0
   298
	PRINT((_L("e_writedatatofile_deter_audiotrk_metadatasize 1")));  
sl@0
   299
    if (determineAudioTrakMetaDataSize(handle, handle->audioSampleTable, audioTrackSize) < 0)
sl@0
   300
        {
sl@0
   301
        mp4free(audioTrackSize);
sl@0
   302
        mp4free(videoTrackSize);
sl@0
   303
        return -1;
sl@0
   304
        }
sl@0
   305
	PRINT((_L("e_writedatatofile_deter_audiotrk_metadatasize 0")));          
sl@0
   306
  }
sl@0
   307
sl@0
   308
  if (haveVideo)
sl@0
   309
  {
sl@0
   310
	PRINT((_L("e_writedatatofile_deter_videotrk_metadatasize 1")));
sl@0
   311
    if (determineVideoTrakMetaDataSize(handle, handle->videoSampleTable, videoTrackSize) < 0)
sl@0
   312
        {
sl@0
   313
        mp4free(audioTrackSize);
sl@0
   314
        mp4free(videoTrackSize);
sl@0
   315
        return -1;
sl@0
   316
        }
sl@0
   317
PRINT((_L("e_writedatatofile_deter_videotrk_metadatasize 0")));        
sl@0
   318
  }
sl@0
   319
sl@0
   320
  if (handle->flags & MP4_FLAG_METADATALAST)
sl@0
   321
  {
sl@0
   322
    metaDataSize += (FTYP_SIZE + ftypdelta);             /* ftyp */
sl@0
   323
    handle->metaDataSize = metaDataSize;
sl@0
   324
  }
sl@0
   325
  else
sl@0
   326
  {
sl@0
   327
    metaDataSize += (FTYP_SIZE + ftypdelta);             /* ftyp */
sl@0
   328
    metaDataSize += 8;                     /* moov atomheader */
sl@0
   329
    metaDataSize += mvhdAtomSize(handle);                   /* mvhd */
sl@0
   330
    if (handle->moovUDTA)
sl@0
   331
        {
sl@0
   332
        metaDataSize += 8 + (mp4_u32)handle->moovUDTA->atomcontentsize;
sl@0
   333
        }
sl@0
   334
    metaDataSize += audioTrackSize->trak;  /* Audio trak */
sl@0
   335
    metaDataSize += videoTrackSize->trak;  /* Video trak */
sl@0
   336
sl@0
   337
    handle->metaDataSize = metaDataSize;
sl@0
   338
  }
sl@0
   339
sl@0
   340
sl@0
   341
  if (!(handle->flags & MP4_FLAG_LONGCLIP))
sl@0
   342
  {
sl@0
   343
    /* Update metadata pointers only if metadata is in memory */
sl@0
   344
sl@0
   345
    if (haveAudio)
sl@0
   346
    {
sl@0
   347
	PRINT((_L("e_writedatatofile_reupdata_audiometadata 1")));     
sl@0
   348
      if (reUpdateAudioMetaData(handle->audioSampleTable, metaDataSize) < 0)
sl@0
   349
      {
sl@0
   350
        mp4free(audioTrackSize);
sl@0
   351
        mp4free(videoTrackSize);
sl@0
   352
sl@0
   353
        return -1;
sl@0
   354
      }
sl@0
   355
	PRINT((_L("e_writedatatofile_reupdata_audiometadata 0")));           
sl@0
   356
    }
sl@0
   357
sl@0
   358
    if (haveVideo)
sl@0
   359
    {
sl@0
   360
	PRINT((_L("e_writedatatofile_reupdata_videometadata 1")));               
sl@0
   361
      if (reUpdateVideoMetaData(handle->videoSampleTable, metaDataSize) < 0)
sl@0
   362
      {
sl@0
   363
        mp4free(audioTrackSize);
sl@0
   364
        mp4free(videoTrackSize);
sl@0
   365
sl@0
   366
        return -1;
sl@0
   367
      }
sl@0
   368
	PRINT((_L("e_writedatatofile_reupdata_videometadata 0")));      
sl@0
   369
    }
sl@0
   370
  }
sl@0
   371
  else
sl@0
   372
  {
sl@0
   373
    /* Write the rest of metadata to temporary files */
sl@0
   374
	PRINT((_L("e_writedatatofile_write_metadatablocks 1")));
sl@0
   375
    if (handle->metaDataBlocks)
sl@0
   376
      if (writeMetaDataTmp(handle) < 0)
sl@0
   377
          {
sl@0
   378
          mp4free(audioTrackSize);
sl@0
   379
          mp4free(videoTrackSize);
sl@0
   380
          return -1;
sl@0
   381
          }
sl@0
   382
	PRINT((_L("e_writedatatofile_write_metadatablocks 0")));          
sl@0
   383
  }
sl@0
   384
sl@0
   385
sl@0
   386
  if (handle->flags & MP4_FLAG_METADATALAST)
sl@0
   387
  {
sl@0
   388
    mp4_u8  buf[16];
sl@0
   389
    mp4_u32 moovSize = 0;
sl@0
   390
sl@0
   391
    moovSize += 8;                     /* moov atomheader */
sl@0
   392
    moovSize += mvhdAtomSize(handle);                   /* mvhd */
sl@0
   393
    moovSize += audioTrackSize->trak;  /* Audio trak */
sl@0
   394
    moovSize += videoTrackSize->trak;  /* Video trak */
sl@0
   395
    if (handle->moovUDTA)
sl@0
   396
        {
sl@0
   397
        moovSize += 8 + handle->moovUDTA->atomcontentsize;
sl@0
   398
        }    
sl@0
   399
        
sl@0
   400
	PRINT((_L("e_writedatatofile_write_moov 1")));
sl@0
   401
    if (writeMOOV(handle, moovSize, haveAudio, haveVideo, audioTrackSize, videoTrackSize) < 0)
sl@0
   402
    {
sl@0
   403
      mp4free(audioTrackSize);
sl@0
   404
      mp4free(videoTrackSize);
sl@0
   405
sl@0
   406
      return -1;
sl@0
   407
    }
sl@0
   408
    PRINT((_L("e_writedatatofile_write_moov 0")));
sl@0
   409
sl@0
   410
    /* Overwrite media data size */
sl@0
   411
	PRINT((_L("e_writedatatofile_update_moov_media_size 1")));
sl@0
   412
	if(!handle->bufferWrite)
sl@0
   413
	{
sl@0
   414
		if (seekFileAbsWrite(handle, (FTYP_SIZE + ftypdelta)) != 0)
sl@0
   415
			{
sl@0
   416
			mp4free(audioTrackSize);
sl@0
   417
			mp4free(videoTrackSize);
sl@0
   418
			return -1;
sl@0
   419
			}
sl@0
   420
	}
sl@0
   421
	
sl@0
   422
	//make sure the buf is large enough to hold the mdat header
sl@0
   423
	TInt i;
sl@0
   424
	i = formatMdatHeader(buf, handle->mediaDataBytes);
sl@0
   425
    if (writeFileUnbuffered(handle, buf, i) < 0)
sl@0
   426
        {
sl@0
   427
        mp4free(audioTrackSize);
sl@0
   428
        mp4free(videoTrackSize);
sl@0
   429
        return -1;
sl@0
   430
        }
sl@0
   431
	PRINT((_L("e_writedatatofile_update_moov_media_size 0")));        
sl@0
   432
  }
sl@0
   433
  else
sl@0
   434
  {
sl@0
   435
	PRINT((_L("e_writedatatofile_write_ftyp 1")));  
sl@0
   436
    if (writeFTYP(handle) < 0)
sl@0
   437
    {
sl@0
   438
      mp4free(audioTrackSize);
sl@0
   439
      mp4free(videoTrackSize);
sl@0
   440
sl@0
   441
      return -1;
sl@0
   442
    }
sl@0
   443
    PRINT((_L("e_writedatatofile_write_ftyp 0")));  
sl@0
   444
sl@0
   445
	PRINT((_L("e_writedatatofile_write_new_moov 1")));  
sl@0
   446
    if (writeMOOV(handle, metaDataSize - (FTYP_SIZE + ftypdelta), haveAudio, haveVideo, audioTrackSize, videoTrackSize) < 0)
sl@0
   447
    {
sl@0
   448
      mp4free(audioTrackSize);
sl@0
   449
      mp4free(videoTrackSize);
sl@0
   450
sl@0
   451
      return -1;
sl@0
   452
    }
sl@0
   453
    PRINT((_L("e_writedatatofile_write_new_moov 0")));
sl@0
   454
sl@0
   455
	PRINT((_L("e_writedatatofile_write_new_mdia 1")));
sl@0
   456
    if (writeMediaData(handle) < 0)
sl@0
   457
    {
sl@0
   458
      mp4free(audioTrackSize);
sl@0
   459
      mp4free(videoTrackSize);
sl@0
   460
sl@0
   461
      return -1;
sl@0
   462
    }
sl@0
   463
    PRINT((_L("e_writedatatofile_write_new_mdia 0")));
sl@0
   464
  }
sl@0
   465
sl@0
   466
PRINT((_L("e_writedatatofile_free_audioandvideotrks 1")));
sl@0
   467
  mp4free(audioTrackSize);
sl@0
   468
  mp4free(videoTrackSize);
sl@0
   469
PRINT((_L("e_writedatatofile_free_audioandvideotrks 0")));
sl@0
   470
PRINT((_L("e_writedatatofile 0")));
sl@0
   471
  return 0;
sl@0
   472
}
sl@0
   473
sl@0
   474
sl@0
   475
/*
sl@0
   476
 * Function:
sl@0
   477
 *
sl@0
   478
 *   mp4_i32 updateDecodingTimeToSample(MP4HandleImp handle,
sl@0
   479
 *                                      sampleTable *st,
sl@0
   480
 *                                      mp4_u32 duration)
sl@0
   481
 *
sl@0
   482
 * Description:
sl@0
   483
 *
sl@0
   484
 *   This function updates stts atom data.
sl@0
   485
 *
sl@0
   486
 * Parameters:
sl@0
   487
 *
sl@0
   488
 *   handle    MP4 library handle
sl@0
   489
 *   st        sampleTable
sl@0
   490
 *   duration  Duration of sample to insert (in media timescale)
sl@0
   491
 *
sl@0
   492
 * Return value:
sl@0
   493
 *
sl@0
   494
 *   0         Success
sl@0
   495
 *   -1        Error
sl@0
   496
 *
sl@0
   497
 */
sl@0
   498
mp4_i32 updateDecodingTimeToSample(MP4HandleImp handle, sampleTable *st, mp4_u32 duration)
sl@0
   499
{
sl@0
   500
  if (!handle)
sl@0
   501
    return -1;
sl@0
   502
sl@0
   503
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
   504
  {
sl@0
   505
    if (st->sttsCurrentEntryCount == 0)
sl@0
   506
    {
sl@0
   507
      st->sttsSampleCount[st->sttsCurrentEntryCount] = 1;
sl@0
   508
      st->sttsSampleDelta[st->sttsCurrentEntryCount] = duration;
sl@0
   509
sl@0
   510
      st->sttsCurrentEntryCount++;
sl@0
   511
      st->sttsEntryCount++;
sl@0
   512
sl@0
   513
      return 0;
sl@0
   514
    }
sl@0
   515
sl@0
   516
    if (st->sttsCurrentEntryCount == st->sttsMaxEntryCount)
sl@0
   517
    {
sl@0
   518
      void *p;
sl@0
   519
sl@0
   520
      p = mp4realloc(st->sttsSampleCount,
sl@0
   521
                     2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
sl@0
   522
                     sizeof(mp4_u32) * st->sttsMaxEntryCount);
sl@0
   523
      if (p == NULL)
sl@0
   524
        return -1;
sl@0
   525
sl@0
   526
      st->sttsSampleCount = (mp4_u32 *)p;
sl@0
   527
sl@0
   528
      p = mp4realloc(st->sttsSampleDelta,
sl@0
   529
                     2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
sl@0
   530
                     sizeof(mp4_u32) * st->sttsMaxEntryCount);
sl@0
   531
      if (p == NULL)
sl@0
   532
        return -1;
sl@0
   533
sl@0
   534
      st->sttsSampleDelta = (mp4_u32 *)p;
sl@0
   535
sl@0
   536
      st->sttsMaxEntryCount *= 2;
sl@0
   537
    }
sl@0
   538
sl@0
   539
    if (st->sttsSampleDelta[st->sttsCurrentEntryCount - 1] == duration)
sl@0
   540
    {
sl@0
   541
      st->sttsSampleCount[st->sttsCurrentEntryCount - 1]++;
sl@0
   542
    }
sl@0
   543
    else
sl@0
   544
    {
sl@0
   545
      st->sttsSampleCount[st->sttsCurrentEntryCount] = 1;
sl@0
   546
      st->sttsSampleDelta[st->sttsCurrentEntryCount] = duration;
sl@0
   547
sl@0
   548
      st->sttsCurrentEntryCount++;
sl@0
   549
      st->sttsEntryCount++;
sl@0
   550
    }
sl@0
   551
  }
sl@0
   552
  else
sl@0
   553
  {
sl@0
   554
    if (st->sttsEntryCount == 0)
sl@0
   555
    {
sl@0
   556
      st->sttsSampleCount[st->sttsEntryCount]++;
sl@0
   557
      st->sttsSampleDelta[st->sttsEntryCount] = duration;
sl@0
   558
sl@0
   559
      st->sttsEntryCount++;
sl@0
   560
sl@0
   561
      return 0;
sl@0
   562
    }
sl@0
   563
sl@0
   564
    if (st->sttsEntryCount == st->sttsMaxEntryCount)
sl@0
   565
    {
sl@0
   566
      void *p;
sl@0
   567
sl@0
   568
      p = mp4realloc(st->sttsSampleCount,
sl@0
   569
                     2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
sl@0
   570
                     sizeof(mp4_u32) * st->sttsMaxEntryCount);
sl@0
   571
      if (p == NULL)
sl@0
   572
        return -1;
sl@0
   573
sl@0
   574
      st->sttsSampleCount = (mp4_u32 *)p;
sl@0
   575
sl@0
   576
      p = mp4realloc(st->sttsSampleDelta,
sl@0
   577
                     2 * sizeof(mp4_u32) * st->sttsMaxEntryCount,
sl@0
   578
                     sizeof(mp4_u32) * st->sttsMaxEntryCount);
sl@0
   579
      if (p == NULL)
sl@0
   580
        return -1;
sl@0
   581
sl@0
   582
      st->sttsSampleDelta = (mp4_u32 *)p;
sl@0
   583
sl@0
   584
      st->sttsMaxEntryCount *= 2;
sl@0
   585
    }
sl@0
   586
sl@0
   587
    if (st->sttsSampleDelta[st->sttsEntryCount - 1] == duration)
sl@0
   588
    {
sl@0
   589
      st->sttsSampleCount[st->sttsEntryCount - 1]++;
sl@0
   590
    }
sl@0
   591
    else
sl@0
   592
    {
sl@0
   593
      st->sttsSampleCount[st->sttsEntryCount] = 1;
sl@0
   594
      st->sttsSampleDelta[st->sttsEntryCount] = duration;
sl@0
   595
sl@0
   596
      st->sttsEntryCount++;
sl@0
   597
    }
sl@0
   598
  }
sl@0
   599
sl@0
   600
sl@0
   601
  return 0;
sl@0
   602
}
sl@0
   603
sl@0
   604
sl@0
   605
/*
sl@0
   606
 * Function:
sl@0
   607
 *
sl@0
   608
 *   mp4_i32 updateSampleSize(MP4HandleImp handle,
sl@0
   609
 *                            sampleTable *st,
sl@0
   610
 *                            mp4_u32 size)
sl@0
   611
 *
sl@0
   612
 * Description:
sl@0
   613
 *
sl@0
   614
 *   This function updates stsz atom data.
sl@0
   615
 *
sl@0
   616
 * Parameters:
sl@0
   617
 *
sl@0
   618
 *   handle    MP4 library handle
sl@0
   619
 *   st        sampleTable
sl@0
   620
 *   size      Size of sample in bytes
sl@0
   621
 *
sl@0
   622
 * Return value:
sl@0
   623
 *
sl@0
   624
 *   0         Success
sl@0
   625
 *   -1        Error
sl@0
   626
 *
sl@0
   627
 */
sl@0
   628
mp4_i32 updateSampleSize(MP4HandleImp handle, sampleTable *st, mp4_u32 size)
sl@0
   629
{
sl@0
   630
  if (!handle)
sl@0
   631
    return -1;
sl@0
   632
sl@0
   633
  if (size == 0)
sl@0
   634
    return -1;
sl@0
   635
sl@0
   636
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
   637
  {
sl@0
   638
    if (st->stszCurrentSampleCount == st->stszMaxSampleCount)
sl@0
   639
    {
sl@0
   640
      void *p;
sl@0
   641
sl@0
   642
      p = mp4realloc(st->stszEntrySize,
sl@0
   643
                     2 * sizeof(mp4_u32) * st->stszMaxSampleCount,
sl@0
   644
                     sizeof(mp4_u32) * st->stszMaxSampleCount);
sl@0
   645
      if (p == NULL)
sl@0
   646
        return -1;
sl@0
   647
sl@0
   648
      st->stszEntrySize = (mp4_u32 *)p;
sl@0
   649
sl@0
   650
      st->stszMaxSampleCount *= 2;
sl@0
   651
    }
sl@0
   652
sl@0
   653
    st->stszEntrySize[st->stszCurrentSampleCount] = size;
sl@0
   654
sl@0
   655
    st->stszCurrentSampleCount++;
sl@0
   656
    st->stszSampleCount++;
sl@0
   657
  }
sl@0
   658
  else
sl@0
   659
  {
sl@0
   660
    if (st->stszSampleCount == st->stszMaxSampleCount)
sl@0
   661
    {
sl@0
   662
      void *p;
sl@0
   663
sl@0
   664
      p = mp4realloc(st->stszEntrySize,
sl@0
   665
                     2 * sizeof(mp4_u32) * st->stszMaxSampleCount,
sl@0
   666
                     sizeof(mp4_u32) * st->stszMaxSampleCount);
sl@0
   667
      if (p == NULL)
sl@0
   668
        return -1;
sl@0
   669
sl@0
   670
      st->stszEntrySize = (mp4_u32 *)p;
sl@0
   671
sl@0
   672
      st->stszMaxSampleCount *= 2;
sl@0
   673
    }
sl@0
   674
sl@0
   675
    st->stszEntrySize[st->stszSampleCount] = size;
sl@0
   676
sl@0
   677
    st->stszSampleCount++;
sl@0
   678
  }
sl@0
   679
sl@0
   680
sl@0
   681
  return 0;
sl@0
   682
}
sl@0
   683
sl@0
   684
sl@0
   685
/*
sl@0
   686
 * Function:
sl@0
   687
 *
sl@0
   688
 *   mp4_i32 updateSampleToChunk(sampleTable *st)
sl@0
   689
 *
sl@0
   690
 * Description:
sl@0
   691
 *
sl@0
   692
 *   This function updates stsc atom data.
sl@0
   693
 *
sl@0
   694
 * Parameters:
sl@0
   695
 *
sl@0
   696
 *   st        sampleTable
sl@0
   697
 *
sl@0
   698
 * Return value:
sl@0
   699
 *
sl@0
   700
 *   0         Success
sl@0
   701
 *   -1        Error
sl@0
   702
 *
sl@0
   703
 */
sl@0
   704
mp4_i32 updateSampleToChunk(sampleTable *st)
sl@0
   705
{
sl@0
   706
  if (st->stscEntryCount != 0)
sl@0
   707
    return 0;
sl@0
   708
sl@0
   709
sl@0
   710
  st->stscFirstChunk[st->stscEntryCount] = st->currentChunk;
sl@0
   711
  st->stscSamplesPerChunk[st->stscEntryCount] = 1;
sl@0
   712
  st->stscSampleDescriptionIndex[st->stscEntryCount] = 1;  /* Note: Need to update here for multiple sample entry support */
sl@0
   713
  st->stscEntryCount++;
sl@0
   714
sl@0
   715
  return 0;
sl@0
   716
}
sl@0
   717
sl@0
   718
sl@0
   719
/*
sl@0
   720
 * Function:
sl@0
   721
 *
sl@0
   722
 *   mp4_i32 updateChunkOffset(MP4HandleImp handle,
sl@0
   723
 *                             sampleTable *st)
sl@0
   724
 *
sl@0
   725
 * Description:
sl@0
   726
 *
sl@0
   727
 *   This function updates stco atom data.
sl@0
   728
 *
sl@0
   729
 * Parameters:
sl@0
   730
 *
sl@0
   731
 *   handle    MP4 library handle
sl@0
   732
 *   st        sampleTable
sl@0
   733
 *
sl@0
   734
 * Return value:
sl@0
   735
 *
sl@0
   736
 *   0         Success
sl@0
   737
 *   -1        Error
sl@0
   738
 *
sl@0
   739
 */
sl@0
   740
mp4_i32 updateChunkOffset(MP4HandleImp handle, sampleTable *st)
sl@0
   741
{
sl@0
   742
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
   743
  {
sl@0
   744
    if (st->stcoCurrentEntryCount == st->stcoMaxEntryCount)
sl@0
   745
    {
sl@0
   746
      void *p;
sl@0
   747
sl@0
   748
      p = mp4realloc(st->stcoChunkOffset,
sl@0
   749
                     2 * sizeof(mp4_u64) * st->stcoMaxEntryCount,
sl@0
   750
                     sizeof(mp4_u64) * st->stcoMaxEntryCount);
sl@0
   751
      if (p == NULL)
sl@0
   752
        return -1;
sl@0
   753
sl@0
   754
      st->stcoChunkOffset = (mp4_u64*)p;
sl@0
   755
sl@0
   756
      st->stcoMaxEntryCount *= 2;
sl@0
   757
    }
sl@0
   758
    
sl@0
   759
    if (handle->flags & MP4_FLAG_METADATALAST)
sl@0
   760
      updateChunkOffset(st, st->stcoCurrentEntryCount, handle->mediaDataBytes);
sl@0
   761
    else
sl@0
   762
      updateChunkOffset(st, st->stcoCurrentEntryCount, handle->bytesInTmpFile);
sl@0
   763
sl@0
   764
    st->stcoCurrentEntryCount++;
sl@0
   765
    st->stcoEntryCount++;
sl@0
   766
  }
sl@0
   767
  else
sl@0
   768
  {
sl@0
   769
    if (st->stcoEntryCount == st->stcoMaxEntryCount)
sl@0
   770
    {
sl@0
   771
      void *p;
sl@0
   772
sl@0
   773
      p = mp4realloc(st->stcoChunkOffset,
sl@0
   774
                     2 * sizeof(mp4_u64) * st->stcoMaxEntryCount,
sl@0
   775
                     sizeof(mp4_u64) * st->stcoMaxEntryCount);
sl@0
   776
      if (p == NULL)
sl@0
   777
        return -1;
sl@0
   778
sl@0
   779
      st->stcoChunkOffset = (mp4_u64 *)p;
sl@0
   780
sl@0
   781
      st->stcoMaxEntryCount *= 2;
sl@0
   782
    }
sl@0
   783
sl@0
   784
    if (handle->flags & MP4_FLAG_METADATALAST)
sl@0
   785
      updateChunkOffset(st, st->stcoEntryCount, handle->mediaDataBytes);
sl@0
   786
    else
sl@0
   787
      updateChunkOffset(st, st->stcoEntryCount, handle->bytesInTmpFile);
sl@0
   788
sl@0
   789
    st->stcoEntryCount++;
sl@0
   790
  }
sl@0
   791
sl@0
   792
sl@0
   793
  return 0;
sl@0
   794
}
sl@0
   795
sl@0
   796
sl@0
   797
/*
sl@0
   798
 * Function:
sl@0
   799
 *
sl@0
   800
 *   mp4_i32 updateSyncSample(MP4HandleImp handle,
sl@0
   801
 *                            sampleTable *st)
sl@0
   802
 *
sl@0
   803
 * Description:
sl@0
   804
 *
sl@0
   805
 *   This function updates stss atom data.
sl@0
   806
 *
sl@0
   807
 * Parameters:
sl@0
   808
 *
sl@0
   809
 *   handle    MP4 library handle
sl@0
   810
 *   st        sampleTable
sl@0
   811
 *
sl@0
   812
 * Return value:
sl@0
   813
 *
sl@0
   814
 *   0         Success
sl@0
   815
 *   -1        Error
sl@0
   816
 *
sl@0
   817
 */
sl@0
   818
mp4_i32 updateSyncSample(MP4HandleImp handle, sampleTable *st)
sl@0
   819
{
sl@0
   820
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
   821
  {
sl@0
   822
    if (st->stssCurrentEntryCount == st->stssMaxEntryCount)
sl@0
   823
    {
sl@0
   824
      void *p;
sl@0
   825
sl@0
   826
      p = mp4realloc(st->stssSampleNumber,
sl@0
   827
                     2 * sizeof(mp4_u32) * st->stssMaxEntryCount,
sl@0
   828
                     sizeof(mp4_u32) * st->stssMaxEntryCount);
sl@0
   829
      if (p == NULL)
sl@0
   830
        return -1;
sl@0
   831
sl@0
   832
      st->stssSampleNumber = (mp4_u32 *)p;
sl@0
   833
sl@0
   834
      st->stssMaxEntryCount *= 2;
sl@0
   835
    }
sl@0
   836
sl@0
   837
    st->stssSampleNumber[st->stssCurrentEntryCount] = handle->videoSampleNum;
sl@0
   838
    st->stssCurrentEntryCount++;
sl@0
   839
    st->stssEntryCount++;
sl@0
   840
  }
sl@0
   841
  else
sl@0
   842
  {
sl@0
   843
    if (st->stssEntryCount == st->stssMaxEntryCount)
sl@0
   844
    {
sl@0
   845
      void *p;
sl@0
   846
sl@0
   847
      p = mp4realloc(st->stssSampleNumber,
sl@0
   848
                     2 * sizeof(mp4_u32) * st->stssMaxEntryCount,
sl@0
   849
                     sizeof(mp4_u32) * st->stssMaxEntryCount);
sl@0
   850
      if (p == NULL)
sl@0
   851
        return -1;
sl@0
   852
sl@0
   853
      st->stssSampleNumber = (mp4_u32 *)p;
sl@0
   854
sl@0
   855
      st->stssMaxEntryCount *= 2;
sl@0
   856
    }
sl@0
   857
sl@0
   858
    st->stssSampleNumber[st->stssEntryCount] = handle->videoSampleNum;
sl@0
   859
    st->stssEntryCount++;
sl@0
   860
  }
sl@0
   861
sl@0
   862
sl@0
   863
  return 0;
sl@0
   864
}
sl@0
   865
sl@0
   866
sl@0
   867
/*
sl@0
   868
 * Function:
sl@0
   869
 *
sl@0
   870
 *   mp4_i32 determineAudioTrakMetaDataSize(MP4HandleImp handle,
sl@0
   871
 *                                          sampleTable *st,
sl@0
   872
 *                                          trakSize *ts)
sl@0
   873
 *
sl@0
   874
 * Description:
sl@0
   875
 *
sl@0
   876
 *   This function calculates the audio track meta data size.
sl@0
   877
 *
sl@0
   878
 * Parameters:
sl@0
   879
 *
sl@0
   880
 *   handle      MP4 library handle
sl@0
   881
 *   st          Sample table data
sl@0
   882
 *   ts          Atom sizes are returned here
sl@0
   883
 *
sl@0
   884
 * Return value:
sl@0
   885
 *
sl@0
   886
 *   0           Success
sl@0
   887
 *
sl@0
   888
 */
sl@0
   889
mp4_i32 determineAudioTrakMetaDataSize(MP4HandleImp handle, sampleTable *st, trakSize *ts)
sl@0
   890
{
sl@0
   891
  if (handle->type & MP4_TYPE_AMR_NB) /* AMR-NB */
sl@0
   892
  {
sl@0
   893
    ts->damr = 17;
sl@0
   894
    ts->samr = 36 + ts->damr;
sl@0
   895
    ts->stsd = 16 + ts->samr;
sl@0
   896
  }
sl@0
   897
  else if (handle->type & MP4_TYPE_AMR_WB) /* AMR-WB */
sl@0
   898
  {
sl@0
   899
    ts->damr = 17;
sl@0
   900
    ts->sawb = 36 + ts->damr;
sl@0
   901
    ts->stsd = 16 + ts->sawb;
sl@0
   902
  }
sl@0
   903
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio)) /* QCELP 13K stored in QCELPSampleEntry */
sl@0
   904
  {
sl@0
   905
    ts->dqcp = 14;
sl@0
   906
    ts->sqcp = 36 + ts->dqcp;
sl@0
   907
    ts->stsd = 16 + ts->sqcp;
sl@0
   908
  } 
sl@0
   909
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio)) /* QCELP 13K stored in MP4AudioDescription */
sl@0
   910
  {
sl@0
   911
    calculateES_DescriptorSize(handle, MP4_TYPE_QCELP_13K);
sl@0
   912
    ts->esds = 12 + handle->ES_DescriptorSize; /*37 + handle->audioDecSpecificInfoSize;*/
sl@0
   913
    ts->mp4a = 36 + ts->esds;
sl@0
   914
    ts->stsd = 16 + ts->mp4a;
sl@0
   915
  }
sl@0
   916
  else /* MPEG audio */
sl@0
   917
  {
sl@0
   918
    calculateES_DescriptorSize(handle, MP4_TYPE_MPEG4_AUDIO);
sl@0
   919
    ts->esds = 12 + handle->ES_DescriptorSize; /*37 + handle->audioDecSpecificInfoSize;*/
sl@0
   920
    ts->mp4a = 36 + ts->esds;
sl@0
   921
    ts->stsd = 16 + ts->mp4a;
sl@0
   922
  }
sl@0
   923
  ts->stts = 16 + st->sttsEntryCount * 8;
sl@0
   924
  ts->stsc = 16 + st->stscEntryCount * 12;
sl@0
   925
  if (st->stszSampleSize != 0)
sl@0
   926
    ts->stsz = 20;
sl@0
   927
  else
sl@0
   928
    ts->stsz = 20 + st->stszSampleCount * 4;
sl@0
   929
  ts->stco = 16 + st->stcoEntryCount * (st->stcoNeed64Bits ? 8 : 4);
sl@0
   930
  ts->stbl = 8 + ts->stsd + ts->stts + ts->stsc + ts->stsz + ts->stco;
sl@0
   931
  ts->dref = 28;
sl@0
   932
  ts->dinf = 8 + ts->dref;
sl@0
   933
  ts->smhd = 16;
sl@0
   934
  ts->minf = 8 + ts->smhd + ts->dinf + ts->stbl;
sl@0
   935
  ts->hdlr = 33;
sl@0
   936
sl@0
   937
  if (handle->audioDuration > MP4_INT_MAX)
sl@0
   938
  {
sl@0
   939
    ts->mdhd = 44;
sl@0
   940
    ts->tkhd = 104;
sl@0
   941
  }
sl@0
   942
  else
sl@0
   943
  {
sl@0
   944
    ts->mdhd = 32;
sl@0
   945
    ts->tkhd = 92;
sl@0
   946
  }
sl@0
   947
sl@0
   948
  ts->mdia = 8 + ts->mdhd + ts->hdlr + ts->minf;
sl@0
   949
  if ( handle->audioUDTA )
sl@0
   950
      {
sl@0
   951
      ts->udta = 8 + handle->audioUDTA->atomcontentsize;
sl@0
   952
      }
sl@0
   953
  ts->trak = 8 + ts->tkhd + ts->mdia + ts->udta;
sl@0
   954
sl@0
   955
  return 0;
sl@0
   956
}
sl@0
   957
sl@0
   958
sl@0
   959
/*
sl@0
   960
 * Function:
sl@0
   961
 *
sl@0
   962
 *   mp4_i32 determineVideoTrakMetaDataSize(MP4HandleImp handle,
sl@0
   963
 *                                          sampleTable *st,
sl@0
   964
 *                                          trakSize *ts)
sl@0
   965
 *
sl@0
   966
 * Description:
sl@0
   967
 *
sl@0
   968
 *   This function calculates the video track meta data size.
sl@0
   969
 *
sl@0
   970
 * Parameters:
sl@0
   971
 *
sl@0
   972
 *   handle      MP4 library handle
sl@0
   973
 *   st          Sample table data
sl@0
   974
 *   ts          Atom sizes are returned here
sl@0
   975
 *
sl@0
   976
 * Return value:
sl@0
   977
 *
sl@0
   978
 *   0           Success
sl@0
   979
 *
sl@0
   980
 */
sl@0
   981
mp4_i32 determineVideoTrakMetaDataSize(MP4HandleImp handle, sampleTable *st, trakSize *ts)
sl@0
   982
{
sl@0
   983
  /* Note: This functions assumes single sample entry per media track. 
sl@0
   984
	   If necessary, modify to support multiple sample entries in the future. */
sl@0
   985
  if ((handle->type & MP4_TYPE_H263_PROFILE_0) || (handle->type & MP4_TYPE_H263_PROFILE_3))
sl@0
   986
  {
sl@0
   987
    ts->d263 = 15;
sl@0
   988
    ts->s263 = 86 + ts->d263;
sl@0
   989
    ts->stsd = 16 + ts->s263;
sl@0
   990
  }
sl@0
   991
  else /* MPEG-4 */
sl@0
   992
   if ((handle->type & MP4_TYPE_MPEG4_VIDEO))		
sl@0
   993
  {
sl@0
   994
    ts->esds = 37 + handle->videoDecSpecificInfoSize;
sl@0
   995
    ts->mp4v = 86 + ts->esds;
sl@0
   996
    ts->stsd = 16 + ts->mp4v;
sl@0
   997
  }
sl@0
   998
  else  /* AVC */
sl@0
   999
  if ( containsAvcVideo( handle->type ) )
sl@0
  1000
  {
sl@0
  1001
    /* Note: If necessary, add btrt and m4ds boxes here in the future. */
sl@0
  1002
   ts->avcc = 8 + handle->videoDecSpecificInfoSize; /*handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize;*/
sl@0
  1003
   ts->avc1 = 86 + ts->avcc;
sl@0
  1004
   ts->stsd = 16 + ts->avc1;
sl@0
  1005
  }
sl@0
  1006
  else
sl@0
  1007
  {
sl@0
  1008
  }
sl@0
  1009
sl@0
  1010
  ts->stts = 16 + st->sttsEntryCount * 8;
sl@0
  1011
  ts->stsc = 16 + st->stscEntryCount * 12;
sl@0
  1012
  if (st->stszSampleSize != 0)
sl@0
  1013
    ts->stsz = 20;
sl@0
  1014
  else
sl@0
  1015
    ts->stsz = 20 + st->stszSampleCount * 4;
sl@0
  1016
  ts->stco = 16 + st->stcoEntryCount * (st->stcoNeed64Bits ? 8 : 4);
sl@0
  1017
  ts->stss = 16 + st->stssEntryCount * 4;
sl@0
  1018
  if( handle->videoSampleTable->sdtpEntryCount )
sl@0
  1019
  	ts->sdtp = 4 + 4 + 1 + 3 + handle->videoSampleTable->sdtpEntryCount; //size + 'SDTP' + ver + flags + dependencies
sl@0
  1020
  else
sl@0
  1021
    ts->sdtp = 0;
sl@0
  1022
sl@0
  1023
  ts->stbl = 8 + ts->stsd + ts->stts + ts->stsc + ts->stsz + ts->stco + ts->stss + ts->sdtp;
sl@0
  1024
  ts->dref = 28;
sl@0
  1025
  ts->dinf = 8 + ts->dref;
sl@0
  1026
  ts->vmhd = 20;
sl@0
  1027
  ts->minf = 8 + ts->vmhd + ts->dinf + ts->stbl;
sl@0
  1028
  ts->hdlr = 33;
sl@0
  1029
  
sl@0
  1030
  if (handle->videoDuration > MP4_INT_MAX)
sl@0
  1031
  {
sl@0
  1032
    ts->mdhd = 44;
sl@0
  1033
    ts->tkhd = 104;
sl@0
  1034
  }
sl@0
  1035
  else
sl@0
  1036
  {
sl@0
  1037
    ts->mdhd = 32;
sl@0
  1038
    ts->tkhd = 92;
sl@0
  1039
  }
sl@0
  1040
sl@0
  1041
  ts->mdia = 8 + ts->mdhd + ts->hdlr + ts->minf;
sl@0
  1042
  if ( handle->videoUDTA )
sl@0
  1043
    {
sl@0
  1044
    ts->udta = 8 + handle->videoUDTA->atomcontentsize;  
sl@0
  1045
    }
sl@0
  1046
  ts->trak = 8 + ts->tkhd + ts->mdia + ts->udta;
sl@0
  1047
sl@0
  1048
  return 0;
sl@0
  1049
}
sl@0
  1050
sl@0
  1051
sl@0
  1052
/*
sl@0
  1053
 * Function:
sl@0
  1054
 *
sl@0
  1055
 *   mp4_i32 reUpdateAudioMetaData(sampleTable *st,
sl@0
  1056
 *                                 mp4_u32 metaDataSize)
sl@0
  1057
 *
sl@0
  1058
 * Description:
sl@0
  1059
 *
sl@0
  1060
 *   This function updates the chunk offsets in the meta data to point to
sl@0
  1061
 *   correct places.
sl@0
  1062
 *
sl@0
  1063
 * Parameters:
sl@0
  1064
 *
sl@0
  1065
 *   st            Sample table data
sl@0
  1066
 *   metaDataSize  Meta data size
sl@0
  1067
 *
sl@0
  1068
 * Return value:
sl@0
  1069
 *
sl@0
  1070
 *   0             Success
sl@0
  1071
 *
sl@0
  1072
 */
sl@0
  1073
mp4_i32 reUpdateAudioMetaData(sampleTable *st, mp4_u32 metaDataSize)
sl@0
  1074
{
sl@0
  1075
  mp4_u32 i;
sl@0
  1076
sl@0
  1077
sl@0
  1078
  for (i = 0; i < st->stcoEntryCount; i++)
sl@0
  1079
    updateChunkOffset(st, i, st->stcoChunkOffset[i] + metaDataSize + MDAT_HEADER_SIZE);
sl@0
  1080
sl@0
  1081
  return 0;
sl@0
  1082
}
sl@0
  1083
sl@0
  1084
sl@0
  1085
/*
sl@0
  1086
 * Function:
sl@0
  1087
 *
sl@0
  1088
 *   mp4_i32 reUpdateVideoMetaData(sampleTable *st,
sl@0
  1089
 *                                 mp4_u32 metaDataSize)
sl@0
  1090
 *
sl@0
  1091
 * Description:
sl@0
  1092
 *
sl@0
  1093
 *   This function updates the chunk offsets in the meta data to point to
sl@0
  1094
 *   correct places.
sl@0
  1095
 *
sl@0
  1096
 * Parameters:
sl@0
  1097
 *
sl@0
  1098
 *   st            Sample table data
sl@0
  1099
 *   metaDataSize  Meta data size
sl@0
  1100
 *
sl@0
  1101
 * Return value:
sl@0
  1102
 *
sl@0
  1103
 *   0             Success
sl@0
  1104
 *
sl@0
  1105
 */
sl@0
  1106
mp4_i32 reUpdateVideoMetaData(sampleTable *st, mp4_u32 metaDataSize)
sl@0
  1107
{
sl@0
  1108
  mp4_u32 i;
sl@0
  1109
sl@0
  1110
sl@0
  1111
  for (i = 0; i < st->stcoEntryCount; i++)
sl@0
  1112
    updateChunkOffset(st, i, st->stcoChunkOffset[i] + metaDataSize + MDAT_HEADER_SIZE);
sl@0
  1113
sl@0
  1114
  return 0;
sl@0
  1115
}
sl@0
  1116
sl@0
  1117
sl@0
  1118
/*
sl@0
  1119
 * Function:
sl@0
  1120
 *
sl@0
  1121
 *   mp4_i32 writeFTYP(MP4HandleImp handle)
sl@0
  1122
 *
sl@0
  1123
 * Description:
sl@0
  1124
 *
sl@0
  1125
 *   Write FTYP atom.
sl@0
  1126
 *
sl@0
  1127
 * Parameters:
sl@0
  1128
 *
sl@0
  1129
 *   handle   MP4 library handle
sl@0
  1130
 *
sl@0
  1131
 * Return value:
sl@0
  1132
 *
sl@0
  1133
 *   0        Success
sl@0
  1134
 *   -1       Error
sl@0
  1135
 *
sl@0
  1136
 */
sl@0
  1137
mp4_i32 writeFTYP(MP4HandleImp handle)
sl@0
  1138
{
sl@0
  1139
  mp4_u8  *buf;
sl@0
  1140
  mp4_u32 i = 0;
sl@0
  1141
  mp4_u8 ftypdelta = 0;
sl@0
  1142
sl@0
  1143
   if ((handle->generate3G2 && !(handle->type &  MP4_TYPE_QCELP_13K)) ||
sl@0
  1144
       (!handle->generate3G2 && !(handle->type &  MP4_TYPE_AMR_WB)))
sl@0
  1145
     ftypdelta = 4; /* one more additional compatible brand */
sl@0
  1146
   else
sl@0
  1147
     ftypdelta = 0;
sl@0
  1148
sl@0
  1149
   if( containsAvcVideo( handle->type ) )
sl@0
  1150
   {
sl@0
  1151
     ftypdelta += 4;
sl@0
  1152
   }
sl@0
  1153
   if(handle->bufferWrite)
sl@0
  1154
		handle->ftypdelta=ftypdelta;
sl@0
  1155
sl@0
  1156
  buf = (mp4_u8 *)mp4malloc(FTYP_SIZE + ftypdelta);
sl@0
  1157
  if (buf == NULL)
sl@0
  1158
    return -1;
sl@0
  1159
sl@0
  1160
  /* Size */
sl@0
  1161
  insertu32(buf+i, (mp4_u32)(FTYP_SIZE + ftypdelta));
sl@0
  1162
  i += 4;
sl@0
  1163
sl@0
  1164
  /* Atom type */
sl@0
  1165
  insertu32(buf+i, (mp4_u32)ATOMTYPE_FTYP);
sl@0
  1166
  i += 4;
sl@0
  1167
sl@0
  1168
  if ( containsAvcVideo( handle->type ) )
sl@0
  1169
  {
sl@0
  1170
      if(handle->generateMP4)
sl@0
  1171
      {
sl@0
  1172
	      /* MPEG-4 Major brand */
sl@0
  1173
	      buf[i++] = 'm';
sl@0
  1174
	      buf[i++] = 'p';
sl@0
  1175
	      buf[i++] = '4';
sl@0
  1176
	      buf[i++] = '2';
sl@0
  1177
      }
sl@0
  1178
sl@0
  1179
	  else
sl@0
  1180
	  {
sl@0
  1181
	    /* AVC is included for 3GPP Release 6 and beyond */
sl@0
  1182
	    /* Major brand */
sl@0
  1183
	    buf[i++] = '3';
sl@0
  1184
	    buf[i++] = 'g';
sl@0
  1185
	    buf[i++] = 'p';
sl@0
  1186
	    buf[i++] = '6';
sl@0
  1187
	  }
sl@0
  1188
  }
sl@0
  1189
  else
sl@0
  1190
  {
sl@0
  1191
    if(handle->generateMP4)
sl@0
  1192
    {
sl@0
  1193
	    /* MPEG-4 Major brand */
sl@0
  1194
	    buf[i++] = 'm';
sl@0
  1195
	    buf[i++] = 'p';
sl@0
  1196
	    buf[i++] = '4';
sl@0
  1197
	    buf[i++] = '2';
sl@0
  1198
    }
sl@0
  1199
    else if(handle->generate3G2)
sl@0
  1200
    {
sl@0
  1201
	    /* 3GPP2 Major brand */
sl@0
  1202
	    buf[i++] = '3';
sl@0
  1203
	    buf[i++] = 'g';
sl@0
  1204
	    buf[i++] = '2';
sl@0
  1205
	    buf[i++] = 'a';
sl@0
  1206
    }
sl@0
  1207
    else
sl@0
  1208
    {
sl@0
  1209
	    /* 3GPP Major brand */
sl@0
  1210
	    buf[i++] = '3';
sl@0
  1211
	    buf[i++] = 'g';
sl@0
  1212
	    buf[i++] = 'p';
sl@0
  1213
	    buf[i++] = '4';
sl@0
  1214
    }
sl@0
  1215
  }
sl@0
  1216
sl@0
  1217
  /* Minor version */
sl@0
  1218
  if(handle->generateMP4)
sl@0
  1219
  {  /* MPEG-4 Minor Version */
sl@0
  1220
      insertu32(buf+i, (mp4_u32)(0)); /* 0 */
sl@0
  1221
      i += 4;
sl@0
  1222
  }
sl@0
  1223
  else if(handle->generate3G2)
sl@0
  1224
  {  /* 3GPP2 Minor Version */
sl@0
  1225
      if( containsAvcVideo( handle->type ) )
sl@0
  1226
      {
sl@0
  1227
      	insertu32(buf+i, (mp4_u32)(2*256*256)); /* VB.0.0 */
sl@0
  1228
      	i += 4;
sl@0
  1229
      }
sl@0
  1230
      else
sl@0
  1231
      {
sl@0
  1232
      	insertu32(buf+i, (mp4_u32)(1*256*256)); /* VA.0.0 */
sl@0
  1233
      	i += 4;
sl@0
  1234
      }
sl@0
  1235
  }
sl@0
  1236
  else  
sl@0
  1237
  { /* 3GPP Minor Version */
sl@0
  1238
      if( containsAvcVideo( handle->type ) )
sl@0
  1239
      {
sl@0
  1240
      	  insertu32(buf+i, (mp4_u32)2*256); /* V6.3.0 */
sl@0
  1241
      	  i += 4;
sl@0
  1242
      }
sl@0
  1243
      else
sl@0
  1244
      {
sl@0
  1245
      	  insertu32(buf+i, (mp4_u32)4*256); /* V4.4.0 */
sl@0
  1246
          i += 4;
sl@0
  1247
      }
sl@0
  1248
  }
sl@0
  1249
sl@0
  1250
  /* Compatible brands */
sl@0
  1251
  if(handle->generateMP4)
sl@0
  1252
  {/* MPEG-4 Compatible Brands */
sl@0
  1253
	  buf[i++] = 'm';
sl@0
  1254
	  buf[i++] = 'p';
sl@0
  1255
	  buf[i++] = '4';
sl@0
  1256
	  buf[i++] = '2';
sl@0
  1257
sl@0
  1258
      buf[i++] = '3';
sl@0
  1259
      buf[i++] = 'g';
sl@0
  1260
      buf[i++] = 'p';
sl@0
  1261
      buf[i++] = '4';
sl@0
  1262
sl@0
  1263
      buf[i++] = 'i';
sl@0
  1264
      buf[i++] = 's';
sl@0
  1265
      buf[i++] = 'o';
sl@0
  1266
      buf[i++] = 'm';
sl@0
  1267
	  if ( containsAvcVideo( handle->type ) )
sl@0
  1268
	  {
sl@0
  1269
		  /* AVC is included for 3GPP Release 6 and beyond */
sl@0
  1270
		  buf[i++] = 'a';
sl@0
  1271
		  buf[i++] = 'v';
sl@0
  1272
		  buf[i++] = 'c';
sl@0
  1273
		  buf[i++] = '1';
sl@0
  1274
	  }
sl@0
  1275
  }
sl@0
  1276
  else if(handle->generate3G2)
sl@0
  1277
  {/* 3GPP2 Compatible Brands */
sl@0
  1278
      if( containsAvcVideo( handle->type ) )
sl@0
  1279
      {
sl@0
  1280
      	  buf[i++] = '3';
sl@0
  1281
	      buf[i++] = 'g';
sl@0
  1282
	      buf[i++] = '2';
sl@0
  1283
	      buf[i++] = 'b';
sl@0
  1284
	      if (!(handle->type &  MP4_TYPE_QCELP_13K))
sl@0
  1285
          { // If 3GPP codecs are used, then put 3GP6 in compatible brands 
sl@0
  1286
              buf[i++] = '3';
sl@0
  1287
              buf[i++] = 'g';
sl@0
  1288
              buf[i++] = 'p';
sl@0
  1289
              buf[i++] = '6';
sl@0
  1290
          }
sl@0
  1291
      }
sl@0
  1292
      else
sl@0
  1293
      {
sl@0
  1294
      	  buf[i++] = '3';
sl@0
  1295
      	  buf[i++] = 'g';
sl@0
  1296
      	  buf[i++] = '2';
sl@0
  1297
      	  buf[i++] = 'a';
sl@0
  1298
          if (!(handle->type &  MP4_TYPE_QCELP_13K))
sl@0
  1299
          { // If 3GPP codecs are used, then put 3GP4 in compatible brands 
sl@0
  1300
              buf[i++] = '3';
sl@0
  1301
              buf[i++] = 'g';
sl@0
  1302
              buf[i++] = 'p';
sl@0
  1303
              buf[i++] = '4';
sl@0
  1304
          }
sl@0
  1305
      }
sl@0
  1306
	  if ( containsAvcVideo( handle->type ) )
sl@0
  1307
	  {
sl@0
  1308
		  /* AVC is included for 3GPP Release 6 and beyond */
sl@0
  1309
		  buf[i++] = 'a';
sl@0
  1310
		  buf[i++] = 'v';
sl@0
  1311
		  buf[i++] = 'c';
sl@0
  1312
		  buf[i++] = '1';
sl@0
  1313
	  }
sl@0
  1314
sl@0
  1315
      buf[i++] = 'i';
sl@0
  1316
      buf[i++] = 's';
sl@0
  1317
      buf[i++] = 'o';
sl@0
  1318
      buf[i++] = 'm';
sl@0
  1319
  }
sl@0
  1320
  else
sl@0
  1321
  {/* 3GPP Compatible Brands */
sl@0
  1322
      if ( containsAvcVideo( handle->type ) )
sl@0
  1323
	  {
sl@0
  1324
	      buf[i++] = '3';
sl@0
  1325
	      buf[i++] = 'g';
sl@0
  1326
	      buf[i++] = 'p';
sl@0
  1327
	      buf[i++] = '6';
sl@0
  1328
	  }
sl@0
  1329
	  else
sl@0
  1330
	  {
sl@0
  1331
	      buf[i++] = '3';
sl@0
  1332
	      buf[i++] = 'g';
sl@0
  1333
	      buf[i++] = 'p';
sl@0
  1334
	      buf[i++] = '4';
sl@0
  1335
	  }
sl@0
  1336
	  
sl@0
  1337
      if (!(handle->type &  MP4_TYPE_AMR_WB))
sl@0
  1338
      { // If 3GPP2 codecs are used, then put 3G2A in compatible brands 
sl@0
  1339
          buf[i++] = '3';
sl@0
  1340
          buf[i++] = 'g';
sl@0
  1341
          buf[i++] = '2';
sl@0
  1342
          buf[i++] = 'a';
sl@0
  1343
      }
sl@0
  1344
sl@0
  1345
      buf[i++] = 'i';
sl@0
  1346
      buf[i++] = 's';
sl@0
  1347
      buf[i++] = 'o';
sl@0
  1348
      buf[i++] = 'm';
sl@0
  1349
sl@0
  1350
	  if ( containsAvcVideo( handle->type ) )
sl@0
  1351
	  {
sl@0
  1352
		  /* AVC is included for 3GPP Release 6 and beyond */
sl@0
  1353
		  buf[i++] = 'a';
sl@0
  1354
		  buf[i++] = 'v';
sl@0
  1355
		  buf[i++] = 'c';
sl@0
  1356
		  buf[i++] = '1';
sl@0
  1357
	  }
sl@0
  1358
      
sl@0
  1359
  }
sl@0
  1360
  if (writeFile(handle, buf, (FTYP_SIZE + ftypdelta)) < 0)
sl@0
  1361
  {
sl@0
  1362
    mp4free(buf);
sl@0
  1363
sl@0
  1364
    return -1;
sl@0
  1365
  }
sl@0
  1366
sl@0
  1367
  mp4free(buf);
sl@0
  1368
sl@0
  1369
  return 0;
sl@0
  1370
}
sl@0
  1371
sl@0
  1372
sl@0
  1373
/*
sl@0
  1374
 * Function:
sl@0
  1375
 *
sl@0
  1376
 *   mp4_i32 writeMOOV(MP4HandleImp handle,
sl@0
  1377
 *                     mp4_u32 moovSize,
sl@0
  1378
 *                     mp4_bool haveAudio,
sl@0
  1379
 *                     mp4_bool haveVideo,
sl@0
  1380
 *                     trakSize *audioTrackSize,
sl@0
  1381
 *                     trakSize *videoTrackSize)
sl@0
  1382
 *
sl@0
  1383
 * Description:
sl@0
  1384
 *
sl@0
  1385
 *   Write MOOV atom.
sl@0
  1386
 *
sl@0
  1387
 * Parameters:
sl@0
  1388
 *
sl@0
  1389
 *   handle          MP4 library handle
sl@0
  1390
 *   moovSize        Size of MOOV atom in bytes
sl@0
  1391
 *   haveAudio       Flag to indicate whether audio exists or not
sl@0
  1392
 *   haveVideo       Flag to indicate whether video exists or not
sl@0
  1393
 *   audioTrackSize  Size of audio track in bytes
sl@0
  1394
 *   videoTrackSize  Size of video track in bytes
sl@0
  1395
 *
sl@0
  1396
 * Return value:
sl@0
  1397
 *
sl@0
  1398
 *   0               Success
sl@0
  1399
 *   -1              Error
sl@0
  1400
 *
sl@0
  1401
 */
sl@0
  1402
mp4_i32 writeMOOV(MP4HandleImp handle, mp4_u32 moovSize, mp4_bool haveAudio, mp4_bool haveVideo, trakSize *audioTrackSize, trakSize *videoTrackSize)
sl@0
  1403
{
sl@0
  1404
  PRINT((_L("e_writemoov 1")));
sl@0
  1405
  mp4_u8  buf[8];
sl@0
  1406
  mp4_u32 i = 0;
sl@0
  1407
sl@0
  1408
sl@0
  1409
  /* Size */
sl@0
  1410
  insertu32(buf+i, moovSize);
sl@0
  1411
  i += 4;
sl@0
  1412
sl@0
  1413
  /* Atom type */
sl@0
  1414
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MOOV);
sl@0
  1415
  i += 4;
sl@0
  1416
sl@0
  1417
  PRINT((_L("e_writemoov_header 1")));
sl@0
  1418
  if (writeFile(handle, buf, 8) < 0)
sl@0
  1419
    return -1;
sl@0
  1420
  PRINT((_L("e_writemoov_header 0")));  
sl@0
  1421
sl@0
  1422
  PRINT((_L("e_writemoov_mvhd 1")));	
sl@0
  1423
  if (writeMVHD(handle) < 0)
sl@0
  1424
    return -1;
sl@0
  1425
  PRINT((_L("e_writemoov_mvhd 0")));
sl@0
  1426
sl@0
  1427
  PRINT((_L("e_writemoov_video 1")));
sl@0
  1428
  if (haveVideo)
sl@0
  1429
    if (writeVideoTrak(handle, videoTrackSize) < 0)
sl@0
  1430
      return -1;
sl@0
  1431
  PRINT((_L("e_writemoov_video 0")));    
sl@0
  1432
sl@0
  1433
  PRINT((_L("e_writemoov_audio 1")));
sl@0
  1434
  if (haveAudio)
sl@0
  1435
    if (writeAudioTrak(handle, audioTrackSize) < 0)
sl@0
  1436
      return -1;
sl@0
  1437
  PRINT((_L("e_writemoov_audio 0")));    
sl@0
  1438
    
sl@0
  1439
  PRINT((_L("e_writemoov_udta 1")));    
sl@0
  1440
  if (handle->moovUDTA)
sl@0
  1441
    {
sl@0
  1442
    if (writeUDTA(handle, handle->moovUDTA) < 0)
sl@0
  1443
        {
sl@0
  1444
        return -1;
sl@0
  1445
        }
sl@0
  1446
    }
sl@0
  1447
  PRINT((_L("e_writemoov_udta 0")));
sl@0
  1448
  PRINT((_L("e_writemoov 0")));
sl@0
  1449
  return 0;
sl@0
  1450
}
sl@0
  1451
sl@0
  1452
sl@0
  1453
/*
sl@0
  1454
 * Function:
sl@0
  1455
 *
sl@0
  1456
 *   mp4_i32 writeMVHD(MP4HandleImp handle)
sl@0
  1457
 *
sl@0
  1458
 * Description:
sl@0
  1459
 *
sl@0
  1460
 *   Write MVHD atom.
sl@0
  1461
 *
sl@0
  1462
 * Parameters:
sl@0
  1463
 *
sl@0
  1464
 *   handle   MP4 library handle
sl@0
  1465
 *
sl@0
  1466
 * Return value:
sl@0
  1467
 *
sl@0
  1468
 *   0        Success
sl@0
  1469
 *   -1       Error
sl@0
  1470
 *
sl@0
  1471
 */
sl@0
  1472
mp4_i32 writeMVHD(MP4HandleImp handle)
sl@0
  1473
{
sl@0
  1474
  mp4_u8  *buf;
sl@0
  1475
  mp4_u32  i = 0;
sl@0
  1476
  mp4_u32  u32;
sl@0
  1477
sl@0
  1478
  size_t mvhdSize = mvhdAtomSize(handle);
sl@0
  1479
      
sl@0
  1480
  buf = (mp4_u8 *)mp4malloc(mvhdSize);
sl@0
  1481
  if (buf == NULL)
sl@0
  1482
    return -1;
sl@0
  1483
sl@0
  1484
  /* Size */
sl@0
  1485
  insertu32(buf+i, (mp4_u32)mvhdSize);
sl@0
  1486
  i += 4;
sl@0
  1487
sl@0
  1488
  /* Atom type */
sl@0
  1489
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MVHD);
sl@0
  1490
  i += 4;
sl@0
  1491
sl@0
  1492
sl@0
  1493
  if (handle->videoDuration > MP4_INT_MAX || handle->audioDuration > MP4_INT_MAX)
sl@0
  1494
  {
sl@0
  1495
      /* Version and flags */
sl@0
  1496
      insertu32(buf+i, (mp4_u32)0x01000000);  //its going to be a version 1 atom
sl@0
  1497
      i += 4;
sl@0
  1498
    
sl@0
  1499
      /* Creation time */
sl@0
  1500
      if (getCurrentTime(&u32) < 0)
sl@0
  1501
        u32 = 0;
sl@0
  1502
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  1503
      i += 8;
sl@0
  1504
    
sl@0
  1505
      /* Modification time */
sl@0
  1506
      if (getCurrentTime(&u32) < 0)
sl@0
  1507
        u32 = 0;
sl@0
  1508
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  1509
      i += 8;
sl@0
  1510
    
sl@0
  1511
      /* Timescale */
sl@0
  1512
      insertu32(buf+i, (mp4_u32)MVHD_TIMESCALE);
sl@0
  1513
      i += 4;
sl@0
  1514
    
sl@0
  1515
      /* Duration */
sl@0
  1516
      {
sl@0
  1517
        mp4_u64  u64;
sl@0
  1518
        mp4_u64  videoDuration = 0;
sl@0
  1519
        mp4_u64  audioDuration = 0;
sl@0
  1520
    
sl@0
  1521
    
sl@0
  1522
        if (handle->videoTimeScale)
sl@0
  1523
          videoDuration = (mp4_u64)((mp4_double)MVHD_TIMESCALE *
sl@0
  1524
                                    (mp4_double)handle->videoDuration /
sl@0
  1525
                                    (mp4_double)handle->videoTimeScale +
sl@0
  1526
                                    (mp4_double)0.5);
sl@0
  1527
        if (handle->audioTimeScale)
sl@0
  1528
          audioDuration = (mp4_u64)((mp4_double)MVHD_TIMESCALE *
sl@0
  1529
                                    (mp4_double)handle->audioDuration /
sl@0
  1530
                                    (mp4_double)handle->audioTimeScale +
sl@0
  1531
                                    (mp4_double)0.5);
sl@0
  1532
    
sl@0
  1533
        if (audioDuration > videoDuration)
sl@0
  1534
          u64 = audioDuration;
sl@0
  1535
        else
sl@0
  1536
          u64 = videoDuration;
sl@0
  1537
    
sl@0
  1538
        insertu64(buf+i, u64);
sl@0
  1539
        i += 8;
sl@0
  1540
      }
sl@0
  1541
 
sl@0
  1542
  }
sl@0
  1543
  else
sl@0
  1544
  {
sl@0
  1545
      /* Version and flags */
sl@0
  1546
      insertu32(buf+i, (mp4_u32)0);
sl@0
  1547
      i += 4;
sl@0
  1548
sl@0
  1549
      /* Creation time */
sl@0
  1550
      if (getCurrentTime(&u32) < 0)
sl@0
  1551
        u32 = 0;
sl@0
  1552
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  1553
      i += 4;
sl@0
  1554
    
sl@0
  1555
      /* Modification time */
sl@0
  1556
      if (getCurrentTime(&u32) < 0)
sl@0
  1557
        u32 = 0;
sl@0
  1558
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  1559
      i += 4;
sl@0
  1560
    
sl@0
  1561
      /* Timescale */
sl@0
  1562
      insertu32(buf+i, (mp4_u32)MVHD_TIMESCALE);
sl@0
  1563
      i += 4;
sl@0
  1564
    
sl@0
  1565
      /* Duration */
sl@0
  1566
      {
sl@0
  1567
        mp4_u32  videoDuration = 0;
sl@0
  1568
        mp4_u32  audioDuration = 0;
sl@0
  1569
    
sl@0
  1570
    
sl@0
  1571
        if (handle->videoTimeScale)
sl@0
  1572
          videoDuration = (mp4_u32)((mp4_double)MVHD_TIMESCALE *
sl@0
  1573
                                    (mp4_double)handle->videoDuration /
sl@0
  1574
                                    (mp4_double)handle->videoTimeScale +
sl@0
  1575
                                    (mp4_double)0.5);
sl@0
  1576
        if (handle->audioTimeScale)
sl@0
  1577
          audioDuration = (mp4_u32)((mp4_double)MVHD_TIMESCALE *
sl@0
  1578
                                    (mp4_double)handle->audioDuration /
sl@0
  1579
                                    (mp4_double)handle->audioTimeScale +
sl@0
  1580
                                    (mp4_double)0.5);
sl@0
  1581
    
sl@0
  1582
        if (audioDuration > videoDuration)
sl@0
  1583
          u32 = audioDuration;
sl@0
  1584
        else
sl@0
  1585
          u32 = videoDuration;
sl@0
  1586
    
sl@0
  1587
        insertu32(buf+i, u32);
sl@0
  1588
        i += 4;
sl@0
  1589
      }
sl@0
  1590
  }
sl@0
  1591
  /* Reserved */
sl@0
  1592
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1593
  i += 4;
sl@0
  1594
sl@0
  1595
  insertu16(buf+i, (mp4_u16)0x0100);
sl@0
  1596
  i += 2;
sl@0
  1597
sl@0
  1598
  insertu16(buf+i, (mp4_u16)0x0000);
sl@0
  1599
  i += 2;
sl@0
  1600
sl@0
  1601
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1602
  i += 4;
sl@0
  1603
sl@0
  1604
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1605
  i += 4;
sl@0
  1606
sl@0
  1607
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1608
  i += 4;
sl@0
  1609
sl@0
  1610
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1611
  i += 4;
sl@0
  1612
sl@0
  1613
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1614
  i += 4;
sl@0
  1615
sl@0
  1616
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1617
  i += 4;
sl@0
  1618
sl@0
  1619
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1620
  i += 4;
sl@0
  1621
sl@0
  1622
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1623
  i += 4;
sl@0
  1624
sl@0
  1625
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1626
  i += 4;
sl@0
  1627
sl@0
  1628
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1629
  i += 4;
sl@0
  1630
sl@0
  1631
  insertu32(buf+i, (mp4_u32)0x40000000);
sl@0
  1632
  i += 4;
sl@0
  1633
sl@0
  1634
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1635
  i += 4;
sl@0
  1636
sl@0
  1637
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1638
  i += 4;
sl@0
  1639
sl@0
  1640
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1641
  i += 4;
sl@0
  1642
sl@0
  1643
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1644
  i += 4;
sl@0
  1645
sl@0
  1646
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1647
  i += 4;
sl@0
  1648
sl@0
  1649
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1650
  i += 4;
sl@0
  1651
sl@0
  1652
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1653
  i += 4;
sl@0
  1654
sl@0
  1655
  if (writeFile(handle, buf, mvhdSize) < 0)
sl@0
  1656
  {
sl@0
  1657
    mp4free(buf);
sl@0
  1658
sl@0
  1659
    return -1;
sl@0
  1660
  }
sl@0
  1661
sl@0
  1662
  mp4free(buf);
sl@0
  1663
sl@0
  1664
  return 0;
sl@0
  1665
}
sl@0
  1666
sl@0
  1667
sl@0
  1668
/*
sl@0
  1669
 * Function:
sl@0
  1670
 *
sl@0
  1671
 *   mp4_i32 writeVideoTrak(MP4HandleImp handle,
sl@0
  1672
 *                          trakSize *ts)
sl@0
  1673
 *
sl@0
  1674
 * Description:
sl@0
  1675
 *
sl@0
  1676
 *   Write video track atom.
sl@0
  1677
 *
sl@0
  1678
 * Parameters:
sl@0
  1679
 *
sl@0
  1680
 *   handle   MP4 library handle
sl@0
  1681
 *   ts       Atom sizes
sl@0
  1682
 *
sl@0
  1683
 * Return value:
sl@0
  1684
 *
sl@0
  1685
 *   0        Success
sl@0
  1686
 *   -1       Error
sl@0
  1687
 *
sl@0
  1688
 */
sl@0
  1689
mp4_i32 writeVideoTrak(MP4HandleImp handle, trakSize *ts)
sl@0
  1690
{
sl@0
  1691
  mp4_u8  buf[8];
sl@0
  1692
  mp4_u32 i = 0;
sl@0
  1693
sl@0
  1694
sl@0
  1695
  /* Size */
sl@0
  1696
  insertu32(buf+i, (mp4_u32)ts->trak);
sl@0
  1697
  i += 4;
sl@0
  1698
sl@0
  1699
  /* Atom type */
sl@0
  1700
  insertu32(buf+i, (mp4_u32)ATOMTYPE_TRAK);
sl@0
  1701
  i += 4;
sl@0
  1702
sl@0
  1703
  if (writeFile(handle, buf, 8) < 0)
sl@0
  1704
    return -1;
sl@0
  1705
sl@0
  1706
  if (writeVideoTKHD(handle, ts) < 0)
sl@0
  1707
    return -1;
sl@0
  1708
sl@0
  1709
  if (writeVideoMDIA(handle, ts) < 0)
sl@0
  1710
    return -1;
sl@0
  1711
  
sl@0
  1712
  if (handle->videoUDTA)
sl@0
  1713
    {
sl@0
  1714
    if (writeUDTA(handle, handle->videoUDTA) < 0)
sl@0
  1715
        return -1;
sl@0
  1716
    }
sl@0
  1717
sl@0
  1718
  return 0;
sl@0
  1719
}
sl@0
  1720
sl@0
  1721
sl@0
  1722
/*
sl@0
  1723
 * Function:
sl@0
  1724
 *
sl@0
  1725
 *   mp4_i32 writeVideoTKHD(MP4HandleImp handle,
sl@0
  1726
 *                          trakSize *ts)
sl@0
  1727
 *
sl@0
  1728
 * Description:
sl@0
  1729
 *
sl@0
  1730
 *   Write TKHD atom.
sl@0
  1731
 *
sl@0
  1732
 * Parameters:
sl@0
  1733
 *
sl@0
  1734
 *   handle   MP4 library handle
sl@0
  1735
 *   ts       Atom sizes
sl@0
  1736
 *
sl@0
  1737
 * Return value:
sl@0
  1738
 *
sl@0
  1739
 *   0        Success
sl@0
  1740
 *   -1       Error
sl@0
  1741
 *
sl@0
  1742
 */
sl@0
  1743
mp4_i32 writeVideoTKHD(MP4HandleImp handle, trakSize *ts)
sl@0
  1744
{
sl@0
  1745
  mp4_u8      *buf;
sl@0
  1746
  mp4_u32     i = 0;
sl@0
  1747
  mp4_u32     u32;
sl@0
  1748
  mp4_double  ud;
sl@0
  1749
sl@0
  1750
sl@0
  1751
  buf = (mp4_u8 *)mp4malloc(ts->tkhd);
sl@0
  1752
  if (buf == NULL)
sl@0
  1753
    return -1;
sl@0
  1754
sl@0
  1755
  /* Size */
sl@0
  1756
  insertu32(buf+i, (mp4_u32)ts->tkhd);
sl@0
  1757
  i += 4;
sl@0
  1758
sl@0
  1759
  /* Atom type */
sl@0
  1760
  insertu32(buf+i, (mp4_u32)ATOMTYPE_TKHD);
sl@0
  1761
  i += 4;
sl@0
  1762
sl@0
  1763
  
sl@0
  1764
  if (handle->videoDuration > MP4_INT_MAX)
sl@0
  1765
  {
sl@0
  1766
      mp4_u64     u64;
sl@0
  1767
      /* Version and flags */
sl@0
  1768
      buf[i++] = 1;     //make this a version 1 atom
sl@0
  1769
      buf[i++] = 0;
sl@0
  1770
      buf[i++] = 0;
sl@0
  1771
      buf[i++] = 7;  /* Track enabled, used in movie and preview */
sl@0
  1772
    
sl@0
  1773
      /* Creation time */
sl@0
  1774
      if (getCurrentTime(&u32) < 0)
sl@0
  1775
        u32 = 0;
sl@0
  1776
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  1777
      i += 8;
sl@0
  1778
    
sl@0
  1779
      /* Modification time */
sl@0
  1780
      if (getCurrentTime(&u32) < 0)
sl@0
  1781
        u32 = 0;
sl@0
  1782
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  1783
      i += 8;
sl@0
  1784
    
sl@0
  1785
      /* Track ID */
sl@0
  1786
      insertu32(buf+i, (mp4_u32)1);
sl@0
  1787
      i += 4;
sl@0
  1788
    
sl@0
  1789
      /* Reserved */
sl@0
  1790
      insertu32(buf+i, (mp4_u32)0);
sl@0
  1791
      i += 4;
sl@0
  1792
    
sl@0
  1793
      /* Duration */
sl@0
  1794
      if ( (handle->videoDuration == 0) || (handle->videoTimeScale == 0) )
sl@0
  1795
          {
sl@0
  1796
          ud = 0;
sl@0
  1797
          }
sl@0
  1798
      else
sl@0
  1799
          {
sl@0
  1800
          ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->videoDuration / (mp4_double)handle->videoTimeScale + (mp4_double)0.5;
sl@0
  1801
          }
sl@0
  1802
    
sl@0
  1803
      u64 = (mp4_u64)ud;
sl@0
  1804
      insertu64(buf+i, u64);
sl@0
  1805
      i += 8;
sl@0
  1806
  }
sl@0
  1807
  else
sl@0
  1808
  {
sl@0
  1809
      /* Version and flags */
sl@0
  1810
      buf[i++] = 0;
sl@0
  1811
      buf[i++] = 0;
sl@0
  1812
      buf[i++] = 0;
sl@0
  1813
      buf[i++] = 7;  /* Track enabled, used in movie and preview */
sl@0
  1814
    
sl@0
  1815
      /* Creation time */
sl@0
  1816
      if (getCurrentTime(&u32) < 0)
sl@0
  1817
        u32 = 0;
sl@0
  1818
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  1819
      i += 4;
sl@0
  1820
    
sl@0
  1821
      /* Modification time */
sl@0
  1822
      if (getCurrentTime(&u32) < 0)
sl@0
  1823
        u32 = 0;
sl@0
  1824
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  1825
      i += 4;
sl@0
  1826
    
sl@0
  1827
      /* Track ID */
sl@0
  1828
      insertu32(buf+i, (mp4_u32)1);
sl@0
  1829
      i += 4;
sl@0
  1830
    
sl@0
  1831
      /* Reserved */
sl@0
  1832
      insertu32(buf+i, (mp4_u32)0);
sl@0
  1833
      i += 4;
sl@0
  1834
    
sl@0
  1835
      /* Duration */
sl@0
  1836
      if ( (handle->videoDuration == 0) || (handle->videoTimeScale == 0) )
sl@0
  1837
          {
sl@0
  1838
          ud = 0;
sl@0
  1839
          }
sl@0
  1840
      else
sl@0
  1841
          {
sl@0
  1842
          ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->videoDuration / (mp4_double)handle->videoTimeScale + (mp4_double)0.5;
sl@0
  1843
          }
sl@0
  1844
    
sl@0
  1845
      u32 = (mp4_u32)ud;
sl@0
  1846
      insertu32(buf+i, u32);
sl@0
  1847
      i += 4;
sl@0
  1848
  }
sl@0
  1849
  /* Reserved */
sl@0
  1850
  insertu32(buf+i, (mp4_u32)0);
sl@0
  1851
  i += 4;
sl@0
  1852
sl@0
  1853
  insertu32(buf+i, (mp4_u32)0);
sl@0
  1854
  i += 4;
sl@0
  1855
sl@0
  1856
  insertu32(buf+i, (mp4_u32)0);
sl@0
  1857
  i += 4;
sl@0
  1858
sl@0
  1859
  insertu16(buf+i, (mp4_u16)0);  /* Visual track */
sl@0
  1860
  i += 2;
sl@0
  1861
sl@0
  1862
  insertu16(buf+i, (mp4_u16)0);
sl@0
  1863
  i += 2;
sl@0
  1864
sl@0
  1865
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1866
  i += 4;
sl@0
  1867
sl@0
  1868
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1869
  i += 4;
sl@0
  1870
sl@0
  1871
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1872
  i += 4;
sl@0
  1873
sl@0
  1874
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1875
  i += 4;
sl@0
  1876
sl@0
  1877
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  1878
  i += 4;
sl@0
  1879
sl@0
  1880
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1881
  i += 4;
sl@0
  1882
sl@0
  1883
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1884
  i += 4;
sl@0
  1885
sl@0
  1886
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  1887
  i += 4;
sl@0
  1888
sl@0
  1889
  insertu32(buf+i, (mp4_u32)0x40000000);
sl@0
  1890
  i += 4;
sl@0
  1891
sl@0
  1892
  insertu16(buf+i, (mp4_u16)handle->videoWidth);  /* Width */
sl@0
  1893
  i += 2;
sl@0
  1894
sl@0
  1895
  insertu16(buf+i, (mp4_u16)0);
sl@0
  1896
  i += 2;
sl@0
  1897
sl@0
  1898
  insertu16(buf+i, (mp4_u16)handle->videoHeight);  /* Height */
sl@0
  1899
  i += 2;
sl@0
  1900
sl@0
  1901
  insertu16(buf+i, (mp4_u16)0);
sl@0
  1902
  i += 2;
sl@0
  1903
sl@0
  1904
  if (writeFile(handle, buf, ts->tkhd) < 0)
sl@0
  1905
  {
sl@0
  1906
    mp4free(buf);
sl@0
  1907
sl@0
  1908
    return -1;
sl@0
  1909
  }
sl@0
  1910
sl@0
  1911
  mp4free(buf);
sl@0
  1912
sl@0
  1913
  return 0;
sl@0
  1914
}
sl@0
  1915
sl@0
  1916
sl@0
  1917
/*
sl@0
  1918
 * Function:
sl@0
  1919
 *
sl@0
  1920
 *   mp4_i32 writeVideoMDIA(MP4HandleImp handle,
sl@0
  1921
 *                          trakSize *ts)
sl@0
  1922
 *
sl@0
  1923
 * Description:
sl@0
  1924
 *
sl@0
  1925
 *   Write video MDIA atom.
sl@0
  1926
 *
sl@0
  1927
 * Parameters:
sl@0
  1928
 *
sl@0
  1929
 *   handle   MP4 library handle
sl@0
  1930
 *   ts       Atom sizes
sl@0
  1931
 *
sl@0
  1932
 * Return value:
sl@0
  1933
 *
sl@0
  1934
 *   0        Success
sl@0
  1935
 *   -1       Error
sl@0
  1936
 *
sl@0
  1937
 */
sl@0
  1938
mp4_i32 writeVideoMDIA(MP4HandleImp handle, trakSize *ts)
sl@0
  1939
{
sl@0
  1940
  mp4_u8  buf[8];
sl@0
  1941
  mp4_u32  i = 0;
sl@0
  1942
sl@0
  1943
sl@0
  1944
  /* Size */
sl@0
  1945
  insertu32(buf+i, (mp4_u32)ts->mdia);
sl@0
  1946
  i += 4;
sl@0
  1947
sl@0
  1948
  /* Atom type */
sl@0
  1949
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MDIA);
sl@0
  1950
  i += 4;
sl@0
  1951
sl@0
  1952
  if (writeFile(handle, buf, 8) < 0)
sl@0
  1953
    return -1;
sl@0
  1954
sl@0
  1955
  if (writeVideoMDHD(handle, ts) < 0)
sl@0
  1956
    return -1;
sl@0
  1957
sl@0
  1958
  if (writeVideoHDLR(handle, ts) < 0)
sl@0
  1959
    return -1;
sl@0
  1960
sl@0
  1961
  if (writeVideoMINF(handle, ts) < 0)
sl@0
  1962
    return -1;
sl@0
  1963
sl@0
  1964
  return 0;
sl@0
  1965
}
sl@0
  1966
sl@0
  1967
sl@0
  1968
/*
sl@0
  1969
 * Function:
sl@0
  1970
 *
sl@0
  1971
 *   mp4_i32 writeVideoMDHD(MP4HandleImp handle,
sl@0
  1972
 *                          trakSize *ts)
sl@0
  1973
 *
sl@0
  1974
 * Description:
sl@0
  1975
 *
sl@0
  1976
 *   Write video MDHD atom.
sl@0
  1977
 *
sl@0
  1978
 * Parameters:
sl@0
  1979
 *
sl@0
  1980
 *   handle   MP4 library handle
sl@0
  1981
 *   ts       Atom sizes
sl@0
  1982
 *
sl@0
  1983
 * Return value:
sl@0
  1984
 *
sl@0
  1985
 *   0        Success
sl@0
  1986
 *   -1       Error
sl@0
  1987
 *
sl@0
  1988
 */
sl@0
  1989
mp4_i32 writeVideoMDHD(MP4HandleImp handle, trakSize *ts)
sl@0
  1990
{
sl@0
  1991
  mp4_u8  *buf;
sl@0
  1992
  mp4_u32  i = 0;
sl@0
  1993
  mp4_u32  u32;
sl@0
  1994
sl@0
  1995
sl@0
  1996
  buf = (mp4_u8 *)mp4malloc(ts->mdhd);
sl@0
  1997
  if (buf == NULL)
sl@0
  1998
    return -1;
sl@0
  1999
sl@0
  2000
  /* Size */
sl@0
  2001
  insertu32(buf+i, (mp4_u32)ts->mdhd);
sl@0
  2002
  i += 4;
sl@0
  2003
sl@0
  2004
  /* Atom type */
sl@0
  2005
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MDHD);
sl@0
  2006
  i += 4;
sl@0
  2007
sl@0
  2008
  if (handle->videoDuration > MP4_INT_MAX)
sl@0
  2009
  {
sl@0
  2010
      /* Version and flags */
sl@0
  2011
      insertu32(buf+i, (mp4_u32)0x01000000); //version 1 atom
sl@0
  2012
      i += 4;
sl@0
  2013
    
sl@0
  2014
      /* Creation time */
sl@0
  2015
      if (getCurrentTime(&u32) < 0)
sl@0
  2016
        u32 = 0;
sl@0
  2017
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  2018
      i += 8;
sl@0
  2019
    
sl@0
  2020
      /* Modification time */
sl@0
  2021
      if (getCurrentTime(&u32) < 0)
sl@0
  2022
        u32 = 0;
sl@0
  2023
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  2024
      i += 8;
sl@0
  2025
    
sl@0
  2026
      /* Timescale */
sl@0
  2027
      insertu32(buf+i, (mp4_u32)handle->videoTimeScale);
sl@0
  2028
      i += 4;
sl@0
  2029
    
sl@0
  2030
      /* Duration */
sl@0
  2031
      insertu64(buf+i, handle->videoDuration);
sl@0
  2032
      i += 8;
sl@0
  2033
  }
sl@0
  2034
  else
sl@0
  2035
  {
sl@0
  2036
      /* Version and flags */
sl@0
  2037
      insertu32(buf+i, (mp4_u32)0);
sl@0
  2038
      i += 4;
sl@0
  2039
    
sl@0
  2040
      /* Creation time */
sl@0
  2041
      if (getCurrentTime(&u32) < 0)
sl@0
  2042
        u32 = 0;
sl@0
  2043
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  2044
      i += 4;
sl@0
  2045
    
sl@0
  2046
      /* Modification time */
sl@0
  2047
      if (getCurrentTime(&u32) < 0)
sl@0
  2048
        u32 = 0;
sl@0
  2049
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  2050
      i += 4;
sl@0
  2051
    
sl@0
  2052
      /* Timescale */
sl@0
  2053
      insertu32(buf+i, (mp4_u32)handle->videoTimeScale);
sl@0
  2054
      i += 4;
sl@0
  2055
    
sl@0
  2056
      /* Duration */
sl@0
  2057
      insertu32(buf+i, (mp4_u32)handle->videoDuration);
sl@0
  2058
      i += 4;
sl@0
  2059
  }
sl@0
  2060
  
sl@0
  2061
  /* Language */
sl@0
  2062
  insertu16(buf+i, (mp4_u16)0x55c4); /* 'und' */
sl@0
  2063
  i += 2;
sl@0
  2064
sl@0
  2065
  /* Reserved */
sl@0
  2066
  insertu16(buf+i, (mp4_u16)0x0000);
sl@0
  2067
  i += 2;
sl@0
  2068
sl@0
  2069
  if (writeFile(handle, buf, ts->mdhd) < 0)
sl@0
  2070
  {
sl@0
  2071
    mp4free(buf);
sl@0
  2072
sl@0
  2073
    return -1;
sl@0
  2074
  }
sl@0
  2075
sl@0
  2076
  mp4free(buf);
sl@0
  2077
sl@0
  2078
  return 0;
sl@0
  2079
}
sl@0
  2080
sl@0
  2081
sl@0
  2082
/*
sl@0
  2083
 * Function:
sl@0
  2084
 *
sl@0
  2085
 *   mp4_i32 writeVideoHDLR(MP4HandleImp handle,
sl@0
  2086
 *                          trakSize *ts)
sl@0
  2087
 *
sl@0
  2088
 * Description:
sl@0
  2089
 *
sl@0
  2090
 *   Write video HDLR atom.
sl@0
  2091
 *
sl@0
  2092
 * Parameters:
sl@0
  2093
 *
sl@0
  2094
 *   handle   MP4 library handle
sl@0
  2095
 *   ts       Atom sizes
sl@0
  2096
 *
sl@0
  2097
 * Return value:
sl@0
  2098
 *
sl@0
  2099
 *   0        Success
sl@0
  2100
 *   -1       Error
sl@0
  2101
 *
sl@0
  2102
 */
sl@0
  2103
mp4_i32 writeVideoHDLR(MP4HandleImp handle, trakSize *ts)
sl@0
  2104
{
sl@0
  2105
  mp4_u8  *buf;
sl@0
  2106
  mp4_u32  i = 0;
sl@0
  2107
sl@0
  2108
sl@0
  2109
  buf = (mp4_u8 *)mp4malloc(ts->hdlr);
sl@0
  2110
  if (buf == NULL)
sl@0
  2111
    return -1;
sl@0
  2112
sl@0
  2113
  /* Size */
sl@0
  2114
  insertu32(buf+i, (mp4_u32)ts->hdlr);
sl@0
  2115
  i += 4;
sl@0
  2116
sl@0
  2117
  /* Atom type */
sl@0
  2118
  insertu32(buf+i, (mp4_u32)ATOMTYPE_HDLR);
sl@0
  2119
  i += 4;
sl@0
  2120
sl@0
  2121
  /* Version and flags */
sl@0
  2122
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2123
  i += 4;
sl@0
  2124
sl@0
  2125
  /* Reserved */
sl@0
  2126
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2127
  i += 4;
sl@0
  2128
sl@0
  2129
  /* Handler type */
sl@0
  2130
  buf[i++] = 'v';
sl@0
  2131
  buf[i++] = 'i';
sl@0
  2132
  buf[i++] = 'd';
sl@0
  2133
  buf[i++] = 'e';
sl@0
  2134
sl@0
  2135
  /* Reserved */
sl@0
  2136
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2137
  i += 4;
sl@0
  2138
sl@0
  2139
  /* Reserved */
sl@0
  2140
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2141
  i += 4;
sl@0
  2142
sl@0
  2143
  /* Reserved */
sl@0
  2144
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2145
  i += 4;
sl@0
  2146
sl@0
  2147
  /* Empty string */
sl@0
  2148
  buf[i++] = 0;
sl@0
  2149
sl@0
  2150
  if (writeFile(handle, buf, ts->hdlr) < 0)
sl@0
  2151
  {
sl@0
  2152
    mp4free(buf);
sl@0
  2153
sl@0
  2154
    return -1;
sl@0
  2155
  }
sl@0
  2156
sl@0
  2157
  mp4free(buf);
sl@0
  2158
sl@0
  2159
  return 0;
sl@0
  2160
}
sl@0
  2161
sl@0
  2162
sl@0
  2163
/*
sl@0
  2164
 * Function:
sl@0
  2165
 *
sl@0
  2166
 *   mp4_i32 writeVideoMINF(MP4HandleImp handle,
sl@0
  2167
 *                          trakSize *ts)
sl@0
  2168
 *
sl@0
  2169
 * Description:
sl@0
  2170
 *
sl@0
  2171
 *   Write video MINF atom.
sl@0
  2172
 *
sl@0
  2173
 * Parameters:
sl@0
  2174
 *
sl@0
  2175
 *   handle   MP4 library handle
sl@0
  2176
 *   ts       Atom sizes
sl@0
  2177
 *
sl@0
  2178
 * Return value:
sl@0
  2179
 *
sl@0
  2180
 *   0        Success
sl@0
  2181
 *   -1       Error
sl@0
  2182
 *
sl@0
  2183
 */
sl@0
  2184
mp4_i32 writeVideoMINF(MP4HandleImp handle, trakSize *ts)
sl@0
  2185
{
sl@0
  2186
  mp4_u8  buf[8];
sl@0
  2187
  mp4_u32  i = 0;
sl@0
  2188
sl@0
  2189
sl@0
  2190
  /* Size */
sl@0
  2191
  insertu32(buf+i, (mp4_u32)ts->minf);
sl@0
  2192
  i += 4;
sl@0
  2193
sl@0
  2194
  /* Atom type */
sl@0
  2195
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MINF);
sl@0
  2196
  i += 4;
sl@0
  2197
sl@0
  2198
  if (writeFile(handle, buf, 8) < 0)
sl@0
  2199
    return -1;
sl@0
  2200
sl@0
  2201
  if (writeVMHD(handle, ts) < 0)
sl@0
  2202
    return -1;
sl@0
  2203
sl@0
  2204
  if (writeDINF(handle, ts) < 0)
sl@0
  2205
    return -1;
sl@0
  2206
sl@0
  2207
  if (writeVideoSTBL(handle, ts) < 0)
sl@0
  2208
    return -1;
sl@0
  2209
sl@0
  2210
  return 0;
sl@0
  2211
}
sl@0
  2212
sl@0
  2213
sl@0
  2214
/*
sl@0
  2215
 * Function:
sl@0
  2216
 *
sl@0
  2217
 *   mp4_i32  writeVMHD(MP4HandleImp handle,
sl@0
  2218
 *                      trakSize *ts)
sl@0
  2219
 *
sl@0
  2220
 * Description:
sl@0
  2221
 *
sl@0
  2222
 *   Write VMHD atom.
sl@0
  2223
 *
sl@0
  2224
 * Parameters:
sl@0
  2225
 *
sl@0
  2226
 *   handle   MP4 library handle
sl@0
  2227
 *   ts       Atom sizes
sl@0
  2228
 *
sl@0
  2229
 * Return value:
sl@0
  2230
 *
sl@0
  2231
 *   0        Success
sl@0
  2232
 *   -1       Error
sl@0
  2233
 *
sl@0
  2234
 */
sl@0
  2235
mp4_i32  writeVMHD(MP4HandleImp handle, trakSize *ts)
sl@0
  2236
{
sl@0
  2237
  mp4_u8  *buf;
sl@0
  2238
  mp4_u32  i = 0;
sl@0
  2239
sl@0
  2240
sl@0
  2241
  buf = (mp4_u8 *)mp4malloc(ts->vmhd);
sl@0
  2242
  if (buf == NULL)
sl@0
  2243
    return -1;
sl@0
  2244
sl@0
  2245
  /* Size */
sl@0
  2246
  insertu32(buf+i, (mp4_u32)ts->vmhd);
sl@0
  2247
  i += 4;
sl@0
  2248
sl@0
  2249
  /* Atom type */
sl@0
  2250
  insertu32(buf+i, (mp4_u32)ATOMTYPE_VMHD);
sl@0
  2251
  i += 4;
sl@0
  2252
sl@0
  2253
  /* Version and flags */
sl@0
  2254
  insertu32(buf+i, (mp4_u32)0x00000001);
sl@0
  2255
  i += 4;
sl@0
  2256
sl@0
  2257
  /* Reserved */
sl@0
  2258
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2259
  i += 4;
sl@0
  2260
sl@0
  2261
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2262
  i += 4;
sl@0
  2263
sl@0
  2264
  if (writeFile(handle, buf, ts->vmhd) < 0)
sl@0
  2265
  {
sl@0
  2266
    mp4free(buf);
sl@0
  2267
sl@0
  2268
    return -1;
sl@0
  2269
  }
sl@0
  2270
sl@0
  2271
  mp4free(buf);
sl@0
  2272
sl@0
  2273
  return 0;
sl@0
  2274
}
sl@0
  2275
sl@0
  2276
sl@0
  2277
/*
sl@0
  2278
 * Function:
sl@0
  2279
 *
sl@0
  2280
 *   mp4_i32 writeDINF(MP4HandleImp handle,
sl@0
  2281
 *                     trakSize *ts)
sl@0
  2282
 *
sl@0
  2283
 * Description:
sl@0
  2284
 *
sl@0
  2285
 *   Write DINF atom.
sl@0
  2286
 *
sl@0
  2287
 * Parameters:
sl@0
  2288
 *
sl@0
  2289
 *   handle   MP4 library handle
sl@0
  2290
 *   ts       Atom sizes
sl@0
  2291
 *
sl@0
  2292
 * Return value:
sl@0
  2293
 *
sl@0
  2294
 *   0        Success
sl@0
  2295
 *   -1       Error
sl@0
  2296
 *
sl@0
  2297
 */
sl@0
  2298
mp4_i32 writeDINF(MP4HandleImp handle, trakSize *ts)
sl@0
  2299
{
sl@0
  2300
  mp4_u8  buf[8];
sl@0
  2301
  mp4_u32  i = 0;
sl@0
  2302
sl@0
  2303
sl@0
  2304
  /* Size */
sl@0
  2305
  insertu32(buf+i, (mp4_u32)ts->dinf);
sl@0
  2306
  i += 4;
sl@0
  2307
sl@0
  2308
  /* Atom type */
sl@0
  2309
  insertu32(buf+i, (mp4_u32)ATOMTYPE_DINF);
sl@0
  2310
  i += 4;
sl@0
  2311
sl@0
  2312
  if (writeFile(handle, buf, 8) < 0)
sl@0
  2313
    return -1;
sl@0
  2314
sl@0
  2315
  if (writeDREF(handle, ts) < 0)
sl@0
  2316
    return -1;
sl@0
  2317
sl@0
  2318
  return 0;
sl@0
  2319
}
sl@0
  2320
sl@0
  2321
sl@0
  2322
/*
sl@0
  2323
 * Function:
sl@0
  2324
 *
sl@0
  2325
 *   mp4_i32  writeDREF(MP4HandleImp handle,
sl@0
  2326
 *                      trakSize *ts)
sl@0
  2327
 *
sl@0
  2328
 * Description:
sl@0
  2329
 *
sl@0
  2330
 *   Write DREF atom.
sl@0
  2331
 *
sl@0
  2332
 * Parameters:
sl@0
  2333
 *
sl@0
  2334
 *   handle   MP4 library handle
sl@0
  2335
 *   ts       Atom sizes
sl@0
  2336
 *
sl@0
  2337
 * Return value:
sl@0
  2338
 *
sl@0
  2339
 *   0        Success
sl@0
  2340
 *   -1       Error
sl@0
  2341
 *
sl@0
  2342
 */
sl@0
  2343
mp4_i32  writeDREF(MP4HandleImp handle, trakSize *ts)
sl@0
  2344
{
sl@0
  2345
  mp4_u8  *buf;
sl@0
  2346
  mp4_u32  i = 0;
sl@0
  2347
sl@0
  2348
sl@0
  2349
  buf = (mp4_u8 *)mp4malloc(ts->dref);
sl@0
  2350
  if (buf == NULL)
sl@0
  2351
    return -1;
sl@0
  2352
sl@0
  2353
  /* Size */
sl@0
  2354
  insertu32(buf+i, (mp4_u32)ts->dref);
sl@0
  2355
  i += 4;
sl@0
  2356
sl@0
  2357
  /* Atom type */
sl@0
  2358
  insertu32(buf+i, (mp4_u32)ATOMTYPE_DREF);
sl@0
  2359
  i += 4;
sl@0
  2360
sl@0
  2361
  /* Version and flags */
sl@0
  2362
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2363
  i += 4;
sl@0
  2364
sl@0
  2365
  /* Entry count */
sl@0
  2366
  insertu32(buf+i, (mp4_u32)1);
sl@0
  2367
  i += 4;
sl@0
  2368
sl@0
  2369
  /* URL atom */
sl@0
  2370
sl@0
  2371
  /* Size */
sl@0
  2372
  insertu32(buf+i, (mp4_u32)12);
sl@0
  2373
  i += 4;
sl@0
  2374
sl@0
  2375
  /* Type */
sl@0
  2376
  insertu32(buf+i, (mp4_u32)ATOMTYPE_URL);
sl@0
  2377
  i += 4;
sl@0
  2378
sl@0
  2379
  /* Version and flags */
sl@0
  2380
  insertu32(buf+i, (mp4_u32)0x00000001);
sl@0
  2381
  i += 4;
sl@0
  2382
sl@0
  2383
  if (writeFile(handle, buf, ts->dref) < 0)
sl@0
  2384
  {
sl@0
  2385
    mp4free(buf);
sl@0
  2386
sl@0
  2387
    return -1;
sl@0
  2388
  }
sl@0
  2389
sl@0
  2390
  mp4free(buf);
sl@0
  2391
sl@0
  2392
  return 0;
sl@0
  2393
}
sl@0
  2394
sl@0
  2395
sl@0
  2396
/*
sl@0
  2397
 * Function:
sl@0
  2398
 *
sl@0
  2399
 *   mp4_i32 writeVideoSTBL(MP4HandleImp handle,
sl@0
  2400
 *                          trakSize *ts)
sl@0
  2401
 *
sl@0
  2402
 * Description:
sl@0
  2403
 *
sl@0
  2404
 *   Write video STBL atom.
sl@0
  2405
 *
sl@0
  2406
 * Parameters:
sl@0
  2407
 *
sl@0
  2408
 *   handle   MP4 library handle
sl@0
  2409
 *   ts       Atom sizes
sl@0
  2410
 *
sl@0
  2411
 * Return value:
sl@0
  2412
 *
sl@0
  2413
 *   0        Success
sl@0
  2414
 *   -1       Error
sl@0
  2415
 *
sl@0
  2416
 */
sl@0
  2417
mp4_i32 writeVideoSTBL(MP4HandleImp handle, trakSize *ts)
sl@0
  2418
{
sl@0
  2419
  mp4_u8  buf[8];
sl@0
  2420
  mp4_u32  i = 0;
sl@0
  2421
sl@0
  2422
sl@0
  2423
  /* Size */
sl@0
  2424
  insertu32(buf+i, (mp4_u32)ts->stbl);
sl@0
  2425
  i += 4;
sl@0
  2426
sl@0
  2427
  /* Atom type */
sl@0
  2428
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STBL);
sl@0
  2429
  i += 4;
sl@0
  2430
sl@0
  2431
  if (writeFile(handle, buf, 8) < 0)
sl@0
  2432
    return -1;
sl@0
  2433
sl@0
  2434
  if (writeVideoSTSD(handle, ts) < 0)
sl@0
  2435
    return -1;
sl@0
  2436
sl@0
  2437
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
  2438
  {
sl@0
  2439
    if (writeVideoSTTSLongClip(handle, ts) < 0)
sl@0
  2440
      return -1;
sl@0
  2441
  }
sl@0
  2442
  else
sl@0
  2443
  {
sl@0
  2444
    if (writeVideoSTTS(handle, ts) < 0)
sl@0
  2445
      return -1;
sl@0
  2446
  }
sl@0
  2447
sl@0
  2448
  if (writeVideoSTSC(handle, ts) < 0)
sl@0
  2449
    return -1;
sl@0
  2450
sl@0
  2451
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
  2452
  {
sl@0
  2453
    if (writeVideoSTSZLongClip(handle, ts) < 0)
sl@0
  2454
      return -1;
sl@0
  2455
	
sl@0
  2456
	if (handle->videoSampleTable->stcoNeed64Bits)
sl@0
  2457
	{
sl@0
  2458
      if (writeVideoCO64LongClip(handle, ts) < 0)
sl@0
  2459
        return -1;
sl@0
  2460
	}
sl@0
  2461
	else
sl@0
  2462
	{
sl@0
  2463
      if (writeVideoSTCOLongClip(handle, ts) < 0)
sl@0
  2464
        return -1;
sl@0
  2465
	}
sl@0
  2466
sl@0
  2467
    if (writeVideoSTSSLongClip(handle, ts) < 0)
sl@0
  2468
      return -1;
sl@0
  2469
    
sl@0
  2470
    if(ts->sdtp && writeVideoSDTPLongClip(handle, ts) < 0)
sl@0
  2471
      return -1;
sl@0
  2472
  }
sl@0
  2473
  else
sl@0
  2474
  {
sl@0
  2475
    if (writeVideoSTSZ(handle, ts) < 0)
sl@0
  2476
      return -1;
sl@0
  2477
sl@0
  2478
	if (handle->videoSampleTable->stcoNeed64Bits)
sl@0
  2479
	{
sl@0
  2480
      if (writeVideoCO64(handle, ts) < 0)
sl@0
  2481
        return -1;
sl@0
  2482
	}
sl@0
  2483
	else
sl@0
  2484
	{
sl@0
  2485
      if (writeVideoSTCO(handle, ts) < 0)
sl@0
  2486
        return -1;
sl@0
  2487
	}
sl@0
  2488
sl@0
  2489
    if (writeVideoSTSS(handle, ts) < 0)
sl@0
  2490
      return -1;
sl@0
  2491
    
sl@0
  2492
    if(ts->sdtp && writeVideoSDTP(handle, ts) < 0)
sl@0
  2493
      return -1;
sl@0
  2494
  }
sl@0
  2495
  return 0;
sl@0
  2496
}
sl@0
  2497
sl@0
  2498
sl@0
  2499
/*
sl@0
  2500
 * Function:
sl@0
  2501
 *
sl@0
  2502
 *   mp4_i32 writeVideoSTSD(MP4HandleImp handle,
sl@0
  2503
 *                          trakSize *ts)
sl@0
  2504
 *
sl@0
  2505
 * Description:
sl@0
  2506
 *
sl@0
  2507
 *   Write video STSD atom.
sl@0
  2508
 *
sl@0
  2509
 * Parameters:
sl@0
  2510
 *
sl@0
  2511
 *   handle   MP4 library handle
sl@0
  2512
 *   ts       Atom sizes
sl@0
  2513
 *
sl@0
  2514
 * Return value:
sl@0
  2515
 *
sl@0
  2516
 *   0        Success
sl@0
  2517
 *   -1       Error
sl@0
  2518
 *
sl@0
  2519
 */
sl@0
  2520
mp4_i32 writeVideoSTSD(MP4HandleImp handle, trakSize *ts)
sl@0
  2521
{
sl@0
  2522
  mp4_u8  buf[16];
sl@0
  2523
  mp4_u32  i = 0;
sl@0
  2524
sl@0
  2525
sl@0
  2526
  /* Size */
sl@0
  2527
  insertu32(buf+i, (mp4_u32)ts->stsd);
sl@0
  2528
  i += 4;
sl@0
  2529
sl@0
  2530
  /* Atom type */
sl@0
  2531
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSD);
sl@0
  2532
  i += 4;
sl@0
  2533
sl@0
  2534
  /* Version and flags */
sl@0
  2535
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2536
  i += 4;
sl@0
  2537
sl@0
  2538
  /* Entry count */
sl@0
  2539
  insertu32(buf+i, (mp4_u32)1);
sl@0
  2540
  i += 4;
sl@0
  2541
sl@0
  2542
  if (writeFile(handle, buf, 16) < 0)
sl@0
  2543
    return -1;
sl@0
  2544
sl@0
  2545
  if (handle->type & MP4_TYPE_MPEG4_VIDEO)
sl@0
  2546
  {
sl@0
  2547
    if (writeMP4V(handle, ts) < 0)
sl@0
  2548
      return -1;
sl@0
  2549
  }
sl@0
  2550
  else if ((handle->type & MP4_TYPE_H263_PROFILE_0) ||
sl@0
  2551
           (handle->type & MP4_TYPE_H263_PROFILE_3))
sl@0
  2552
  {
sl@0
  2553
    if (writeS263(handle, ts) < 0)
sl@0
  2554
      return -1;
sl@0
  2555
  }
sl@0
  2556
  else if ( containsAvcVideo( handle->type ) )
sl@0
  2557
  {
sl@0
  2558
	  if (writeAVC1(handle, ts) < 0)
sl@0
  2559
		  return -1;
sl@0
  2560
  }
sl@0
  2561
  else
sl@0
  2562
  {
sl@0
  2563
  }
sl@0
  2564
sl@0
  2565
  return 0;
sl@0
  2566
}
sl@0
  2567
sl@0
  2568
sl@0
  2569
/*
sl@0
  2570
 * Function:
sl@0
  2571
 *
sl@0
  2572
 *   mp4_i32 writeMP4V(MP4HandleImp handle,
sl@0
  2573
 *                     trakSize *ts)
sl@0
  2574
 *
sl@0
  2575
 * Description:
sl@0
  2576
 *
sl@0
  2577
 *   Write MP4V atom.
sl@0
  2578
 *
sl@0
  2579
 * Parameters:
sl@0
  2580
 *
sl@0
  2581
 *   handle   MP4 library handle
sl@0
  2582
 *   ts       Atom sizes
sl@0
  2583
 *
sl@0
  2584
 * Return value:
sl@0
  2585
 *
sl@0
  2586
 *   0        Success
sl@0
  2587
 *   -1       Error
sl@0
  2588
 *
sl@0
  2589
 */
sl@0
  2590
mp4_i32 writeMP4V(MP4HandleImp handle, trakSize *ts)
sl@0
  2591
{
sl@0
  2592
  mp4_u8  *buf;
sl@0
  2593
  mp4_u32  i = 0;
sl@0
  2594
sl@0
  2595
sl@0
  2596
  buf = (mp4_u8 *)mp4malloc(86);
sl@0
  2597
  if (buf == NULL)
sl@0
  2598
    return -1;
sl@0
  2599
sl@0
  2600
  /* Size */
sl@0
  2601
  insertu32(buf+i, (mp4_u32)ts->mp4v);
sl@0
  2602
  i += 4;
sl@0
  2603
sl@0
  2604
  /* Atom type */
sl@0
  2605
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MP4V);
sl@0
  2606
  i += 4;
sl@0
  2607
sl@0
  2608
  /* Reserved */
sl@0
  2609
  buf[i++] = 0;
sl@0
  2610
  buf[i++] = 0;
sl@0
  2611
  buf[i++] = 0;
sl@0
  2612
  buf[i++] = 0;
sl@0
  2613
  buf[i++] = 0;
sl@0
  2614
  buf[i++] = 0;
sl@0
  2615
sl@0
  2616
  /* Data reference index */
sl@0
  2617
  insertu16(buf+i, (mp4_u16)1);
sl@0
  2618
  i += 2;
sl@0
  2619
sl@0
  2620
  /* Reserved */
sl@0
  2621
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2622
  i += 4;
sl@0
  2623
sl@0
  2624
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2625
  i += 4;
sl@0
  2626
sl@0
  2627
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2628
  i += 4;
sl@0
  2629
sl@0
  2630
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2631
  i += 4;
sl@0
  2632
sl@0
  2633
  /* Width */
sl@0
  2634
  insertu16(buf+i, (mp4_u16)handle->videoWidth);
sl@0
  2635
  i += 2;
sl@0
  2636
sl@0
  2637
  /* Height */
sl@0
  2638
  insertu16(buf+i, (mp4_u16)handle->videoHeight);
sl@0
  2639
  i += 2;
sl@0
  2640
sl@0
  2641
  /* Reserved */
sl@0
  2642
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  2643
  i += 4;
sl@0
  2644
sl@0
  2645
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  2646
  i += 4;
sl@0
  2647
sl@0
  2648
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2649
  i += 4;
sl@0
  2650
sl@0
  2651
  insertu16(buf+i, (mp4_u16)1);
sl@0
  2652
  i += 2;
sl@0
  2653
sl@0
  2654
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2655
  i += 4;
sl@0
  2656
sl@0
  2657
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2658
  i += 4;
sl@0
  2659
sl@0
  2660
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2661
  i += 4;
sl@0
  2662
sl@0
  2663
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2664
  i += 4;
sl@0
  2665
sl@0
  2666
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2667
  i += 4;
sl@0
  2668
sl@0
  2669
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2670
  i += 4;
sl@0
  2671
sl@0
  2672
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2673
  i += 4;
sl@0
  2674
sl@0
  2675
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2676
  i += 4;
sl@0
  2677
sl@0
  2678
  insertu16(buf+i, (mp4_u16)24);
sl@0
  2679
  i += 2;
sl@0
  2680
sl@0
  2681
  insertu16(buf+i, (mp4_u16)0xffff);
sl@0
  2682
  i += 2;
sl@0
  2683
sl@0
  2684
  if (writeFile(handle, buf, 86) < 0)
sl@0
  2685
  {
sl@0
  2686
    mp4free(buf);
sl@0
  2687
sl@0
  2688
    return -1;
sl@0
  2689
  }
sl@0
  2690
sl@0
  2691
  if (writeVideoESD(handle, ts) < 0)
sl@0
  2692
  {
sl@0
  2693
    mp4free(buf);
sl@0
  2694
sl@0
  2695
    return -1;
sl@0
  2696
  }
sl@0
  2697
sl@0
  2698
  mp4free(buf);
sl@0
  2699
sl@0
  2700
  return 0;
sl@0
  2701
}
sl@0
  2702
sl@0
  2703
sl@0
  2704
/*
sl@0
  2705
 * Function:
sl@0
  2706
 *
sl@0
  2707
 *   mp4_i32 writeVideoESD(MP4HandleImp handle,
sl@0
  2708
 *                         trakSize *ts)
sl@0
  2709
 *
sl@0
  2710
 * Description:
sl@0
  2711
 *
sl@0
  2712
 *   Write video ESD atom.
sl@0
  2713
 *
sl@0
  2714
 * Parameters:
sl@0
  2715
 *
sl@0
  2716
 *   handle   MP4 library handle
sl@0
  2717
 *   ts       Atom sizes
sl@0
  2718
 *
sl@0
  2719
 * Return value:
sl@0
  2720
 *
sl@0
  2721
 *   0        Success
sl@0
  2722
 *   -1       Error
sl@0
  2723
 *
sl@0
  2724
 */
sl@0
  2725
mp4_i32 writeVideoESD(MP4HandleImp handle, trakSize *ts)
sl@0
  2726
{
sl@0
  2727
  mp4_u8  *buf;
sl@0
  2728
  mp4_u32  i = 0;
sl@0
  2729
sl@0
  2730
sl@0
  2731
  buf = (mp4_u8 *)mp4malloc(ts->esds);
sl@0
  2732
  if (buf == NULL)
sl@0
  2733
    return -1;
sl@0
  2734
sl@0
  2735
  /* Size */
sl@0
  2736
  insertu32(buf+i, (mp4_u32)ts->esds);
sl@0
  2737
  i += 4;
sl@0
  2738
sl@0
  2739
  /* Atom type */
sl@0
  2740
  insertu32(buf+i, (mp4_u32)ATOMTYPE_ESD);
sl@0
  2741
  i += 4;
sl@0
  2742
sl@0
  2743
  /* Version and flags */
sl@0
  2744
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2745
  i += 4;
sl@0
  2746
sl@0
  2747
  /* ES_DescrTag */
sl@0
  2748
  buf[i++] = 0x03;
sl@0
  2749
sl@0
  2750
  /* Size */
sl@0
  2751
  buf[i++] = (mp4_u8)(23 + handle->videoDecSpecificInfoSize);
sl@0
  2752
sl@0
  2753
  /* ES_ID */
sl@0
  2754
  insertu16(buf+i, (mp4_u16)0);
sl@0
  2755
  i += 2;
sl@0
  2756
sl@0
  2757
  /* Flags */
sl@0
  2758
  buf[i++] = 0;
sl@0
  2759
sl@0
  2760
  /* DecoderConfigDescrTag */
sl@0
  2761
  buf[i++] = 0x04;
sl@0
  2762
sl@0
  2763
  /* Size */
sl@0
  2764
  buf[i++] = (mp4_u8)(15 + handle->videoDecSpecificInfoSize);
sl@0
  2765
sl@0
  2766
  /* ObjectTypeIndication */
sl@0
  2767
  buf[i++] = 0x20;
sl@0
  2768
sl@0
  2769
  /* Flags */
sl@0
  2770
  buf[i++] = 0x11;
sl@0
  2771
sl@0
  2772
  /* BufferSizeDB */
sl@0
  2773
  buf[i++] = 0x00;
sl@0
  2774
  buf[i++] = 0x50;
sl@0
  2775
  buf[i++] = 0x00;
sl@0
  2776
sl@0
  2777
  /* MaxBitrate */
sl@0
  2778
  insertu32(buf+i, (mp4_u32)handle->videoMaxBitrate);
sl@0
  2779
  i += 4;
sl@0
  2780
sl@0
  2781
  /* AvgBitrate */
sl@0
  2782
  insertu32(buf+i, (mp4_u32)handle->videoAvgBitrate);
sl@0
  2783
  i += 4;
sl@0
  2784
sl@0
  2785
  /* DecSpecificInfoTag */
sl@0
  2786
  buf[i++] = 0x05;
sl@0
  2787
sl@0
  2788
  /* Size */
sl@0
  2789
  buf[i++] = (mp4_u8)handle->videoDecSpecificInfoSize;
sl@0
  2790
sl@0
  2791
  /* DecoderSpecificInfo */
sl@0
  2792
  mp4memcpy(buf+i, handle->videoDecSpecificInfo, handle->videoDecSpecificInfoSize);
sl@0
  2793
  i += handle->videoDecSpecificInfoSize;
sl@0
  2794
sl@0
  2795
  /* SLConfigDescrTag */
sl@0
  2796
  buf[i++] = 0x06;
sl@0
  2797
sl@0
  2798
  /* Size */
sl@0
  2799
  buf[i++] = 1;
sl@0
  2800
sl@0
  2801
  /* */
sl@0
  2802
  buf[i++] = 2;
sl@0
  2803
sl@0
  2804
  if (writeFile(handle, buf, ts->esds) < 0)
sl@0
  2805
  {
sl@0
  2806
    mp4free(buf);
sl@0
  2807
sl@0
  2808
    return -1;
sl@0
  2809
  }
sl@0
  2810
sl@0
  2811
  mp4free(buf);
sl@0
  2812
sl@0
  2813
  return 0;
sl@0
  2814
}
sl@0
  2815
sl@0
  2816
sl@0
  2817
/*
sl@0
  2818
 * Function:
sl@0
  2819
 *
sl@0
  2820
 *   mp4_i32 writeS263(MP4HandleImp handle,
sl@0
  2821
 *                     trakSize *ts)
sl@0
  2822
 *
sl@0
  2823
 * Description:
sl@0
  2824
 *
sl@0
  2825
 *   Write S263 atom.
sl@0
  2826
 *
sl@0
  2827
 * Parameters:
sl@0
  2828
 *
sl@0
  2829
 *   handle   MP4 library handle
sl@0
  2830
 *   ts       Atom sizes
sl@0
  2831
 *
sl@0
  2832
 * Return value:
sl@0
  2833
 *
sl@0
  2834
 *   0        Success
sl@0
  2835
 *   -1       Error
sl@0
  2836
 *
sl@0
  2837
 */
sl@0
  2838
mp4_i32 writeS263(MP4HandleImp handle, trakSize *ts)
sl@0
  2839
{
sl@0
  2840
  mp4_u8  *buf;
sl@0
  2841
  mp4_u32  i = 0;
sl@0
  2842
sl@0
  2843
sl@0
  2844
  buf = (mp4_u8 *)mp4malloc(86);
sl@0
  2845
  if (buf == NULL)
sl@0
  2846
    return -1;
sl@0
  2847
sl@0
  2848
  /* Size */
sl@0
  2849
  insertu32(buf+i, (mp4_u32)ts->s263);
sl@0
  2850
  i += 4;
sl@0
  2851
sl@0
  2852
  /* Atom type */
sl@0
  2853
  insertu32(buf+i, (mp4_u32)ATOMTYPE_S263);
sl@0
  2854
  i += 4;
sl@0
  2855
sl@0
  2856
  /* Reserved */
sl@0
  2857
  buf[i++] = 0;
sl@0
  2858
  buf[i++] = 0;
sl@0
  2859
  buf[i++] = 0;
sl@0
  2860
  buf[i++] = 0;
sl@0
  2861
  buf[i++] = 0;
sl@0
  2862
  buf[i++] = 0;
sl@0
  2863
sl@0
  2864
  /* Data reference index */
sl@0
  2865
  insertu16(buf+i, (mp4_u16)1);
sl@0
  2866
  i += 2;
sl@0
  2867
sl@0
  2868
  /* Reserved */
sl@0
  2869
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2870
  i += 4;
sl@0
  2871
sl@0
  2872
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2873
  i += 4;
sl@0
  2874
sl@0
  2875
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2876
  i += 4;
sl@0
  2877
sl@0
  2878
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2879
  i += 4;
sl@0
  2880
sl@0
  2881
  /* Width */
sl@0
  2882
  insertu16(buf+i, (mp4_u16)handle->videoWidth);
sl@0
  2883
  i += 2;
sl@0
  2884
sl@0
  2885
  /* Height */
sl@0
  2886
  insertu16(buf+i, (mp4_u16)handle->videoHeight);
sl@0
  2887
  i += 2;
sl@0
  2888
sl@0
  2889
  /* Reserved */
sl@0
  2890
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  2891
  i += 4;
sl@0
  2892
sl@0
  2893
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  2894
  i += 4;
sl@0
  2895
sl@0
  2896
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2897
  i += 4;
sl@0
  2898
sl@0
  2899
  insertu16(buf+i, (mp4_u16)1);
sl@0
  2900
  i += 2;
sl@0
  2901
sl@0
  2902
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2903
  i += 4;
sl@0
  2904
sl@0
  2905
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2906
  i += 4;
sl@0
  2907
sl@0
  2908
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2909
  i += 4;
sl@0
  2910
sl@0
  2911
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2912
  i += 4;
sl@0
  2913
sl@0
  2914
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2915
  i += 4;
sl@0
  2916
sl@0
  2917
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2918
  i += 4;
sl@0
  2919
sl@0
  2920
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2921
  i += 4;
sl@0
  2922
sl@0
  2923
  insertu32(buf+i, (mp4_u32)0);
sl@0
  2924
  i += 4;
sl@0
  2925
sl@0
  2926
  insertu16(buf+i, (mp4_u16)24);
sl@0
  2927
  i += 2;
sl@0
  2928
sl@0
  2929
  insertu16(buf+i, (mp4_u16)0xffff);
sl@0
  2930
  i += 2;
sl@0
  2931
sl@0
  2932
  if (writeFile(handle, buf, 86) < 0)
sl@0
  2933
  {
sl@0
  2934
    mp4free(buf);
sl@0
  2935
sl@0
  2936
    return -1;
sl@0
  2937
  }
sl@0
  2938
sl@0
  2939
  if (writeD263(handle, ts) < 0)
sl@0
  2940
  {
sl@0
  2941
    mp4free(buf);
sl@0
  2942
sl@0
  2943
    return -1;
sl@0
  2944
  }
sl@0
  2945
sl@0
  2946
  mp4free(buf);
sl@0
  2947
sl@0
  2948
  return 0;
sl@0
  2949
}
sl@0
  2950
sl@0
  2951
sl@0
  2952
/*
sl@0
  2953
 * Function:
sl@0
  2954
 *
sl@0
  2955
 *   mp4_i32 writeD263(MP4HandleImp handle,
sl@0
  2956
 *                     trakSize *ts)
sl@0
  2957
 *
sl@0
  2958
 * Description:
sl@0
  2959
 *
sl@0
  2960
 *   Write D263 atom.
sl@0
  2961
 *
sl@0
  2962
 * Parameters:
sl@0
  2963
 *
sl@0
  2964
 *   handle   MP4 library handle
sl@0
  2965
 *   ts       Atom sizes
sl@0
  2966
 *
sl@0
  2967
 * Return value:
sl@0
  2968
 *
sl@0
  2969
 *   0        Success
sl@0
  2970
 *   -1       Error
sl@0
  2971
 *
sl@0
  2972
 */
sl@0
  2973
mp4_i32 writeD263(MP4HandleImp handle, trakSize *ts)
sl@0
  2974
{
sl@0
  2975
  mp4_u8  buf[15];
sl@0
  2976
  mp4_u32  i = 0;
sl@0
  2977
sl@0
  2978
sl@0
  2979
  /* Size */
sl@0
  2980
  insertu32(buf+i, (mp4_u32)ts->d263);
sl@0
  2981
  i += 4;
sl@0
  2982
sl@0
  2983
  /* Atom type */
sl@0
  2984
  insertu32(buf+i, (mp4_u32)ATOMTYPE_D263);
sl@0
  2985
  i += 4;
sl@0
  2986
sl@0
  2987
  /* Vendor */
sl@0
  2988
  buf[i++] = 'S';
sl@0
  2989
  buf[i++] = '6';
sl@0
  2990
  buf[i++] = '0';
sl@0
  2991
  buf[i++] = ' ';
sl@0
  2992
sl@0
  2993
  /* Decoder version */
sl@0
  2994
  buf[i++] = 0;
sl@0
  2995
sl@0
  2996
  /* H263_Level */
sl@0
  2997
  buf[i++] = handle->videoLevel;
sl@0
  2998
sl@0
  2999
  /* H263_Profile */
sl@0
  3000
  if (handle->type & MP4_TYPE_H263_PROFILE_0)
sl@0
  3001
    buf[i++] = 0;
sl@0
  3002
  else if (handle->type & MP4_TYPE_H263_PROFILE_3)
sl@0
  3003
    buf[i++] = 3;
sl@0
  3004
  else
sl@0
  3005
    return -1;
sl@0
  3006
sl@0
  3007
  if (writeFile(handle, buf, 15) < 0)
sl@0
  3008
    return -1;
sl@0
  3009
sl@0
  3010
  return 0;
sl@0
  3011
}
sl@0
  3012
sl@0
  3013
/*
sl@0
  3014
 * Function:
sl@0
  3015
 *
sl@0
  3016
 *   mp4_i32 writeAVC1(MP4HandleImp handle,
sl@0
  3017
 *                     trakSize *ts)
sl@0
  3018
 *
sl@0
  3019
 * Description:
sl@0
  3020
 *
sl@0
  3021
 *   Write AVC1 atom.
sl@0
  3022
 *
sl@0
  3023
 * Parameters:
sl@0
  3024
 *
sl@0
  3025
 *   handle   MP4 library handle
sl@0
  3026
 *   ts       Atom sizes
sl@0
  3027
 *
sl@0
  3028
 * Return value:
sl@0
  3029
 *
sl@0
  3030
 *   0        Success
sl@0
  3031
 *   -1       Error
sl@0
  3032
 *
sl@0
  3033
 */
sl@0
  3034
mp4_i32 writeAVC1(MP4HandleImp handle, trakSize *ts)
sl@0
  3035
{
sl@0
  3036
  mp4_u8  *buf;
sl@0
  3037
  mp4_u32  i = 0;
sl@0
  3038
sl@0
  3039
sl@0
  3040
  buf = (mp4_u8 *)mp4malloc(86);
sl@0
  3041
  if (buf == NULL)
sl@0
  3042
    return -1;
sl@0
  3043
sl@0
  3044
  /* Size */
sl@0
  3045
  insertu32(buf+i, (mp4_u32)ts->avc1);
sl@0
  3046
  i += 4;
sl@0
  3047
sl@0
  3048
  /* Atom type */
sl@0
  3049
  insertu32(buf+i, (mp4_u32)ATOMTYPE_AVC1);
sl@0
  3050
  i += 4;
sl@0
  3051
sl@0
  3052
  /* Reserved */
sl@0
  3053
  buf[i++] = 0;
sl@0
  3054
  buf[i++] = 0;
sl@0
  3055
  buf[i++] = 0;
sl@0
  3056
  buf[i++] = 0;
sl@0
  3057
  buf[i++] = 0;
sl@0
  3058
  buf[i++] = 0;
sl@0
  3059
sl@0
  3060
  /* Data reference index */
sl@0
  3061
  insertu16(buf+i, (mp4_u16)1);
sl@0
  3062
  i += 2;
sl@0
  3063
sl@0
  3064
  /* Reserved */
sl@0
  3065
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3066
  i += 4;
sl@0
  3067
sl@0
  3068
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3069
  i += 4;
sl@0
  3070
sl@0
  3071
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3072
  i += 4;
sl@0
  3073
sl@0
  3074
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3075
  i += 4;
sl@0
  3076
sl@0
  3077
  /* Width */
sl@0
  3078
  insertu16(buf+i, (mp4_u16)handle->videoWidth);
sl@0
  3079
  i += 2;
sl@0
  3080
sl@0
  3081
  /* Height */
sl@0
  3082
  insertu16(buf+i, (mp4_u16)handle->videoHeight);
sl@0
  3083
  i += 2;
sl@0
  3084
sl@0
  3085
  /* H-res (default is 72dpi = 0x00480000) */
sl@0
  3086
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  3087
  i += 4;
sl@0
  3088
sl@0
  3089
  /* V-res (default is 72dpi = 0x00480000) */
sl@0
  3090
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  3091
  i += 4;
sl@0
  3092
sl@0
  3093
  /* Reserved */
sl@0
  3094
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3095
  i += 4;
sl@0
  3096
  
sl@0
  3097
  /* Frame count (default is 1) */
sl@0
  3098
  insertu16(buf+i, (mp4_u16)1);
sl@0
  3099
  i += 2;
sl@0
  3100
sl@0
  3101
  /* Compressor name (32 byte string) */
sl@0
  3102
  // The spec *recommends* inserting "\012AVC Coding" here
sl@0
  3103
  // but we just have a string of nulls.
sl@0
  3104
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3105
  i += 4;
sl@0
  3106
sl@0
  3107
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3108
  i += 4;
sl@0
  3109
sl@0
  3110
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3111
  i += 4;
sl@0
  3112
sl@0
  3113
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3114
  i += 4;
sl@0
  3115
sl@0
  3116
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3117
  i += 4;
sl@0
  3118
sl@0
  3119
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3120
  i += 4;
sl@0
  3121
sl@0
  3122
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3123
  i += 4;
sl@0
  3124
sl@0
  3125
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3126
  i += 4;
sl@0
  3127
sl@0
  3128
  /* Depth (default is 0x0018 which indicates colour images with no alpha) */
sl@0
  3129
  insertu16(buf+i, (mp4_u16)24);
sl@0
  3130
  i += 2;
sl@0
  3131
sl@0
  3132
  /* Pre-defined (-1) */
sl@0
  3133
  insertu16(buf+i, (mp4_u16)0xffff);
sl@0
  3134
  i += 2;
sl@0
  3135
sl@0
  3136
  if (writeFile(handle, buf, 86) < 0)
sl@0
  3137
  {
sl@0
  3138
    mp4free(buf);
sl@0
  3139
sl@0
  3140
    return -1;
sl@0
  3141
  }
sl@0
  3142
sl@0
  3143
  if (writeAVCC(handle, ts) < 0)
sl@0
  3144
  {
sl@0
  3145
    mp4free(buf);
sl@0
  3146
sl@0
  3147
    return -1;
sl@0
  3148
  }
sl@0
  3149
sl@0
  3150
  /* Note: If necessary, include writing of btrt and m4ds atoms. */
sl@0
  3151
sl@0
  3152
  mp4free(buf);
sl@0
  3153
sl@0
  3154
  return 0;
sl@0
  3155
}
sl@0
  3156
sl@0
  3157
/*
sl@0
  3158
 * Function:
sl@0
  3159
 *
sl@0
  3160
 *   mp4_i32 writeAVCC(MP4HandleImp handle,
sl@0
  3161
 *                     trakSize *ts)
sl@0
  3162
 *
sl@0
  3163
 * Description:
sl@0
  3164
 *
sl@0
  3165
 *   Write AVCC atom.
sl@0
  3166
 *
sl@0
  3167
 * Parameters:
sl@0
  3168
 *
sl@0
  3169
 *   handle   MP4 library handle
sl@0
  3170
 *   ts       Atom sizes
sl@0
  3171
 *
sl@0
  3172
 * Return value:
sl@0
  3173
 *
sl@0
  3174
 *   0        Success
sl@0
  3175
 *   -1       Error
sl@0
  3176
 *
sl@0
  3177
 */
sl@0
  3178
mp4_i32 writeAVCC(MP4HandleImp handle, trakSize *ts)
sl@0
  3179
{
sl@0
  3180
  mp4_u8  *buf;
sl@0
  3181
  mp4_u32  i = 0;
sl@0
  3182
sl@0
  3183
sl@0
  3184
  buf = (mp4_u8 *)mp4malloc(ts->avcc);
sl@0
  3185
  if (buf == NULL)
sl@0
  3186
    return -1;
sl@0
  3187
sl@0
  3188
  /* Size */
sl@0
  3189
  insertu32(buf+i, (mp4_u32)ts->avcc);
sl@0
  3190
  i += 4;
sl@0
  3191
sl@0
  3192
  /* Atom type */
sl@0
  3193
  insertu32(buf+i, (mp4_u32)ATOMTYPE_AVCC);
sl@0
  3194
  i += 4;
sl@0
  3195
sl@0
  3196
  /*mp4memcpy(buf+i, handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfig, 
sl@0
  3197
									 handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize);*/
sl@0
  3198
  
sl@0
  3199
  mp4memcpy(buf+i, handle->videoDecSpecificInfo, handle->videoDecSpecificInfoSize);
sl@0
  3200
sl@0
  3201
  /*i += handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize;*/
sl@0
  3202
sl@0
  3203
  i += handle->videoDecSpecificInfoSize;
sl@0
  3204
sl@0
  3205
  if (writeFile(handle, buf, ts->avcc) < 0)
sl@0
  3206
  {
sl@0
  3207
    mp4free(buf);
sl@0
  3208
sl@0
  3209
    return -1;
sl@0
  3210
  }
sl@0
  3211
sl@0
  3212
  mp4free(buf);
sl@0
  3213
sl@0
  3214
  return 0;
sl@0
  3215
}
sl@0
  3216
sl@0
  3217
sl@0
  3218
/*
sl@0
  3219
 * Function:
sl@0
  3220
 *
sl@0
  3221
 *   mp4_i32 writeVideoSTTS(MP4HandleImp handle,
sl@0
  3222
 *                          trakSize *ts)
sl@0
  3223
 *
sl@0
  3224
 * Description:
sl@0
  3225
 *
sl@0
  3226
 *   Write video STTS atom.
sl@0
  3227
 *
sl@0
  3228
 * Parameters:
sl@0
  3229
 *
sl@0
  3230
 *   handle   MP4 library handle
sl@0
  3231
 *   ts       Atom sizes
sl@0
  3232
 *
sl@0
  3233
 * Return value:
sl@0
  3234
 *
sl@0
  3235
 *   0        Success
sl@0
  3236
 *   -1       Error
sl@0
  3237
 *
sl@0
  3238
 */
sl@0
  3239
mp4_i32 writeVideoSTTS(MP4HandleImp handle, trakSize *ts)
sl@0
  3240
{
sl@0
  3241
  mp4_u8   *buf;
sl@0
  3242
  mp4_u32  i = 0;
sl@0
  3243
  mp4_u32  j;
sl@0
  3244
sl@0
  3245
sl@0
  3246
  buf = (mp4_u8 *)mp4malloc(ts->stts);
sl@0
  3247
  if (buf == NULL)
sl@0
  3248
    return -1;
sl@0
  3249
sl@0
  3250
  /* Size */
sl@0
  3251
  insertu32(buf+i, (mp4_u32)ts->stts);
sl@0
  3252
  i += 4;
sl@0
  3253
sl@0
  3254
  /* Atom type */
sl@0
  3255
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
sl@0
  3256
  i += 4;
sl@0
  3257
sl@0
  3258
  /* Version and flags */
sl@0
  3259
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3260
  i += 4;
sl@0
  3261
sl@0
  3262
  /* Entry count */
sl@0
  3263
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsEntryCount);
sl@0
  3264
  i += 4;
sl@0
  3265
sl@0
  3266
  /* Sample count and sample delta */
sl@0
  3267
  for (j = 0; j < handle->videoSampleTable->sttsEntryCount; j++)
sl@0
  3268
  {
sl@0
  3269
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsSampleCount[j]);
sl@0
  3270
    i += 4;
sl@0
  3271
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsSampleDelta[j]);
sl@0
  3272
    i += 4;
sl@0
  3273
  }
sl@0
  3274
sl@0
  3275
  if (writeFile(handle, buf, ts->stts) < 0)
sl@0
  3276
  {
sl@0
  3277
    mp4free(buf);
sl@0
  3278
sl@0
  3279
    return -1;
sl@0
  3280
  }
sl@0
  3281
sl@0
  3282
  mp4free(buf);
sl@0
  3283
sl@0
  3284
  return 0;
sl@0
  3285
}
sl@0
  3286
sl@0
  3287
sl@0
  3288
/*
sl@0
  3289
 * Function:
sl@0
  3290
 *
sl@0
  3291
 *   mp4_i32 writeVideoSTTSLongClip(MP4HandleImp handle,
sl@0
  3292
 *                                  trakSize *ts)
sl@0
  3293
 *
sl@0
  3294
 * Description:
sl@0
  3295
 *
sl@0
  3296
 *   Write video STTS atom.
sl@0
  3297
 *
sl@0
  3298
 * Parameters:
sl@0
  3299
 *
sl@0
  3300
 *   handle   MP4 library handle
sl@0
  3301
 *   ts       Atom sizes
sl@0
  3302
 *
sl@0
  3303
 * Return value:
sl@0
  3304
 *
sl@0
  3305
 *   0        Success
sl@0
  3306
 *   -1       Error
sl@0
  3307
 *
sl@0
  3308
 */
sl@0
  3309
mp4_i32 writeVideoSTTSLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  3310
{
sl@0
  3311
  mp4_u8   *buf;
sl@0
  3312
  mp4_u8   *buf2;
sl@0
  3313
  mp4_u32  i = 0;
sl@0
  3314
  mp4_u32  j;
sl@0
  3315
  mp4_u32  left;
sl@0
  3316
  mp4_u32  bytestoread;
sl@0
  3317
sl@0
  3318
sl@0
  3319
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  3320
  if (buf == NULL)
sl@0
  3321
    return -1;
sl@0
  3322
sl@0
  3323
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
sl@0
  3324
  if (buf2 == NULL)
sl@0
  3325
    {
sl@0
  3326
    mp4free(buf);
sl@0
  3327
    return -1;
sl@0
  3328
    }
sl@0
  3329
sl@0
  3330
  /* Size */
sl@0
  3331
  insertu32(buf+i, (mp4_u32)ts->stts);
sl@0
  3332
  i += 4;
sl@0
  3333
sl@0
  3334
  /* Atom type */
sl@0
  3335
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
sl@0
  3336
  i += 4;
sl@0
  3337
sl@0
  3338
  /* Version and flags */
sl@0
  3339
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3340
  i += 4;
sl@0
  3341
sl@0
  3342
  /* Entry count */
sl@0
  3343
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->sttsEntryCount);
sl@0
  3344
  i += 4;
sl@0
  3345
sl@0
  3346
  if (writeFile(handle, buf, i) < 0)
sl@0
  3347
  {
sl@0
  3348
    mp4free(buf);
sl@0
  3349
    mp4free(buf2);
sl@0
  3350
sl@0
  3351
    return -1;
sl@0
  3352
  }
sl@0
  3353
sl@0
  3354
  /* Sample count and delta */
sl@0
  3355
sl@0
  3356
  /* Seek to the beginning of temporary files */
sl@0
  3357
sl@0
  3358
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
sl@0
  3359
      {
sl@0
  3360
      mp4free(buf);
sl@0
  3361
      mp4free(buf2);
sl@0
  3362
      return -1;
sl@0
  3363
      }
sl@0
  3364
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
sl@0
  3365
      {
sl@0
  3366
      mp4free(buf);
sl@0
  3367
      mp4free(buf2);
sl@0
  3368
      return -1;
sl@0
  3369
      }
sl@0
  3370
sl@0
  3371
  left = handle->videoSampleTable->sttsEntryCount * 4; /* Bytes left in each file */
sl@0
  3372
sl@0
  3373
  while (left)
sl@0
  3374
  {
sl@0
  3375
    if (left > METADATA_COPY_BUFFERSIZE / 2)
sl@0
  3376
      bytestoread = METADATA_COPY_BUFFERSIZE / 2;
sl@0
  3377
    else
sl@0
  3378
      bytestoread = left;
sl@0
  3379
sl@0
  3380
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
sl@0
  3381
    {
sl@0
  3382
      mp4free(buf);
sl@0
  3383
      mp4free(buf2);
sl@0
  3384
sl@0
  3385
      return -1;
sl@0
  3386
    }
sl@0
  3387
sl@0
  3388
    for (j = 0; j < bytestoread; j += 4)
sl@0
  3389
    {
sl@0
  3390
      insertu32(buf + 2*j, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  3391
    }
sl@0
  3392
sl@0
  3393
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
sl@0
  3394
    {
sl@0
  3395
      mp4free(buf);
sl@0
  3396
      mp4free(buf2);
sl@0
  3397
sl@0
  3398
      return -1;
sl@0
  3399
    }
sl@0
  3400
sl@0
  3401
    for (j = 0; j < bytestoread; j += 4)
sl@0
  3402
    {
sl@0
  3403
      insertu32(buf + 2*j + 4, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  3404
    }
sl@0
  3405
sl@0
  3406
    if (writeFile(handle, buf, 2 * bytestoread) < 0)
sl@0
  3407
    {
sl@0
  3408
      mp4free(buf);
sl@0
  3409
      mp4free(buf2);
sl@0
  3410
sl@0
  3411
      return -1;
sl@0
  3412
    }
sl@0
  3413
sl@0
  3414
    left -= bytestoread;
sl@0
  3415
  }
sl@0
  3416
sl@0
  3417
  mp4free(buf);
sl@0
  3418
  mp4free(buf2);
sl@0
  3419
sl@0
  3420
sl@0
  3421
  return 0;
sl@0
  3422
}
sl@0
  3423
sl@0
  3424
sl@0
  3425
/*
sl@0
  3426
 * Function:
sl@0
  3427
 *
sl@0
  3428
 *   mp4_i32 writeVideoSTSC(MP4HandleImp handle,
sl@0
  3429
 *                          trakSize *ts)
sl@0
  3430
 *
sl@0
  3431
 * Description:
sl@0
  3432
 *
sl@0
  3433
 *   Write video STSC atom.
sl@0
  3434
 *
sl@0
  3435
 * Parameters:
sl@0
  3436
 *
sl@0
  3437
 *   handle   MP4 library handle
sl@0
  3438
 *   ts       Atom sizes
sl@0
  3439
 *
sl@0
  3440
 * Return value:
sl@0
  3441
 *
sl@0
  3442
 *   0        Success
sl@0
  3443
 *   -1       Error
sl@0
  3444
 *
sl@0
  3445
 */
sl@0
  3446
mp4_i32 writeVideoSTSC(MP4HandleImp handle, trakSize *ts)
sl@0
  3447
{
sl@0
  3448
  mp4_u8   *buf;
sl@0
  3449
  mp4_u32  i = 0;
sl@0
  3450
  mp4_u32  j;
sl@0
  3451
sl@0
  3452
sl@0
  3453
  buf = (mp4_u8 *)mp4malloc(ts->stsc);
sl@0
  3454
  if (buf == NULL)
sl@0
  3455
    return -1;
sl@0
  3456
sl@0
  3457
  /* Size */
sl@0
  3458
  insertu32(buf+i, (mp4_u32)ts->stsc);
sl@0
  3459
  i += 4;
sl@0
  3460
sl@0
  3461
  /* Atom type */
sl@0
  3462
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSC);
sl@0
  3463
  i += 4;
sl@0
  3464
sl@0
  3465
  /* Version and flags */
sl@0
  3466
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3467
  i += 4;
sl@0
  3468
sl@0
  3469
  /* Entry count */
sl@0
  3470
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscEntryCount);
sl@0
  3471
  i += 4;
sl@0
  3472
sl@0
  3473
  /* First chunk, samples per chunk and sample description index */
sl@0
  3474
  for (j = 0; j < handle->videoSampleTable->stscEntryCount; j++)
sl@0
  3475
  {
sl@0
  3476
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscFirstChunk[j]);
sl@0
  3477
    i += 4;
sl@0
  3478
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscSamplesPerChunk[j]);
sl@0
  3479
    i += 4;
sl@0
  3480
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stscSampleDescriptionIndex[j]);
sl@0
  3481
    i += 4;
sl@0
  3482
  }
sl@0
  3483
sl@0
  3484
  if (writeFile(handle, buf, ts->stsc) < 0)
sl@0
  3485
  {
sl@0
  3486
    mp4free(buf);
sl@0
  3487
sl@0
  3488
    return -1;
sl@0
  3489
  }
sl@0
  3490
sl@0
  3491
  mp4free(buf);
sl@0
  3492
sl@0
  3493
  return 0;
sl@0
  3494
}
sl@0
  3495
sl@0
  3496
sl@0
  3497
/*
sl@0
  3498
 * Function:
sl@0
  3499
 *
sl@0
  3500
 *   mp4_i32 writeVideoSTSZ(MP4HandleImp handle,
sl@0
  3501
 *                          trakSize *ts)
sl@0
  3502
 *
sl@0
  3503
 * Description:
sl@0
  3504
 *
sl@0
  3505
 *   Write video STSZ atom.
sl@0
  3506
 *
sl@0
  3507
 * Parameters:
sl@0
  3508
 *
sl@0
  3509
 *   handle   MP4 library handle
sl@0
  3510
 *   ts       Atom sizes
sl@0
  3511
 *
sl@0
  3512
 * Return value:
sl@0
  3513
 *
sl@0
  3514
 *   0        Success
sl@0
  3515
 *   -1       Error
sl@0
  3516
 *
sl@0
  3517
 */
sl@0
  3518
mp4_i32 writeVideoSTSZ(MP4HandleImp handle, trakSize *ts)
sl@0
  3519
{
sl@0
  3520
  mp4_u8  *buf;
sl@0
  3521
  mp4_u32  i = 0;
sl@0
  3522
  mp4_u32  j;
sl@0
  3523
sl@0
  3524
sl@0
  3525
  buf = (mp4_u8 *)mp4malloc(ts->stsz);
sl@0
  3526
  if (buf == NULL)
sl@0
  3527
    return -1;
sl@0
  3528
sl@0
  3529
  /* Size */
sl@0
  3530
  insertu32(buf+i, (mp4_u32)ts->stsz);
sl@0
  3531
  i += 4;
sl@0
  3532
sl@0
  3533
  /* Atom type */
sl@0
  3534
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
sl@0
  3535
  i += 4;
sl@0
  3536
sl@0
  3537
  /* Version and flags */
sl@0
  3538
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3539
  i += 4;
sl@0
  3540
sl@0
  3541
  /* Sample size */
sl@0
  3542
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleSize);
sl@0
  3543
  i += 4;
sl@0
  3544
sl@0
  3545
  /* Sample count */
sl@0
  3546
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleCount);
sl@0
  3547
  i += 4;
sl@0
  3548
sl@0
  3549
  /* Entry sizes */
sl@0
  3550
  if (handle->videoSampleTable->stszSampleSize == 0)
sl@0
  3551
  {
sl@0
  3552
    for (j = 0; j < handle->videoSampleTable->stszSampleCount; j++)
sl@0
  3553
    {
sl@0
  3554
      insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszEntrySize[j]);
sl@0
  3555
      i += 4;
sl@0
  3556
    }
sl@0
  3557
  }
sl@0
  3558
sl@0
  3559
  if (writeFile(handle, buf, ts->stsz) < 0)
sl@0
  3560
  {
sl@0
  3561
    mp4free(buf);
sl@0
  3562
sl@0
  3563
    return -1;
sl@0
  3564
  }
sl@0
  3565
sl@0
  3566
  mp4free(buf);
sl@0
  3567
sl@0
  3568
  return 0;
sl@0
  3569
}
sl@0
  3570
sl@0
  3571
sl@0
  3572
/*
sl@0
  3573
 * Function:
sl@0
  3574
 *
sl@0
  3575
 *   mp4_i32 writeVideoSTSZLongClip(MP4HandleImp handle,
sl@0
  3576
 *                                  trakSize *ts)
sl@0
  3577
 *
sl@0
  3578
 * Description:
sl@0
  3579
 *
sl@0
  3580
 *   Write video STSZ atom.
sl@0
  3581
 *
sl@0
  3582
 * Parameters:
sl@0
  3583
 *
sl@0
  3584
 *   handle   MP4 library handle
sl@0
  3585
 *   ts       Atom sizes
sl@0
  3586
 *
sl@0
  3587
 * Return value:
sl@0
  3588
 *
sl@0
  3589
 *   0        Success
sl@0
  3590
 *   -1       Error
sl@0
  3591
 *
sl@0
  3592
 */
sl@0
  3593
mp4_i32 writeVideoSTSZLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  3594
{
sl@0
  3595
  mp4_u8  *buf;
sl@0
  3596
  mp4_u8  *buf2;
sl@0
  3597
  mp4_u32  i = 0;
sl@0
  3598
  mp4_u32  j;
sl@0
  3599
  mp4_u32  left;
sl@0
  3600
  mp4_u32  bytestoread;
sl@0
  3601
sl@0
  3602
sl@0
  3603
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  3604
  if (buf == NULL)
sl@0
  3605
    return -1;
sl@0
  3606
sl@0
  3607
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  3608
  if (buf2 == NULL)
sl@0
  3609
    {
sl@0
  3610
    mp4free(buf);
sl@0
  3611
    return -1;
sl@0
  3612
    }
sl@0
  3613
sl@0
  3614
  /* Size */
sl@0
  3615
  insertu32(buf+i, (mp4_u32)ts->stsz);
sl@0
  3616
  i += 4;
sl@0
  3617
sl@0
  3618
  /* Atom type */
sl@0
  3619
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
sl@0
  3620
  i += 4;
sl@0
  3621
sl@0
  3622
  /* Version and flags */
sl@0
  3623
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3624
  i += 4;
sl@0
  3625
sl@0
  3626
  /* Sample size */
sl@0
  3627
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleSize);
sl@0
  3628
  i += 4;
sl@0
  3629
sl@0
  3630
  /* Sample count */
sl@0
  3631
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stszSampleCount);
sl@0
  3632
  i += 4;
sl@0
  3633
sl@0
  3634
  if (writeFile(handle, buf, i) < 0)
sl@0
  3635
  {
sl@0
  3636
    mp4free(buf);
sl@0
  3637
    mp4free(buf2);
sl@0
  3638
sl@0
  3639
    return -1;
sl@0
  3640
  }
sl@0
  3641
sl@0
  3642
  /* Entry sizes */
sl@0
  3643
sl@0
  3644
  if (handle->videoSampleTable->stszSampleSize == 0)
sl@0
  3645
  {
sl@0
  3646
    /* Seek to the beginning of temporary file */
sl@0
  3647
sl@0
  3648
    if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
sl@0
  3649
        {
sl@0
  3650
        mp4free(buf);
sl@0
  3651
        mp4free(buf2);
sl@0
  3652
        return -1;
sl@0
  3653
        }
sl@0
  3654
sl@0
  3655
    left = handle->videoSampleTable->stszSampleCount * 4; /* Bytes left in the file */
sl@0
  3656
sl@0
  3657
    while (left)
sl@0
  3658
    {
sl@0
  3659
      if (left > METADATA_COPY_BUFFERSIZE)
sl@0
  3660
        bytestoread = METADATA_COPY_BUFFERSIZE;
sl@0
  3661
      else
sl@0
  3662
        bytestoread = left;
sl@0
  3663
sl@0
  3664
      if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
sl@0
  3665
      {
sl@0
  3666
        mp4free(buf);
sl@0
  3667
        mp4free(buf2);
sl@0
  3668
sl@0
  3669
        return -1;
sl@0
  3670
      }
sl@0
  3671
sl@0
  3672
      for (j = 0; j < bytestoread; j += 4)
sl@0
  3673
      {
sl@0
  3674
        insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  3675
      }
sl@0
  3676
sl@0
  3677
      if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  3678
      {
sl@0
  3679
        mp4free(buf);
sl@0
  3680
        mp4free(buf2);
sl@0
  3681
sl@0
  3682
        return -1;
sl@0
  3683
      }
sl@0
  3684
sl@0
  3685
      left -= bytestoread;
sl@0
  3686
    }
sl@0
  3687
  }
sl@0
  3688
sl@0
  3689
  mp4free(buf);
sl@0
  3690
  mp4free(buf2);
sl@0
  3691
sl@0
  3692
sl@0
  3693
  return 0;
sl@0
  3694
}
sl@0
  3695
sl@0
  3696
sl@0
  3697
/*
sl@0
  3698
 * Function:
sl@0
  3699
 *
sl@0
  3700
 *   mp4_i32 writeVideoSTCO(MP4HandleImp handle,
sl@0
  3701
 *                          trakSize *ts)
sl@0
  3702
 *
sl@0
  3703
 * Description:
sl@0
  3704
 *
sl@0
  3705
 *   Write video STCO atom.
sl@0
  3706
 *
sl@0
  3707
 * Parameters:
sl@0
  3708
 *
sl@0
  3709
 *   handle   MP4 library handle
sl@0
  3710
 *   ts       Atom sizes
sl@0
  3711
 *
sl@0
  3712
 * Return value:
sl@0
  3713
 *
sl@0
  3714
 *   0        Success
sl@0
  3715
 *   -1       Error
sl@0
  3716
 *
sl@0
  3717
 */
sl@0
  3718
mp4_i32 writeVideoSTCO(MP4HandleImp handle, trakSize *ts)
sl@0
  3719
{
sl@0
  3720
  mp4_u8  *buf;
sl@0
  3721
  mp4_u32  i = 0;
sl@0
  3722
  mp4_u32  j;
sl@0
  3723
sl@0
  3724
sl@0
  3725
  buf = (mp4_u8 *)mp4malloc(ts->stco);
sl@0
  3726
  if (buf == NULL)
sl@0
  3727
    return -1;
sl@0
  3728
sl@0
  3729
  /* Size */
sl@0
  3730
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  3731
  i += 4;
sl@0
  3732
sl@0
  3733
  /* Atom type */
sl@0
  3734
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
sl@0
  3735
  i += 4;
sl@0
  3736
sl@0
  3737
  /* Version and flags */
sl@0
  3738
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3739
  i += 4;
sl@0
  3740
sl@0
  3741
  /* Entry count */
sl@0
  3742
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
sl@0
  3743
  i += 4;
sl@0
  3744
sl@0
  3745
  /* Chunk offsets */
sl@0
  3746
  for (j = 0; j < handle->videoSampleTable->stcoEntryCount; j++)
sl@0
  3747
  {
sl@0
  3748
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoChunkOffset[j]);
sl@0
  3749
    i += 4;
sl@0
  3750
  }
sl@0
  3751
sl@0
  3752
  if (writeFile(handle, buf, ts->stco) < 0)
sl@0
  3753
  {
sl@0
  3754
    mp4free(buf);
sl@0
  3755
sl@0
  3756
    return -1;
sl@0
  3757
  }
sl@0
  3758
sl@0
  3759
  mp4free(buf);
sl@0
  3760
sl@0
  3761
  return 0;
sl@0
  3762
}
sl@0
  3763
sl@0
  3764
/*
sl@0
  3765
 * Function:
sl@0
  3766
 *
sl@0
  3767
 *   mp4_i32 writeVideoCO64(MP4HandleImp handle,
sl@0
  3768
 *                          trakSize *ts)
sl@0
  3769
 *
sl@0
  3770
 * Description:
sl@0
  3771
 *
sl@0
  3772
 *   Write video CO64 atom.
sl@0
  3773
 *
sl@0
  3774
 * Parameters:
sl@0
  3775
 *
sl@0
  3776
 *   handle   MP4 library handle
sl@0
  3777
 *   ts       Atom sizes
sl@0
  3778
 *
sl@0
  3779
 * Return value:
sl@0
  3780
 *
sl@0
  3781
 *   0        Success
sl@0
  3782
 *   -1       Error
sl@0
  3783
 *
sl@0
  3784
 */
sl@0
  3785
mp4_i32 writeVideoCO64(MP4HandleImp handle, trakSize *ts)
sl@0
  3786
{
sl@0
  3787
  mp4_u8  *buf;
sl@0
  3788
  mp4_u32  i = 0;
sl@0
  3789
  mp4_u32  j;
sl@0
  3790
sl@0
  3791
sl@0
  3792
  buf = (mp4_u8 *)mp4malloc(ts->stco);
sl@0
  3793
  if (buf == NULL)
sl@0
  3794
    return -1;
sl@0
  3795
sl@0
  3796
  /* Size */
sl@0
  3797
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  3798
  i += 4;
sl@0
  3799
sl@0
  3800
  /* Atom type */
sl@0
  3801
  insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
sl@0
  3802
  i += 4;
sl@0
  3803
sl@0
  3804
  /* Version and flags */
sl@0
  3805
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3806
  i += 4;
sl@0
  3807
sl@0
  3808
  /* Entry count */
sl@0
  3809
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
sl@0
  3810
  i += 4;
sl@0
  3811
sl@0
  3812
  /* Chunk offsets */
sl@0
  3813
  for (j = 0; j < handle->videoSampleTable->stcoEntryCount; j++)
sl@0
  3814
  {
sl@0
  3815
    insertu64(buf+i, (mp4_u64)handle->videoSampleTable->stcoChunkOffset[j]);
sl@0
  3816
    i += 8;
sl@0
  3817
  }
sl@0
  3818
sl@0
  3819
  if (writeFile(handle, buf, ts->stco) < 0)
sl@0
  3820
  {
sl@0
  3821
    mp4free(buf);
sl@0
  3822
sl@0
  3823
    return -1;
sl@0
  3824
  }
sl@0
  3825
sl@0
  3826
  mp4free(buf);
sl@0
  3827
sl@0
  3828
  return 0;
sl@0
  3829
}
sl@0
  3830
sl@0
  3831
/*
sl@0
  3832
 * Function:
sl@0
  3833
 *
sl@0
  3834
 *   mp4_i32 writeVideoSTCOLongClip(MP4HandleImp handle,
sl@0
  3835
 *                                  trakSize *ts)
sl@0
  3836
 *
sl@0
  3837
 * Description:
sl@0
  3838
 *
sl@0
  3839
 *   Write video STCO atom.
sl@0
  3840
 *
sl@0
  3841
 * Parameters:
sl@0
  3842
 *
sl@0
  3843
 *   handle   MP4 library handle
sl@0
  3844
 *   ts       Atom sizes
sl@0
  3845
 *
sl@0
  3846
 * Return value:
sl@0
  3847
 *
sl@0
  3848
 *   0        Success
sl@0
  3849
 *   -1       Error
sl@0
  3850
 *
sl@0
  3851
 */
sl@0
  3852
mp4_i32 writeVideoSTCOLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  3853
{
sl@0
  3854
  mp4_u8   *buf;
sl@0
  3855
  mp4_u8   *buf2;
sl@0
  3856
  mp4_u32  i = 0;
sl@0
  3857
  mp4_u32  j;
sl@0
  3858
  mp4_u32  left;
sl@0
  3859
  mp4_u32  bytestoread;
sl@0
  3860
  mp4_u32  bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
sl@0
  3861
  																					  //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
sl@0
  3862
	
sl@0
  3863
  buf = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  3864
  if (buf == NULL)
sl@0
  3865
    return -1;
sl@0
  3866
sl@0
  3867
  buf2 = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  3868
  if (buf2 == NULL)
sl@0
  3869
    {
sl@0
  3870
    mp4free(buf);
sl@0
  3871
    return -1;
sl@0
  3872
    }
sl@0
  3873
sl@0
  3874
  /* Size */
sl@0
  3875
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  3876
  i += 4;
sl@0
  3877
sl@0
  3878
  /* Atom type */
sl@0
  3879
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
sl@0
  3880
  i += 4;
sl@0
  3881
sl@0
  3882
  /* Version and flags */
sl@0
  3883
  insertu32(buf+i, (mp4_u32)0);
sl@0
  3884
  i += 4;
sl@0
  3885
sl@0
  3886
  /* Entry count */
sl@0
  3887
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
sl@0
  3888
  i += 4;
sl@0
  3889
sl@0
  3890
  if (writeFile(handle, buf, i) < 0)
sl@0
  3891
  {
sl@0
  3892
    mp4free(buf);
sl@0
  3893
    mp4free(buf2);
sl@0
  3894
sl@0
  3895
    return -1;
sl@0
  3896
  }
sl@0
  3897
sl@0
  3898
  /* Chunk offsets */
sl@0
  3899
sl@0
  3900
  /* Seek to the beginning of temporary file */
sl@0
  3901
sl@0
  3902
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
sl@0
  3903
    {
sl@0
  3904
    mp4free(buf);
sl@0
  3905
    mp4free(buf2);
sl@0
  3906
    return -1;
sl@0
  3907
    }
sl@0
  3908
sl@0
  3909
  left = handle->videoSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
sl@0
  3910
sl@0
  3911
  while (left)
sl@0
  3912
  {
sl@0
  3913
    if (left > bufferSize)
sl@0
  3914
      bytestoread = bufferSize;
sl@0
  3915
    else
sl@0
  3916
      bytestoread = left;
sl@0
  3917
sl@0
  3918
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
sl@0
  3919
    {
sl@0
  3920
      mp4free(buf);
sl@0
  3921
      mp4free(buf2);
sl@0
  3922
sl@0
  3923
      return -1;
sl@0
  3924
    }
sl@0
  3925
sl@0
  3926
    for (j = 0; j < bytestoread; j += 8)
sl@0
  3927
    {
sl@0
  3928
      ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
sl@0
  3929
      insertu32(buf + j/2, ((mp4_u64 *)buf2)[j / 8]);
sl@0
  3930
    }
sl@0
  3931
sl@0
  3932
    if (writeFile(handle, buf, bytestoread/2) < 0)
sl@0
  3933
    {
sl@0
  3934
      mp4free(buf);
sl@0
  3935
      mp4free(buf2);
sl@0
  3936
sl@0
  3937
      return -1;
sl@0
  3938
    }
sl@0
  3939
sl@0
  3940
    left -= bytestoread;
sl@0
  3941
  }
sl@0
  3942
sl@0
  3943
  mp4free(buf);
sl@0
  3944
  mp4free(buf2);
sl@0
  3945
sl@0
  3946
sl@0
  3947
  return 0;
sl@0
  3948
}
sl@0
  3949
sl@0
  3950
/*
sl@0
  3951
 * Function:
sl@0
  3952
 *
sl@0
  3953
 *   mp4_i32 writeVideoCO64LongClip(MP4HandleImp handle,
sl@0
  3954
 *                                  trakSize *ts)
sl@0
  3955
 *
sl@0
  3956
 * Description:
sl@0
  3957
 *
sl@0
  3958
 *   Write video CO64 atom.
sl@0
  3959
 *
sl@0
  3960
 * Parameters:
sl@0
  3961
 *
sl@0
  3962
 *   handle   MP4 library handle
sl@0
  3963
 *   ts       Atom sizes
sl@0
  3964
 *
sl@0
  3965
 * Return value:
sl@0
  3966
 *
sl@0
  3967
 *   0        Success
sl@0
  3968
 *   -1       Error
sl@0
  3969
 *
sl@0
  3970
 */
sl@0
  3971
mp4_i32 writeVideoCO64LongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  3972
{
sl@0
  3973
  mp4_u8   *buf;
sl@0
  3974
  mp4_u8   *buf2;
sl@0
  3975
  mp4_u32  i = 0;
sl@0
  3976
  mp4_u32  j;
sl@0
  3977
  mp4_u32  left;
sl@0
  3978
  mp4_u32  bytestoread;
sl@0
  3979
  mp4_u32  bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
sl@0
  3980
  																					  //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
sl@0
  3981
	
sl@0
  3982
  buf = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  3983
  if (buf == NULL)
sl@0
  3984
    return -1;
sl@0
  3985
sl@0
  3986
  buf2 = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  3987
  if (buf2 == NULL)
sl@0
  3988
    {
sl@0
  3989
    mp4free(buf);
sl@0
  3990
    return -1;
sl@0
  3991
    }
sl@0
  3992
sl@0
  3993
  /* Size */
sl@0
  3994
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  3995
  i += 4;
sl@0
  3996
sl@0
  3997
  /* Atom type */
sl@0
  3998
  insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
sl@0
  3999
  i += 4;
sl@0
  4000
sl@0
  4001
  /* Version and flags */
sl@0
  4002
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4003
  i += 4;
sl@0
  4004
sl@0
  4005
  /* Entry count */
sl@0
  4006
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stcoEntryCount);
sl@0
  4007
  i += 4;
sl@0
  4008
sl@0
  4009
  if (writeFile(handle, buf, i) < 0)
sl@0
  4010
  {
sl@0
  4011
    mp4free(buf);
sl@0
  4012
    mp4free(buf2);
sl@0
  4013
sl@0
  4014
    return -1;
sl@0
  4015
  }
sl@0
  4016
sl@0
  4017
  /* Chunk offsets */
sl@0
  4018
sl@0
  4019
  /* Seek to the beginning of temporary file */
sl@0
  4020
sl@0
  4021
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
sl@0
  4022
    {
sl@0
  4023
    mp4free(buf);
sl@0
  4024
    mp4free(buf2);
sl@0
  4025
    return -1;
sl@0
  4026
    }
sl@0
  4027
sl@0
  4028
  left = handle->videoSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
sl@0
  4029
sl@0
  4030
  while (left)
sl@0
  4031
  {
sl@0
  4032
    if (left > bufferSize)
sl@0
  4033
      bytestoread = bufferSize;
sl@0
  4034
    else
sl@0
  4035
      bytestoread = left;
sl@0
  4036
sl@0
  4037
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
sl@0
  4038
    {
sl@0
  4039
      mp4free(buf);
sl@0
  4040
      mp4free(buf2);
sl@0
  4041
sl@0
  4042
      return -1;
sl@0
  4043
    }
sl@0
  4044
sl@0
  4045
    for (j = 0; j < bytestoread; j += 8)
sl@0
  4046
    {
sl@0
  4047
      ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
sl@0
  4048
      insertu64(buf + j, ((mp4_u64 *)buf2)[j / 8]);
sl@0
  4049
    }
sl@0
  4050
sl@0
  4051
    if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  4052
    {
sl@0
  4053
      mp4free(buf);
sl@0
  4054
      mp4free(buf2);
sl@0
  4055
sl@0
  4056
      return -1;
sl@0
  4057
    }
sl@0
  4058
sl@0
  4059
    left -= bytestoread;
sl@0
  4060
  }
sl@0
  4061
sl@0
  4062
  mp4free(buf);
sl@0
  4063
  mp4free(buf2);
sl@0
  4064
sl@0
  4065
sl@0
  4066
  return 0;
sl@0
  4067
}
sl@0
  4068
sl@0
  4069
/*
sl@0
  4070
 * Function:
sl@0
  4071
 *
sl@0
  4072
 *   mp4_i32 writeVideoSTSS(MP4HandleImp handle,
sl@0
  4073
 *                          trakSize *ts)
sl@0
  4074
 *
sl@0
  4075
 * Description:
sl@0
  4076
 *
sl@0
  4077
 *   Write video STSS atom.
sl@0
  4078
 *
sl@0
  4079
 * Parameters:
sl@0
  4080
 *
sl@0
  4081
 *   handle   MP4 library handle
sl@0
  4082
 *   ts       Atom sizes
sl@0
  4083
 *
sl@0
  4084
 * Return value:
sl@0
  4085
 *
sl@0
  4086
 *   0        Success
sl@0
  4087
 *   -1       Error
sl@0
  4088
 *
sl@0
  4089
 */
sl@0
  4090
mp4_i32 writeVideoSTSS(MP4HandleImp handle, trakSize *ts)
sl@0
  4091
{
sl@0
  4092
  mp4_u8  *buf;
sl@0
  4093
  mp4_u32  i = 0;
sl@0
  4094
  mp4_u32  j;
sl@0
  4095
sl@0
  4096
sl@0
  4097
  buf = (mp4_u8 *)mp4malloc(ts->stss);
sl@0
  4098
  if (buf == NULL)
sl@0
  4099
    return -1;
sl@0
  4100
sl@0
  4101
  /* Size */
sl@0
  4102
  insertu32(buf+i, (mp4_u32)ts->stss);
sl@0
  4103
  i += 4;
sl@0
  4104
sl@0
  4105
  /* Atom type */
sl@0
  4106
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSS);
sl@0
  4107
  i += 4;
sl@0
  4108
sl@0
  4109
  /* Version and flags */
sl@0
  4110
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4111
  i += 4;
sl@0
  4112
sl@0
  4113
  /* Entry count */
sl@0
  4114
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssEntryCount);
sl@0
  4115
  i += 4;
sl@0
  4116
sl@0
  4117
  /* Sample numbers */
sl@0
  4118
  for (j = 0; j < handle->videoSampleTable->stssEntryCount; j++)
sl@0
  4119
  {
sl@0
  4120
    insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssSampleNumber[j]);
sl@0
  4121
    i += 4;
sl@0
  4122
  }
sl@0
  4123
sl@0
  4124
  if (writeFile(handle, buf, ts->stss) < 0)
sl@0
  4125
  {
sl@0
  4126
    mp4free(buf);
sl@0
  4127
sl@0
  4128
    return -1;
sl@0
  4129
  }
sl@0
  4130
sl@0
  4131
  mp4free(buf);
sl@0
  4132
sl@0
  4133
  return 0;
sl@0
  4134
}
sl@0
  4135
sl@0
  4136
sl@0
  4137
/*
sl@0
  4138
 * Function:
sl@0
  4139
 *
sl@0
  4140
 *   mp4_i32 writeVideoSTSSLongClip(MP4HandleImp handle,
sl@0
  4141
 *                                  trakSize *ts)
sl@0
  4142
 *
sl@0
  4143
 * Description:
sl@0
  4144
 *
sl@0
  4145
 *   Write video STSS atom.
sl@0
  4146
 *
sl@0
  4147
 * Parameters:
sl@0
  4148
 *
sl@0
  4149
 *   handle   MP4 library handle
sl@0
  4150
 *   ts       Atom sizes
sl@0
  4151
 *
sl@0
  4152
 * Return value:
sl@0
  4153
 *
sl@0
  4154
 *   0        Success
sl@0
  4155
 *   -1       Error
sl@0
  4156
 *
sl@0
  4157
 */
sl@0
  4158
mp4_i32 writeVideoSTSSLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  4159
{
sl@0
  4160
  mp4_u8   *buf;
sl@0
  4161
  mp4_u8   *buf2;
sl@0
  4162
  mp4_u32  i = 0;
sl@0
  4163
  mp4_u32  j;
sl@0
  4164
  mp4_u32  left;
sl@0
  4165
  mp4_u32  bytestoread;
sl@0
  4166
sl@0
  4167
sl@0
  4168
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  4169
  if (buf == NULL)
sl@0
  4170
    return -1;
sl@0
  4171
sl@0
  4172
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  4173
  if (buf2 == NULL)
sl@0
  4174
      {
sl@0
  4175
      mp4free(buf);
sl@0
  4176
      return -1;
sl@0
  4177
      }
sl@0
  4178
sl@0
  4179
  /* Size */
sl@0
  4180
  insertu32(buf+i, (mp4_u32)ts->stss);
sl@0
  4181
  i += 4;
sl@0
  4182
sl@0
  4183
  /* Atom type */
sl@0
  4184
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSS);
sl@0
  4185
  i += 4;
sl@0
  4186
sl@0
  4187
  /* Version and flags */
sl@0
  4188
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4189
  i += 4;
sl@0
  4190
sl@0
  4191
  /* Entry count */
sl@0
  4192
  insertu32(buf+i, (mp4_u32)handle->videoSampleTable->stssEntryCount);
sl@0
  4193
  i += 4;
sl@0
  4194
sl@0
  4195
  if (writeFile(handle, buf, i) < 0)
sl@0
  4196
  {
sl@0
  4197
    mp4free(buf);
sl@0
  4198
    mp4free(buf2);
sl@0
  4199
sl@0
  4200
    return -1;
sl@0
  4201
  }
sl@0
  4202
sl@0
  4203
  /* Sample numbers */
sl@0
  4204
sl@0
  4205
  /* Seek to the beginning of temporary file */
sl@0
  4206
sl@0
  4207
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
sl@0
  4208
    {
sl@0
  4209
    mp4free(buf);
sl@0
  4210
    mp4free(buf2);
sl@0
  4211
    return -1;
sl@0
  4212
    }
sl@0
  4213
sl@0
  4214
  left = handle->videoSampleTable->stssEntryCount * 4; /* Bytes left in the file */
sl@0
  4215
sl@0
  4216
  while (left)
sl@0
  4217
  {
sl@0
  4218
    if (left > METADATA_COPY_BUFFERSIZE)
sl@0
  4219
      bytestoread = METADATA_COPY_BUFFERSIZE;
sl@0
  4220
    else
sl@0
  4221
      bytestoread = left;
sl@0
  4222
sl@0
  4223
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
sl@0
  4224
    {
sl@0
  4225
      mp4free(buf);
sl@0
  4226
      mp4free(buf2);
sl@0
  4227
sl@0
  4228
      return -1;
sl@0
  4229
    }
sl@0
  4230
sl@0
  4231
    for (j = 0; j < bytestoread; j += 4)
sl@0
  4232
    {
sl@0
  4233
      insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  4234
    }
sl@0
  4235
sl@0
  4236
    if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  4237
    {
sl@0
  4238
      mp4free(buf);
sl@0
  4239
      mp4free(buf2);
sl@0
  4240
sl@0
  4241
      return -1;
sl@0
  4242
    }
sl@0
  4243
sl@0
  4244
    left -= bytestoread;
sl@0
  4245
  }
sl@0
  4246
sl@0
  4247
  mp4free(buf);
sl@0
  4248
  mp4free(buf2);
sl@0
  4249
sl@0
  4250
sl@0
  4251
  return 0;
sl@0
  4252
}
sl@0
  4253
sl@0
  4254
sl@0
  4255
/*
sl@0
  4256
 * Function:
sl@0
  4257
 *
sl@0
  4258
 *   mp4_i32 writeAudioTrak(MP4HandleImp handle,
sl@0
  4259
 *                          trakSize *ts)
sl@0
  4260
 *
sl@0
  4261
 * Description:
sl@0
  4262
 *
sl@0
  4263
 *   Write audio track atom.
sl@0
  4264
 *
sl@0
  4265
 * Parameters:
sl@0
  4266
 *
sl@0
  4267
 *   handle   MP4 library handle
sl@0
  4268
 *   ts       Atom sizes
sl@0
  4269
 *
sl@0
  4270
 * Return value:
sl@0
  4271
 *
sl@0
  4272
 *   0        Success
sl@0
  4273
 *   -1       Error
sl@0
  4274
 *
sl@0
  4275
 */
sl@0
  4276
mp4_i32 writeAudioTrak(MP4HandleImp handle, trakSize *ts)
sl@0
  4277
{
sl@0
  4278
  mp4_u8  buf[8];
sl@0
  4279
  mp4_u32  i = 0;
sl@0
  4280
sl@0
  4281
sl@0
  4282
  /* Size */
sl@0
  4283
  insertu32(buf+i, (mp4_u32)ts->trak);
sl@0
  4284
  i += 4;
sl@0
  4285
sl@0
  4286
  /* Atom type */
sl@0
  4287
  insertu32(buf+i, (mp4_u32)ATOMTYPE_TRAK);
sl@0
  4288
  i += 4;
sl@0
  4289
sl@0
  4290
  if (writeFile(handle, buf, 8) < 0)
sl@0
  4291
    return -1;
sl@0
  4292
sl@0
  4293
  if (writeAudioTKHD(handle, ts) < 0)
sl@0
  4294
    return -1;
sl@0
  4295
sl@0
  4296
  if (writeAudioMDIA(handle, ts) < 0)
sl@0
  4297
    return -1;
sl@0
  4298
  
sl@0
  4299
  if (handle->audioUDTA)
sl@0
  4300
    {
sl@0
  4301
    if (writeUDTA(handle, handle->audioUDTA) < 0)
sl@0
  4302
        return -1;
sl@0
  4303
    }  
sl@0
  4304
sl@0
  4305
  return 0;
sl@0
  4306
}
sl@0
  4307
sl@0
  4308
sl@0
  4309
/*
sl@0
  4310
 * Function:
sl@0
  4311
 *
sl@0
  4312
 *   mp4_i32 writeAudioTKHD(MP4HandleImp handle,
sl@0
  4313
 *                          trakSize *ts)
sl@0
  4314
 *
sl@0
  4315
 * Description:
sl@0
  4316
 *
sl@0
  4317
 *   Write audio TKHD atom.
sl@0
  4318
 *
sl@0
  4319
 * Parameters:
sl@0
  4320
 *
sl@0
  4321
 *   handle   MP4 library handle
sl@0
  4322
 *   ts       Atom sizes
sl@0
  4323
 *
sl@0
  4324
 * Return value:
sl@0
  4325
 *
sl@0
  4326
 *   0        Success
sl@0
  4327
 *   -1       Error
sl@0
  4328
 *
sl@0
  4329
 */
sl@0
  4330
mp4_i32 writeAudioTKHD(MP4HandleImp handle, trakSize *ts)
sl@0
  4331
{
sl@0
  4332
  mp4_u8      *buf;
sl@0
  4333
  mp4_u32     i = 0;
sl@0
  4334
  mp4_u32     u32;
sl@0
  4335
  mp4_double  ud;
sl@0
  4336
sl@0
  4337
sl@0
  4338
  buf = (mp4_u8 *)mp4malloc(ts->tkhd);
sl@0
  4339
  if (buf == NULL)
sl@0
  4340
    return -1;
sl@0
  4341
sl@0
  4342
  /* Size */
sl@0
  4343
  insertu32(buf+i, (mp4_u32)ts->tkhd);
sl@0
  4344
  i += 4;
sl@0
  4345
sl@0
  4346
  /* Atom type */
sl@0
  4347
  insertu32(buf+i, (mp4_u32)ATOMTYPE_TKHD);
sl@0
  4348
  i += 4;
sl@0
  4349
sl@0
  4350
  
sl@0
  4351
  if (handle->audioDuration > MP4_INT_MAX)
sl@0
  4352
  {
sl@0
  4353
      mp4_u64     u64;
sl@0
  4354
      /* Version and flags */
sl@0
  4355
      buf[i++] = 1;
sl@0
  4356
      buf[i++] = 0;
sl@0
  4357
      buf[i++] = 0;
sl@0
  4358
      buf[i++] = 7;  /* Track enabled, used in movie and preview */
sl@0
  4359
    
sl@0
  4360
      /* Creation time */
sl@0
  4361
      if (getCurrentTime(&u32) < 0)
sl@0
  4362
        u32 = 0;
sl@0
  4363
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  4364
      i += 8;
sl@0
  4365
    
sl@0
  4366
      /* Modification time */
sl@0
  4367
      if (getCurrentTime(&u32) < 0)
sl@0
  4368
        u32 = 0;
sl@0
  4369
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  4370
      i += 8;
sl@0
  4371
    
sl@0
  4372
      /* Track ID */
sl@0
  4373
      insertu32(buf+i, (mp4_u32)2);
sl@0
  4374
      i += 4;
sl@0
  4375
    
sl@0
  4376
      /* Reserved */
sl@0
  4377
      insertu32(buf+i, (mp4_u32)0);
sl@0
  4378
      i += 4;
sl@0
  4379
    
sl@0
  4380
      /* Duration */
sl@0
  4381
      if ( ( handle->audioTimeScale == 0 ) || ( handle->audioDuration == 0 ) )
sl@0
  4382
          {
sl@0
  4383
          ud = 0;
sl@0
  4384
          }
sl@0
  4385
      else
sl@0
  4386
          {
sl@0
  4387
          ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->audioDuration / (mp4_double)handle->audioTimeScale + (mp4_double)0.5;
sl@0
  4388
          }
sl@0
  4389
      u64 = (mp4_u64)ud;
sl@0
  4390
      insertu64(buf+i, u64);
sl@0
  4391
      i += 8;
sl@0
  4392
sl@0
  4393
  }
sl@0
  4394
  else
sl@0
  4395
  {
sl@0
  4396
      /* Version and flags */
sl@0
  4397
      buf[i++] = 0;
sl@0
  4398
      buf[i++] = 0;
sl@0
  4399
      buf[i++] = 0;
sl@0
  4400
      buf[i++] = 7;  /* Track enabled, used in movie and preview */
sl@0
  4401
    
sl@0
  4402
      /* Creation time */
sl@0
  4403
      if (getCurrentTime(&u32) < 0)
sl@0
  4404
        u32 = 0;
sl@0
  4405
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  4406
      i += 4;
sl@0
  4407
    
sl@0
  4408
      /* Modification time */
sl@0
  4409
      if (getCurrentTime(&u32) < 0)
sl@0
  4410
        u32 = 0;
sl@0
  4411
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  4412
      i += 4;
sl@0
  4413
    
sl@0
  4414
      /* Track ID */
sl@0
  4415
      insertu32(buf+i, (mp4_u32)2);
sl@0
  4416
      i += 4;
sl@0
  4417
    
sl@0
  4418
      /* Reserved */
sl@0
  4419
      insertu32(buf+i, (mp4_u32)0);
sl@0
  4420
      i += 4;
sl@0
  4421
    
sl@0
  4422
      /* Duration */
sl@0
  4423
      if ( ( handle->audioTimeScale == 0 ) || ( handle->audioDuration == 0 ) )
sl@0
  4424
          {
sl@0
  4425
          ud = 0;
sl@0
  4426
          }
sl@0
  4427
      else
sl@0
  4428
          {
sl@0
  4429
          ud = (mp4_double)MVHD_TIMESCALE * (mp4_double)handle->audioDuration / (mp4_double)handle->audioTimeScale + (mp4_double)0.5;
sl@0
  4430
          }
sl@0
  4431
      u32 = (mp4_u32)ud;
sl@0
  4432
      insertu32(buf+i, u32);
sl@0
  4433
      i += 4;
sl@0
  4434
  }
sl@0
  4435
  /* Reserved */
sl@0
  4436
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4437
  i += 4;
sl@0
  4438
sl@0
  4439
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4440
  i += 4;
sl@0
  4441
sl@0
  4442
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4443
  i += 4;
sl@0
  4444
sl@0
  4445
  insertu16(buf+i, (mp4_u16)0x0100);  /* Audio track */
sl@0
  4446
  i += 2;
sl@0
  4447
sl@0
  4448
  insertu16(buf+i, (mp4_u16)0);
sl@0
  4449
  i += 2;
sl@0
  4450
sl@0
  4451
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  4452
  i += 4;
sl@0
  4453
sl@0
  4454
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4455
  i += 4;
sl@0
  4456
sl@0
  4457
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4458
  i += 4;
sl@0
  4459
sl@0
  4460
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4461
  i += 4;
sl@0
  4462
sl@0
  4463
  insertu32(buf+i, (mp4_u32)0x00010000);
sl@0
  4464
  i += 4;
sl@0
  4465
sl@0
  4466
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4467
  i += 4;
sl@0
  4468
sl@0
  4469
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4470
  i += 4;
sl@0
  4471
sl@0
  4472
  insertu32(buf+i, (mp4_u32)0x00000000);
sl@0
  4473
  i += 4;
sl@0
  4474
sl@0
  4475
  insertu32(buf+i, (mp4_u32)0x40000000);
sl@0
  4476
  i += 4;
sl@0
  4477
sl@0
  4478
  insertu32(buf+i, (mp4_u32)0);  /* Audio track */
sl@0
  4479
  i += 4;
sl@0
  4480
sl@0
  4481
  insertu32(buf+i, (mp4_u32)0);  /* Audio track */
sl@0
  4482
  i += 4;
sl@0
  4483
sl@0
  4484
  if (writeFile(handle, buf, ts->tkhd) < 0)
sl@0
  4485
  {
sl@0
  4486
    mp4free(buf);
sl@0
  4487
sl@0
  4488
    return -1;
sl@0
  4489
  }
sl@0
  4490
sl@0
  4491
  mp4free(buf);
sl@0
  4492
sl@0
  4493
  return 0;
sl@0
  4494
}
sl@0
  4495
sl@0
  4496
sl@0
  4497
/*
sl@0
  4498
 * Function:
sl@0
  4499
 *
sl@0
  4500
 *   mp4_i32 writeAudioMDIA(MP4HandleImp handle,
sl@0
  4501
 *                          trakSize *ts)
sl@0
  4502
 *
sl@0
  4503
 * Description:
sl@0
  4504
 *
sl@0
  4505
 *   Write audio MDIA atom.
sl@0
  4506
 *
sl@0
  4507
 * Parameters:
sl@0
  4508
 *
sl@0
  4509
 *   handle   MP4 library handle
sl@0
  4510
 *   ts       Atom sizes
sl@0
  4511
 *
sl@0
  4512
 * Return value:
sl@0
  4513
 *
sl@0
  4514
 *   0        Success
sl@0
  4515
 *   -1       Error
sl@0
  4516
 *
sl@0
  4517
 */
sl@0
  4518
mp4_i32 writeAudioMDIA(MP4HandleImp handle, trakSize *ts)
sl@0
  4519
{
sl@0
  4520
  mp4_u8  buf[8];
sl@0
  4521
  mp4_u32  i = 0;
sl@0
  4522
sl@0
  4523
sl@0
  4524
  /* Size */
sl@0
  4525
  insertu32(buf+i, (mp4_u32)ts->mdia);
sl@0
  4526
  i += 4;
sl@0
  4527
sl@0
  4528
  /* Atom type */
sl@0
  4529
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MDIA);
sl@0
  4530
  i += 4;
sl@0
  4531
sl@0
  4532
  if (writeFile(handle, buf, 8) < 0)
sl@0
  4533
    return -1;
sl@0
  4534
sl@0
  4535
  if (writeAudioMDHD(handle, ts) < 0)
sl@0
  4536
    return -1;
sl@0
  4537
sl@0
  4538
  if (writeAudioHDLR(handle, ts) < 0)
sl@0
  4539
    return -1;
sl@0
  4540
sl@0
  4541
  if (writeAudioMINF(handle, ts) < 0)
sl@0
  4542
    return -1;
sl@0
  4543
sl@0
  4544
  return 0;
sl@0
  4545
}
sl@0
  4546
sl@0
  4547
sl@0
  4548
/*
sl@0
  4549
 * Function:
sl@0
  4550
 *
sl@0
  4551
 *   mp4_i32 writeAudioMDHD(MP4HandleImp handle,
sl@0
  4552
 *                          trakSize *ts)
sl@0
  4553
 *
sl@0
  4554
 * Description:
sl@0
  4555
 *
sl@0
  4556
 *   Write audio MDHD atom.
sl@0
  4557
 *
sl@0
  4558
 * Parameters:
sl@0
  4559
 *
sl@0
  4560
 *   handle   MP4 library handle
sl@0
  4561
 *   ts       Atom sizes
sl@0
  4562
 *
sl@0
  4563
 * Return value:
sl@0
  4564
 *
sl@0
  4565
 *   0        Success
sl@0
  4566
 *   -1       Error
sl@0
  4567
 *
sl@0
  4568
 */
sl@0
  4569
mp4_i32 writeAudioMDHD(MP4HandleImp handle, trakSize *ts)
sl@0
  4570
{
sl@0
  4571
  mp4_u8  *buf;
sl@0
  4572
  mp4_u32  i = 0;
sl@0
  4573
  mp4_u32  u32;
sl@0
  4574
sl@0
  4575
sl@0
  4576
  buf = (mp4_u8 *)mp4malloc(ts->mdhd);
sl@0
  4577
  if (buf == NULL)
sl@0
  4578
    return -1;
sl@0
  4579
sl@0
  4580
  /* Size */
sl@0
  4581
  insertu32(buf+i, (mp4_u32)ts->mdhd);
sl@0
  4582
  i += 4;
sl@0
  4583
sl@0
  4584
  /* Atom type */
sl@0
  4585
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MDHD);
sl@0
  4586
  i += 4;
sl@0
  4587
sl@0
  4588
  if (handle->audioDuration > MP4_INT_MAX)
sl@0
  4589
  {
sl@0
  4590
      /* Version and flags */
sl@0
  4591
      insertu32(buf+i, (mp4_u32)0x1000000);     //version 1 atom
sl@0
  4592
      i += 4;
sl@0
  4593
    
sl@0
  4594
      /* Creation time */
sl@0
  4595
      if (getCurrentTime(&u32) < 0)
sl@0
  4596
        u32 = 0;
sl@0
  4597
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  4598
      i += 8;
sl@0
  4599
    
sl@0
  4600
      /* Modification time */
sl@0
  4601
      if (getCurrentTime(&u32) < 0)
sl@0
  4602
        u32 = 0;
sl@0
  4603
      insertu64(buf+i, (mp4_u64)u32);
sl@0
  4604
      i += 8;
sl@0
  4605
    
sl@0
  4606
      /* Timescale */
sl@0
  4607
      insertu32(buf+i, (mp4_u32)handle->audioTimeScale);
sl@0
  4608
      i += 4;
sl@0
  4609
    
sl@0
  4610
      /* Duration */
sl@0
  4611
      insertu64(buf+i, handle->audioDuration);
sl@0
  4612
      i += 8;
sl@0
  4613
      
sl@0
  4614
  }
sl@0
  4615
  else
sl@0
  4616
  {
sl@0
  4617
      /* Version and flags */
sl@0
  4618
      insertu32(buf+i, (mp4_u32)0);
sl@0
  4619
      i += 4;
sl@0
  4620
    
sl@0
  4621
      /* Creation time */
sl@0
  4622
      if (getCurrentTime(&u32) < 0)
sl@0
  4623
        u32 = 0;
sl@0
  4624
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  4625
      i += 4;
sl@0
  4626
    
sl@0
  4627
      /* Modification time */
sl@0
  4628
      if (getCurrentTime(&u32) < 0)
sl@0
  4629
        u32 = 0;
sl@0
  4630
      insertu32(buf+i, (mp4_u32)u32);
sl@0
  4631
      i += 4;
sl@0
  4632
    
sl@0
  4633
      /* Timescale */
sl@0
  4634
      insertu32(buf+i, (mp4_u32)handle->audioTimeScale);
sl@0
  4635
      i += 4;
sl@0
  4636
    
sl@0
  4637
      /* Duration */
sl@0
  4638
      insertu32(buf+i, (mp4_u32)handle->audioDuration);
sl@0
  4639
      i += 4;
sl@0
  4640
  }
sl@0
  4641
sl@0
  4642
  /* Language */
sl@0
  4643
  insertu16(buf+i, (mp4_u16)0x55c4); /* 'und' */
sl@0
  4644
  i += 2;
sl@0
  4645
sl@0
  4646
  /* Reserved */
sl@0
  4647
  insertu16(buf+i, (mp4_u16)0x0000);
sl@0
  4648
  i += 2;
sl@0
  4649
sl@0
  4650
  if (writeFile(handle, buf, ts->mdhd) < 0)
sl@0
  4651
  {
sl@0
  4652
    mp4free(buf);
sl@0
  4653
sl@0
  4654
    return -1;
sl@0
  4655
  }
sl@0
  4656
sl@0
  4657
  mp4free(buf);
sl@0
  4658
sl@0
  4659
  return 0;
sl@0
  4660
}
sl@0
  4661
sl@0
  4662
sl@0
  4663
/*
sl@0
  4664
 * Function:
sl@0
  4665
 *
sl@0
  4666
 *   mp4_i32 writeAudioHDLR(MP4HandleImp handle,
sl@0
  4667
 *                          trakSize *ts)
sl@0
  4668
 *
sl@0
  4669
 * Description:
sl@0
  4670
 *
sl@0
  4671
 *   Write audio HDLR atom.
sl@0
  4672
 *
sl@0
  4673
 * Parameters:
sl@0
  4674
 *
sl@0
  4675
 *   handle   MP4 library handle
sl@0
  4676
 *   ts       Atom sizes
sl@0
  4677
 *
sl@0
  4678
 * Return value:
sl@0
  4679
 *
sl@0
  4680
 *   0        Success
sl@0
  4681
 *   -1       Error
sl@0
  4682
 *
sl@0
  4683
 */
sl@0
  4684
mp4_i32 writeAudioHDLR(MP4HandleImp handle, trakSize *ts)
sl@0
  4685
{
sl@0
  4686
  mp4_u8  *buf;
sl@0
  4687
  mp4_u32  i = 0;
sl@0
  4688
sl@0
  4689
sl@0
  4690
  buf = (mp4_u8 *)mp4malloc(ts->hdlr);
sl@0
  4691
  if (buf == NULL)
sl@0
  4692
    return -1;
sl@0
  4693
sl@0
  4694
  /* Size */
sl@0
  4695
  insertu32(buf+i, (mp4_u32)ts->hdlr);
sl@0
  4696
  i += 4;
sl@0
  4697
sl@0
  4698
  /* Atom type */
sl@0
  4699
  insertu32(buf+i, (mp4_u32)ATOMTYPE_HDLR);
sl@0
  4700
  i += 4;
sl@0
  4701
sl@0
  4702
  /* Version and flags */
sl@0
  4703
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4704
  i += 4;
sl@0
  4705
sl@0
  4706
  /* Reserved */
sl@0
  4707
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4708
  i += 4;
sl@0
  4709
sl@0
  4710
  /* Handler type */
sl@0
  4711
  buf[i++] = 's';
sl@0
  4712
  buf[i++] = 'o';
sl@0
  4713
  buf[i++] = 'u';
sl@0
  4714
  buf[i++] = 'n';
sl@0
  4715
sl@0
  4716
  /* Reserved */
sl@0
  4717
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4718
  i += 4;
sl@0
  4719
sl@0
  4720
  /* Reserved */
sl@0
  4721
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4722
  i += 4;
sl@0
  4723
sl@0
  4724
  /* Reserved */
sl@0
  4725
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4726
  i += 4;
sl@0
  4727
sl@0
  4728
  /* Empty string */
sl@0
  4729
  buf[i++] = 0;
sl@0
  4730
sl@0
  4731
  if (writeFile(handle, buf, ts->hdlr) < 0)
sl@0
  4732
  {
sl@0
  4733
    mp4free(buf);
sl@0
  4734
sl@0
  4735
    return -1;
sl@0
  4736
  }
sl@0
  4737
sl@0
  4738
  mp4free(buf);
sl@0
  4739
sl@0
  4740
  return 0;
sl@0
  4741
}
sl@0
  4742
sl@0
  4743
sl@0
  4744
/*
sl@0
  4745
 * Function:
sl@0
  4746
 *
sl@0
  4747
 *   mp4_i32 writeAudioMINF(MP4HandleImp handle,
sl@0
  4748
 *                          trakSize *ts)
sl@0
  4749
 *
sl@0
  4750
 * Description:
sl@0
  4751
 *
sl@0
  4752
 *   Write audio MINF atom.
sl@0
  4753
 *
sl@0
  4754
 * Parameters:
sl@0
  4755
 *
sl@0
  4756
 *   handle   MP4 library handle
sl@0
  4757
 *   ts       Atom sizes
sl@0
  4758
 *
sl@0
  4759
 * Return value:
sl@0
  4760
 *
sl@0
  4761
 *   0        Success
sl@0
  4762
 *   -1       Error
sl@0
  4763
 *
sl@0
  4764
 */
sl@0
  4765
mp4_i32 writeAudioMINF(MP4HandleImp handle, trakSize *ts)
sl@0
  4766
{
sl@0
  4767
  mp4_u8  buf[8];
sl@0
  4768
  mp4_u32  i = 0;
sl@0
  4769
sl@0
  4770
sl@0
  4771
  /* Size */
sl@0
  4772
  insertu32(buf+i, (mp4_u32)ts->minf);
sl@0
  4773
  i += 4;
sl@0
  4774
sl@0
  4775
  /* Atom type */
sl@0
  4776
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MINF);
sl@0
  4777
  i += 4;
sl@0
  4778
sl@0
  4779
  if (writeFile(handle, buf, 8) < 0)
sl@0
  4780
    return -1;
sl@0
  4781
sl@0
  4782
  if (writeSMHD(handle, ts) < 0)
sl@0
  4783
    return -1;
sl@0
  4784
sl@0
  4785
  if (writeDINF(handle, ts) < 0)
sl@0
  4786
    return -1;
sl@0
  4787
sl@0
  4788
  if (writeAudioSTBL(handle, ts) < 0)
sl@0
  4789
    return -1;
sl@0
  4790
sl@0
  4791
  return 0;
sl@0
  4792
}
sl@0
  4793
sl@0
  4794
sl@0
  4795
/*
sl@0
  4796
 * Function:
sl@0
  4797
 *
sl@0
  4798
 *   mp4_i32  writeSMHD(MP4HandleImp handle,
sl@0
  4799
 *                      trakSize *ts)
sl@0
  4800
 *
sl@0
  4801
 * Description:
sl@0
  4802
 *
sl@0
  4803
 *   Write SMHD atom.
sl@0
  4804
 *
sl@0
  4805
 * Parameters:
sl@0
  4806
 *
sl@0
  4807
 *   handle   MP4 library handle
sl@0
  4808
 *   ts       Atom sizes
sl@0
  4809
 *
sl@0
  4810
 * Return value:
sl@0
  4811
 *
sl@0
  4812
 *   0        Success
sl@0
  4813
 *   -1       Error
sl@0
  4814
 *
sl@0
  4815
 */
sl@0
  4816
mp4_i32  writeSMHD(MP4HandleImp handle, trakSize *ts)
sl@0
  4817
{
sl@0
  4818
  mp4_u8  *buf;
sl@0
  4819
  mp4_u32  i = 0;
sl@0
  4820
sl@0
  4821
sl@0
  4822
  buf = (mp4_u8 *)mp4malloc(ts->smhd);
sl@0
  4823
  if (buf == NULL)
sl@0
  4824
    return -1;
sl@0
  4825
sl@0
  4826
  /* Size */
sl@0
  4827
  insertu32(buf+i, (mp4_u32)ts->smhd);
sl@0
  4828
  i += 4;
sl@0
  4829
sl@0
  4830
  /* Atom type */
sl@0
  4831
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SMHD);
sl@0
  4832
  i += 4;
sl@0
  4833
sl@0
  4834
  /* Version and flags */
sl@0
  4835
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4836
  i += 4;
sl@0
  4837
sl@0
  4838
  /* Reserved */
sl@0
  4839
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4840
  i += 4;
sl@0
  4841
sl@0
  4842
  if (writeFile(handle, buf, ts->smhd) < 0)
sl@0
  4843
  {
sl@0
  4844
    mp4free(buf);
sl@0
  4845
sl@0
  4846
    return -1;
sl@0
  4847
  }
sl@0
  4848
sl@0
  4849
  mp4free(buf);
sl@0
  4850
sl@0
  4851
  return 0;
sl@0
  4852
}
sl@0
  4853
sl@0
  4854
sl@0
  4855
/*
sl@0
  4856
 * Function:
sl@0
  4857
 *
sl@0
  4858
 *   mp4_i32 writeAudioSTBL(MP4HandleImp handle,
sl@0
  4859
 *                          trakSize *ts)
sl@0
  4860
 *
sl@0
  4861
 * Description:
sl@0
  4862
 *
sl@0
  4863
 *   Write audio STBL atom.
sl@0
  4864
 *
sl@0
  4865
 * Parameters:
sl@0
  4866
 *
sl@0
  4867
 *   handle   MP4 library handle
sl@0
  4868
 *   ts       Atom sizes
sl@0
  4869
 *
sl@0
  4870
 * Return value:
sl@0
  4871
 *
sl@0
  4872
 *   0        Success
sl@0
  4873
 *   -1       Error
sl@0
  4874
 *
sl@0
  4875
 */
sl@0
  4876
mp4_i32 writeAudioSTBL(MP4HandleImp handle, trakSize *ts)
sl@0
  4877
{
sl@0
  4878
  mp4_u8  buf[8];
sl@0
  4879
  mp4_u32  i = 0;
sl@0
  4880
sl@0
  4881
sl@0
  4882
  /* Size */
sl@0
  4883
  insertu32(buf+i, (mp4_u32)ts->stbl);
sl@0
  4884
  i += 4;
sl@0
  4885
sl@0
  4886
  /* Atom type */
sl@0
  4887
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STBL);
sl@0
  4888
  i += 4;
sl@0
  4889
sl@0
  4890
  if (writeFile(handle, buf, 8) < 0)
sl@0
  4891
    return -1;
sl@0
  4892
sl@0
  4893
  if (writeAudioSTSD(handle, ts) < 0)
sl@0
  4894
    return -1;
sl@0
  4895
sl@0
  4896
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
  4897
  {
sl@0
  4898
    if (writeAudioSTTSLongClip(handle, ts) < 0)
sl@0
  4899
      return -1;
sl@0
  4900
  }
sl@0
  4901
  else
sl@0
  4902
  {
sl@0
  4903
    if (writeAudioSTTS(handle, ts) < 0)
sl@0
  4904
      return -1;
sl@0
  4905
  }
sl@0
  4906
sl@0
  4907
  if (writeAudioSTSC(handle, ts) < 0)
sl@0
  4908
    return -1;
sl@0
  4909
sl@0
  4910
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
  4911
  {
sl@0
  4912
    if (writeAudioSTSZLongClip(handle, ts) < 0)
sl@0
  4913
      return -1;
sl@0
  4914
    
sl@0
  4915
	if (handle->audioSampleTable->stcoNeed64Bits)
sl@0
  4916
	{
sl@0
  4917
	  if (writeAudioCO64LongClip(handle, ts) < 0)
sl@0
  4918
      	return -1;
sl@0
  4919
	}
sl@0
  4920
	else
sl@0
  4921
	{
sl@0
  4922
	  if (writeAudioSTCOLongClip(handle, ts) < 0)
sl@0
  4923
        return -1;
sl@0
  4924
	}
sl@0
  4925
  }
sl@0
  4926
  else
sl@0
  4927
  {
sl@0
  4928
    if (writeAudioSTSZ(handle, ts) < 0)
sl@0
  4929
      return -1;
sl@0
  4930
sl@0
  4931
	if (handle->audioSampleTable->stcoNeed64Bits)
sl@0
  4932
	{
sl@0
  4933
      if (writeAudioCO64(handle, ts) < 0)
sl@0
  4934
        return -1;
sl@0
  4935
	}
sl@0
  4936
	else
sl@0
  4937
	{
sl@0
  4938
      if (writeAudioSTCO(handle, ts) < 0)
sl@0
  4939
        return -1;
sl@0
  4940
	}
sl@0
  4941
  }
sl@0
  4942
sl@0
  4943
sl@0
  4944
  return 0;
sl@0
  4945
}
sl@0
  4946
sl@0
  4947
sl@0
  4948
/*
sl@0
  4949
 * Function:
sl@0
  4950
 *
sl@0
  4951
 *   mp4_i32  writeAudioSTSD(MP4HandleImp handle,
sl@0
  4952
 *                           trakSize *ts)
sl@0
  4953
 *
sl@0
  4954
 * Description:
sl@0
  4955
 *
sl@0
  4956
 *   Write audio STSD atom.
sl@0
  4957
 *
sl@0
  4958
 * Parameters:
sl@0
  4959
 *
sl@0
  4960
 *   handle   MP4 library handle
sl@0
  4961
 *   ts       Atom sizes
sl@0
  4962
 *
sl@0
  4963
 * Return value:
sl@0
  4964
 *
sl@0
  4965
 *   0        Success
sl@0
  4966
 *   -1       Error
sl@0
  4967
 *
sl@0
  4968
 */
sl@0
  4969
mp4_i32 writeAudioSTSD(MP4HandleImp handle, trakSize *ts)
sl@0
  4970
{
sl@0
  4971
  mp4_u8  buf[16];
sl@0
  4972
  mp4_u32 i = 0;
sl@0
  4973
sl@0
  4974
sl@0
  4975
  /* Size */
sl@0
  4976
  insertu32(buf+i, (mp4_u32)ts->stsd);
sl@0
  4977
  i += 4;
sl@0
  4978
sl@0
  4979
  /* Atom type */
sl@0
  4980
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSD);
sl@0
  4981
  i += 4;
sl@0
  4982
sl@0
  4983
  /* Version and flags */
sl@0
  4984
  insertu32(buf+i, (mp4_u32)0);
sl@0
  4985
  i += 4;
sl@0
  4986
sl@0
  4987
  /* Entry count */
sl@0
  4988
  insertu32(buf+i, (mp4_u32)1);
sl@0
  4989
  i += 4;
sl@0
  4990
sl@0
  4991
  if (writeFile(handle, buf, 16) < 0)
sl@0
  4992
    return -1;
sl@0
  4993
sl@0
  4994
  if (handle->type & MP4_TYPE_MPEG4_AUDIO)
sl@0
  4995
  {
sl@0
  4996
    if (writeMP4A(handle, ts) < 0)
sl@0
  4997
      return -1;
sl@0
  4998
  }
sl@0
  4999
  else if (handle->type & MP4_TYPE_AMR_NB)
sl@0
  5000
  {
sl@0
  5001
    if (writeSAMR(handle, ts) < 0)
sl@0
  5002
      return -1;
sl@0
  5003
  }
sl@0
  5004
  else if (handle->type & MP4_TYPE_AMR_WB)
sl@0
  5005
  {
sl@0
  5006
    if (writeSAWB(handle, ts) < 0)
sl@0
  5007
      return -1;
sl@0
  5008
  }
sl@0
  5009
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio))
sl@0
  5010
  {
sl@0
  5011
    if (writeSQCP(handle, ts) < 0)
sl@0
  5012
      return -1;
sl@0
  5013
  }
sl@0
  5014
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
sl@0
  5015
  {
sl@0
  5016
    if (writeMP4A(handle, ts) < 0)
sl@0
  5017
      return -1;
sl@0
  5018
  }
sl@0
  5019
  else
sl@0
  5020
  {
sl@0
  5021
  }
sl@0
  5022
sl@0
  5023
  return 0;
sl@0
  5024
}
sl@0
  5025
sl@0
  5026
sl@0
  5027
/*
sl@0
  5028
 * Function:
sl@0
  5029
 *
sl@0
  5030
 *   mp4_i32 writeMP4A(MP4HandleImp handle,
sl@0
  5031
 *                     trakSize *ts)
sl@0
  5032
 *
sl@0
  5033
 * Description:
sl@0
  5034
 *
sl@0
  5035
 *   Write MP4A atom.
sl@0
  5036
 *
sl@0
  5037
 * Parameters:
sl@0
  5038
 *
sl@0
  5039
 *   handle   MP4 library handle
sl@0
  5040
 *   ts       Atom sizes
sl@0
  5041
 *
sl@0
  5042
 * Return value:
sl@0
  5043
 *
sl@0
  5044
 *   0        Success
sl@0
  5045
 *   -1       Error
sl@0
  5046
 *
sl@0
  5047
 */
sl@0
  5048
mp4_i32 writeMP4A(MP4HandleImp handle, trakSize *ts)
sl@0
  5049
{
sl@0
  5050
  mp4_u8  *buf;
sl@0
  5051
  mp4_u32  i = 0;
sl@0
  5052
sl@0
  5053
sl@0
  5054
  buf = (mp4_u8 *)mp4malloc(36);
sl@0
  5055
  if (buf == NULL)
sl@0
  5056
    return -1;
sl@0
  5057
sl@0
  5058
  /* Size */
sl@0
  5059
  insertu32(buf+i, (mp4_u32)ts->mp4a);
sl@0
  5060
  i += 4;
sl@0
  5061
sl@0
  5062
  /* Atom type */
sl@0
  5063
  insertu32(buf+i, (mp4_u32)ATOMTYPE_MP4A);
sl@0
  5064
  i += 4;
sl@0
  5065
sl@0
  5066
  /* Reserved */
sl@0
  5067
  buf[i++] = 0;
sl@0
  5068
  buf[i++] = 0;
sl@0
  5069
  buf[i++] = 0;
sl@0
  5070
  buf[i++] = 0;
sl@0
  5071
  buf[i++] = 0;
sl@0
  5072
  buf[i++] = 0;
sl@0
  5073
sl@0
  5074
  /* Data reference index */
sl@0
  5075
  insertu16(buf+i, (mp4_u16)1);
sl@0
  5076
  i += 2;
sl@0
  5077
sl@0
  5078
  /* Reserved */
sl@0
  5079
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5080
  i += 4;
sl@0
  5081
sl@0
  5082
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5083
  i += 4;
sl@0
  5084
sl@0
  5085
  insertu16(buf+i, (mp4_u16)2);
sl@0
  5086
  i += 2;
sl@0
  5087
sl@0
  5088
  insertu16(buf+i, (mp4_u16)16);
sl@0
  5089
  i += 2;
sl@0
  5090
sl@0
  5091
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5092
  i += 4;
sl@0
  5093
sl@0
  5094
  /* Timescale */
sl@0
  5095
  insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
sl@0
  5096
  i += 2;
sl@0
  5097
sl@0
  5098
  /* Reserved */
sl@0
  5099
  insertu16(buf+i, (mp4_u16)0);
sl@0
  5100
  i += 2;
sl@0
  5101
sl@0
  5102
  if (writeFile(handle, buf, 36) < 0)
sl@0
  5103
  {
sl@0
  5104
    mp4free(buf);
sl@0
  5105
sl@0
  5106
    return -1;
sl@0
  5107
  }
sl@0
  5108
sl@0
  5109
  if (writeAudioESD(handle, ts) < 0)
sl@0
  5110
  {
sl@0
  5111
    mp4free(buf);
sl@0
  5112
sl@0
  5113
    return -1;
sl@0
  5114
  }
sl@0
  5115
sl@0
  5116
  mp4free(buf);
sl@0
  5117
sl@0
  5118
  return 0;
sl@0
  5119
}
sl@0
  5120
sl@0
  5121
sl@0
  5122
/*
sl@0
  5123
 * Function:
sl@0
  5124
 *
sl@0
  5125
 *   mp4_i32 writeAudioESD(MP4HandleImp handle,
sl@0
  5126
 *                         trakSize *ts)
sl@0
  5127
 *
sl@0
  5128
 * Description:
sl@0
  5129
 *
sl@0
  5130
 *   Write audio ESD atom.
sl@0
  5131
 *
sl@0
  5132
 * Parameters:
sl@0
  5133
 *
sl@0
  5134
 *   handle   MP4 library handle
sl@0
  5135
 *   ts       Atom sizes
sl@0
  5136
 *
sl@0
  5137
 * Return value:
sl@0
  5138
 *
sl@0
  5139
 *   0        Success
sl@0
  5140
 *   -1       Error
sl@0
  5141
 *
sl@0
  5142
 */
sl@0
  5143
mp4_i32 writeAudioESD(MP4HandleImp handle, trakSize *ts)
sl@0
  5144
{
sl@0
  5145
  mp4_u8  *buf;
sl@0
  5146
  mp4_u32  i = 0;
sl@0
  5147
  mp4_u32  bitrate = 0;
sl@0
  5148
  mp4_u32 num_of_bytes = 0;
sl@0
  5149
  mp4_u32 size = 0;
sl@0
  5150
  mp4_u32 index = 0;
sl@0
  5151
  mp4_u32 tempnum = 0;
sl@0
  5152
sl@0
  5153
  mp4_u32 size1, size2;
sl@0
  5154
  mp4_u32 numofsizebytes1, numofsizebytes2;
sl@0
  5155
sl@0
  5156
  buf = (mp4_u8 *)mp4malloc(ts->esds);
sl@0
  5157
  if (buf == NULL)
sl@0
  5158
    return -1;
sl@0
  5159
sl@0
  5160
  /* Calculate the necessary size information */
sl@0
  5161
  size1 = handle->audioDecSpecificInfoSize;
sl@0
  5162
  if (size1 < 128)
sl@0
  5163
    numofsizebytes1 = 1;
sl@0
  5164
  else
sl@0
  5165
  {
sl@0
  5166
      numofsizebytes1 = 1;
sl@0
  5167
      while ( size1 >= 128 ) 
sl@0
  5168
      {
sl@0
  5169
        size1 = size1 >> 7;
sl@0
  5170
        numofsizebytes1++;
sl@0
  5171
      }  
sl@0
  5172
  }
sl@0
  5173
sl@0
  5174
  size2 = 14 + numofsizebytes1 + handle->audioDecSpecificInfoSize;
sl@0
  5175
   if (size2 < 128)
sl@0
  5176
      numofsizebytes2 = 1;
sl@0
  5177
    else
sl@0
  5178
    {
sl@0
  5179
        numofsizebytes2 = 1;
sl@0
  5180
        while ( size2 >= 128 ) 
sl@0
  5181
        {
sl@0
  5182
          size2 = size2 >> 7;
sl@0
  5183
          numofsizebytes2++;
sl@0
  5184
        }  
sl@0
  5185
    }
sl@0
  5186
    /* End of size calculations */
sl@0
  5187
sl@0
  5188
  /* Size */
sl@0
  5189
  insertu32(buf+i, (mp4_u32)ts->esds);
sl@0
  5190
  i += 4;
sl@0
  5191
sl@0
  5192
  /* Atom type */
sl@0
  5193
  insertu32(buf+i, (mp4_u32)ATOMTYPE_ESD);
sl@0
  5194
  i += 4;
sl@0
  5195
sl@0
  5196
  /* Version and flags */
sl@0
  5197
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5198
  i += 4;
sl@0
  5199
sl@0
  5200
  /* ES_DescrTag */
sl@0
  5201
  buf[i++] = 0x03;
sl@0
  5202
sl@0
  5203
  /* Size */
sl@0
  5204
  size = 21 + numofsizebytes1 + numofsizebytes2 + handle->audioDecSpecificInfoSize; 
sl@0
  5205
  if (size < 128)
sl@0
  5206
    buf[i++] = (mp4_u8)(size);
sl@0
  5207
  else
sl@0
  5208
  {
sl@0
  5209
      num_of_bytes = 0;
sl@0
  5210
      while ( size >= 128 ) 
sl@0
  5211
      {
sl@0
  5212
        size = size >> 7;
sl@0
  5213
        num_of_bytes++;
sl@0
  5214
      }  
sl@0
  5215
      size = 21 + numofsizebytes1 + numofsizebytes2 + handle->audioDecSpecificInfoSize; 
sl@0
  5216
      for(index = num_of_bytes; index > 0; index--)  
sl@0
  5217
      {
sl@0
  5218
        tempnum = size >> (7 * index); 
sl@0
  5219
        buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
sl@0
  5220
        size -= (tempnum << (7 * index));
sl@0
  5221
      }
sl@0
  5222
      buf[i++] = (mp4_u8)size;
sl@0
  5223
  }
sl@0
  5224
sl@0
  5225
  /* ES_ID */
sl@0
  5226
  insertu16(buf+i, (mp4_u16)0);
sl@0
  5227
  i += 2;
sl@0
  5228
sl@0
  5229
  /* Flags */
sl@0
  5230
  buf[i++] = 0;
sl@0
  5231
sl@0
  5232
  /* DecoderConfigDescrTag */
sl@0
  5233
  buf[i++] = 0x04;
sl@0
  5234
sl@0
  5235
  /* Size */
sl@0
  5236
  size =  14 + numofsizebytes1 + handle->audioDecSpecificInfoSize; 
sl@0
  5237
  if (size < 128)
sl@0
  5238
    buf[i++] = (mp4_u8)(size);
sl@0
  5239
  else
sl@0
  5240
  {
sl@0
  5241
      num_of_bytes = 0;
sl@0
  5242
      while ( size >= 128 ) 
sl@0
  5243
      {
sl@0
  5244
        size = size >> 7;
sl@0
  5245
        num_of_bytes++;
sl@0
  5246
      }  
sl@0
  5247
      size =  14 + numofsizebytes1 + handle->audioDecSpecificInfoSize; 
sl@0
  5248
      for(index = num_of_bytes; index > 0; index--)  
sl@0
  5249
      {
sl@0
  5250
        tempnum = size >> (7 * index); 
sl@0
  5251
        buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
sl@0
  5252
        size -= (tempnum << (7 * index));
sl@0
  5253
      }
sl@0
  5254
      buf[i++] = (mp4_u8)size;
sl@0
  5255
  }
sl@0
  5256
sl@0
  5257
  /* ObjectTypeIndication */
sl@0
  5258
  if (handle->type & MP4_TYPE_MPEG4_AUDIO)
sl@0
  5259
    buf[i++] = 0x40;
sl@0
  5260
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
sl@0
  5261
    buf[i++] = 0xE1;
sl@0
  5262
  else
sl@0
  5263
  {
sl@0
  5264
  }
sl@0
  5265
sl@0
  5266
  /* Flags */
sl@0
  5267
  buf[i++] = 0x15;
sl@0
  5268
sl@0
  5269
  /* BufferSizeDB */
sl@0
  5270
  if (handle->type & MP4_TYPE_MPEG4_AUDIO) 
sl@0
  5271
  {
sl@0
  5272
      buf[i++] = 0x00;
sl@0
  5273
      buf[i++] = 0x00;
sl@0
  5274
      buf[i++] = 0x00;
sl@0
  5275
  }
sl@0
  5276
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio))
sl@0
  5277
  { /* 4096 for QCELP 13K */
sl@0
  5278
      buf[i++] = 0x00;
sl@0
  5279
      buf[i++] = 0x10;
sl@0
  5280
      buf[i++] = 0x00;
sl@0
  5281
  }
sl@0
  5282
  else
sl@0
  5283
  {
sl@0
  5284
  }
sl@0
  5285
sl@0
  5286
sl@0
  5287
  if ((handle->audioDuration != 0) && (handle->audioTimeScale != 0))
sl@0
  5288
    bitrate = (mp4_u32)((mp4_double)8 *
sl@0
  5289
                              (mp4_double)handle->audioMediaDataSize /
sl@0
  5290
                              ((mp4_double)handle->audioDuration /
sl@0
  5291
                               (mp4_double)handle->audioTimeScale));
sl@0
  5292
  else
sl@0
  5293
    bitrate = 0;
sl@0
  5294
sl@0
  5295
  /* MaxBitrate */
sl@0
  5296
  insertu32(buf+i, (mp4_u32)bitrate); /*0x00010000*/
sl@0
  5297
  i += 4;
sl@0
  5298
sl@0
  5299
  /* AvgBitrate */
sl@0
  5300
  insertu32(buf+i, (mp4_u32)bitrate);/*0x00008000*/
sl@0
  5301
  i += 4;
sl@0
  5302
sl@0
  5303
  /* DecSpecificInfoTag */
sl@0
  5304
  buf[i++] = 0x05;
sl@0
  5305
sl@0
  5306
  /* Size */
sl@0
  5307
  size = handle->audioDecSpecificInfoSize;
sl@0
  5308
  if (size < 128)
sl@0
  5309
    buf[i++] = (mp4_u8)(size);
sl@0
  5310
  else
sl@0
  5311
  {
sl@0
  5312
      num_of_bytes = 0;
sl@0
  5313
      while ( size >= 128 ) 
sl@0
  5314
      {
sl@0
  5315
        size = size >> 7;
sl@0
  5316
        num_of_bytes++;
sl@0
  5317
      }  
sl@0
  5318
      size = handle->audioDecSpecificInfoSize;
sl@0
  5319
      for(index = num_of_bytes; index > 0; index--)  
sl@0
  5320
      {
sl@0
  5321
        tempnum = size >> (7 * index); 
sl@0
  5322
        buf[i++] = (mp4_u8)(0x80 | (mp4_u8) tempnum);
sl@0
  5323
        size -= (tempnum << (7 * index));
sl@0
  5324
      }
sl@0
  5325
      buf[i++] = (mp4_u8)size;
sl@0
  5326
  }
sl@0
  5327
sl@0
  5328
  /* DecoderSpecificInfo */
sl@0
  5329
  mp4memcpy(buf+i, handle->audioDecSpecificInfo, handle->audioDecSpecificInfoSize);
sl@0
  5330
  i += handle->audioDecSpecificInfoSize;
sl@0
  5331
sl@0
  5332
  /* SLConfigDescrTag */
sl@0
  5333
  buf[i++] = 0x06;
sl@0
  5334
sl@0
  5335
  /* Size */
sl@0
  5336
  buf[i++] = 1;
sl@0
  5337
sl@0
  5338
  /* */
sl@0
  5339
  buf[i++] = 2;
sl@0
  5340
sl@0
  5341
  if (writeFile(handle, buf, ts->esds) < 0)
sl@0
  5342
  {
sl@0
  5343
    mp4free(buf);
sl@0
  5344
sl@0
  5345
    return -1;
sl@0
  5346
  }
sl@0
  5347
sl@0
  5348
  mp4free(buf);
sl@0
  5349
sl@0
  5350
  return 0;
sl@0
  5351
}
sl@0
  5352
sl@0
  5353
sl@0
  5354
/*
sl@0
  5355
 * Function:
sl@0
  5356
 *
sl@0
  5357
 *   mp4_i32 writeSAMR(MP4HandleImp handle,
sl@0
  5358
 *                     trakSize *ts)
sl@0
  5359
 *
sl@0
  5360
 * Description:
sl@0
  5361
 *
sl@0
  5362
 *   Write SAMR atom.
sl@0
  5363
 *
sl@0
  5364
 * Parameters:
sl@0
  5365
 *
sl@0
  5366
 *   handle   MP4 library handle
sl@0
  5367
 *   ts       Atom sizes
sl@0
  5368
 *
sl@0
  5369
 * Return value:
sl@0
  5370
 *
sl@0
  5371
 *   0        Success
sl@0
  5372
 *   -1       Error
sl@0
  5373
 *
sl@0
  5374
 */
sl@0
  5375
mp4_i32  writeSAMR(MP4HandleImp handle, trakSize *ts)
sl@0
  5376
{
sl@0
  5377
  mp4_u8  *buf;
sl@0
  5378
  mp4_u32  i = 0;
sl@0
  5379
sl@0
  5380
sl@0
  5381
  buf = (mp4_u8 *)mp4malloc(36);
sl@0
  5382
  if (buf == NULL)
sl@0
  5383
    return -1;
sl@0
  5384
sl@0
  5385
  /* Size */
sl@0
  5386
  insertu32(buf+i, (mp4_u32)ts->samr);
sl@0
  5387
  i += 4;
sl@0
  5388
sl@0
  5389
  /* Atom type */
sl@0
  5390
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SAMR);
sl@0
  5391
  i += 4;
sl@0
  5392
sl@0
  5393
  /* Reserved */
sl@0
  5394
  buf[i++] = 0;
sl@0
  5395
  buf[i++] = 0;
sl@0
  5396
  buf[i++] = 0;
sl@0
  5397
  buf[i++] = 0;
sl@0
  5398
  buf[i++] = 0;
sl@0
  5399
  buf[i++] = 0;
sl@0
  5400
sl@0
  5401
  /* Data reference index */
sl@0
  5402
  insertu16(buf+i, (mp4_u16)1);
sl@0
  5403
  i += 2;
sl@0
  5404
sl@0
  5405
  /* Reserved */
sl@0
  5406
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5407
  i += 4;
sl@0
  5408
sl@0
  5409
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5410
  i += 4;
sl@0
  5411
sl@0
  5412
  insertu16(buf+i, (mp4_u16)2);
sl@0
  5413
  i += 2;
sl@0
  5414
sl@0
  5415
  insertu16(buf+i, (mp4_u16)16);
sl@0
  5416
  i += 2;
sl@0
  5417
sl@0
  5418
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5419
  i += 4;
sl@0
  5420
sl@0
  5421
  /* Timescale */
sl@0
  5422
  insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
sl@0
  5423
  i += 2;
sl@0
  5424
sl@0
  5425
  /* Reserved */
sl@0
  5426
  insertu16(buf+i, (mp4_u16)0);
sl@0
  5427
  i += 2;
sl@0
  5428
sl@0
  5429
  if (writeFile(handle, buf, 36) < 0)
sl@0
  5430
  {
sl@0
  5431
    mp4free(buf);
sl@0
  5432
sl@0
  5433
    return -1;
sl@0
  5434
  }
sl@0
  5435
sl@0
  5436
  if (writeDAMR(handle, ts) < 0)
sl@0
  5437
  {
sl@0
  5438
    mp4free(buf);
sl@0
  5439
sl@0
  5440
    return -1;
sl@0
  5441
  }
sl@0
  5442
sl@0
  5443
  mp4free(buf);
sl@0
  5444
sl@0
  5445
  return 0;
sl@0
  5446
}
sl@0
  5447
sl@0
  5448
sl@0
  5449
/*
sl@0
  5450
 * Function:
sl@0
  5451
 *
sl@0
  5452
 *   mp4_i32 writeSAWB(MP4HandleImp handle,
sl@0
  5453
 *                     trakSize *ts)
sl@0
  5454
 *
sl@0
  5455
 * Description:
sl@0
  5456
 *
sl@0
  5457
 *   Write SAWB atom.
sl@0
  5458
 *
sl@0
  5459
 * Parameters:
sl@0
  5460
 *
sl@0
  5461
 *   handle   MP4 library handle
sl@0
  5462
 *   ts       Atom sizes
sl@0
  5463
 *
sl@0
  5464
 * Return value:
sl@0
  5465
 *
sl@0
  5466
 *   0        Success
sl@0
  5467
 *   -1       Error
sl@0
  5468
 *
sl@0
  5469
 */
sl@0
  5470
mp4_i32 writeSAWB(MP4HandleImp handle, trakSize *ts)
sl@0
  5471
{
sl@0
  5472
  mp4_u8  *buf;
sl@0
  5473
  mp4_u32 i = 0;
sl@0
  5474
sl@0
  5475
sl@0
  5476
  buf = (mp4_u8 *)mp4malloc(36);
sl@0
  5477
  if (buf == NULL)
sl@0
  5478
    return -1;
sl@0
  5479
sl@0
  5480
  /* Size */
sl@0
  5481
  insertu32(buf+i, (mp4_u32)ts->sawb);
sl@0
  5482
  i += 4;
sl@0
  5483
sl@0
  5484
  /* Atom type */
sl@0
  5485
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SAWB);
sl@0
  5486
  i += 4;
sl@0
  5487
sl@0
  5488
  /* Reserved */
sl@0
  5489
  buf[i++] = 0;
sl@0
  5490
  buf[i++] = 0;
sl@0
  5491
  buf[i++] = 0;
sl@0
  5492
  buf[i++] = 0;
sl@0
  5493
  buf[i++] = 0;
sl@0
  5494
  buf[i++] = 0;
sl@0
  5495
sl@0
  5496
  /* Data reference index */
sl@0
  5497
  insertu16(buf+i, (mp4_u16)1);
sl@0
  5498
  i += 2;
sl@0
  5499
sl@0
  5500
  /* Reserved */
sl@0
  5501
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5502
  i += 4;
sl@0
  5503
sl@0
  5504
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5505
  i += 4;
sl@0
  5506
sl@0
  5507
  insertu16(buf+i, (mp4_u16)2);
sl@0
  5508
  i += 2;
sl@0
  5509
sl@0
  5510
  insertu16(buf+i, (mp4_u16)16);
sl@0
  5511
  i += 2;
sl@0
  5512
sl@0
  5513
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5514
  i += 4;
sl@0
  5515
sl@0
  5516
  /* Timescale */
sl@0
  5517
  insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
sl@0
  5518
  i += 2;
sl@0
  5519
sl@0
  5520
  /* Reserved */
sl@0
  5521
  insertu16(buf+i, (mp4_u16)0);
sl@0
  5522
  i += 2;
sl@0
  5523
sl@0
  5524
  if (writeFile(handle, buf, 36) < 0)
sl@0
  5525
  {
sl@0
  5526
    mp4free(buf);
sl@0
  5527
sl@0
  5528
    return -1;
sl@0
  5529
  }
sl@0
  5530
sl@0
  5531
  if (writeDAMR(handle, ts) < 0)
sl@0
  5532
  {
sl@0
  5533
    mp4free(buf);
sl@0
  5534
sl@0
  5535
    return -1;
sl@0
  5536
  }
sl@0
  5537
sl@0
  5538
  mp4free(buf);
sl@0
  5539
sl@0
  5540
  return 0;
sl@0
  5541
}
sl@0
  5542
sl@0
  5543
sl@0
  5544
/*
sl@0
  5545
 * Function:
sl@0
  5546
 *
sl@0
  5547
 *   mp4_i32 writeDAMR(MP4HandleImp handle,
sl@0
  5548
 *                     trakSize *ts)
sl@0
  5549
 *
sl@0
  5550
 * Description:
sl@0
  5551
 *
sl@0
  5552
 *   Write DAMR atom.
sl@0
  5553
 *
sl@0
  5554
 * Parameters:
sl@0
  5555
 *
sl@0
  5556
 *   handle   MP4 library handle
sl@0
  5557
 *   ts       Atom sizes
sl@0
  5558
 *
sl@0
  5559
 * Return value:
sl@0
  5560
 *
sl@0
  5561
 *   0        Success
sl@0
  5562
 *   -1       Error
sl@0
  5563
 *
sl@0
  5564
 */
sl@0
  5565
mp4_i32 writeDAMR(MP4HandleImp handle, trakSize *ts)
sl@0
  5566
{
sl@0
  5567
  mp4_u8  buf[17];
sl@0
  5568
  mp4_u32  i = 0;
sl@0
  5569
sl@0
  5570
sl@0
  5571
  /* Size */
sl@0
  5572
  insertu32(buf+i, (mp4_u32)ts->damr);
sl@0
  5573
  i += 4;
sl@0
  5574
sl@0
  5575
  /* Atom type */
sl@0
  5576
  insertu32(buf+i, (mp4_u32)ATOMTYPE_DAMR);
sl@0
  5577
  i += 4;
sl@0
  5578
sl@0
  5579
  /* Vendor */
sl@0
  5580
  buf[i++] = 'S';
sl@0
  5581
  buf[i++] = '6';
sl@0
  5582
  buf[i++] = '0';
sl@0
  5583
  buf[i++] = ' ';
sl@0
  5584
sl@0
  5585
  /* Decoder version */
sl@0
  5586
  buf[i++] = 0;
sl@0
  5587
sl@0
  5588
  /* Mode set */
sl@0
  5589
  insertu16(buf+i, (mp4_u16)handle->audioModeSet);
sl@0
  5590
  i += 2;
sl@0
  5591
sl@0
  5592
  /* Mode change period */
sl@0
  5593
  buf[i++] = 0;
sl@0
  5594
sl@0
  5595
  /* Frames per sample */
sl@0
  5596
  buf[i++] = handle->audioFramesPerSample;
sl@0
  5597
sl@0
  5598
  if (writeFile(handle, buf, 17) < 0)
sl@0
  5599
    return -1;
sl@0
  5600
sl@0
  5601
  return 0;
sl@0
  5602
}
sl@0
  5603
sl@0
  5604
sl@0
  5605
/*
sl@0
  5606
 * Function:
sl@0
  5607
 *
sl@0
  5608
 *   mp4_i32 writeAudioSTTS(MP4HandleImp handle,
sl@0
  5609
 *                          trakSize *ts)
sl@0
  5610
 *
sl@0
  5611
 * Description:
sl@0
  5612
 *
sl@0
  5613
 *   Write audio STTS atom.
sl@0
  5614
 *
sl@0
  5615
 * Parameters:
sl@0
  5616
 *
sl@0
  5617
 *   handle   MP4 library handle
sl@0
  5618
 *   ts       Atom sizes
sl@0
  5619
 *
sl@0
  5620
 * Return value:
sl@0
  5621
 *
sl@0
  5622
 *   0        Success
sl@0
  5623
 *   -1       Error
sl@0
  5624
 *
sl@0
  5625
 */
sl@0
  5626
mp4_i32 writeAudioSTTS(MP4HandleImp handle, trakSize *ts)
sl@0
  5627
{
sl@0
  5628
  mp4_u8  *buf;
sl@0
  5629
  mp4_u32  i = 0;
sl@0
  5630
  mp4_u32  j;
sl@0
  5631
sl@0
  5632
sl@0
  5633
  buf = (mp4_u8 *)mp4malloc(ts->stts);
sl@0
  5634
  if (buf == NULL)
sl@0
  5635
    return -1;
sl@0
  5636
sl@0
  5637
  /* Size */
sl@0
  5638
  insertu32(buf+i, (mp4_u32)ts->stts);
sl@0
  5639
  i += 4;
sl@0
  5640
sl@0
  5641
  /* Atom type */
sl@0
  5642
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
sl@0
  5643
  i += 4;
sl@0
  5644
sl@0
  5645
  /* Version and flags */
sl@0
  5646
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5647
  i += 4;
sl@0
  5648
sl@0
  5649
  /* Entry count */
sl@0
  5650
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsEntryCount);
sl@0
  5651
  i += 4;
sl@0
  5652
sl@0
  5653
  /* Sample count and sample delta */
sl@0
  5654
  for (j = 0; j < handle->audioSampleTable->sttsEntryCount; j++)
sl@0
  5655
  {
sl@0
  5656
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsSampleCount[j]);
sl@0
  5657
    i += 4;
sl@0
  5658
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsSampleDelta[j]);
sl@0
  5659
    i += 4;
sl@0
  5660
  }
sl@0
  5661
sl@0
  5662
  if (writeFile(handle, buf, ts->stts) < 0)
sl@0
  5663
  {
sl@0
  5664
    mp4free(buf);
sl@0
  5665
sl@0
  5666
    return -1;
sl@0
  5667
  }
sl@0
  5668
sl@0
  5669
  mp4free(buf);
sl@0
  5670
sl@0
  5671
  return 0;
sl@0
  5672
}
sl@0
  5673
sl@0
  5674
sl@0
  5675
/*
sl@0
  5676
 * Function:
sl@0
  5677
 *
sl@0
  5678
 *   mp4_i32 writeAudioSTTSLongClip(MP4HandleImp handle,
sl@0
  5679
 *                                  trakSize *ts)
sl@0
  5680
 *
sl@0
  5681
 * Description:
sl@0
  5682
 *
sl@0
  5683
 *   Write audio STTS atom.
sl@0
  5684
 *
sl@0
  5685
 * Parameters:
sl@0
  5686
 *
sl@0
  5687
 *   handle   MP4 library handle
sl@0
  5688
 *   ts       Atom sizes
sl@0
  5689
 *
sl@0
  5690
 * Return value:
sl@0
  5691
 *
sl@0
  5692
 *   0        Success
sl@0
  5693
 *   -1       Error
sl@0
  5694
 *
sl@0
  5695
 */
sl@0
  5696
mp4_i32 writeAudioSTTSLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  5697
{
sl@0
  5698
  mp4_u8   *buf;
sl@0
  5699
  mp4_u8   *buf2;
sl@0
  5700
  mp4_u32  i = 0;
sl@0
  5701
  mp4_u32  j;
sl@0
  5702
  mp4_u32  left;
sl@0
  5703
  mp4_u32  bytestoread;
sl@0
  5704
sl@0
  5705
sl@0
  5706
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  5707
  if (buf == NULL)
sl@0
  5708
    return -1;
sl@0
  5709
sl@0
  5710
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
sl@0
  5711
  if (buf2 == NULL)
sl@0
  5712
      {
sl@0
  5713
      mp4free(buf);
sl@0
  5714
      return -1;
sl@0
  5715
      }
sl@0
  5716
sl@0
  5717
  /* Size */
sl@0
  5718
  insertu32(buf+i, (mp4_u32)ts->stts);
sl@0
  5719
  i += 4;
sl@0
  5720
sl@0
  5721
  /* Atom type */
sl@0
  5722
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STTS);
sl@0
  5723
  i += 4;
sl@0
  5724
sl@0
  5725
  /* Version and flags */
sl@0
  5726
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5727
  i += 4;
sl@0
  5728
sl@0
  5729
  /* Entry count */
sl@0
  5730
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->sttsEntryCount);
sl@0
  5731
  i += 4;
sl@0
  5732
sl@0
  5733
  if (writeFile(handle, buf, i) < 0)
sl@0
  5734
  {
sl@0
  5735
    mp4free(buf);
sl@0
  5736
    mp4free(buf2);
sl@0
  5737
sl@0
  5738
    return -1;
sl@0
  5739
  }
sl@0
  5740
sl@0
  5741
  /* Sample count and delta */
sl@0
  5742
sl@0
  5743
  /* Seek to the beginning of temporary files */
sl@0
  5744
sl@0
  5745
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
sl@0
  5746
      {
sl@0
  5747
      mp4free(buf);
sl@0
  5748
      mp4free(buf2);
sl@0
  5749
      return -1;
sl@0
  5750
      }
sl@0
  5751
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
sl@0
  5752
      {
sl@0
  5753
      mp4free(buf);
sl@0
  5754
      mp4free(buf2);
sl@0
  5755
      return -1;
sl@0
  5756
      }
sl@0
  5757
sl@0
  5758
  left = handle->audioSampleTable->sttsEntryCount * 4; /* Bytes left in each file */
sl@0
  5759
sl@0
  5760
  while (left)
sl@0
  5761
  {
sl@0
  5762
    if (left > METADATA_COPY_BUFFERSIZE / 2)
sl@0
  5763
      bytestoread = METADATA_COPY_BUFFERSIZE / 2;
sl@0
  5764
    else
sl@0
  5765
      bytestoread = left;
sl@0
  5766
sl@0
  5767
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
sl@0
  5768
    {
sl@0
  5769
      mp4free(buf);
sl@0
  5770
      mp4free(buf2);
sl@0
  5771
sl@0
  5772
      return -1;
sl@0
  5773
    }
sl@0
  5774
sl@0
  5775
    for (j = 0; j < bytestoread; j += 4)
sl@0
  5776
    {
sl@0
  5777
      insertu32(buf + 2*j, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  5778
    }
sl@0
  5779
sl@0
  5780
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
sl@0
  5781
    {
sl@0
  5782
      mp4free(buf);
sl@0
  5783
      mp4free(buf2);
sl@0
  5784
sl@0
  5785
      return -1;
sl@0
  5786
    }
sl@0
  5787
sl@0
  5788
    for (j = 0; j < bytestoread; j += 4)
sl@0
  5789
    {
sl@0
  5790
      insertu32(buf + 2*j + 4, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  5791
    }
sl@0
  5792
sl@0
  5793
    if (writeFile(handle, buf, 2 * bytestoread) < 0)
sl@0
  5794
    {
sl@0
  5795
      mp4free(buf);
sl@0
  5796
      mp4free(buf2);
sl@0
  5797
sl@0
  5798
      return -1;
sl@0
  5799
    }
sl@0
  5800
sl@0
  5801
    left -= bytestoread;
sl@0
  5802
  }
sl@0
  5803
sl@0
  5804
  mp4free(buf);
sl@0
  5805
  mp4free(buf2);
sl@0
  5806
sl@0
  5807
sl@0
  5808
  return 0;
sl@0
  5809
}
sl@0
  5810
sl@0
  5811
sl@0
  5812
/*
sl@0
  5813
 * Function:
sl@0
  5814
 *
sl@0
  5815
 *   mp4_i32 writeAudioSTSC(MP4HandleImp handle,
sl@0
  5816
 *                          trakSize *ts)
sl@0
  5817
 *
sl@0
  5818
 * Description:
sl@0
  5819
 *
sl@0
  5820
 *   Write audio STSC atom.
sl@0
  5821
 *
sl@0
  5822
 * Parameters:
sl@0
  5823
 *
sl@0
  5824
 *   handle   MP4 library handle
sl@0
  5825
 *   ts       Atom sizes
sl@0
  5826
 *
sl@0
  5827
 * Return value:
sl@0
  5828
 *
sl@0
  5829
 *   0        Success
sl@0
  5830
 *   -1       Error
sl@0
  5831
 *
sl@0
  5832
 */
sl@0
  5833
mp4_i32 writeAudioSTSC(MP4HandleImp handle, trakSize *ts)
sl@0
  5834
{
sl@0
  5835
  mp4_u8  *buf;
sl@0
  5836
  mp4_u32  i = 0;
sl@0
  5837
  mp4_u32  j;
sl@0
  5838
sl@0
  5839
sl@0
  5840
  buf = (mp4_u8 *)mp4malloc(ts->stsc);
sl@0
  5841
  if (buf == NULL)
sl@0
  5842
    return -1;
sl@0
  5843
sl@0
  5844
  /* Size */
sl@0
  5845
  insertu32(buf+i, (mp4_u32)ts->stsc);
sl@0
  5846
  i += 4;
sl@0
  5847
sl@0
  5848
  /* Atom type */
sl@0
  5849
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSC);
sl@0
  5850
  i += 4;
sl@0
  5851
sl@0
  5852
  /* Version and flags */
sl@0
  5853
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5854
  i += 4;
sl@0
  5855
sl@0
  5856
  /* Entry count */
sl@0
  5857
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscEntryCount);
sl@0
  5858
  i += 4;
sl@0
  5859
sl@0
  5860
  /* First chunk, samples per chunk and sample description index */
sl@0
  5861
  for (j = 0; j < handle->audioSampleTable->stscEntryCount; j++)
sl@0
  5862
  {
sl@0
  5863
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscFirstChunk[j]);
sl@0
  5864
    i += 4;
sl@0
  5865
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscSamplesPerChunk[j]);
sl@0
  5866
    i += 4;
sl@0
  5867
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stscSampleDescriptionIndex[j]);
sl@0
  5868
    i += 4;
sl@0
  5869
  }
sl@0
  5870
sl@0
  5871
  if (writeFile(handle, buf, ts->stsc) < 0)
sl@0
  5872
  {
sl@0
  5873
    mp4free(buf);
sl@0
  5874
sl@0
  5875
    return -1;
sl@0
  5876
  }
sl@0
  5877
sl@0
  5878
  mp4free(buf);
sl@0
  5879
sl@0
  5880
  return 0;
sl@0
  5881
}
sl@0
  5882
sl@0
  5883
sl@0
  5884
/*
sl@0
  5885
 * Function:
sl@0
  5886
 *
sl@0
  5887
 *   mp4_i32 writeAudioSTSZ(MP4HandleImp handle,
sl@0
  5888
 *                          trakSize *ts)
sl@0
  5889
 *
sl@0
  5890
 * Description:
sl@0
  5891
 *
sl@0
  5892
 *   Write audio STSZ atom.
sl@0
  5893
 *
sl@0
  5894
 * Parameters:
sl@0
  5895
 *
sl@0
  5896
 *   handle   MP4 library handle
sl@0
  5897
 *   ts       Atom sizes
sl@0
  5898
 *
sl@0
  5899
 * Return value:
sl@0
  5900
 *
sl@0
  5901
 *   0        Success
sl@0
  5902
 *   -1       Error
sl@0
  5903
 *
sl@0
  5904
 */
sl@0
  5905
mp4_i32 writeAudioSTSZ(MP4HandleImp handle, trakSize *ts)
sl@0
  5906
{
sl@0
  5907
  mp4_u8  *buf;
sl@0
  5908
  mp4_u32  i = 0;
sl@0
  5909
  mp4_u32  j;
sl@0
  5910
sl@0
  5911
sl@0
  5912
  buf = (mp4_u8 *)mp4malloc(ts->stsz);
sl@0
  5913
  if (buf == NULL)
sl@0
  5914
    return -1;
sl@0
  5915
sl@0
  5916
  /* Size */
sl@0
  5917
  insertu32(buf+i, (mp4_u32)ts->stsz);
sl@0
  5918
  i += 4;
sl@0
  5919
sl@0
  5920
  /* Atom type */
sl@0
  5921
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
sl@0
  5922
  i += 4;
sl@0
  5923
sl@0
  5924
  /* Version and flags */
sl@0
  5925
  insertu32(buf+i, (mp4_u32)0);
sl@0
  5926
  i += 4;
sl@0
  5927
sl@0
  5928
  /* Sample size */
sl@0
  5929
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleSize);
sl@0
  5930
  i += 4;
sl@0
  5931
sl@0
  5932
  /* Sample count */
sl@0
  5933
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleCount);
sl@0
  5934
  i += 4;
sl@0
  5935
sl@0
  5936
  /* Entry sizes */
sl@0
  5937
  if (handle->audioSampleTable->stszSampleSize == 0)
sl@0
  5938
  {
sl@0
  5939
    for (j = 0; j < handle->audioSampleTable->stszSampleCount; j++)
sl@0
  5940
    {
sl@0
  5941
      insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszEntrySize[j]);
sl@0
  5942
      i += 4;
sl@0
  5943
    }
sl@0
  5944
  }
sl@0
  5945
sl@0
  5946
  if (writeFile(handle, buf, ts->stsz) < 0)
sl@0
  5947
  {
sl@0
  5948
    mp4free(buf);
sl@0
  5949
sl@0
  5950
    return -1;
sl@0
  5951
  }
sl@0
  5952
sl@0
  5953
  mp4free(buf);
sl@0
  5954
sl@0
  5955
  return 0;
sl@0
  5956
}
sl@0
  5957
sl@0
  5958
sl@0
  5959
/*
sl@0
  5960
 * Function:
sl@0
  5961
 *
sl@0
  5962
 *   mp4_i32 writeAudioSTSZLongClip(MP4HandleImp handle,
sl@0
  5963
 *                                  trakSize *ts)
sl@0
  5964
 *
sl@0
  5965
 * Description:
sl@0
  5966
 *
sl@0
  5967
 *   Write audio STSZ atom.
sl@0
  5968
 *
sl@0
  5969
 * Parameters:
sl@0
  5970
 *
sl@0
  5971
 *   handle   MP4 library handle
sl@0
  5972
 *   ts       Atom sizes
sl@0
  5973
 *
sl@0
  5974
 * Return value:
sl@0
  5975
 *
sl@0
  5976
 *   0        Success
sl@0
  5977
 *   -1       Error
sl@0
  5978
 *
sl@0
  5979
 */
sl@0
  5980
mp4_i32 writeAudioSTSZLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  5981
{
sl@0
  5982
  mp4_u8  *buf;
sl@0
  5983
  mp4_u8  *buf2;
sl@0
  5984
  mp4_u32  i = 0;
sl@0
  5985
  mp4_u32  j;
sl@0
  5986
  mp4_u32  left;
sl@0
  5987
  mp4_u32  bytestoread;
sl@0
  5988
sl@0
  5989
sl@0
  5990
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  5991
  if (buf == NULL)
sl@0
  5992
    return -1;
sl@0
  5993
sl@0
  5994
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  5995
  if (buf2 == NULL)
sl@0
  5996
      {
sl@0
  5997
      mp4free(buf);
sl@0
  5998
      return -1;
sl@0
  5999
      }
sl@0
  6000
sl@0
  6001
  /* Size */
sl@0
  6002
  insertu32(buf+i, (mp4_u32)ts->stsz);
sl@0
  6003
  i += 4;
sl@0
  6004
sl@0
  6005
  /* Atom type */
sl@0
  6006
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STSZ);
sl@0
  6007
  i += 4;
sl@0
  6008
sl@0
  6009
  /* Version and flags */
sl@0
  6010
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6011
  i += 4;
sl@0
  6012
sl@0
  6013
  /* Sample size */
sl@0
  6014
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleSize);
sl@0
  6015
  i += 4;
sl@0
  6016
sl@0
  6017
  /* Sample count */
sl@0
  6018
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stszSampleCount);
sl@0
  6019
  i += 4;
sl@0
  6020
sl@0
  6021
  if (writeFile(handle, buf, i) < 0)
sl@0
  6022
  {
sl@0
  6023
    mp4free(buf);
sl@0
  6024
    mp4free(buf2);
sl@0
  6025
sl@0
  6026
    return -1;
sl@0
  6027
  }
sl@0
  6028
sl@0
  6029
  /* Entry sizes */
sl@0
  6030
sl@0
  6031
  if (handle->audioSampleTable->stszSampleSize == 0)
sl@0
  6032
  {
sl@0
  6033
    /* Seek to the beginning of temporary file */
sl@0
  6034
sl@0
  6035
    if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
sl@0
  6036
        {
sl@0
  6037
        mp4free(buf);
sl@0
  6038
        mp4free(buf2);
sl@0
  6039
        return -1;
sl@0
  6040
        }
sl@0
  6041
sl@0
  6042
    left = handle->audioSampleTable->stszSampleCount * 4; /* Bytes left in the file */
sl@0
  6043
sl@0
  6044
    while (left)
sl@0
  6045
    {
sl@0
  6046
      if (left > METADATA_COPY_BUFFERSIZE)
sl@0
  6047
        bytestoread = METADATA_COPY_BUFFERSIZE;
sl@0
  6048
      else
sl@0
  6049
        bytestoread = left;
sl@0
  6050
sl@0
  6051
      if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
sl@0
  6052
      {
sl@0
  6053
        mp4free(buf);
sl@0
  6054
        mp4free(buf2);
sl@0
  6055
sl@0
  6056
        return -1;
sl@0
  6057
      }
sl@0
  6058
sl@0
  6059
      for (j = 0; j < bytestoread; j += 4)
sl@0
  6060
      {
sl@0
  6061
        insertu32(buf + j, ((mp4_u32 *)buf2)[j / 4]);
sl@0
  6062
      }
sl@0
  6063
sl@0
  6064
      if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  6065
      {
sl@0
  6066
        mp4free(buf);
sl@0
  6067
        mp4free(buf2);
sl@0
  6068
sl@0
  6069
        return -1;
sl@0
  6070
      }
sl@0
  6071
sl@0
  6072
      left -= bytestoread;
sl@0
  6073
    }
sl@0
  6074
  }
sl@0
  6075
sl@0
  6076
  mp4free(buf);
sl@0
  6077
  mp4free(buf2);
sl@0
  6078
sl@0
  6079
sl@0
  6080
  return 0;
sl@0
  6081
}
sl@0
  6082
sl@0
  6083
sl@0
  6084
/*
sl@0
  6085
 * Function:
sl@0
  6086
 *
sl@0
  6087
 *   mp4_i32 writeAudioSTCO(MP4HandleImp handle,
sl@0
  6088
 *                          trakSize *ts)
sl@0
  6089
 *
sl@0
  6090
 * Description:
sl@0
  6091
 *
sl@0
  6092
 *   Write audio STCO atom.
sl@0
  6093
 *
sl@0
  6094
 * Parameters:
sl@0
  6095
 *
sl@0
  6096
 *   handle   MP4 library handle
sl@0
  6097
 *   ts       Atom sizes
sl@0
  6098
 *
sl@0
  6099
 * Return value:
sl@0
  6100
 *
sl@0
  6101
 *   0        Success
sl@0
  6102
 *   -1       Error
sl@0
  6103
 *
sl@0
  6104
 */
sl@0
  6105
mp4_i32 writeAudioSTCO(MP4HandleImp handle, trakSize *ts)
sl@0
  6106
{
sl@0
  6107
  mp4_u8  *buf;
sl@0
  6108
  mp4_u32  i = 0;
sl@0
  6109
  mp4_u32  j;
sl@0
  6110
sl@0
  6111
sl@0
  6112
  buf = (mp4_u8 *)mp4malloc(ts->stco);
sl@0
  6113
  if (buf == NULL)
sl@0
  6114
    return -1;
sl@0
  6115
sl@0
  6116
  /* Size */
sl@0
  6117
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  6118
  i += 4;
sl@0
  6119
sl@0
  6120
  /* Atom type */
sl@0
  6121
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
sl@0
  6122
  i += 4;
sl@0
  6123
sl@0
  6124
  /* Version and flags */
sl@0
  6125
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6126
  i += 4;
sl@0
  6127
sl@0
  6128
  /* Entry count */
sl@0
  6129
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
sl@0
  6130
  i += 4;
sl@0
  6131
sl@0
  6132
  /* Chunk offsets */
sl@0
  6133
  for (j = 0; j < handle->audioSampleTable->stcoEntryCount; j++)
sl@0
  6134
  {
sl@0
  6135
    insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoChunkOffset[j]);
sl@0
  6136
    i += 4;
sl@0
  6137
  }
sl@0
  6138
sl@0
  6139
  if (writeFile(handle, buf, ts->stco) < 0)
sl@0
  6140
  {
sl@0
  6141
    mp4free(buf);
sl@0
  6142
sl@0
  6143
    return -1;
sl@0
  6144
  }
sl@0
  6145
sl@0
  6146
  mp4free(buf);
sl@0
  6147
sl@0
  6148
  return 0;
sl@0
  6149
}
sl@0
  6150
sl@0
  6151
/*
sl@0
  6152
 * Function:
sl@0
  6153
 *
sl@0
  6154
 *   mp4_i32 writeAudioCO64(MP4HandleImp handle,
sl@0
  6155
 *                          trakSize *ts)
sl@0
  6156
 *
sl@0
  6157
 * Description:
sl@0
  6158
 *
sl@0
  6159
 *   Write audio CO64 atom.
sl@0
  6160
 *
sl@0
  6161
 * Parameters:
sl@0
  6162
 *
sl@0
  6163
 *   handle   MP4 library handle
sl@0
  6164
 *   ts       Atom sizes
sl@0
  6165
 *
sl@0
  6166
 * Return value:
sl@0
  6167
 *
sl@0
  6168
 *   0        Success
sl@0
  6169
 *   -1       Error
sl@0
  6170
 *
sl@0
  6171
 */
sl@0
  6172
mp4_i32 writeAudioCO64(MP4HandleImp handle, trakSize *ts)
sl@0
  6173
{
sl@0
  6174
  mp4_u8  *buf;
sl@0
  6175
  mp4_u32  i = 0;
sl@0
  6176
  mp4_u32  j;
sl@0
  6177
sl@0
  6178
sl@0
  6179
  buf = (mp4_u8 *)mp4malloc(ts->stco);
sl@0
  6180
  if (buf == NULL)
sl@0
  6181
    return -1;
sl@0
  6182
sl@0
  6183
  /* Size */
sl@0
  6184
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  6185
  i += 4;
sl@0
  6186
sl@0
  6187
  /* Atom type */
sl@0
  6188
  insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
sl@0
  6189
  i += 4;
sl@0
  6190
sl@0
  6191
  /* Version and flags */
sl@0
  6192
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6193
  i += 4;
sl@0
  6194
sl@0
  6195
  /* Entry count */
sl@0
  6196
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
sl@0
  6197
  i += 4;
sl@0
  6198
sl@0
  6199
  /* Chunk offsets */
sl@0
  6200
  for (j = 0; j < handle->audioSampleTable->stcoEntryCount; j++)
sl@0
  6201
  {
sl@0
  6202
    insertu64(buf+j, (mp4_u64)handle->audioSampleTable->stcoChunkOffset[j]);
sl@0
  6203
  }
sl@0
  6204
sl@0
  6205
  if (writeFile(handle, buf, ts->stco) < 0)
sl@0
  6206
  {
sl@0
  6207
    mp4free(buf);
sl@0
  6208
sl@0
  6209
    return -1;
sl@0
  6210
  }
sl@0
  6211
sl@0
  6212
  mp4free(buf);
sl@0
  6213
sl@0
  6214
  return 0;
sl@0
  6215
}
sl@0
  6216
sl@0
  6217
/*
sl@0
  6218
 * Function:
sl@0
  6219
 *
sl@0
  6220
 *   mp4_i32 writeAudioSTCOLongClip(MP4HandleImp handle,
sl@0
  6221
 *                                  trakSize *ts)
sl@0
  6222
 *
sl@0
  6223
 * Description:
sl@0
  6224
 *
sl@0
  6225
 *   Write audio STCO atom.
sl@0
  6226
 *
sl@0
  6227
 * Parameters:
sl@0
  6228
 *
sl@0
  6229
 *   handle   MP4 library handle
sl@0
  6230
 *   ts       Atom sizes
sl@0
  6231
 *
sl@0
  6232
 * Return value:
sl@0
  6233
 *
sl@0
  6234
 *   0        Success
sl@0
  6235
 *   -1       Error
sl@0
  6236
 *
sl@0
  6237
 */
sl@0
  6238
mp4_i32 writeAudioSTCOLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  6239
{
sl@0
  6240
  mp4_u8   *buf;
sl@0
  6241
  mp4_u8   *buf2;
sl@0
  6242
  mp4_u32  i = 0;
sl@0
  6243
  mp4_u32  j;
sl@0
  6244
  mp4_u32  left;
sl@0
  6245
  mp4_u32  bytestoread;
sl@0
  6246
  mp4_u32  bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
sl@0
  6247
  																					  //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
sl@0
  6248
sl@0
  6249
sl@0
  6250
  buf = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  6251
  if (buf == NULL)
sl@0
  6252
    return -1;
sl@0
  6253
sl@0
  6254
  buf2 = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  6255
  if (buf2 == NULL)
sl@0
  6256
      {
sl@0
  6257
      mp4free(buf);
sl@0
  6258
      return -1;
sl@0
  6259
      }
sl@0
  6260
sl@0
  6261
  /* Size */
sl@0
  6262
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  6263
  i += 4;
sl@0
  6264
sl@0
  6265
  /* Atom type */
sl@0
  6266
  insertu32(buf+i, (mp4_u32)ATOMTYPE_STCO);
sl@0
  6267
  i += 4;
sl@0
  6268
sl@0
  6269
  /* Version and flags */
sl@0
  6270
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6271
  i += 4;
sl@0
  6272
sl@0
  6273
  /* Entry count */
sl@0
  6274
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
sl@0
  6275
  i += 4;
sl@0
  6276
sl@0
  6277
  if (writeFile(handle, buf, i) < 0)
sl@0
  6278
  {
sl@0
  6279
    mp4free(buf);
sl@0
  6280
    mp4free(buf2);
sl@0
  6281
sl@0
  6282
    return -1;
sl@0
  6283
  }
sl@0
  6284
sl@0
  6285
  /* Chunk offsets */
sl@0
  6286
sl@0
  6287
  /* Seek to the beginning of temporary file */
sl@0
  6288
sl@0
  6289
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6290
  {
sl@0
  6291
    mp4free(buf);
sl@0
  6292
    mp4free(buf2);
sl@0
  6293
    return -1;
sl@0
  6294
  }
sl@0
  6295
sl@0
  6296
  left = handle->audioSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
sl@0
  6297
sl@0
  6298
  while (left)
sl@0
  6299
  {
sl@0
  6300
    if (left > bufferSize)
sl@0
  6301
      bytestoread = bufferSize;
sl@0
  6302
    else
sl@0
  6303
      bytestoread = left;
sl@0
  6304
sl@0
  6305
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6306
    {
sl@0
  6307
      mp4free(buf);
sl@0
  6308
      mp4free(buf2);
sl@0
  6309
sl@0
  6310
      return -1;
sl@0
  6311
    }
sl@0
  6312
sl@0
  6313
    for (j = 0; j < bytestoread; j += 8)
sl@0
  6314
    {
sl@0
  6315
      ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
sl@0
  6316
      insertu32(buf + j/2, ((mp4_u64 *)buf2)[j / 8]);
sl@0
  6317
    }
sl@0
  6318
sl@0
  6319
    if (writeFile(handle, buf, bytestoread/2) < 0)
sl@0
  6320
    {
sl@0
  6321
      mp4free(buf);
sl@0
  6322
      mp4free(buf2);
sl@0
  6323
sl@0
  6324
      return -1;
sl@0
  6325
    }
sl@0
  6326
sl@0
  6327
    left -= bytestoread;
sl@0
  6328
  }
sl@0
  6329
sl@0
  6330
  mp4free(buf);
sl@0
  6331
  mp4free(buf2);
sl@0
  6332
sl@0
  6333
sl@0
  6334
  return 0;
sl@0
  6335
}
sl@0
  6336
sl@0
  6337
/*
sl@0
  6338
 * Function:
sl@0
  6339
 *
sl@0
  6340
 *   mp4_i32 writeAudioCO64LongClip(MP4HandleImp handle,
sl@0
  6341
 *                                  trakSize *ts)
sl@0
  6342
 *
sl@0
  6343
 * Description:
sl@0
  6344
 *
sl@0
  6345
 *   Write audio CO64 atom.
sl@0
  6346
 *
sl@0
  6347
 * Parameters:
sl@0
  6348
 *
sl@0
  6349
 *   handle   MP4 library handle
sl@0
  6350
 *   ts       Atom sizes
sl@0
  6351
 *
sl@0
  6352
 * Return value:
sl@0
  6353
 *
sl@0
  6354
 *   0        Success
sl@0
  6355
 *   -1       Error
sl@0
  6356
 *
sl@0
  6357
 */
sl@0
  6358
mp4_i32 writeAudioCO64LongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  6359
{
sl@0
  6360
  mp4_u8   *buf;
sl@0
  6361
  mp4_u8   *buf2;
sl@0
  6362
  mp4_u32  i = 0;
sl@0
  6363
  mp4_u32  j;
sl@0
  6364
  mp4_u32  left;
sl@0
  6365
  mp4_u32  bytestoread;
sl@0
  6366
  mp4_u32  bufferSize = (METADATA_COPY_BUFFERSIZE/sizeof(mp4_u64)) * sizeof(mp4_u64); //must be a multiple of u64
sl@0
  6367
  																					  //METADATA_COPY_BUFFERSIZE is only guaranteed to be a multiple of 4
sl@0
  6368
sl@0
  6369
sl@0
  6370
  buf = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  6371
  if (buf == NULL)
sl@0
  6372
    return -1;
sl@0
  6373
sl@0
  6374
  buf2 = (mp4_u8 *)mp4malloc(bufferSize);
sl@0
  6375
  if (buf2 == NULL)
sl@0
  6376
      {
sl@0
  6377
      mp4free(buf);
sl@0
  6378
      return -1;
sl@0
  6379
      }
sl@0
  6380
sl@0
  6381
  /* Size */
sl@0
  6382
  insertu32(buf+i, (mp4_u32)ts->stco);
sl@0
  6383
  i += 4;
sl@0
  6384
sl@0
  6385
  /* Atom type */
sl@0
  6386
  insertu32(buf+i, (mp4_u32)ATOMTYPE_CO64);
sl@0
  6387
  i += 4;
sl@0
  6388
sl@0
  6389
  /* Version and flags */
sl@0
  6390
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6391
  i += 4;
sl@0
  6392
sl@0
  6393
  /* Entry count */
sl@0
  6394
  insertu32(buf+i, (mp4_u32)handle->audioSampleTable->stcoEntryCount);
sl@0
  6395
  i += 4;
sl@0
  6396
sl@0
  6397
  if (writeFile(handle, buf, i) < 0)
sl@0
  6398
  {
sl@0
  6399
    mp4free(buf);
sl@0
  6400
    mp4free(buf2);
sl@0
  6401
sl@0
  6402
    return -1;
sl@0
  6403
  }
sl@0
  6404
sl@0
  6405
  /* Chunk offsets */
sl@0
  6406
sl@0
  6407
  /* Seek to the beginning of temporary file */
sl@0
  6408
sl@0
  6409
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6410
  {
sl@0
  6411
    mp4free(buf);
sl@0
  6412
    mp4free(buf2);
sl@0
  6413
    return -1;
sl@0
  6414
  }
sl@0
  6415
sl@0
  6416
  left = handle->audioSampleTable->stcoEntryCount * 8; /* Bytes left in the file */
sl@0
  6417
sl@0
  6418
  while (left)
sl@0
  6419
  {
sl@0
  6420
    if (left > bufferSize)
sl@0
  6421
      bytestoread = bufferSize;
sl@0
  6422
    else
sl@0
  6423
      bytestoread = left;
sl@0
  6424
sl@0
  6425
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6426
    {
sl@0
  6427
      mp4free(buf);
sl@0
  6428
      mp4free(buf2);
sl@0
  6429
sl@0
  6430
      return -1;
sl@0
  6431
    }
sl@0
  6432
sl@0
  6433
    for (j = 0; j < bytestoread; j += 8)
sl@0
  6434
    {
sl@0
  6435
      ((mp4_u64 *)buf2)[j / 8] += (handle->metaDataSize + MDAT_HEADER_SIZE); /* Update chunk offsets */
sl@0
  6436
      insertu64(buf + j, ((mp4_u64 *)buf2)[j / 8]);
sl@0
  6437
    }
sl@0
  6438
sl@0
  6439
    if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  6440
    {
sl@0
  6441
      mp4free(buf);
sl@0
  6442
      mp4free(buf2);
sl@0
  6443
sl@0
  6444
      return -1;
sl@0
  6445
    }
sl@0
  6446
sl@0
  6447
    left -= bytestoread;
sl@0
  6448
  }
sl@0
  6449
sl@0
  6450
  mp4free(buf);
sl@0
  6451
  mp4free(buf2);
sl@0
  6452
sl@0
  6453
sl@0
  6454
  return 0;
sl@0
  6455
}
sl@0
  6456
sl@0
  6457
sl@0
  6458
/*
sl@0
  6459
 * Function:
sl@0
  6460
 *
sl@0
  6461
 *   mp4_i32 writeMediaData(MP4HandleImp handle)
sl@0
  6462
 *
sl@0
  6463
 * Description:
sl@0
  6464
 *
sl@0
  6465
 *   This function writes media data to the output file.
sl@0
  6466
 *
sl@0
  6467
 *   Before writing media data to the output file, meta data has
sl@0
  6468
 *   been written to the file. Media data that is in tmpfile is
sl@0
  6469
 *   read from there and written to the end of the output file.
sl@0
  6470
 *
sl@0
  6471
 * Parameters:
sl@0
  6472
 *
sl@0
  6473
 *   handle    MP4 library handle
sl@0
  6474
 *
sl@0
  6475
 * Return value:
sl@0
  6476
 *
sl@0
  6477
 *   0         Success
sl@0
  6478
 *   -1        Error
sl@0
  6479
 *
sl@0
  6480
 */
sl@0
  6481
mp4_i32 writeMediaData(MP4HandleImp handle)
sl@0
  6482
{
sl@0
  6483
  mp4_u8  *buf;
sl@0
  6484
  mp4_u32 i = 0;
sl@0
  6485
  mp4_u64 left;
sl@0
  6486
  mp4_u32 bytestoread;
sl@0
  6487
sl@0
  6488
sl@0
  6489
  buf = (mp4_u8 *)mp4malloc(1024);
sl@0
  6490
  if (buf == NULL)
sl@0
  6491
    return -1;
sl@0
  6492
sl@0
  6493
sl@0
  6494
  i = formatMdatHeader(buf, handle->bytesInTmpFile);
sl@0
  6495
  if (writeFile(handle, buf, i) < 0)
sl@0
  6496
  {
sl@0
  6497
    mp4free(buf);
sl@0
  6498
sl@0
  6499
    return -1;
sl@0
  6500
  }
sl@0
  6501
sl@0
  6502
  /* Seek to the beginning of tmpfile */
sl@0
  6503
  if (seekTmpFileAbs(handle, 0) < 0)
sl@0
  6504
      {
sl@0
  6505
      mp4free(buf);
sl@0
  6506
      return -1;
sl@0
  6507
      }
sl@0
  6508
sl@0
  6509
  left = handle->bytesInTmpFile;
sl@0
  6510
sl@0
  6511
  while (left)
sl@0
  6512
  {
sl@0
  6513
    if (left > 1024)
sl@0
  6514
      bytestoread = 1024;
sl@0
  6515
    else
sl@0
  6516
      bytestoread = left;
sl@0
  6517
sl@0
  6518
    if (readTmpFile(handle, buf, bytestoread) < 0)
sl@0
  6519
    {
sl@0
  6520
      mp4free(buf);
sl@0
  6521
sl@0
  6522
      return -1;
sl@0
  6523
    }
sl@0
  6524
sl@0
  6525
    if (writeFile(handle, buf, bytestoread) < 0)
sl@0
  6526
    {
sl@0
  6527
      mp4free(buf);
sl@0
  6528
sl@0
  6529
      return -1;
sl@0
  6530
    }
sl@0
  6531
sl@0
  6532
    left -= bytestoread;
sl@0
  6533
  }
sl@0
  6534
sl@0
  6535
  mp4free(buf);
sl@0
  6536
sl@0
  6537
  return 0;
sl@0
  6538
}
sl@0
  6539
sl@0
  6540
/*
sl@0
  6541
 * Function:
sl@0
  6542
 *
sl@0
  6543
 *   mp4_i32 insertu64(mp4_u8 *buf,
sl@0
  6544
 *                     mp4_u64 value)
sl@0
  6545
 *
sl@0
  6546
 * Description:
sl@0
  6547
 *
sl@0
  6548
 *   This function writes value into buf taking into account the endianism
sl@0
  6549
 *   of the current computer.
sl@0
  6550
 *
sl@0
  6551
 *   It is assumed that the caller of the function has allocated enough
sl@0
  6552
 *   space for buf.
sl@0
  6553
 *
sl@0
  6554
 * Parameters:
sl@0
  6555
 *
sl@0
  6556
 *   buf      Buffer to write to
sl@0
  6557
 *   value    Value to write to buf
sl@0
  6558
 *
sl@0
  6559
 * Return value:
sl@0
  6560
 *
sl@0
  6561
 *   0        Success
sl@0
  6562
 *
sl@0
  6563
 */
sl@0
  6564
mp4_i32 insertu64(mp4_u8 *buf, mp4_u64 value)
sl@0
  6565
{
sl@0
  6566
  mp4_u64 u64;
sl@0
  6567
sl@0
  6568
sl@0
  6569
  u64 = u64endian(value);
sl@0
  6570
  mp4memcpy(buf, &u64, sizeof(mp4_u64));
sl@0
  6571
sl@0
  6572
  return 0;
sl@0
  6573
}
sl@0
  6574
sl@0
  6575
sl@0
  6576
/*
sl@0
  6577
 * Function:
sl@0
  6578
 *
sl@0
  6579
 *   mp4_i32 insertu32(mp4_u8 *buf,
sl@0
  6580
 *                     mp4_u32 value)
sl@0
  6581
 *
sl@0
  6582
 * Description:
sl@0
  6583
 *
sl@0
  6584
 *   This function writes value into buf taking into account the endianism
sl@0
  6585
 *   of the current computer.
sl@0
  6586
 *
sl@0
  6587
 *   It is assumed that the caller of the function has allocated enough
sl@0
  6588
 *   space for buf.
sl@0
  6589
 *
sl@0
  6590
 * Parameters:
sl@0
  6591
 *
sl@0
  6592
 *   buf      Buffer to write to
sl@0
  6593
 *   value    Value to write to buf
sl@0
  6594
 *
sl@0
  6595
 * Return value:
sl@0
  6596
 *
sl@0
  6597
 *   0        Success
sl@0
  6598
 *
sl@0
  6599
 */
sl@0
  6600
mp4_i32 insertu32(mp4_u8 *buf, mp4_u32 value)
sl@0
  6601
{
sl@0
  6602
  mp4_u32 u32;
sl@0
  6603
sl@0
  6604
sl@0
  6605
  u32 = u32endian(value);
sl@0
  6606
  mp4memcpy(buf, &u32, 4);
sl@0
  6607
sl@0
  6608
  return 0;
sl@0
  6609
}
sl@0
  6610
sl@0
  6611
sl@0
  6612
/*
sl@0
  6613
 * Function:
sl@0
  6614
 *
sl@0
  6615
 *   mp4_i32 insertu16(mp4_u8 *buf,
sl@0
  6616
 *                     mp4_u16 value)
sl@0
  6617
 *
sl@0
  6618
 * Description:
sl@0
  6619
 *
sl@0
  6620
 *   This function writes value into buf taking into account the endianism
sl@0
  6621
 *   of the current computer.
sl@0
  6622
 *
sl@0
  6623
 *   It is assumed that the caller of the function has allocated enough
sl@0
  6624
 *   space for buf.
sl@0
  6625
 *
sl@0
  6626
 * Parameters:
sl@0
  6627
 *
sl@0
  6628
 *   buf      Buffer to write to
sl@0
  6629
 *   value    Value to write to buf
sl@0
  6630
 *
sl@0
  6631
 * Return value:
sl@0
  6632
 *
sl@0
  6633
 *   0        Success
sl@0
  6634
 *
sl@0
  6635
 */
sl@0
  6636
mp4_i32 insertu16(mp4_u8 *buf, mp4_u16 value)
sl@0
  6637
{
sl@0
  6638
  mp4_u16 u16;
sl@0
  6639
sl@0
  6640
sl@0
  6641
  u16 = u16endian(value);
sl@0
  6642
  mp4memcpy(buf, &u16, 2);
sl@0
  6643
sl@0
  6644
  return 0;
sl@0
  6645
}
sl@0
  6646
sl@0
  6647
sl@0
  6648
/*
sl@0
  6649
 * Function:
sl@0
  6650
 *
sl@0
  6651
 *   mp4_i32 writeMetaDataTmp(MP4HandleImp handle)
sl@0
  6652
 *
sl@0
  6653
 * Description:
sl@0
  6654
 *
sl@0
  6655
 *   This function writes metadata accumulated in memory to the disk.
sl@0
  6656
 *
sl@0
  6657
 * Parameters:
sl@0
  6658
 *
sl@0
  6659
 *   handle    MP4 library handle
sl@0
  6660
 *
sl@0
  6661
 * Return value:
sl@0
  6662
 *
sl@0
  6663
 *   0         Success
sl@0
  6664
 *   -1        Error
sl@0
  6665
 *
sl@0
  6666
 */
sl@0
  6667
mp4_i32 writeMetaDataTmp(MP4HandleImp handle)
sl@0
  6668
{
sl@0
  6669
  PRINT((_L("e_writemetadatatmp 1")));
sl@0
  6670
  if (handle->videoSampleTable)
sl@0
  6671
  {
sl@0
  6672
  	PRINT((_L("e_writemetadatatmp_writemetadata_video 1")));
sl@0
  6673
    if (writeMetaDataFileNum(handle,
sl@0
  6674
                             (mp4_u8 *)handle->videoSampleTable->sttsSampleCount,
sl@0
  6675
                             handle->videoSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
sl@0
  6676
                             METADATAFILE_VIDEO_STTS_SAMPLE_COUNT) < 0)
sl@0
  6677
      return -1;
sl@0
  6678
sl@0
  6679
    if (writeMetaDataFileNum(handle,
sl@0
  6680
                             (mp4_u8 *)handle->videoSampleTable->sttsSampleDelta,
sl@0
  6681
                             handle->videoSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
sl@0
  6682
                             METADATAFILE_VIDEO_STTS_SAMPLE_DELTA) < 0)
sl@0
  6683
      return -1;
sl@0
  6684
sl@0
  6685
    if (writeMetaDataFileNum(handle,
sl@0
  6686
                             (mp4_u8 *)handle->videoSampleTable->stszEntrySize,
sl@0
  6687
                             handle->videoSampleTable->stszCurrentSampleCount * sizeof(mp4_u32),
sl@0
  6688
                             METADATAFILE_VIDEO_STSZ_ENTRY_SIZE) < 0)
sl@0
  6689
      return -1;
sl@0
  6690
sl@0
  6691
    if (writeMetaDataFileNum(handle,
sl@0
  6692
                             (mp4_u8 *)handle->videoSampleTable->stcoChunkOffset,
sl@0
  6693
                             handle->videoSampleTable->stcoCurrentEntryCount * sizeof(mp4_u64),
sl@0
  6694
                             METADATAFILE_VIDEO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6695
      return -1;
sl@0
  6696
sl@0
  6697
    if (writeMetaDataFileNum(handle,
sl@0
  6698
                             (mp4_u8 *)handle->videoSampleTable->stssSampleNumber,
sl@0
  6699
                             handle->videoSampleTable->stssCurrentEntryCount * sizeof(mp4_u32),
sl@0
  6700
                             METADATAFILE_VIDEO_STSS_SAMPLE_NUMBER) < 0)
sl@0
  6701
      return -1;
sl@0
  6702
sl@0
  6703
    if (writeMetaDataFileNum(handle,
sl@0
  6704
                             (mp4_u8 *)handle->videoSampleTable->sdtpSampleDependency,
sl@0
  6705
                             handle->videoSampleTable->sdtpCurrentEntryCount * sizeof(mp4_u8),
sl@0
  6706
                             METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
sl@0
  6707
      return -1;
sl@0
  6708
  	PRINT((_L("e_writemetadatatmp_writemetadata_video 0")));
sl@0
  6709
  }
sl@0
  6710
sl@0
  6711
  if (handle->audioSampleTable)
sl@0
  6712
  {
sl@0
  6713
  	PRINT((_L("e_writemetadatatmp_writemetadata_audio 1")));
sl@0
  6714
    if (writeMetaDataFileNum(handle,
sl@0
  6715
                             (mp4_u8 *)handle->audioSampleTable->sttsSampleCount,
sl@0
  6716
                             handle->audioSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
sl@0
  6717
                             METADATAFILE_AUDIO_STTS_SAMPLE_COUNT) < 0)
sl@0
  6718
      return -1;
sl@0
  6719
sl@0
  6720
    if (writeMetaDataFileNum(handle,
sl@0
  6721
                             (mp4_u8 *)handle->audioSampleTable->sttsSampleDelta,
sl@0
  6722
                             handle->audioSampleTable->sttsCurrentEntryCount * sizeof(mp4_u32),
sl@0
  6723
                             METADATAFILE_AUDIO_STTS_SAMPLE_DELTA) < 0)
sl@0
  6724
      return -1;
sl@0
  6725
sl@0
  6726
    if (writeMetaDataFileNum(handle,
sl@0
  6727
                             (mp4_u8 *)handle->audioSampleTable->stszEntrySize,
sl@0
  6728
                             handle->audioSampleTable->stszCurrentSampleCount * sizeof(mp4_u32),
sl@0
  6729
                             METADATAFILE_AUDIO_STSZ_ENTRY_SIZE) < 0)
sl@0
  6730
      return -1;
sl@0
  6731
sl@0
  6732
    if (writeMetaDataFileNum(handle,
sl@0
  6733
                             (mp4_u8 *)handle->audioSampleTable->stcoChunkOffset,
sl@0
  6734
                             handle->audioSampleTable->stcoCurrentEntryCount * sizeof(mp4_u64),
sl@0
  6735
                             METADATAFILE_AUDIO_STCO_CHUNK_OFFSET) < 0)
sl@0
  6736
      return -1;
sl@0
  6737
  	PRINT((_L("e_writemetadatatmp_writemetadata_audio 0")));      
sl@0
  6738
  }
sl@0
  6739
sl@0
  6740
	if (handle->videoSampleTable)
sl@0
  6741
		{
sl@0
  6742
  		handle->videoSampleTable->sttsCurrentEntryCount  = 0;
sl@0
  6743
  		handle->videoSampleTable->stszCurrentSampleCount = 0;
sl@0
  6744
  		handle->videoSampleTable->stcoCurrentEntryCount  = 0;
sl@0
  6745
  		handle->videoSampleTable->stssCurrentEntryCount  = 0;
sl@0
  6746
  		handle->videoSampleTable->sdtpCurrentEntryCount  = 0;  
sl@0
  6747
		}
sl@0
  6748
sl@0
  6749
	if (handle->audioSampleTable)
sl@0
  6750
		{		
sl@0
  6751
  		handle->audioSampleTable->sttsCurrentEntryCount  = 0;
sl@0
  6752
  		handle->audioSampleTable->stszCurrentSampleCount = 0;
sl@0
  6753
  		handle->audioSampleTable->stcoCurrentEntryCount  = 0;		
sl@0
  6754
		}
sl@0
  6755
sl@0
  6756
  handle->metaDataBlocks = 0;
sl@0
  6757
  handle->metaDataOnDisk = MP4TRUE;
sl@0
  6758
sl@0
  6759
  PRINT((_L("e_writemetadatatmp 0")));
sl@0
  6760
  return 0;
sl@0
  6761
}
sl@0
  6762
sl@0
  6763
/*
sl@0
  6764
 * Function:
sl@0
  6765
 *
sl@0
  6766
 *   mp4_i32 writeSQCP(MP4HandleImp handle,
sl@0
  6767
 *                     trakSize *ts)
sl@0
  6768
 *
sl@0
  6769
 * Description:
sl@0
  6770
 *
sl@0
  6771
 *   Write SQCP atom.
sl@0
  6772
 *
sl@0
  6773
 * Parameters:
sl@0
  6774
 *
sl@0
  6775
 *   handle   MP4 library handle
sl@0
  6776
 *   ts       Atom sizes
sl@0
  6777
 *
sl@0
  6778
 * Return value:
sl@0
  6779
 *
sl@0
  6780
 *   0        Success
sl@0
  6781
 *   -1       Error
sl@0
  6782
 *
sl@0
  6783
 */
sl@0
  6784
mp4_i32  writeSQCP(MP4HandleImp handle, trakSize *ts)
sl@0
  6785
{
sl@0
  6786
  mp4_u8  *buf;
sl@0
  6787
  mp4_u32  i = 0;
sl@0
  6788
sl@0
  6789
sl@0
  6790
  buf = (mp4_u8 *)mp4malloc(36);
sl@0
  6791
  if (buf == NULL)
sl@0
  6792
    return -1;
sl@0
  6793
sl@0
  6794
  /* Size */
sl@0
  6795
  insertu32(buf+i, (mp4_u32)ts->sqcp);
sl@0
  6796
  i += 4;
sl@0
  6797
sl@0
  6798
  /* Atom type */
sl@0
  6799
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SQCP);
sl@0
  6800
  i += 4;
sl@0
  6801
sl@0
  6802
  /* Reserved */
sl@0
  6803
  buf[i++] = 0;
sl@0
  6804
  buf[i++] = 0;
sl@0
  6805
  buf[i++] = 0;
sl@0
  6806
  buf[i++] = 0;
sl@0
  6807
  buf[i++] = 0;
sl@0
  6808
  buf[i++] = 0;
sl@0
  6809
sl@0
  6810
  /* Data reference index */
sl@0
  6811
  insertu16(buf+i, (mp4_u16)1);
sl@0
  6812
  i += 2;
sl@0
  6813
sl@0
  6814
  /* Reserved */
sl@0
  6815
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6816
  i += 4;
sl@0
  6817
sl@0
  6818
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6819
  i += 4;
sl@0
  6820
sl@0
  6821
  insertu16(buf+i, (mp4_u16)2);
sl@0
  6822
  i += 2;
sl@0
  6823
sl@0
  6824
  insertu16(buf+i, (mp4_u16)16);
sl@0
  6825
  i += 2;
sl@0
  6826
sl@0
  6827
  insertu32(buf+i, (mp4_u32)0);
sl@0
  6828
  i += 4;
sl@0
  6829
sl@0
  6830
  /* Timescale */
sl@0
  6831
  insertu16(buf+i, (mp4_u16)handle->audioTimeScale);
sl@0
  6832
  i += 2;
sl@0
  6833
sl@0
  6834
  /* Reserved */
sl@0
  6835
  insertu16(buf+i, (mp4_u16)0);
sl@0
  6836
  i += 2;
sl@0
  6837
sl@0
  6838
  if (writeFile(handle, buf, 36) < 0)
sl@0
  6839
  {
sl@0
  6840
    mp4free(buf);
sl@0
  6841
sl@0
  6842
    return -1;
sl@0
  6843
  }
sl@0
  6844
sl@0
  6845
  if (writeDQCP(handle, ts) < 0)
sl@0
  6846
  {
sl@0
  6847
    mp4free(buf);
sl@0
  6848
sl@0
  6849
    return -1;
sl@0
  6850
  }
sl@0
  6851
sl@0
  6852
  mp4free(buf);
sl@0
  6853
sl@0
  6854
  return 0;
sl@0
  6855
}
sl@0
  6856
sl@0
  6857
/*
sl@0
  6858
 * Function:
sl@0
  6859
 *
sl@0
  6860
 *   mp4_i32 writeDQCP(MP4HandleImp handle,
sl@0
  6861
 *                     trakSize *ts)
sl@0
  6862
 *
sl@0
  6863
 * Description:
sl@0
  6864
 *
sl@0
  6865
 *   Write DQCP atom.
sl@0
  6866
 *
sl@0
  6867
 * Parameters:
sl@0
  6868
 *
sl@0
  6869
 *   handle   MP4 library handle
sl@0
  6870
 *   ts       Atom sizes
sl@0
  6871
 *
sl@0
  6872
 * Return value:
sl@0
  6873
 *
sl@0
  6874
 *   0        Success
sl@0
  6875
 *   -1       Error
sl@0
  6876
 *
sl@0
  6877
 */
sl@0
  6878
mp4_i32 writeDQCP(MP4HandleImp handle, trakSize *ts)
sl@0
  6879
{
sl@0
  6880
  mp4_u8  buf[14];
sl@0
  6881
  mp4_u32  i = 0;
sl@0
  6882
sl@0
  6883
sl@0
  6884
  /* Size */
sl@0
  6885
  insertu32(buf+i, (mp4_u32)ts->dqcp);
sl@0
  6886
  i += 4;
sl@0
  6887
sl@0
  6888
  /* Atom type */
sl@0
  6889
  insertu32(buf+i, (mp4_u32)ATOMTYPE_DQCP);
sl@0
  6890
  i += 4;
sl@0
  6891
sl@0
  6892
  /* Vendor */
sl@0
  6893
  buf[i++] = 'n';
sl@0
  6894
  buf[i++] = 'o';
sl@0
  6895
  buf[i++] = 'k';
sl@0
  6896
  buf[i++] = 'i';
sl@0
  6897
sl@0
  6898
  /* Decoder version */
sl@0
  6899
  buf[i++] = 0;
sl@0
  6900
sl@0
  6901
  /* Mode set */
sl@0
  6902
//  insertu16(buf+i, (mp4_u16)handle->audioModeSet);
sl@0
  6903
//  i += 2;
sl@0
  6904
sl@0
  6905
  /* Mode change period */
sl@0
  6906
//  buf[i++] = 0;
sl@0
  6907
sl@0
  6908
  /* Frames per sample */
sl@0
  6909
  buf[i++] = handle->audioFramesPerSample;
sl@0
  6910
sl@0
  6911
  if (writeFile(handle, buf, 14) < 0)
sl@0
  6912
    return -1;
sl@0
  6913
sl@0
  6914
  return 0;
sl@0
  6915
}
sl@0
  6916
sl@0
  6917
/*
sl@0
  6918
 * Function:
sl@0
  6919
 *
sl@0
  6920
 *   mp4_i32 calculateES_DescriptorSize(mp4_u32 type)
sl@0
  6921
 *
sl@0
  6922
 * Description:
sl@0
  6923
 *
sl@0
  6924
 *   Calculated the ES_Descriptor size inside the ESDS box.
sl@0
  6925
 *    Updates handle->ES_DescriptorSize;
sl@0
  6926
 *
sl@0
  6927
 * Parameters:
sl@0
  6928
 *
sl@0
  6929
 *   handle   MP4 library handle
sl@0
  6930
 *  type        the media type:
sl@0
  6931
 *                  MP4_TYPE_QCELP_13K
sl@0
  6932
 *                  MP4_TYPE_MPEG_AUDIO
sl@0
  6933
 *                  MP4_TYPE_MPEG4_VIDEO 
sl@0
  6934
 *
sl@0
  6935
 * Return value:
sl@0
  6936
 *
sl@0
  6937
 *   0        Success
sl@0
  6938
 *
sl@0
  6939
 */
sl@0
  6940
mp4_i32 calculateES_DescriptorSize(MP4HandleImp handle, mp4_u32 type)
sl@0
  6941
{
sl@0
  6942
  mp4_u32 size1, size2, size3;
sl@0
  6943
  mp4_u32 numofsizebytes1, numofsizebytes2, numofsizebytes3;
sl@0
  6944
  mp4_u32 decspecinfosize = 0;
sl@0
  6945
sl@0
  6946
  if (((type & MP4_TYPE_QCELP_13K) && (handle->qcelpStoredAsMPEGAudio)) ||
sl@0
  6947
        (type & MP4_TYPE_MPEG4_AUDIO))
sl@0
  6948
    decspecinfosize = handle->audioDecSpecificInfoSize;
sl@0
  6949
  else /* MPEG video case */
sl@0
  6950
    decspecinfosize = handle->videoDecSpecificInfoSize;
sl@0
  6951
sl@0
  6952
  size1 = decspecinfosize;
sl@0
  6953
  if (size1 < 128)
sl@0
  6954
    numofsizebytes1 = 1;
sl@0
  6955
  else
sl@0
  6956
  {
sl@0
  6957
      numofsizebytes1 = 1;
sl@0
  6958
      while ( size1 >= 128 ) 
sl@0
  6959
      {
sl@0
  6960
        size1 = size1 >> 7;
sl@0
  6961
        numofsizebytes1++;
sl@0
  6962
      }  
sl@0
  6963
  }
sl@0
  6964
sl@0
  6965
  size2 = 14 + numofsizebytes1 + decspecinfosize;
sl@0
  6966
   if (size2 < 128)
sl@0
  6967
      numofsizebytes2 = 1;
sl@0
  6968
    else
sl@0
  6969
    {
sl@0
  6970
        numofsizebytes2 = 1;
sl@0
  6971
        while ( size2 >= 128 ) 
sl@0
  6972
        {
sl@0
  6973
          size2 = size2 >> 7;
sl@0
  6974
          numofsizebytes2++;
sl@0
  6975
        }  
sl@0
  6976
    }
sl@0
  6977
sl@0
  6978
  size3 = 21 + numofsizebytes1 + numofsizebytes2 + decspecinfosize;
sl@0
  6979
   if (size3 < 128)
sl@0
  6980
      numofsizebytes3 = 1;
sl@0
  6981
    else
sl@0
  6982
    {
sl@0
  6983
        numofsizebytes3 = 1;
sl@0
  6984
        while ( size3 >= 128 ) 
sl@0
  6985
        {
sl@0
  6986
          size3 = size3 >> 7;
sl@0
  6987
          numofsizebytes3++;
sl@0
  6988
        }  
sl@0
  6989
    }
sl@0
  6990
sl@0
  6991
    /* ES_DescriptorSize contains the size of the ES_Descriptor Field, including the 0x03 (ES_ID Tag) */
sl@0
  6992
    handle->ES_DescriptorSize =  21 + numofsizebytes1 + numofsizebytes2 + decspecinfosize + numofsizebytes3 + 1;
sl@0
  6993
    return 0;
sl@0
  6994
}
sl@0
  6995
sl@0
  6996
/*
sl@0
  6997
 * Function:
sl@0
  6998
 *
sl@0
  6999
 *   mp4_i32 writeUDTA(MP4HandleImp handle,
sl@0
  7000
 *                     userDataAtom *udta)
sl@0
  7001
 *
sl@0
  7002
 * Description:
sl@0
  7003
 *
sl@0
  7004
 *   Write UDTA atom.
sl@0
  7005
 *
sl@0
  7006
 * Parameters:
sl@0
  7007
 *
sl@0
  7008
 *   handle   MP4 library handle
sl@0
  7009
 *   ts       Atom sizes
sl@0
  7010
 *
sl@0
  7011
 * Return value:
sl@0
  7012
 *
sl@0
  7013
 *   0        Success
sl@0
  7014
 *   -1       Error
sl@0
  7015
 *
sl@0
  7016
 */
sl@0
  7017
mp4_i32  writeUDTA(MP4HandleImp handle, userDataAtom *udta)
sl@0
  7018
{
sl@0
  7019
  mp4_u8  buf[8];
sl@0
  7020
  mp4_u32 i = 0;
sl@0
  7021
sl@0
  7022
sl@0
  7023
  /* Size */
sl@0
  7024
  insertu32(buf+i, 8 + (mp4_u32)udta->atomcontentsize);
sl@0
  7025
  i += 4;
sl@0
  7026
sl@0
  7027
  /* Atom type */
sl@0
  7028
  insertu32(buf+i, (mp4_u32)ATOMTYPE_UDTA);
sl@0
  7029
  i += 4;
sl@0
  7030
sl@0
  7031
  if (writeFile(handle, buf, 8) < 0)
sl@0
  7032
    return -1;
sl@0
  7033
sl@0
  7034
  if (writeFile(handle, udta->contentdata, udta->atomcontentsize) < 0)
sl@0
  7035
    return -1;
sl@0
  7036
sl@0
  7037
  return 0;
sl@0
  7038
}
sl@0
  7039
sl@0
  7040
/*
sl@0
  7041
 * Function:
sl@0
  7042
 *
sl@0
  7043
 *   mp4_i32 updateVideoDependencyMetaData(MP4HandleImp handle,
sl@0
  7044
 *                                         mp4_u8 aDependsOn,
sl@0
  7045
 *                                         mp4_u8 aIsDependentOn,
sl@0
  7046
 *                                         mp4_u8 aHasRedundancy)
sl@0
  7047
 *
sl@0
  7048
 * Description:
sl@0
  7049
 *
sl@0
  7050
 *   Updates SDTP video dependency data
sl@0
  7051
 *
sl@0
  7052
 * Parameters:
sl@0
  7053
 *
sl@0
  7054
 *   handle          MP4 library handle
sl@0
  7055
 *   aDependsOn      This frame's dependency on other frames
sl@0
  7056
 *   aIsDependentOn  Other frames's dependency on this frame
sl@0
  7057
 *   aHasRedundancy  Whether there is redundant coding in this frame
sl@0
  7058
 *
sl@0
  7059
 * Return value:
sl@0
  7060
 *
sl@0
  7061
 *   0        Success
sl@0
  7062
 *   -1       Error
sl@0
  7063
 *
sl@0
  7064
 */
sl@0
  7065
mp4_i32 updateVideoDependencyMetaData(MP4HandleImp handle, mp4_u8 aDependsOn, mp4_u8 aIsDependentOn, mp4_u8 aHasRedundancy)
sl@0
  7066
{
sl@0
  7067
  if (handle->flags & MP4_FLAG_LONGCLIP)
sl@0
  7068
  {
sl@0
  7069
    if (handle->videoSampleTable->sdtpCurrentEntryCount == handle->videoSampleTable->sdtpMaxEntryCount)
sl@0
  7070
    {
sl@0
  7071
      void *p;
sl@0
  7072
sl@0
  7073
      p = mp4realloc(handle->videoSampleTable->sdtpSampleDependency,
sl@0
  7074
                     2 * sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount,
sl@0
  7075
                     sizeof(mp4_u8) * handle->videoSampleTable->stssMaxEntryCount);
sl@0
  7076
      if (p == NULL)
sl@0
  7077
        return -1;
sl@0
  7078
sl@0
  7079
      handle->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)p;
sl@0
  7080
sl@0
  7081
      handle->videoSampleTable->sdtpMaxEntryCount *= 2;
sl@0
  7082
    }
sl@0
  7083
sl@0
  7084
    handle->videoSampleTable->sdtpSampleDependency[handle->videoSampleTable->sdtpCurrentEntryCount] = (aDependsOn << 4) | (aIsDependentOn << 2) | (aHasRedundancy);
sl@0
  7085
    handle->videoSampleTable->sdtpCurrentEntryCount++;
sl@0
  7086
    handle->videoSampleTable->sdtpEntryCount++;
sl@0
  7087
  }
sl@0
  7088
  else
sl@0
  7089
  {
sl@0
  7090
    if (handle->videoSampleTable->sdtpEntryCount == handle->videoSampleTable->sdtpMaxEntryCount)
sl@0
  7091
    {
sl@0
  7092
      void *p;
sl@0
  7093
sl@0
  7094
      p = mp4realloc(handle->videoSampleTable->sdtpSampleDependency,
sl@0
  7095
                     2 * sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount,
sl@0
  7096
                     sizeof(mp4_u8) * handle->videoSampleTable->sdtpMaxEntryCount);
sl@0
  7097
      if (p == NULL)
sl@0
  7098
        return -1;
sl@0
  7099
sl@0
  7100
      handle->videoSampleTable->sdtpSampleDependency = (mp4_u8 *)p;
sl@0
  7101
sl@0
  7102
      handle->videoSampleTable->sdtpMaxEntryCount *= 2;
sl@0
  7103
    }
sl@0
  7104
sl@0
  7105
    handle->videoSampleTable->sdtpSampleDependency[handle->videoSampleTable->sdtpEntryCount] = (aDependsOn << 4) | (aIsDependentOn << 2) | (aHasRedundancy);
sl@0
  7106
    handle->videoSampleTable->sdtpEntryCount++;
sl@0
  7107
  }
sl@0
  7108
sl@0
  7109
  return 0;
sl@0
  7110
}
sl@0
  7111
sl@0
  7112
/*
sl@0
  7113
 * Function:
sl@0
  7114
 *
sl@0
  7115
 *   mp4_i32 writeVideoSDTP(MP4HandleImp handle,
sl@0
  7116
 *                          trakSize *ts)
sl@0
  7117
 *
sl@0
  7118
 * Description:
sl@0
  7119
 *
sl@0
  7120
 *   Write video SDTP atom.
sl@0
  7121
 *
sl@0
  7122
 * Parameters:
sl@0
  7123
 *
sl@0
  7124
 *   handle   MP4 library handle
sl@0
  7125
 *   ts       Atom sizes
sl@0
  7126
 *
sl@0
  7127
 * Return value:
sl@0
  7128
 *
sl@0
  7129
 *   0        Success
sl@0
  7130
 *   -1       Error
sl@0
  7131
 *
sl@0
  7132
 */
sl@0
  7133
mp4_i32 writeVideoSDTP(MP4HandleImp handle, trakSize *ts)
sl@0
  7134
{
sl@0
  7135
  mp4_u8  *buf;
sl@0
  7136
  mp4_u32  i = 0;
sl@0
  7137
  mp4_u32  j;
sl@0
  7138
sl@0
  7139
  buf = (mp4_u8 *)mp4malloc(ts->sdtp);
sl@0
  7140
  if (buf == NULL)
sl@0
  7141
    return -1;
sl@0
  7142
sl@0
  7143
  /* Size */
sl@0
  7144
  insertu32(buf+i, (mp4_u32)ts->sdtp);
sl@0
  7145
  i += 4;
sl@0
  7146
sl@0
  7147
  /* Atom type */
sl@0
  7148
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SDTP);
sl@0
  7149
  i += 4;
sl@0
  7150
sl@0
  7151
  /* Version and flags */
sl@0
  7152
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7153
  i += 4;
sl@0
  7154
sl@0
  7155
  /* Sample dependencies */
sl@0
  7156
  for (j = 0; j < handle->videoSampleTable->sdtpEntryCount; j++)
sl@0
  7157
  {
sl@0
  7158
    buf[i++] = (mp4_u8)handle->videoSampleTable->sdtpSampleDependency[j];
sl@0
  7159
  }
sl@0
  7160
sl@0
  7161
  if (writeFile(handle, buf, ts->sdtp) < 0)
sl@0
  7162
  {
sl@0
  7163
    mp4free(buf);
sl@0
  7164
sl@0
  7165
    return -1;
sl@0
  7166
  }
sl@0
  7167
sl@0
  7168
  mp4free(buf);
sl@0
  7169
sl@0
  7170
  return 0;
sl@0
  7171
}
sl@0
  7172
sl@0
  7173
/*
sl@0
  7174
 * Function:
sl@0
  7175
 *
sl@0
  7176
 *   mp4_i32 writeVideoSDTPLongClip(MP4HandleImp handle,
sl@0
  7177
 *                                  trakSize *ts)
sl@0
  7178
 *
sl@0
  7179
 * Description:
sl@0
  7180
 *
sl@0
  7181
 *   Write video SDTP atom.
sl@0
  7182
 *
sl@0
  7183
 * Parameters:
sl@0
  7184
 *
sl@0
  7185
 *   handle   MP4 library handle
sl@0
  7186
 *   ts       Atom sizes
sl@0
  7187
 *
sl@0
  7188
 * Return value:
sl@0
  7189
 *
sl@0
  7190
 *   0        Success
sl@0
  7191
 *   -1       Error
sl@0
  7192
 *
sl@0
  7193
 */
sl@0
  7194
mp4_i32 writeVideoSDTPLongClip(MP4HandleImp handle, trakSize *ts)
sl@0
  7195
{
sl@0
  7196
  mp4_u8   *buf;
sl@0
  7197
  mp4_u8   *buf2;
sl@0
  7198
  mp4_u32  i = 0;
sl@0
  7199
  mp4_u32  left;
sl@0
  7200
  mp4_u32  bytestoread;
sl@0
  7201
sl@0
  7202
sl@0
  7203
  buf = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE);
sl@0
  7204
  if (buf == NULL)
sl@0
  7205
    return -1;
sl@0
  7206
sl@0
  7207
  buf2 = (mp4_u8 *)mp4malloc(METADATA_COPY_BUFFERSIZE / 2);
sl@0
  7208
  if (buf2 == NULL)
sl@0
  7209
    {
sl@0
  7210
    mp4free(buf);
sl@0
  7211
    return -1;
sl@0
  7212
    }
sl@0
  7213
sl@0
  7214
  /* Size */
sl@0
  7215
  insertu32(buf+i, (mp4_u32)ts->sdtp);
sl@0
  7216
  i += 4;
sl@0
  7217
sl@0
  7218
  /* Atom type */
sl@0
  7219
  insertu32(buf+i, (mp4_u32)ATOMTYPE_SDTP);
sl@0
  7220
  i += 4;
sl@0
  7221
sl@0
  7222
  /* Version and flags */
sl@0
  7223
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7224
  i += 4;
sl@0
  7225
sl@0
  7226
  if (writeFile(handle, buf, i) < 0)
sl@0
  7227
  {
sl@0
  7228
    mp4free(buf);
sl@0
  7229
    mp4free(buf2);
sl@0
  7230
sl@0
  7231
    return -1;
sl@0
  7232
  }
sl@0
  7233
sl@0
  7234
  /* Sample count and delta */
sl@0
  7235
sl@0
  7236
  /* Seek to the beginning of temporary files */
sl@0
  7237
sl@0
  7238
  if (seekMetaDataFileNumAbs(handle, 0, METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
sl@0
  7239
      {
sl@0
  7240
      mp4free(buf);
sl@0
  7241
      mp4free(buf2);
sl@0
  7242
      return -1;
sl@0
  7243
      }
sl@0
  7244
sl@0
  7245
  left = handle->videoSampleTable->sdtpEntryCount; /* Bytes left in each file */
sl@0
  7246
sl@0
  7247
  while (left)
sl@0
  7248
  {
sl@0
  7249
    if (left > METADATA_COPY_BUFFERSIZE / 2)
sl@0
  7250
      bytestoread = METADATA_COPY_BUFFERSIZE / 2;
sl@0
  7251
    else
sl@0
  7252
      bytestoread = left;
sl@0
  7253
sl@0
  7254
    if (readMetaDataFileNum(handle, buf2, bytestoread, METADATAFILE_VIDEO_SDTP_SAMPLE_DEPENDENCY) < 0)
sl@0
  7255
    {
sl@0
  7256
      mp4free(buf);
sl@0
  7257
      mp4free(buf2);
sl@0
  7258
sl@0
  7259
      return -1;
sl@0
  7260
    }
sl@0
  7261
sl@0
  7262
    if (writeFile(handle, buf2, bytestoread) < 0)
sl@0
  7263
    {
sl@0
  7264
      mp4free(buf);
sl@0
  7265
      mp4free(buf2);
sl@0
  7266
sl@0
  7267
      return -1;
sl@0
  7268
    }
sl@0
  7269
sl@0
  7270
    left -= bytestoread;
sl@0
  7271
  }
sl@0
  7272
sl@0
  7273
  mp4free(buf);
sl@0
  7274
  mp4free(buf2);
sl@0
  7275
sl@0
  7276
sl@0
  7277
  return 0;
sl@0
  7278
}
sl@0
  7279
sl@0
  7280
/*
sl@0
  7281
 * Function:
sl@0
  7282
 *
sl@0
  7283
 *   mp4_i32 writeAVCP(MP4HandleImp handle,
sl@0
  7284
 *                     trakSize *ts)
sl@0
  7285
 *
sl@0
  7286
 * Description:
sl@0
  7287
 *
sl@0
  7288
 *   Write AVCP atom.
sl@0
  7289
 *
sl@0
  7290
 * Parameters:
sl@0
  7291
 *
sl@0
  7292
 *   handle   MP4 library handle
sl@0
  7293
 *   ts       Atom sizes
sl@0
  7294
 *
sl@0
  7295
 * Return value:
sl@0
  7296
 *
sl@0
  7297
 *   0        Success
sl@0
  7298
 *   -1       Error
sl@0
  7299
 *
sl@0
  7300
 */
sl@0
  7301
mp4_i32 writeAVCP(MP4HandleImp handle, trakSize *ts)
sl@0
  7302
{
sl@0
  7303
  mp4_u8  *buf;
sl@0
  7304
  mp4_u32  i = 0;
sl@0
  7305
sl@0
  7306
sl@0
  7307
  buf = (mp4_u8 *)mp4malloc(86+7); // 86 = size of VisualSampleEntry, 7 = size of AVCDecoderConfigurationRecord
sl@0
  7308
  								 // with PPS and SPS sizes set to 0
sl@0
  7309
  if (buf == NULL)
sl@0
  7310
    return -1;
sl@0
  7311
sl@0
  7312
  /* Size */
sl@0
  7313
  insertu32(buf+i, (mp4_u32)ts->avcp);
sl@0
  7314
  i += 4;
sl@0
  7315
sl@0
  7316
  /* Atom type */
sl@0
  7317
  insertu32(buf+i, (mp4_u32)ATOMTYPE_AVCP);
sl@0
  7318
  i += 4;
sl@0
  7319
sl@0
  7320
  /* Reserved */
sl@0
  7321
  buf[i++] = 0;
sl@0
  7322
  buf[i++] = 0;
sl@0
  7323
  buf[i++] = 0;
sl@0
  7324
  buf[i++] = 0;
sl@0
  7325
  buf[i++] = 0;
sl@0
  7326
  buf[i++] = 0;
sl@0
  7327
sl@0
  7328
  /* Data reference index */
sl@0
  7329
  insertu16(buf+i, (mp4_u16)1);
sl@0
  7330
  i += 2;
sl@0
  7331
sl@0
  7332
  /* Reserved */
sl@0
  7333
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7334
  i += 4;
sl@0
  7335
sl@0
  7336
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7337
  i += 4;
sl@0
  7338
sl@0
  7339
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7340
  i += 4;
sl@0
  7341
sl@0
  7342
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7343
  i += 4;
sl@0
  7344
sl@0
  7345
  /* Width */
sl@0
  7346
  insertu16(buf+i, (mp4_u16)handle->videoWidth);
sl@0
  7347
  i += 2;
sl@0
  7348
sl@0
  7349
  /* Height */
sl@0
  7350
  insertu16(buf+i, (mp4_u16)handle->videoHeight);
sl@0
  7351
  i += 2;
sl@0
  7352
sl@0
  7353
  /* Reserved */
sl@0
  7354
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  7355
  i += 4;
sl@0
  7356
sl@0
  7357
  insertu32(buf+i, (mp4_u32)0x00480000);
sl@0
  7358
  i += 4;
sl@0
  7359
sl@0
  7360
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7361
  i += 4;
sl@0
  7362
sl@0
  7363
  insertu16(buf+i, (mp4_u16)1);
sl@0
  7364
  i += 2;
sl@0
  7365
sl@0
  7366
// Compressorname
sl@0
  7367
  buf[i++] = 14;
sl@0
  7368
  insertu32(buf+i, (mp4_u32)0x41564320); // "AVC "
sl@0
  7369
  i += 4;
sl@0
  7370
  insertu32(buf+i, (mp4_u32)0x70617261); // "para"
sl@0
  7371
  i += 4;
sl@0
  7372
  insertu32(buf+i, (mp4_u32)0x6d657465); // "mete"
sl@0
  7373
  i += 4;
sl@0
  7374
  insertu16(buf+i, (mp4_u16)0x7273); // "rs"
sl@0
  7375
  i += 2;
sl@0
  7376
  buf[i++] = 0;
sl@0
  7377
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7378
  i += 4;
sl@0
  7379
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7380
  i += 4;
sl@0
  7381
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7382
  i += 4;
sl@0
  7383
  insertu32(buf+i, (mp4_u32)0);
sl@0
  7384
  i += 4;
sl@0
  7385
sl@0
  7386
  insertu16(buf+i, (mp4_u16)24);
sl@0
  7387
  i += 2;
sl@0
  7388
sl@0
  7389
  insertu16(buf+i, (mp4_u16)0xffff);
sl@0
  7390
  i += 2;
sl@0
  7391
sl@0
  7392
  // AVCC without picparams & seqparams
sl@0
  7393
  mp4memcpy(buf+i, handle->videoDecSpecificInfo, 5); // 5 = configurationVersion + AVCProfileIndication +
sl@0
  7394
													 //     profile_compatibility + AVCLevelIndication +
sl@0
  7395
													 //     '111111' + lengthSizeMinusOne (2 bits)
sl@0
  7396
  i += 5;
sl@0
  7397
  buf[i++] = 0xE0 | 0; // '111' + numOfSequenceParameterSets (5 bits)
sl@0
  7398
  buf[i++] = 0;        // numOfPictureParameterSets
sl@0
  7399
  
sl@0
  7400
  if (writeFile(handle, buf, 86+7) < 0)
sl@0
  7401
  {
sl@0
  7402
    mp4free(buf);
sl@0
  7403
sl@0
  7404
    return -1;
sl@0
  7405
  }
sl@0
  7406
  
sl@0
  7407
  mp4free(buf);
sl@0
  7408
sl@0
  7409
  return 0;
sl@0
  7410
}
sl@0
  7411
sl@0
  7412
/*
sl@0
  7413
 * Function:
sl@0
  7414
 *
sl@0
  7415
 *   mp4_i32 formatMdatHeader(mp4_u8 *buffer, 
sl@0
  7416
 *                            mp4_u64 size)
sl@0
  7417
 *
sl@0
  7418
 * Description:
sl@0
  7419
 *
sl@0
  7420
 *   Formats the MDAT header into buffer
sl@0
  7421
 *
sl@0
  7422
 * Parameters:
sl@0
  7423
 *
sl@0
  7424
 *   buffer   buffer to write the MDAT header into
sl@0
  7425
 *   size     Size of the media data (excluding the MDAT header)
sl@0
  7426
 *
sl@0
  7427
 * Return value:
sl@0
  7428
 *
sl@0
  7429
 *   size of header
sl@0
  7430
 *
sl@0
  7431
 */
sl@0
  7432
mp4_i32 formatMdatHeader(mp4_u8 *buf, mp4_u64 size)
sl@0
  7433
{
sl@0
  7434
  TInt i = 0;
sl@0
  7435
  if (size < MP4_INT_MAX)
sl@0
  7436
  {
sl@0
  7437
  	//insert free box
sl@0
  7438
    insertu32(buf, (mp4_u32)8);
sl@0
  7439
    i += sizeof(mp4_u32);
sl@0
  7440
    insertu32(buf + i, (mp4_u32)ATOMTYPE_FREE);
sl@0
  7441
    i += sizeof(mp4_u32);
sl@0
  7442
    
sl@0
  7443
    //insert mdat box
sl@0
  7444
    insertu32(buf + i, (mp4_u32)size + 8);
sl@0
  7445
    i += sizeof(mp4_u32);
sl@0
  7446
    insertu32(buf + i, (mp4_u32)ATOMTYPE_MDAT);
sl@0
  7447
    i += sizeof(mp4_u32);
sl@0
  7448
  }
sl@0
  7449
  else
sl@0
  7450
  {
sl@0
  7451
    //insert mdat box
sl@0
  7452
    insertu32(buf + i, (mp4_u32)1);
sl@0
  7453
    i += sizeof(mp4_u32);
sl@0
  7454
    insertu32(buf + i, (mp4_u32)ATOMTYPE_MDAT);
sl@0
  7455
    i += sizeof(mp4_u32);
sl@0
  7456
	insertu64(buf + i, (mp4_u64)size + 16);        
sl@0
  7457
	i += sizeof(mp4_u64);
sl@0
  7458
  }
sl@0
  7459
sl@0
  7460
  ASSERT(MDAT_HEADER_SIZE == i);  
sl@0
  7461
  return i;
sl@0
  7462
}
sl@0
  7463
	
sl@0
  7464
// End of File