os/mm/mmplugins/lib3gp/impl/src/atom.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 "mp4buffer.h"
sl@0
    21
#include "mp4endian.h"
sl@0
    22
#include "mp4file.h"
sl@0
    23
#include "mp4utils.h"
sl@0
    24
sl@0
    25
// MACROS
sl@0
    26
// Debug print macro
sl@0
    27
#ifdef _DEBUG
sl@0
    28
#include <e32svr.h>
sl@0
    29
//#define PRINT(x) RDebug::Print x
sl@0
    30
#define PRINT(x)
sl@0
    31
#else
sl@0
    32
#define PRINT(x)
sl@0
    33
#endif
sl@0
    34
sl@0
    35
mp4_i32 readBoxHeader(MP4HandleImp handle, mp4_i64* size, mp4_u32* type);
sl@0
    36
 
sl@0
    37
/*
sl@0
    38
 * Function:
sl@0
    39
 *
sl@0
    40
 *   mp4_i32 metaDataAvailable(MP4HandleImp handle)
sl@0
    41
 *
sl@0
    42
 * Description:
sl@0
    43
 *
sl@0
    44
 *   This function determines whether meta data is available for reading
sl@0
    45
 *   or not.
sl@0
    46
 *
sl@0
    47
 *   Meta data is available if the input is in a file.
sl@0
    48
 *
sl@0
    49
 *   When reading from a stream, meta data is considered available if
sl@0
    50
 *   it is in the beginning of the stream and the entire Moov atom has
sl@0
    51
 *   been received. FTYP atom is allowed before MOOV atom.
sl@0
    52
 *
sl@0
    53
 * Parameters:
sl@0
    54
 *
sl@0
    55
 *   handle   MP4 library handle
sl@0
    56
 *
sl@0
    57
 * Return value:
sl@0
    58
 *
sl@0
    59
 *   0                Meta data is not available because enough data has not
sl@0
    60
 *                    been inserted into the library
sl@0
    61
 *   1                Meta data is available
sl@0
    62
 *   Negative value   Meta data is not available because of fatal error
sl@0
    63
 *
sl@0
    64
 */
sl@0
    65
mp4_i32 metaDataAvailable(MP4HandleImp handle)
sl@0
    66
{
sl@0
    67
  mp4_u32 size;
sl@0
    68
  mp4_u32 type;
sl@0
    69
sl@0
    70
sl@0
    71
  /* Meta data is available if the input is in a file or if a complete file has been inputted as a stream*/
sl@0
    72
sl@0
    73
  if (handle->file)
sl@0
    74
    return 1;
sl@0
    75
sl@0
    76
  /* When reading from a stream, meta data is considered available if
sl@0
    77
     it is in the beginning of the stream and the entire MOOV atom has
sl@0
    78
     been received. FTYP atom is allowed before MOOV atom. */
sl@0
    79
sl@0
    80
  if (!handle->ftypRead)
sl@0
    81
  {
sl@0
    82
    if (peekData(handle, handle->buf, 8) < 0) /* 8 bytes are not available */
sl@0
    83
        return 0;
sl@0
    84
sl@0
    85
    size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
    86
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
    87
sl@0
    88
    if (type == ATOMTYPE_FTYP)
sl@0
    89
    {
sl@0
    90
      if (getBufferedBytes(handle) - handle->position < size) /* FTYP is not available */
sl@0
    91
        return 0;
sl@0
    92
      if ((handle->ftyp = (fileTypeAtom *)mp4malloc(sizeof(fileTypeAtom))) == NULL)
sl@0
    93
        return -100;
sl@0
    94
      if (readFTYP(handle, handle->ftyp) < 0)
sl@0
    95
        return -2;
sl@0
    96
    }
sl@0
    97
  }
sl@0
    98
sl@0
    99
  // Now the ftyp is read. No need to chedk MOOV presence for full files in the memory.
sl@0
   100
  if (handle->LastWriteDataCalled == MP4TRUE)
sl@0
   101
      return 1;
sl@0
   102
sl@0
   103
  if (handle->LastWriteDataCalled == MP4FALSE)
sl@0
   104
  {//Whole stream is not fed to the internal memory yet. 
sl@0
   105
   for (;;)
sl@0
   106
    {
sl@0
   107
      if (peekData(handle, handle->buf, 8) < 0)
sl@0
   108
        return 0;
sl@0
   109
sl@0
   110
      size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   111
      type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
   112
sl@0
   113
      if (type == ATOMTYPE_MOOV)
sl@0
   114
        {
sl@0
   115
        if (getBufferedBytes(handle) - handle->absPosition >= size) /* Entire Moov is available */
sl@0
   116
            {
sl@0
   117
            return 1;        
sl@0
   118
            }
sl@0
   119
        else
sl@0
   120
            {
sl@0
   121
            return 0;
sl@0
   122
            }
sl@0
   123
        }
sl@0
   124
sl@0
   125
      if ((mp4_i32)size <= 0)
sl@0
   126
        return -1;
sl@0
   127
sl@0
   128
      handle->absPosition+=size;
sl@0
   129
    }
sl@0
   130
  }
sl@0
   131
  return 0;
sl@0
   132
}
sl@0
   133
sl@0
   134
sl@0
   135
/*
sl@0
   136
 * Function:
sl@0
   137
 *
sl@0
   138
 *   mp4_i32 readFTYP(MP4HandleImp handle,
sl@0
   139
 *                    fileTypeAtom *ftyp)
sl@0
   140
 *
sl@0
   141
 * Description:
sl@0
   142
 *
sl@0
   143
 *   This function parses one FTYP atom.
sl@0
   144
 *
sl@0
   145
 * Parameters:
sl@0
   146
 *
sl@0
   147
 *   handle             MP4 library handle
sl@0
   148
 *   ftyp               FTYP pointer
sl@0
   149
 *
sl@0
   150
 * Return value:
sl@0
   151
 *
sl@0
   152
 *   Negative integer   Error
sl@0
   153
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
   154
 *
sl@0
   155
 */
sl@0
   156
mp4_i32 readFTYP(MP4HandleImp handle, fileTypeAtom *ftyp)
sl@0
   157
{
sl@0
   158
  mp4_i32 bytesread;
sl@0
   159
  mp4_i32 totalbytesread = 0;
sl@0
   160
  mp4_u32 n = 0;
sl@0
   161
  mp4_i32 compatiblebrandsize = 0;
sl@0
   162
sl@0
   163
sl@0
   164
  if ((ftyp->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
   165
    return -100;
sl@0
   166
sl@0
   167
  bytesread = readAtomHeader(handle, ftyp->atomhdr);
sl@0
   168
  if (bytesread < 0)
sl@0
   169
    return -1;
sl@0
   170
  totalbytesread += bytesread;
sl@0
   171
sl@0
   172
  if (ftyp->atomhdr->type != ATOMTYPE_FTYP)
sl@0
   173
    return -1;
sl@0
   174
sl@0
   175
  if (ftyp->atomhdr->size < 16) // 8(header)+8bytes needed for major and minor brand
sl@0
   176
    return -1;
sl@0
   177
sl@0
   178
  bytesread = readData(handle, handle->buf, 4);
sl@0
   179
  if (bytesread < 0)
sl@0
   180
    return -1;
sl@0
   181
  ftyp->majorBrand = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   182
  totalbytesread += bytesread;
sl@0
   183
sl@0
   184
  bytesread = readData(handle, handle->buf, 4);
sl@0
   185
  if (bytesread < 0)
sl@0
   186
    return -1;
sl@0
   187
  ftyp->minorVersion = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   188
  totalbytesread += bytesread;
sl@0
   189
sl@0
   190
  if (ftyp->atomhdr->size == (mp4_u32)totalbytesread)
sl@0
   191
    return totalbytesread;
sl@0
   192
sl@0
   193
  compatiblebrandsize = (mp4_i32)ftyp->atomhdr->size - totalbytesread;
sl@0
   194
  if ( compatiblebrandsize < 4 )   // at this point we must have at least 1 compatible brand
sl@0
   195
    return -1;
sl@0
   196
  if ( compatiblebrandsize > 20*4) // maximum of 20 compatible brands 4byte entries
sl@0
   197
    return -1;
sl@0
   198
  if ( compatiblebrandsize % 4 ) // must be able to divide by 4
sl@0
   199
    return -1;
sl@0
   200
sl@0
   201
  ftyp->compatibleBrands = (mp4_u32 *)mp4malloc( compatiblebrandsize );
sl@0
   202
  if (ftyp->compatibleBrands == NULL)
sl@0
   203
    return -1;
sl@0
   204
sl@0
   205
  while ((mp4_u32)totalbytesread < ftyp->atomhdr->size)
sl@0
   206
  {
sl@0
   207
    bytesread = readData(handle, handle->buf, 4);
sl@0
   208
    if (bytesread < 0)
sl@0
   209
      return -1;
sl@0
   210
sl@0
   211
    ftyp->compatibleBrands[n] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   212
sl@0
   213
    n++;
sl@0
   214
    totalbytesread += bytesread;
sl@0
   215
  }
sl@0
   216
sl@0
   217
  return totalbytesread;
sl@0
   218
}
sl@0
   219
sl@0
   220
sl@0
   221
/*
sl@0
   222
 * Function:
sl@0
   223
 *
sl@0
   224
 *   mp4_i32 readMetaData(MP4HandleImp handle)
sl@0
   225
 *
sl@0
   226
 * Description:
sl@0
   227
 *
sl@0
   228
 *   This function reads the meta data from the file/stream and stores
sl@0
   229
 *   the information in the atom structures available via handle.
sl@0
   230
 *
sl@0
   231
 * Parameters:
sl@0
   232
 *
sl@0
   233
 *   handle  MP4 library handle
sl@0
   234
 *
sl@0
   235
 * Return value:
sl@0
   236
 *
sl@0
   237
 *   Negative value   Error
sl@0
   238
 *   >= 0             Success. Value tells the number of bytes read.
sl@0
   239
 *
sl@0
   240
 */
sl@0
   241
mp4_i32 readMetaData(MP4HandleImp handle)
sl@0
   242
{
sl@0
   243
  mp4_i32 bytesread;
sl@0
   244
  mp4_i32 totalbytesread = 0;
sl@0
   245
sl@0
   246
sl@0
   247
  if (handle->file)
sl@0
   248
  {
sl@0
   249
    mp4_u64 size;
sl@0
   250
    mp4_u32 type;
sl@0
   251
sl@0
   252
sl@0
   253
    if (seekFileAbs(handle, 0) < 0)
sl@0
   254
      return -1;
sl@0
   255
sl@0
   256
    /* Seek to the start of FTYP atom */
sl@0
   257
sl@0
   258
    for (;;)
sl@0
   259
    {
sl@0
   260
      if (readBoxHeader(handle, &size, &type) <0)
sl@0
   261
        return -1;
sl@0
   262
sl@0
   263
      if (type == ATOMTYPE_FTYP)
sl@0
   264
      {
sl@0
   265
        /* Read FTYP */
sl@0
   266
sl@0
   267
        if ((handle->ftyp = (fileTypeAtom *)mp4malloc(sizeof(fileTypeAtom))) == NULL)
sl@0
   268
          return -100;
sl@0
   269
        bytesread = readFTYP(handle, handle->ftyp);
sl@0
   270
        if (bytesread < 0)
sl@0
   271
          return -3;
sl@0
   272
        totalbytesread += bytesread;
sl@0
   273
sl@0
   274
        break;
sl@0
   275
      }
sl@0
   276
sl@0
   277
      if (size <= 0)
sl@0
   278
        return -1;
sl@0
   279
sl@0
   280
      if (seekFile(handle, size) != 0)
sl@0
   281
        return -1;
sl@0
   282
    }
sl@0
   283
sl@0
   284
    if (seekFileAbs(handle, 0) < 0)
sl@0
   285
      return -1;
sl@0
   286
sl@0
   287
    /* Seek to the start of MOOV atom */
sl@0
   288
    for (;;)
sl@0
   289
    {
sl@0
   290
      if (readBoxHeader(handle, &size, &type) <0)
sl@0
   291
        return -1;
sl@0
   292
sl@0
   293
      if (type == ATOMTYPE_MOOV)
sl@0
   294
        break;
sl@0
   295
sl@0
   296
      if (size <= 0)
sl@0
   297
        return -1;
sl@0
   298
sl@0
   299
      if (seekFile(handle, size) != 0)
sl@0
   300
        return -1;
sl@0
   301
    }
sl@0
   302
  }
sl@0
   303
sl@0
   304
  // If all data of a file is in the memory and the file does not have MOOV box right after FTYP, 
sl@0
   305
  // then we need to seek for the location of the MOOV first
sl@0
   306
sl@0
   307
  if (handle->LastWriteDataCalled == MP4TRUE)
sl@0
   308
  { 
sl@0
   309
    mp4_u32 size;
sl@0
   310
    mp4_u32 type;
sl@0
   311
    // Seek until the beginning of MOOV box.
sl@0
   312
    for(;;)
sl@0
   313
    {
sl@0
   314
        if (peekData(handle, handle->buf, 8) < 0)
sl@0
   315
            return -1;
sl@0
   316
sl@0
   317
        size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   318
        type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
   319
    
sl@0
   320
        if (type == ATOMTYPE_MOOV)
sl@0
   321
          break;
sl@0
   322
sl@0
   323
        if ((mp4_i32)size <= 0)
sl@0
   324
          return -1;
sl@0
   325
sl@0
   326
        if (discardData(handle, size) < 0)
sl@0
   327
          return -1;
sl@0
   328
    }
sl@0
   329
  }
sl@0
   330
sl@0
   331
  if ((handle->moov = (movieAtom *)mp4malloc(sizeof(movieAtom))) == NULL)
sl@0
   332
    return -100;
sl@0
   333
sl@0
   334
  bytesread = readMoov(handle, handle->moov);
sl@0
   335
  if (bytesread < 0)
sl@0
   336
    return -3;
sl@0
   337
  totalbytesread += bytesread;
sl@0
   338
sl@0
   339
  if (handle->moov->trakAudio)
sl@0
   340
  {
sl@0
   341
    mp4_u32 audiotype;
sl@0
   342
	mp4_i32 errorAudio = 0;
sl@0
   343
sl@0
   344
	errorAudio = determineAudioType(handle, &audiotype);
sl@0
   345
    if ( errorAudio == 0 )
sl@0
   346
    {
sl@0
   347
	   	handle->type |= audiotype;    	
sl@0
   348
    
sl@0
   349
	    /* Move to the beginning of the 1st audio frame */
sl@0
   350
	    switch (advanceAudioSample(handle, handle->moov->trakAudio))
sl@0
   351
	    {
sl@0
   352
	    case -1:
sl@0
   353
	      return -1;
sl@0
   354
	    case -2:
sl@0
   355
	      handle->audioLast = MP4TRUE;
sl@0
   356
	      break;
sl@0
   357
	    default:
sl@0
   358
	      break;
sl@0
   359
	    }
sl@0
   360
	}
sl@0
   361
	else if (errorAudio == -2)
sl@0
   362
	{
sl@0
   363
		handle->type |= audiotype;	
sl@0
   364
	}
sl@0
   365
	else
sl@0
   366
	{
sl@0
   367
		return -1;
sl@0
   368
	}
sl@0
   369
  }
sl@0
   370
sl@0
   371
  if (handle->moov->trakVideo)
sl@0
   372
  {
sl@0
   373
    mp4_u32 videotype;
sl@0
   374
    mp4_i32 errorVideo = 0;
sl@0
   375
sl@0
   376
	errorVideo = determineVideoType(handle, &videotype);
sl@0
   377
    if ( errorVideo == 0 )
sl@0
   378
    {
sl@0
   379
	   	handle->type |= videotype;    	
sl@0
   380
    
sl@0
   381
    	/* Move to the beginning of the 1st video frame */
sl@0
   382
	    switch (advanceVideoFrame(handle, handle->moov->trakVideo))
sl@0
   383
	    {
sl@0
   384
	    case -1:
sl@0
   385
	      return -1;
sl@0
   386
	    case -2:
sl@0
   387
	       handle->videoLast = MP4TRUE;
sl@0
   388
	      break;
sl@0
   389
	    default:
sl@0
   390
	      break;
sl@0
   391
	    }
sl@0
   392
	}
sl@0
   393
	else if (errorVideo == -2)
sl@0
   394
	{
sl@0
   395
	   	handle->type |= videotype;	
sl@0
   396
	}
sl@0
   397
	else
sl@0
   398
	{
sl@0
   399
		return -1;
sl@0
   400
	}
sl@0
   401
  }
sl@0
   402
sl@0
   403
  return totalbytesread;
sl@0
   404
}
sl@0
   405
sl@0
   406
sl@0
   407
/*
sl@0
   408
 * Function:
sl@0
   409
 *
sl@0
   410
 *   mp4_i32 readMoov(MP4HandleImp handle,
sl@0
   411
 *                    movieAtom *moov)
sl@0
   412
 *
sl@0
   413
 * Description:
sl@0
   414
 *
sl@0
   415
 *   This function parses one MOOV atom.
sl@0
   416
 *
sl@0
   417
 * Parameters:
sl@0
   418
 *
sl@0
   419
 *   handle             MP4 library handle
sl@0
   420
 *   moov               MOOV pointer
sl@0
   421
 *
sl@0
   422
 * Return value:
sl@0
   423
 *
sl@0
   424
 *   Negative integer   Error
sl@0
   425
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
   426
 *
sl@0
   427
 */
sl@0
   428
mp4_i32 readMoov(MP4HandleImp handle, movieAtom *moov)
sl@0
   429
{
sl@0
   430
  mp4_i32 bytesread;
sl@0
   431
  mp4_i32 totalbytesread = 0;
sl@0
   432
sl@0
   433
sl@0
   434
  if ((moov->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
   435
    return -100;
sl@0
   436
sl@0
   437
  bytesread = readAtomHeader(handle, moov->atomhdr);
sl@0
   438
  if (bytesread < 0)
sl@0
   439
    return -1;
sl@0
   440
  totalbytesread += bytesread;
sl@0
   441
sl@0
   442
  if (moov->atomhdr->type != ATOMTYPE_MOOV)
sl@0
   443
    return -1;
sl@0
   444
sl@0
   445
  while ((mp4_u32)totalbytesread < handle->moov->atomhdr->size)
sl@0
   446
  {
sl@0
   447
    mp4_u32 type;
sl@0
   448
sl@0
   449
sl@0
   450
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
   451
      return -1;
sl@0
   452
sl@0
   453
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
   454
sl@0
   455
    switch (type)
sl@0
   456
    {
sl@0
   457
    case ATOMTYPE_MVHD:
sl@0
   458
sl@0
   459
      if (moov->mvhd) /* MVHD has already been read, more than one is not allowed */
sl@0
   460
        return -1;
sl@0
   461
sl@0
   462
      if ((moov->mvhd = (movieHeaderAtom *)mp4malloc(sizeof(movieHeaderAtom))) == NULL)
sl@0
   463
        return -100;
sl@0
   464
sl@0
   465
      bytesread = readMVHD(handle, moov->mvhd);
sl@0
   466
      if (bytesread < 0)
sl@0
   467
        return -1;
sl@0
   468
      totalbytesread += bytesread;
sl@0
   469
sl@0
   470
      break;
sl@0
   471
sl@0
   472
    case ATOMTYPE_IODS:
sl@0
   473
sl@0
   474
      if (moov->iods) /* IODS has already been read, more than one is not allowed */
sl@0
   475
        return -1;
sl@0
   476
sl@0
   477
      if ((moov->iods = (objectDescriptorAtom *)mp4malloc(sizeof(objectDescriptorAtom))) == NULL)
sl@0
   478
        return -100;
sl@0
   479
sl@0
   480
      bytesread = readIODS(handle, moov->iods);
sl@0
   481
      if (bytesread < 0)
sl@0
   482
        return -1;
sl@0
   483
      totalbytesread += bytesread;
sl@0
   484
sl@0
   485
      break;
sl@0
   486
sl@0
   487
    case ATOMTYPE_TRAK:
sl@0
   488
sl@0
   489
      {
sl@0
   490
        trackAtom *ta;
sl@0
   491
sl@0
   492
        if ((ta = (trackAtom *)mp4malloc(sizeof(trackAtom))) == NULL)
sl@0
   493
          return -100;
sl@0
   494
sl@0
   495
        bytesread = readTRAK(handle, ta);
sl@0
   496
        if (bytesread < 0)
sl@0
   497
        {
sl@0
   498
          if (freeTRAK(ta) < 0)
sl@0
   499
            return -1;
sl@0
   500
          return -1;
sl@0
   501
        }
sl@0
   502
        totalbytesread += bytesread;
sl@0
   503
sl@0
   504
        if (!ta->mdia)
sl@0
   505
        {
sl@0
   506
          if (freeTRAK(ta) < 0)
sl@0
   507
            return -1;
sl@0
   508
          return -1;
sl@0
   509
        }
sl@0
   510
        if (!ta->mdia->hdlr)
sl@0
   511
        {
sl@0
   512
          if (freeTRAK(ta) < 0)
sl@0
   513
            return -1;
sl@0
   514
          return -1;
sl@0
   515
        }
sl@0
   516
sl@0
   517
        if (ta->mdia->hdlr->handlerType != HANDLERTYPE_VIDE &&
sl@0
   518
            ta->mdia->hdlr->handlerType != HANDLERTYPE_SOUN) /* Track is neither video nor audio */
sl@0
   519
        {
sl@0
   520
          /* Do nothing with the unknown track */
sl@0
   521
          if (freeTRAK(ta) < 0)
sl@0
   522
            return -1;
sl@0
   523
          break;
sl@0
   524
        }
sl@0
   525
sl@0
   526
        if (ta->mdia->hdlr->handlerType == HANDLERTYPE_VIDE)
sl@0
   527
        {
sl@0
   528
	        if (moov->trakVideo) /* Video Track already read */
sl@0
   529
	        {
sl@0
   530
	          if (freeTRAK(ta) < 0)
sl@0
   531
	            return -1;
sl@0
   532
	        }
sl@0
   533
	        else
sl@0
   534
	        {
sl@0
   535
	          moov->trakVideo = ta;
sl@0
   536
	        }
sl@0
   537
        }
sl@0
   538
		else if (ta->mdia->hdlr->handlerType == HANDLERTYPE_SOUN)
sl@0
   539
        {
sl@0
   540
	        if (moov->trakAudio) /* Audio Track already read */
sl@0
   541
	        {
sl@0
   542
	          if (freeTRAK(ta) < 0)
sl@0
   543
	            return -1;
sl@0
   544
	        }
sl@0
   545
	        else
sl@0
   546
	        {
sl@0
   547
	          moov->trakAudio = ta;
sl@0
   548
	        }
sl@0
   549
        }
sl@0
   550
        else
sl@0
   551
        {
sl@0
   552
        }
sl@0
   553
        break;
sl@0
   554
      }
sl@0
   555
sl@0
   556
    case ATOMTYPE_UDTA:
sl@0
   557
sl@0
   558
      {
sl@0
   559
      if (moov->udta) /* UDTA has already been read */
sl@0
   560
          {
sl@0
   561
          bytesread = readUnknown(handle);
sl@0
   562
          if (bytesread < 0)
sl@0
   563
            return -1;
sl@0
   564
          totalbytesread += bytesread;
sl@0
   565
          break;
sl@0
   566
          }
sl@0
   567
sl@0
   568
sl@0
   569
      if ((moov->udta = (userDataAtom *)mp4malloc(sizeof(userDataAtom))) == NULL)
sl@0
   570
        return -100;
sl@0
   571
sl@0
   572
      bytesread = readUDTA(handle, moov->udta);
sl@0
   573
      if (bytesread < 0)
sl@0
   574
        return -1;
sl@0
   575
      totalbytesread += bytesread;
sl@0
   576
sl@0
   577
      break;
sl@0
   578
      }
sl@0
   579
      
sl@0
   580
    case ATOMTYPE_META:
sl@0
   581
        
sl@0
   582
        {
sl@0
   583
        if (moov->meta) /* META has already been read, more than one is not allowed */
sl@0
   584
          return -1;
sl@0
   585
           
sl@0
   586
        if ((moov->meta = (metaAtom *)mp4malloc(sizeof(metaAtom))) == NULL)
sl@0
   587
            return -100;
sl@0
   588
sl@0
   589
        bytesread = readMeta(handle, moov->meta);
sl@0
   590
        if (bytesread < 0)
sl@0
   591
          return -1;
sl@0
   592
        totalbytesread += bytesread;
sl@0
   593
        
sl@0
   594
        break;
sl@0
   595
        }
sl@0
   596
        
sl@0
   597
    default:
sl@0
   598
sl@0
   599
      bytesread = readUnknown(handle);
sl@0
   600
      if (bytesread < 0)
sl@0
   601
        return -1;
sl@0
   602
      totalbytesread += bytesread;
sl@0
   603
sl@0
   604
      break;
sl@0
   605
    }
sl@0
   606
  }
sl@0
   607
sl@0
   608
  return totalbytesread;
sl@0
   609
}
sl@0
   610
sl@0
   611
sl@0
   612
/*
sl@0
   613
 * Function:
sl@0
   614
 *
sl@0
   615
 *   mp4_i32 readAtomheader(MP4HandleImp handle,
sl@0
   616
 *                          atomHeader *ah)
sl@0
   617
 *
sl@0
   618
 * Description:
sl@0
   619
 *
sl@0
   620
 *   This function reads an atom header and stores the information
sl@0
   621
 *   in ah.
sl@0
   622
 *
sl@0
   623
 * Parameters:
sl@0
   624
 *
sl@0
   625
 *   handle           MP4 library handle
sl@0
   626
 *   ah               atomHeader structure that is used to store the
sl@0
   627
 *                    information
sl@0
   628
 *
sl@0
   629
 * Return value:
sl@0
   630
 *
sl@0
   631
 *   Negative value   Error
sl@0
   632
 *   >= 0             Success. Value tells how many bytes were read.
sl@0
   633
 *
sl@0
   634
 */
sl@0
   635
mp4_i32 readAtomHeader(MP4HandleImp handle, atomHeader *ah)
sl@0
   636
{
sl@0
   637
  mp4_i32 bytesread;
sl@0
   638
  mp4_i32 totalbytesread = 0;
sl@0
   639
sl@0
   640
  //PRINT((_L("readAtomHeader")));
sl@0
   641
  bytesread = readData(handle, handle->buf, 4);
sl@0
   642
  if (bytesread < 0)
sl@0
   643
    return -1;
sl@0
   644
  ah->size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   645
  totalbytesread += bytesread;
sl@0
   646
sl@0
   647
  bytesread = readData(handle, handle->buf, 4);
sl@0
   648
  if (bytesread < 0)
sl@0
   649
    return -1;
sl@0
   650
  ah->type = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   651
  totalbytesread += bytesread;
sl@0
   652
sl@0
   653
  if (ah->size == 1)
sl@0
   654
  {
sl@0
   655
    bytesread = readData(handle, handle->buf, 8);
sl@0
   656
    if (bytesread < 0)
sl@0
   657
      return -1;
sl@0
   658
    ah->largeSize = u64endian(*((mp4_u64 *)handle->buf));
sl@0
   659
    totalbytesread += bytesread;
sl@0
   660
  }
sl@0
   661
sl@0
   662
  if (ah->type == ATOMTYPE_UUID)
sl@0
   663
  {
sl@0
   664
    bytesread = readData(handle, handle->buf, 16);
sl@0
   665
    if (bytesread < 0)
sl@0
   666
      return -1;
sl@0
   667
    mp4memcpy(ah->extendedType, handle->buf, 16);
sl@0
   668
    totalbytesread += bytesread;
sl@0
   669
  }
sl@0
   670
sl@0
   671
  //PRINT((_L("   size %u, size %Lu, type %c%c%c%c"), ah->size, ah->largeSize,((unsigned char *)(&ah->type))[3], ((unsigned char *)(&ah->type))[2], ((unsigned char *)(&ah->type))[1], ((unsigned char *)(&ah->type))[0]));
sl@0
   672
  return totalbytesread;
sl@0
   673
}
sl@0
   674
sl@0
   675
sl@0
   676
/*
sl@0
   677
 * Function:
sl@0
   678
 *
sl@0
   679
 *   mp4_i32 readFullAtomHeader(MP4HandleImp handle,
sl@0
   680
 *                              atomHeader *ah)
sl@0
   681
 *
sl@0
   682
 * Description:
sl@0
   683
 *
sl@0
   684
 *   This function reads a full atom header and stores the information
sl@0
   685
 *   in ah.
sl@0
   686
 *
sl@0
   687
 * Parameters:
sl@0
   688
 *
sl@0
   689
 *   handle           MP4 library handle
sl@0
   690
 *   ah               atomHeader structure that is used to store the
sl@0
   691
 *                    information
sl@0
   692
 *
sl@0
   693
 * Return value:
sl@0
   694
 *
sl@0
   695
 *   Negative value   Error
sl@0
   696
 *   >= 0             Success. Value tells how many bytes were read.
sl@0
   697
 *
sl@0
   698
 */
sl@0
   699
mp4_i32 readFullAtomHeader(MP4HandleImp handle, atomHeader *ah)
sl@0
   700
{
sl@0
   701
  mp4_i32 bytesread;
sl@0
   702
  mp4_i32 totalbytesread = 0;
sl@0
   703
sl@0
   704
  //PRINT((_L("readFullAtomHeader")));
sl@0
   705
sl@0
   706
  bytesread = readData(handle, handle->buf, 4);
sl@0
   707
  if (bytesread < 0)
sl@0
   708
    return -1;
sl@0
   709
  ah->size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   710
  totalbytesread += bytesread;
sl@0
   711
sl@0
   712
  bytesread = readData(handle, handle->buf, 4);
sl@0
   713
  if (bytesread < 0)
sl@0
   714
    return -1;
sl@0
   715
  ah->type = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   716
  totalbytesread += bytesread;
sl@0
   717
sl@0
   718
  bytesread = readData(handle, handle->buf, 1);
sl@0
   719
  if (bytesread < 0)
sl@0
   720
    return -1;
sl@0
   721
  ah->version = *(handle->buf);
sl@0
   722
  totalbytesread += bytesread;
sl@0
   723
sl@0
   724
  bytesread = readData(handle, handle->buf, 3);
sl@0
   725
  if (bytesread < 0)
sl@0
   726
    return -1;
sl@0
   727
  mp4memcpy(ah->flags, handle->buf, 3);
sl@0
   728
  totalbytesread += bytesread;
sl@0
   729
sl@0
   730
  //PRINT((_L("   size %u, size %Lu, type %c%c%c%c"), ah->size, ah->largeSize,((unsigned char *)(&ah->type))[3], ((unsigned char *)(&ah->type))[2], ((unsigned char *)(&ah->type))[1], ((unsigned char *)(&ah->type))[0]));
sl@0
   731
  return totalbytesread;
sl@0
   732
}
sl@0
   733
sl@0
   734
sl@0
   735
/*
sl@0
   736
 * Function:
sl@0
   737
 *
sl@0
   738
 *   mp4_i32 readMVHD(MP4HandleImp handle,
sl@0
   739
 *                    movieHeaderAtom *mvhd)
sl@0
   740
 *
sl@0
   741
 * Description:
sl@0
   742
 *
sl@0
   743
 *   This function parses one MVHD atom.
sl@0
   744
 *
sl@0
   745
 * Parameters:
sl@0
   746
 *
sl@0
   747
 *   handle             MP4 library handle
sl@0
   748
 *   mvhd               MVHD pointer
sl@0
   749
 *
sl@0
   750
 * Return value:
sl@0
   751
 *
sl@0
   752
 *   Negative integer   Error
sl@0
   753
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
   754
 *
sl@0
   755
 */
sl@0
   756
mp4_i32 readMVHD(MP4HandleImp handle, movieHeaderAtom *mvhd)
sl@0
   757
{
sl@0
   758
  mp4_i32 bytesread;
sl@0
   759
  mp4_i32 totalbytesread = 0;
sl@0
   760
sl@0
   761
sl@0
   762
  if ((mvhd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
   763
    return -100;
sl@0
   764
sl@0
   765
  bytesread = readFullAtomHeader(handle, mvhd->atomhdr);
sl@0
   766
  if (bytesread < 0)
sl@0
   767
    return -1;
sl@0
   768
  totalbytesread += bytesread;
sl@0
   769
sl@0
   770
  if (mvhd->atomhdr->type != ATOMTYPE_MVHD)
sl@0
   771
    return -1;
sl@0
   772
sl@0
   773
  if (mvhd->atomhdr->version == 1) /* 64 bit */
sl@0
   774
  {
sl@0
   775
    bytesread = readData(handle, handle->buf, 8);
sl@0
   776
    if (bytesread < 0)
sl@0
   777
      return -1;
sl@0
   778
    mvhd->creationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
   779
    totalbytesread += bytesread;
sl@0
   780
sl@0
   781
    bytesread = readData(handle, handle->buf, 8);
sl@0
   782
    if (bytesread < 0)
sl@0
   783
      return -1;
sl@0
   784
    mvhd->modificationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
   785
    totalbytesread += bytesread;
sl@0
   786
sl@0
   787
    bytesread = readData(handle, handle->buf, 4);
sl@0
   788
    if (bytesread < 0)
sl@0
   789
      return -1;
sl@0
   790
    mvhd->timeScale = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   791
    totalbytesread += bytesread;
sl@0
   792
sl@0
   793
    bytesread = readData(handle, handle->buf, 8);
sl@0
   794
    if (bytesread < 0)
sl@0
   795
      return -1;
sl@0
   796
    mvhd->duration64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
   797
    totalbytesread += bytesread;
sl@0
   798
  }
sl@0
   799
  else /* 32 bit */
sl@0
   800
  {
sl@0
   801
    bytesread = readData(handle, handle->buf, 4);
sl@0
   802
    if (bytesread < 0)
sl@0
   803
      return -1;
sl@0
   804
    mvhd->creationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   805
    totalbytesread += bytesread;
sl@0
   806
sl@0
   807
    bytesread = readData(handle, handle->buf, 4);
sl@0
   808
    if (bytesread < 0)
sl@0
   809
      return -1;
sl@0
   810
    mvhd->modificationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   811
    totalbytesread += bytesread;
sl@0
   812
sl@0
   813
    bytesread = readData(handle, handle->buf, 4);
sl@0
   814
    if (bytesread < 0)
sl@0
   815
      return -1;
sl@0
   816
    mvhd->timeScale = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   817
    totalbytesread += bytesread;
sl@0
   818
sl@0
   819
    bytesread = readData(handle, handle->buf, 4);
sl@0
   820
    if (bytesread < 0)
sl@0
   821
      return -1;
sl@0
   822
    mvhd->duration = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   823
    totalbytesread += bytesread;
sl@0
   824
  }
sl@0
   825
sl@0
   826
  bytesread = discardData(handle, 76);
sl@0
   827
  if (bytesread < 0)
sl@0
   828
    return -1;
sl@0
   829
  totalbytesread += bytesread;
sl@0
   830
sl@0
   831
  bytesread = readData(handle, handle->buf, 4);
sl@0
   832
  if (bytesread < 0)
sl@0
   833
    return -1;
sl@0
   834
  mvhd->nextTrackID = u32endian(*((mp4_u32 *)handle->buf));
sl@0
   835
  totalbytesread += bytesread;
sl@0
   836
sl@0
   837
  return totalbytesread;
sl@0
   838
}
sl@0
   839
sl@0
   840
sl@0
   841
/*
sl@0
   842
 * Function:
sl@0
   843
 *
sl@0
   844
 *   mp4_i32 readIODS(MP4HandleImp handle,
sl@0
   845
 *                    objectDescriptorAtom *iods)
sl@0
   846
 *
sl@0
   847
 * Description:
sl@0
   848
 *
sl@0
   849
 *   This function parses one IODS atom.
sl@0
   850
 *
sl@0
   851
 * Parameters:
sl@0
   852
 *
sl@0
   853
 *   handle             MP4 library handle
sl@0
   854
 *   iods               IODS pointer
sl@0
   855
 *
sl@0
   856
 * Return value:
sl@0
   857
 *
sl@0
   858
 *   Negative integer   Error
sl@0
   859
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
   860
 *
sl@0
   861
 */
sl@0
   862
mp4_i32 readIODS(MP4HandleImp handle, objectDescriptorAtom *iods)
sl@0
   863
{
sl@0
   864
  mp4_i32 bytesread;
sl@0
   865
  mp4_i32 totalbytesread = 0;
sl@0
   866
sl@0
   867
sl@0
   868
  if ((iods->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
   869
    return -100;
sl@0
   870
sl@0
   871
  bytesread = readFullAtomHeader(handle, iods->atomhdr);
sl@0
   872
  if (bytesread < 0)
sl@0
   873
    return -1;
sl@0
   874
  totalbytesread += bytesread;
sl@0
   875
sl@0
   876
  if (iods->atomhdr->type != ATOMTYPE_IODS)
sl@0
   877
    return -1;
sl@0
   878
sl@0
   879
  bytesread = discardData(handle, iods->atomhdr->size - totalbytesread);
sl@0
   880
  if (bytesread < 0)
sl@0
   881
    return -1;
sl@0
   882
  totalbytesread += bytesread;
sl@0
   883
sl@0
   884
  return totalbytesread;
sl@0
   885
}
sl@0
   886
sl@0
   887
sl@0
   888
/*
sl@0
   889
 * Function:
sl@0
   890
 *
sl@0
   891
 *   mp4_i32 readTRAK(MP4HandleImp handle,
sl@0
   892
 *                    trackAtom *trak)
sl@0
   893
 *
sl@0
   894
 * Description:
sl@0
   895
 *
sl@0
   896
 *   This function parses one TRAK atom.
sl@0
   897
 *
sl@0
   898
 * Parameters:
sl@0
   899
 *
sl@0
   900
 *   handle             MP4 library handle
sl@0
   901
 *   trak               TRAK pointer
sl@0
   902
 *
sl@0
   903
 * Return value:
sl@0
   904
 *
sl@0
   905
 *   Negative integer   Error
sl@0
   906
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
   907
 *
sl@0
   908
 */
sl@0
   909
mp4_i32 readTRAK(MP4HandleImp handle, trackAtom *trak)
sl@0
   910
{
sl@0
   911
  mp4_i32 bytesread;
sl@0
   912
  mp4_i32 totalbytesread = 0;
sl@0
   913
sl@0
   914
sl@0
   915
  if ((trak->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
   916
    return -100;
sl@0
   917
sl@0
   918
  bytesread = readAtomHeader(handle, trak->atomhdr);
sl@0
   919
  if (bytesread < 0)
sl@0
   920
    return -1;
sl@0
   921
  totalbytesread += bytesread;
sl@0
   922
sl@0
   923
  if (trak->atomhdr->type != ATOMTYPE_TRAK)
sl@0
   924
    return -1;
sl@0
   925
sl@0
   926
sl@0
   927
  while ((mp4_u32)totalbytesread < trak->atomhdr->size)
sl@0
   928
  {
sl@0
   929
    mp4_u32 type;
sl@0
   930
sl@0
   931
sl@0
   932
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
   933
      return -1;
sl@0
   934
sl@0
   935
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
   936
sl@0
   937
    switch (type)
sl@0
   938
    {
sl@0
   939
    case ATOMTYPE_TKHD:
sl@0
   940
sl@0
   941
      if (trak->tkhd) /* MVHD has already been read, more than one is not allowed */
sl@0
   942
        return -1;
sl@0
   943
sl@0
   944
      if ((trak->tkhd = (trackHeaderAtom *)mp4malloc(sizeof(trackHeaderAtom))) == NULL)
sl@0
   945
        return -100;
sl@0
   946
sl@0
   947
      bytesread = readTKHD(handle, trak->tkhd);
sl@0
   948
      if (bytesread < 0)
sl@0
   949
        return -1;
sl@0
   950
      totalbytesread += bytesread;
sl@0
   951
sl@0
   952
      break;
sl@0
   953
sl@0
   954
    case ATOMTYPE_TREF:
sl@0
   955
sl@0
   956
      if (trak->tref) /* TREF has already been read, more than one is not allowed */
sl@0
   957
        return -1;
sl@0
   958
sl@0
   959
      if ((trak->tref = (trackReferenceAtom *)mp4malloc(sizeof(trackReferenceAtom))) == NULL)
sl@0
   960
        return -100;
sl@0
   961
sl@0
   962
      bytesread = readTREF(handle, trak->tref);
sl@0
   963
      if (bytesread < 0)
sl@0
   964
        return -1;
sl@0
   965
      totalbytesread += bytesread;
sl@0
   966
sl@0
   967
      break;
sl@0
   968
sl@0
   969
    case ATOMTYPE_EDTS:
sl@0
   970
sl@0
   971
      if (trak->edts) /* EDTS has already been read, more than one is not allowed */
sl@0
   972
        return -1;
sl@0
   973
sl@0
   974
      if ((trak->edts = (editListContainerAtom *)mp4malloc(sizeof(editListContainerAtom))) == NULL)
sl@0
   975
        return -100;
sl@0
   976
sl@0
   977
      bytesread = readEDTS(handle, trak->edts);
sl@0
   978
      if (bytesread < 0)
sl@0
   979
        return -1;
sl@0
   980
      totalbytesread += bytesread;
sl@0
   981
sl@0
   982
      break;
sl@0
   983
sl@0
   984
    case ATOMTYPE_MDIA:
sl@0
   985
sl@0
   986
      if (trak->mdia) /* MDIA has already been read, more than one is not allowed */
sl@0
   987
        return -1;
sl@0
   988
sl@0
   989
      if ((trak->mdia = (mediaAtom *)mp4malloc(sizeof(mediaAtom))) == NULL)
sl@0
   990
        return -100;
sl@0
   991
sl@0
   992
      bytesread = readMDIA(handle, trak->mdia);
sl@0
   993
      if (bytesread < 0)
sl@0
   994
        return -1;
sl@0
   995
      totalbytesread += bytesread;
sl@0
   996
sl@0
   997
      break;
sl@0
   998
sl@0
   999
    case ATOMTYPE_UDTA:
sl@0
  1000
      {
sl@0
  1001
      if (trak->udta) /* UDTA has already been read */
sl@0
  1002
          {
sl@0
  1003
          bytesread = readUnknown(handle);
sl@0
  1004
          if (bytesread < 0)
sl@0
  1005
            return -1;
sl@0
  1006
          totalbytesread += bytesread;
sl@0
  1007
          break;
sl@0
  1008
          }
sl@0
  1009
sl@0
  1010
      if ((trak->udta = (userDataAtom *)mp4malloc(sizeof(userDataAtom))) == NULL)
sl@0
  1011
        return -100;
sl@0
  1012
sl@0
  1013
      bytesread = readUDTA(handle, trak->udta);
sl@0
  1014
      if (bytesread < 0)
sl@0
  1015
        return -1;
sl@0
  1016
      totalbytesread += bytesread;
sl@0
  1017
sl@0
  1018
      break;
sl@0
  1019
      }
sl@0
  1020
sl@0
  1021
    default:
sl@0
  1022
sl@0
  1023
      bytesread = readUnknown(handle);
sl@0
  1024
      if (bytesread < 0)
sl@0
  1025
        return -1;
sl@0
  1026
      totalbytesread += bytesread;
sl@0
  1027
sl@0
  1028
      break;
sl@0
  1029
    }
sl@0
  1030
  }
sl@0
  1031
sl@0
  1032
  return totalbytesread;
sl@0
  1033
}
sl@0
  1034
sl@0
  1035
sl@0
  1036
/*
sl@0
  1037
 * Function:
sl@0
  1038
 *
sl@0
  1039
 *   mp4_i32 readUnknown(MP4HandleImp handle)
sl@0
  1040
 *
sl@0
  1041
 * Description:
sl@0
  1042
 *
sl@0
  1043
 *   This function reads one atom of unknown type. Atom contents are
sl@0
  1044
 *   discarded.
sl@0
  1045
 *
sl@0
  1046
 * Parameters:
sl@0
  1047
 *
sl@0
  1048
 *   handle             MP4 library handle
sl@0
  1049
 *
sl@0
  1050
 * Return value:
sl@0
  1051
 *
sl@0
  1052
 *   Negative integer   Error
sl@0
  1053
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1054
 *
sl@0
  1055
 */
sl@0
  1056
mp4_i32 readUnknown(MP4HandleImp handle)
sl@0
  1057
{
sl@0
  1058
  mp4_i32 bytesread;
sl@0
  1059
  mp4_i32 totalbytesread = 0;
sl@0
  1060
  mp4_u32 size;
sl@0
  1061
sl@0
  1062
sl@0
  1063
  bytesread = readData(handle, handle->buf, 4);
sl@0
  1064
  if (bytesread < 0)
sl@0
  1065
    return -1;
sl@0
  1066
  totalbytesread += bytesread;
sl@0
  1067
sl@0
  1068
  size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1069
  if ( size < 4 )
sl@0
  1070
  {
sl@0
  1071
  	return -1;
sl@0
  1072
  }
sl@0
  1073
sl@0
  1074
  if ( handle->file )
sl@0
  1075
  {
sl@0
  1076
  	if ( seekFile(handle, size - totalbytesread) < 0 )
sl@0
  1077
  	{
sl@0
  1078
  	   return -1;	
sl@0
  1079
  	}
sl@0
  1080
  	else
sl@0
  1081
  	{
sl@0
  1082
  	   return size;	
sl@0
  1083
  	}
sl@0
  1084
  }
sl@0
  1085
  else
sl@0
  1086
  {
sl@0
  1087
  	bytesread = discardData(handle, size - totalbytesread);
sl@0
  1088
	  if (bytesread < 0)
sl@0
  1089
    	return -1;
sl@0
  1090
  	totalbytesread += bytesread;
sl@0
  1091
  }
sl@0
  1092
  return totalbytesread;
sl@0
  1093
}
sl@0
  1094
sl@0
  1095
sl@0
  1096
/*
sl@0
  1097
 * Function:
sl@0
  1098
 *
sl@0
  1099
 *   mp4_i32 readTKHD(MP4HandleImp handle,
sl@0
  1100
 *                    trackHeaderAtom *tkhd)
sl@0
  1101
 *
sl@0
  1102
 * Description:
sl@0
  1103
 *
sl@0
  1104
 *   This function parses one TKHD atom.
sl@0
  1105
 *
sl@0
  1106
 * Parameters:
sl@0
  1107
 *
sl@0
  1108
 *   handle             MP4 library handle
sl@0
  1109
 *   tkhd               TKHD pointer
sl@0
  1110
 *
sl@0
  1111
 * Return value:
sl@0
  1112
 *
sl@0
  1113
 *   Negative integer   Error
sl@0
  1114
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1115
 *
sl@0
  1116
 */
sl@0
  1117
mp4_i32 readTKHD(MP4HandleImp handle, trackHeaderAtom *tkhd)
sl@0
  1118
{
sl@0
  1119
  mp4_i32 bytesread;
sl@0
  1120
  mp4_i32 totalbytesread = 0;
sl@0
  1121
sl@0
  1122
sl@0
  1123
  if ((tkhd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1124
    return -100;
sl@0
  1125
sl@0
  1126
  bytesread = readFullAtomHeader(handle, tkhd->atomhdr);
sl@0
  1127
  if (bytesread < 0)
sl@0
  1128
    return -1;
sl@0
  1129
  totalbytesread += bytesread;
sl@0
  1130
sl@0
  1131
  if (tkhd->atomhdr->type != ATOMTYPE_TKHD)
sl@0
  1132
    return -1;
sl@0
  1133
sl@0
  1134
  if (tkhd->atomhdr->version == 1) /* 64 bit */
sl@0
  1135
  {
sl@0
  1136
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1137
    if (bytesread < 0)
sl@0
  1138
      return -1;
sl@0
  1139
    tkhd->creationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1140
    totalbytesread += bytesread;
sl@0
  1141
sl@0
  1142
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1143
    if (bytesread < 0)
sl@0
  1144
      return -1;
sl@0
  1145
    tkhd->modificationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1146
    totalbytesread += bytesread;
sl@0
  1147
sl@0
  1148
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1149
    if (bytesread < 0)
sl@0
  1150
      return -1;
sl@0
  1151
    tkhd->trackID = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1152
    totalbytesread += bytesread;
sl@0
  1153
sl@0
  1154
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1155
    if (bytesread < 0)
sl@0
  1156
      return -1;
sl@0
  1157
    tkhd->reserved = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1158
    totalbytesread += bytesread;
sl@0
  1159
sl@0
  1160
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1161
    if (bytesread < 0)
sl@0
  1162
      return -1;
sl@0
  1163
    tkhd->duration64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1164
    totalbytesread += bytesread;
sl@0
  1165
  }
sl@0
  1166
  else /* 32 bit */
sl@0
  1167
  {
sl@0
  1168
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1169
    if (bytesread < 0)
sl@0
  1170
      return -1;
sl@0
  1171
    tkhd->creationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1172
    totalbytesread += bytesread;
sl@0
  1173
sl@0
  1174
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1175
    if (bytesread < 0)
sl@0
  1176
      return -1;
sl@0
  1177
    tkhd->modificationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1178
    totalbytesread += bytesread;
sl@0
  1179
sl@0
  1180
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1181
    if (bytesread < 0)
sl@0
  1182
      return -1;
sl@0
  1183
    tkhd->trackID = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1184
    totalbytesread += bytesread;
sl@0
  1185
sl@0
  1186
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1187
    if (bytesread < 0)
sl@0
  1188
      return -1;
sl@0
  1189
    tkhd->reserved = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1190
    totalbytesread += bytesread;
sl@0
  1191
sl@0
  1192
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1193
    if (bytesread < 0)
sl@0
  1194
      return -1;
sl@0
  1195
    tkhd->duration = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1196
    totalbytesread += bytesread;
sl@0
  1197
  }
sl@0
  1198
sl@0
  1199
  bytesread = discardData(handle, 52);
sl@0
  1200
  if (bytesread < 0)
sl@0
  1201
    return -1;
sl@0
  1202
  totalbytesread += bytesread;
sl@0
  1203
sl@0
  1204
  bytesread = readData(handle, handle->buf, 4);
sl@0
  1205
  if (bytesread < 0)
sl@0
  1206
    return -1;
sl@0
  1207
  tkhd->width = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  1208
  totalbytesread += bytesread;
sl@0
  1209
sl@0
  1210
  bytesread = readData(handle, handle->buf, 4);
sl@0
  1211
  if (bytesread < 0)
sl@0
  1212
    return -1;
sl@0
  1213
  tkhd->height = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  1214
  totalbytesread += bytesread;
sl@0
  1215
sl@0
  1216
  return totalbytesread;
sl@0
  1217
}
sl@0
  1218
sl@0
  1219
sl@0
  1220
/*
sl@0
  1221
 * Function:
sl@0
  1222
 *
sl@0
  1223
 *   mp4_i32 readTREF(MP4HandleImp handle,
sl@0
  1224
 *                    trackReferenceAtom *tref)
sl@0
  1225
 *
sl@0
  1226
 * Description:
sl@0
  1227
 *
sl@0
  1228
 *   This function parses one TREF atom and discards the contents.
sl@0
  1229
 *
sl@0
  1230
 * Parameters:
sl@0
  1231
 *
sl@0
  1232
 *   handle             MP4 library handle
sl@0
  1233
 *   tref               TREF pointer
sl@0
  1234
 *
sl@0
  1235
 * Return value:
sl@0
  1236
 *
sl@0
  1237
 *   Negative integer   Error
sl@0
  1238
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1239
 *
sl@0
  1240
 */
sl@0
  1241
mp4_i32 readTREF(MP4HandleImp handle, trackReferenceAtom *tref)
sl@0
  1242
{
sl@0
  1243
  mp4_i32 bytesread;
sl@0
  1244
  mp4_i32 totalbytesread = 0;
sl@0
  1245
sl@0
  1246
sl@0
  1247
  if ((tref->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1248
    return -100;
sl@0
  1249
sl@0
  1250
  bytesread = readAtomHeader(handle, tref->atomhdr);
sl@0
  1251
  if (bytesread < 0)
sl@0
  1252
    return -1;
sl@0
  1253
  totalbytesread += bytesread;
sl@0
  1254
sl@0
  1255
  if (tref->atomhdr->type != ATOMTYPE_TREF)
sl@0
  1256
    return -1;
sl@0
  1257
sl@0
  1258
  bytesread = discardData(handle, tref->atomhdr->size - totalbytesread);
sl@0
  1259
  if (bytesread < 0)
sl@0
  1260
    return -1;
sl@0
  1261
  totalbytesread += bytesread;
sl@0
  1262
sl@0
  1263
  return totalbytesread;
sl@0
  1264
}
sl@0
  1265
sl@0
  1266
sl@0
  1267
/*
sl@0
  1268
 * Function:
sl@0
  1269
 *
sl@0
  1270
 *   mp4_i32 readEDTS(MP4HandleImp handle,
sl@0
  1271
 *                    editListContainerAtom *edts)
sl@0
  1272
 *
sl@0
  1273
 * Description:
sl@0
  1274
 *
sl@0
  1275
 *   This function parses one EDTS atom and discards the contents.
sl@0
  1276
 *
sl@0
  1277
 * Parameters:
sl@0
  1278
 *
sl@0
  1279
 *   handle             MP4 library handle
sl@0
  1280
 *   edts               EDTS pointer
sl@0
  1281
 *
sl@0
  1282
 * Return value:
sl@0
  1283
 *
sl@0
  1284
 *   Negative integer   Error
sl@0
  1285
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1286
 *
sl@0
  1287
 */
sl@0
  1288
mp4_i32 readEDTS(MP4HandleImp handle, editListContainerAtom *edts)
sl@0
  1289
{
sl@0
  1290
  mp4_i32 bytesread;
sl@0
  1291
  mp4_i32 totalbytesread = 0;
sl@0
  1292
sl@0
  1293
sl@0
  1294
  if ((edts->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1295
    return -100;
sl@0
  1296
sl@0
  1297
  bytesread = readAtomHeader(handle, edts->atomhdr);
sl@0
  1298
  if (bytesread < 0)
sl@0
  1299
    return -1;
sl@0
  1300
  totalbytesread += bytesread;
sl@0
  1301
sl@0
  1302
  if (edts->atomhdr->type != ATOMTYPE_EDTS)
sl@0
  1303
    return -1;
sl@0
  1304
sl@0
  1305
  bytesread = discardData(handle, edts->atomhdr->size - totalbytesread);
sl@0
  1306
  if (bytesread < 0)
sl@0
  1307
    return -1;
sl@0
  1308
  totalbytesread += bytesread;
sl@0
  1309
sl@0
  1310
  return totalbytesread;
sl@0
  1311
}
sl@0
  1312
sl@0
  1313
sl@0
  1314
/*
sl@0
  1315
 * Function:
sl@0
  1316
 *
sl@0
  1317
 *   mp4_i32 readMDIA(MP4HandleImp handle,
sl@0
  1318
 *                    mediaAtom *mdia)
sl@0
  1319
 *
sl@0
  1320
 * Description:
sl@0
  1321
 *
sl@0
  1322
 *   This function parses one MDIA atom.
sl@0
  1323
 *
sl@0
  1324
 * Parameters:
sl@0
  1325
 *
sl@0
  1326
 *   handle             MP4 library handle
sl@0
  1327
 *   mdia               MDIA pointer
sl@0
  1328
 *
sl@0
  1329
 * Return value:
sl@0
  1330
 *
sl@0
  1331
 *   Negative integer   Error
sl@0
  1332
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1333
 *
sl@0
  1334
 */
sl@0
  1335
mp4_i32 readMDIA(MP4HandleImp handle, mediaAtom *mdia)
sl@0
  1336
{
sl@0
  1337
  mp4_i32 bytesread;
sl@0
  1338
  mp4_i32 totalbytesread = 0;
sl@0
  1339
sl@0
  1340
sl@0
  1341
  if ((mdia->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1342
    return -100;
sl@0
  1343
sl@0
  1344
  bytesread = readAtomHeader(handle, mdia->atomhdr);
sl@0
  1345
  if (bytesread < 0)
sl@0
  1346
    return -1;
sl@0
  1347
  totalbytesread += bytesread;
sl@0
  1348
sl@0
  1349
  if (mdia->atomhdr->type != ATOMTYPE_MDIA)
sl@0
  1350
    return -1;
sl@0
  1351
sl@0
  1352
sl@0
  1353
  while ((mp4_u32)totalbytesread < mdia->atomhdr->size)
sl@0
  1354
  {
sl@0
  1355
    mp4_u32 type;
sl@0
  1356
sl@0
  1357
sl@0
  1358
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  1359
      return -1;
sl@0
  1360
sl@0
  1361
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  1362
sl@0
  1363
    switch (type)
sl@0
  1364
    {
sl@0
  1365
    case ATOMTYPE_MDHD:
sl@0
  1366
sl@0
  1367
      if (mdia->mdhd) /* MDHD has already been read, more than one is not allowed */
sl@0
  1368
        return -1;
sl@0
  1369
sl@0
  1370
      if ((mdia->mdhd = (mediaHeaderAtom *)mp4malloc(sizeof(mediaHeaderAtom))) == NULL)
sl@0
  1371
        return -100;
sl@0
  1372
sl@0
  1373
      bytesread = readMDHD(handle, mdia->mdhd);
sl@0
  1374
      if (bytesread < 0)
sl@0
  1375
        return -1;
sl@0
  1376
      totalbytesread += bytesread;
sl@0
  1377
sl@0
  1378
      break;
sl@0
  1379
sl@0
  1380
    case ATOMTYPE_HDLR:
sl@0
  1381
sl@0
  1382
      if (mdia->hdlr) /* HDLR has already been read, more than one is not allowed */
sl@0
  1383
        return -1;
sl@0
  1384
sl@0
  1385
      if ((mdia->hdlr = (handlerAtom *)mp4malloc(sizeof(handlerAtom))) == NULL)
sl@0
  1386
        return -100;
sl@0
  1387
sl@0
  1388
      bytesread = readHDLR(handle, mdia->hdlr);
sl@0
  1389
      if (bytesread < 0)
sl@0
  1390
        return -1;
sl@0
  1391
      totalbytesread += bytesread;
sl@0
  1392
sl@0
  1393
      break;
sl@0
  1394
sl@0
  1395
    case ATOMTYPE_MINF:
sl@0
  1396
sl@0
  1397
      if (mdia->minf) /* MINF has already been read, more than one is not allowed */
sl@0
  1398
        return -1;
sl@0
  1399
sl@0
  1400
      if ((mdia->minf = (mediaInformationAtom *)mp4malloc(sizeof(mediaInformationAtom))) == NULL)
sl@0
  1401
        return -100;
sl@0
  1402
sl@0
  1403
      bytesread = readMINF(handle, mdia->minf);
sl@0
  1404
      if (bytesread < 0)
sl@0
  1405
        return -1;
sl@0
  1406
      totalbytesread += bytesread;
sl@0
  1407
sl@0
  1408
      break;
sl@0
  1409
sl@0
  1410
    default:
sl@0
  1411
sl@0
  1412
      bytesread = readUnknown(handle);
sl@0
  1413
      if (bytesread < 0)
sl@0
  1414
        return -1;
sl@0
  1415
      totalbytesread += bytesread;
sl@0
  1416
sl@0
  1417
      break;
sl@0
  1418
    }
sl@0
  1419
  }
sl@0
  1420
sl@0
  1421
  return totalbytesread;
sl@0
  1422
}
sl@0
  1423
sl@0
  1424
sl@0
  1425
/*
sl@0
  1426
 * Function:
sl@0
  1427
 *
sl@0
  1428
 *   mp4_i32 readMDHD(MP4HandleImp handle,
sl@0
  1429
 *                    mediaHeaderAtom *mdhd)
sl@0
  1430
 *
sl@0
  1431
 * Description:
sl@0
  1432
 *
sl@0
  1433
 *   This function parses one MDHD atom.
sl@0
  1434
 *
sl@0
  1435
 * Parameters:
sl@0
  1436
 *
sl@0
  1437
 *   handle             MP4 library handle
sl@0
  1438
 *   mdhd               MDHD pointer
sl@0
  1439
 *
sl@0
  1440
 * Return value:
sl@0
  1441
 *
sl@0
  1442
 *   Negative integer   Error
sl@0
  1443
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1444
 *
sl@0
  1445
 */
sl@0
  1446
mp4_i32 readMDHD(MP4HandleImp handle, mediaHeaderAtom *mdhd)
sl@0
  1447
{
sl@0
  1448
  mp4_i32 bytesread;
sl@0
  1449
  mp4_i32 totalbytesread = 0;
sl@0
  1450
sl@0
  1451
sl@0
  1452
  if ((mdhd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1453
    return -100;
sl@0
  1454
sl@0
  1455
  bytesread = readFullAtomHeader(handle, mdhd->atomhdr);
sl@0
  1456
  if (bytesread < 0)
sl@0
  1457
    return -1;
sl@0
  1458
  totalbytesread += bytesread;
sl@0
  1459
sl@0
  1460
  if (mdhd->atomhdr->type != ATOMTYPE_MDHD)
sl@0
  1461
    return -1;
sl@0
  1462
sl@0
  1463
sl@0
  1464
  if (mdhd->atomhdr->version == 1) /* 64 bit */
sl@0
  1465
  {
sl@0
  1466
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1467
    if (bytesread < 0)
sl@0
  1468
      return -1;
sl@0
  1469
    mdhd->creationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1470
    totalbytesread += bytesread;
sl@0
  1471
sl@0
  1472
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1473
    if (bytesread < 0)
sl@0
  1474
      return -1;
sl@0
  1475
    mdhd->modificationTime64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1476
    totalbytesread += bytesread;
sl@0
  1477
sl@0
  1478
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1479
    if (bytesread < 0)
sl@0
  1480
      return -1;
sl@0
  1481
    mdhd->timeScale = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1482
    totalbytesread += bytesread;
sl@0
  1483
sl@0
  1484
    bytesread = readData(handle, handle->buf, 8);
sl@0
  1485
    if (bytesread < 0)
sl@0
  1486
      return -1;
sl@0
  1487
    mdhd->duration64 = u64endian(*((mp4_u64 *)handle->buf));
sl@0
  1488
    totalbytesread += bytesread;
sl@0
  1489
  }
sl@0
  1490
  else /* 32 bit */
sl@0
  1491
  {
sl@0
  1492
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1493
    if (bytesread < 0)
sl@0
  1494
      return -1;
sl@0
  1495
    mdhd->creationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1496
    totalbytesread += bytesread;
sl@0
  1497
sl@0
  1498
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1499
    if (bytesread < 0)
sl@0
  1500
      return -1;
sl@0
  1501
    mdhd->modificationTime = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1502
    totalbytesread += bytesread;
sl@0
  1503
sl@0
  1504
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1505
    if (bytesread < 0)
sl@0
  1506
      return -1;
sl@0
  1507
    mdhd->timeScale = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1508
    totalbytesread += bytesread;
sl@0
  1509
sl@0
  1510
    bytesread = readData(handle, handle->buf, 4);
sl@0
  1511
    if (bytesread < 0)
sl@0
  1512
      return -1;
sl@0
  1513
    mdhd->duration = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1514
    totalbytesread += bytesread;
sl@0
  1515
  }
sl@0
  1516
sl@0
  1517
  bytesread = discardData(handle, 4);
sl@0
  1518
  if (bytesread < 0)
sl@0
  1519
    return -1;
sl@0
  1520
  totalbytesread += bytesread;
sl@0
  1521
sl@0
  1522
  return totalbytesread;
sl@0
  1523
}
sl@0
  1524
sl@0
  1525
sl@0
  1526
/*
sl@0
  1527
 * Function:
sl@0
  1528
 *
sl@0
  1529
 *   mp4_i32 readHDLR(MP4HandleImp handle,
sl@0
  1530
 *                    handlerAtom *hdlr)
sl@0
  1531
 *
sl@0
  1532
 * Description:
sl@0
  1533
 *
sl@0
  1534
 *   This function parses one HDLR atom.
sl@0
  1535
 *
sl@0
  1536
 * Parameters:
sl@0
  1537
 *
sl@0
  1538
 *   handle             MP4 library handle
sl@0
  1539
 *   hdlr               HDLR pointer
sl@0
  1540
 *
sl@0
  1541
 * Return value:
sl@0
  1542
 *
sl@0
  1543
 *   Negative integer   Error
sl@0
  1544
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1545
 *
sl@0
  1546
 */
sl@0
  1547
mp4_i32 readHDLR(MP4HandleImp handle, handlerAtom *hdlr)
sl@0
  1548
{
sl@0
  1549
  mp4_i32 bytesread;
sl@0
  1550
  mp4_i32 totalbytesread = 0;
sl@0
  1551
sl@0
  1552
sl@0
  1553
  if ((hdlr->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1554
    return -100;
sl@0
  1555
sl@0
  1556
  bytesread = readFullAtomHeader(handle, hdlr->atomhdr);
sl@0
  1557
  if (bytesread < 0)
sl@0
  1558
    return -1;
sl@0
  1559
  totalbytesread += bytesread;
sl@0
  1560
sl@0
  1561
  if (hdlr->atomhdr->type != ATOMTYPE_HDLR)
sl@0
  1562
    return -1;
sl@0
  1563
sl@0
  1564
sl@0
  1565
  bytesread = discardData(handle, 4);
sl@0
  1566
  if (bytesread < 0)
sl@0
  1567
    return -1;
sl@0
  1568
  totalbytesread += bytesread;
sl@0
  1569
sl@0
  1570
  bytesread = readData(handle, handle->buf, 4);
sl@0
  1571
  if (bytesread < 0)
sl@0
  1572
    return -1;
sl@0
  1573
  hdlr->handlerType = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1574
  totalbytesread += bytesread;
sl@0
  1575
sl@0
  1576
  bytesread = discardData(handle, hdlr->atomhdr->size - totalbytesread);
sl@0
  1577
  if (bytesread < 0)
sl@0
  1578
    return -1;
sl@0
  1579
  totalbytesread += bytesread;
sl@0
  1580
sl@0
  1581
  return totalbytesread;
sl@0
  1582
}
sl@0
  1583
sl@0
  1584
sl@0
  1585
/*
sl@0
  1586
 * Function:
sl@0
  1587
 *
sl@0
  1588
 *   mp4_i32 readMINF(MP4HandleImp handle,
sl@0
  1589
 *                    mediaInformationAtom *minf)
sl@0
  1590
 *
sl@0
  1591
 * Description:
sl@0
  1592
 *
sl@0
  1593
 *   This function parses one MINF atom.
sl@0
  1594
 *
sl@0
  1595
 * Parameters:
sl@0
  1596
 *
sl@0
  1597
 *   handle             MP4 library handle
sl@0
  1598
 *   minf               MINF pointer
sl@0
  1599
 *
sl@0
  1600
 * Return value:
sl@0
  1601
 *
sl@0
  1602
 *   Negative integer   Error
sl@0
  1603
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1604
 *
sl@0
  1605
 */
sl@0
  1606
mp4_i32 readMINF(MP4HandleImp handle, mediaInformationAtom *minf)
sl@0
  1607
{
sl@0
  1608
  mp4_i32 bytesread;
sl@0
  1609
  mp4_i32 totalbytesread = 0;
sl@0
  1610
sl@0
  1611
sl@0
  1612
  if ((minf->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1613
    return -100;
sl@0
  1614
sl@0
  1615
  bytesread = readAtomHeader(handle, minf->atomhdr);
sl@0
  1616
  if (bytesread < 0)
sl@0
  1617
    return -1;
sl@0
  1618
  totalbytesread += bytesread;
sl@0
  1619
sl@0
  1620
  if (minf->atomhdr->type != ATOMTYPE_MINF)
sl@0
  1621
    return -1;
sl@0
  1622
sl@0
  1623
sl@0
  1624
  while ((mp4_u32)totalbytesread < minf->atomhdr->size)
sl@0
  1625
  {
sl@0
  1626
    mp4_u32 type;
sl@0
  1627
sl@0
  1628
sl@0
  1629
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  1630
      return -1;
sl@0
  1631
sl@0
  1632
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  1633
sl@0
  1634
    switch (type)
sl@0
  1635
    {
sl@0
  1636
    case ATOMTYPE_VMHD:
sl@0
  1637
sl@0
  1638
      if (minf->vmhd || minf->smhd) /* VMHD or SMHD has already been read, more than one is not allowed */
sl@0
  1639
        return -1;
sl@0
  1640
sl@0
  1641
      if ((minf->vmhd = (videoMediaHeaderAtom *)mp4malloc(sizeof(videoMediaHeaderAtom))) == NULL)
sl@0
  1642
        return -100;
sl@0
  1643
sl@0
  1644
      bytesread = readVMHD(handle, minf->vmhd);
sl@0
  1645
      if (bytesread < 0)
sl@0
  1646
        return -1;
sl@0
  1647
      totalbytesread += bytesread;
sl@0
  1648
sl@0
  1649
      break;
sl@0
  1650
sl@0
  1651
    case ATOMTYPE_SMHD:
sl@0
  1652
sl@0
  1653
      if (minf->smhd || minf->vmhd) /* SMHD or VMHD has already been read, more than one is not allowed */
sl@0
  1654
        return -1;
sl@0
  1655
sl@0
  1656
      if ((minf->smhd = (soundMediaHeaderAtom *)mp4malloc(sizeof(soundMediaHeaderAtom))) == NULL)
sl@0
  1657
        return -100;
sl@0
  1658
sl@0
  1659
      bytesread = readSMHD(handle, minf->smhd);
sl@0
  1660
      if (bytesread < 0)
sl@0
  1661
        return -1;
sl@0
  1662
      totalbytesread += bytesread;
sl@0
  1663
sl@0
  1664
      break;
sl@0
  1665
sl@0
  1666
    case ATOMTYPE_DINF:
sl@0
  1667
sl@0
  1668
      if (minf->dinf) /* DINF has already been read, more than one is not allowed */
sl@0
  1669
        return -1;
sl@0
  1670
sl@0
  1671
      if ((minf->dinf = (dataInformationAtom *)mp4malloc(sizeof(dataInformationAtom))) == NULL)
sl@0
  1672
        return -100;
sl@0
  1673
sl@0
  1674
      bytesread = readDINF(handle, minf->dinf);
sl@0
  1675
      if (bytesread < 0)
sl@0
  1676
        return -1;
sl@0
  1677
      totalbytesread += bytesread;
sl@0
  1678
sl@0
  1679
      break;
sl@0
  1680
sl@0
  1681
    case ATOMTYPE_STBL:
sl@0
  1682
sl@0
  1683
      if (minf->stbl) /* STBL has already been read, more than one is not allowed */
sl@0
  1684
        return -1;
sl@0
  1685
sl@0
  1686
      if ((minf->stbl = (sampleTableAtom *)mp4malloc(sizeof(sampleTableAtom))) == NULL)
sl@0
  1687
        return -100;
sl@0
  1688
sl@0
  1689
      bytesread = readSTBL(handle, minf->stbl);
sl@0
  1690
      if (bytesread < 0)
sl@0
  1691
        return -1;
sl@0
  1692
      totalbytesread += bytesread;
sl@0
  1693
sl@0
  1694
      break;
sl@0
  1695
sl@0
  1696
    default:
sl@0
  1697
sl@0
  1698
      bytesread = readUnknown(handle);
sl@0
  1699
      if (bytesread < 0)
sl@0
  1700
        return -1;
sl@0
  1701
      totalbytesread += bytesread;
sl@0
  1702
sl@0
  1703
      break;
sl@0
  1704
    }
sl@0
  1705
  }
sl@0
  1706
sl@0
  1707
  return totalbytesread;
sl@0
  1708
}
sl@0
  1709
sl@0
  1710
sl@0
  1711
/*
sl@0
  1712
 * Function:
sl@0
  1713
 *
sl@0
  1714
 *   mp4_i32 readVMHD(MP4HandleImp handle,
sl@0
  1715
 *                    videoMediaHeaderAtom *vmhd)
sl@0
  1716
 *
sl@0
  1717
 * Description:
sl@0
  1718
 *
sl@0
  1719
 *   This function parses one VMHD atom.
sl@0
  1720
 *
sl@0
  1721
 * Parameters:
sl@0
  1722
 *
sl@0
  1723
 *   handle             MP4 library handle
sl@0
  1724
 *   vmhd               VMHD pointer
sl@0
  1725
 *
sl@0
  1726
 * Return value:
sl@0
  1727
 *
sl@0
  1728
 *   Negative integer   Error
sl@0
  1729
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1730
 *
sl@0
  1731
 */
sl@0
  1732
mp4_i32 readVMHD(MP4HandleImp handle, videoMediaHeaderAtom *vmhd)
sl@0
  1733
{
sl@0
  1734
  mp4_i32 bytesread;
sl@0
  1735
  mp4_i32 totalbytesread = 0;
sl@0
  1736
sl@0
  1737
sl@0
  1738
  if ((vmhd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1739
    return -100;
sl@0
  1740
sl@0
  1741
  bytesread = readFullAtomHeader(handle, vmhd->atomhdr);
sl@0
  1742
  if (bytesread < 0)
sl@0
  1743
    return -1;
sl@0
  1744
  totalbytesread += bytesread;
sl@0
  1745
sl@0
  1746
  if (vmhd->atomhdr->type != ATOMTYPE_VMHD)
sl@0
  1747
    return -1;
sl@0
  1748
sl@0
  1749
sl@0
  1750
  bytesread = discardData(handle, vmhd->atomhdr->size - totalbytesread);
sl@0
  1751
  if (bytesread < 0)
sl@0
  1752
    return -1;
sl@0
  1753
  totalbytesread += bytesread;
sl@0
  1754
sl@0
  1755
  return totalbytesread;
sl@0
  1756
}
sl@0
  1757
sl@0
  1758
sl@0
  1759
/*
sl@0
  1760
 * Function:
sl@0
  1761
 *
sl@0
  1762
 *   mp4_i32 readSMHD(MP4HandleImp handle,
sl@0
  1763
 *                    soundMediaHeaderAtom *smhd)
sl@0
  1764
 *
sl@0
  1765
 * Description:
sl@0
  1766
 *
sl@0
  1767
 *   This function parses one SMHD atom.
sl@0
  1768
 *
sl@0
  1769
 * Parameters:
sl@0
  1770
 *
sl@0
  1771
 *   handle             MP4 library handle
sl@0
  1772
 *   smhd               SMHD pointer
sl@0
  1773
 *
sl@0
  1774
 * Return value:
sl@0
  1775
 *
sl@0
  1776
 *   Negative integer   Error
sl@0
  1777
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1778
 *
sl@0
  1779
 */
sl@0
  1780
mp4_i32 readSMHD(MP4HandleImp handle, soundMediaHeaderAtom *smhd)
sl@0
  1781
{
sl@0
  1782
  mp4_i32 bytesread;
sl@0
  1783
  mp4_i32 totalbytesread = 0;
sl@0
  1784
sl@0
  1785
sl@0
  1786
  if ((smhd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1787
    return -100;
sl@0
  1788
sl@0
  1789
  bytesread = readFullAtomHeader(handle, smhd->atomhdr);
sl@0
  1790
  if (bytesread < 0)
sl@0
  1791
    return -1;
sl@0
  1792
  totalbytesread += bytesread;
sl@0
  1793
sl@0
  1794
  if (smhd->atomhdr->type != ATOMTYPE_SMHD)
sl@0
  1795
    return -1;
sl@0
  1796
sl@0
  1797
sl@0
  1798
  bytesread = discardData(handle, smhd->atomhdr->size - totalbytesread);
sl@0
  1799
  if (bytesread < 0)
sl@0
  1800
    return -1;
sl@0
  1801
  totalbytesread += bytesread;
sl@0
  1802
sl@0
  1803
  return totalbytesread;
sl@0
  1804
}
sl@0
  1805
sl@0
  1806
sl@0
  1807
/*
sl@0
  1808
 * Function:
sl@0
  1809
 *
sl@0
  1810
 *   mp4_i32 readDINF(MP4HandleImp handle,
sl@0
  1811
 *                    dataInformationAtom *dinf)
sl@0
  1812
 *
sl@0
  1813
 * Description:
sl@0
  1814
 *
sl@0
  1815
 *   This function parses one DINF atom.
sl@0
  1816
 *
sl@0
  1817
 * Parameters:
sl@0
  1818
 *
sl@0
  1819
 *   handle             MP4 library handle
sl@0
  1820
 *   dinf               DINF pointer
sl@0
  1821
 *
sl@0
  1822
 * Return value:
sl@0
  1823
 *
sl@0
  1824
 *   Negative integer   Error
sl@0
  1825
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1826
 *
sl@0
  1827
 */
sl@0
  1828
mp4_i32 readDINF(MP4HandleImp handle, dataInformationAtom *dinf)
sl@0
  1829
{
sl@0
  1830
  mp4_i32 bytesread;
sl@0
  1831
  mp4_i32 totalbytesread = 0;
sl@0
  1832
sl@0
  1833
sl@0
  1834
  if ((dinf->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1835
    return -100;
sl@0
  1836
sl@0
  1837
  bytesread = readAtomHeader(handle, dinf->atomhdr);
sl@0
  1838
  if (bytesread < 0)
sl@0
  1839
    return -1;
sl@0
  1840
  totalbytesread += bytesread;
sl@0
  1841
sl@0
  1842
  if (dinf->atomhdr->type != ATOMTYPE_DINF)
sl@0
  1843
    return -1;
sl@0
  1844
sl@0
  1845
sl@0
  1846
  while ((mp4_u32)totalbytesread < dinf->atomhdr->size)
sl@0
  1847
  {
sl@0
  1848
    mp4_u32 type;
sl@0
  1849
sl@0
  1850
sl@0
  1851
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  1852
      return -1;
sl@0
  1853
sl@0
  1854
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  1855
sl@0
  1856
    switch (type)
sl@0
  1857
    {
sl@0
  1858
    case ATOMTYPE_DREF:
sl@0
  1859
sl@0
  1860
      if (dinf->dref) /* DINF has already been read, more than one is not allowed */
sl@0
  1861
        return -1;
sl@0
  1862
sl@0
  1863
      if ((dinf->dref = (dataReferenceAtom *)mp4malloc(sizeof(dataReferenceAtom))) == NULL)
sl@0
  1864
        return -100;
sl@0
  1865
sl@0
  1866
      bytesread = readDREF(handle, dinf->dref);
sl@0
  1867
      if (bytesread < 0)
sl@0
  1868
        return -1;
sl@0
  1869
      totalbytesread += bytesread;
sl@0
  1870
sl@0
  1871
      break;
sl@0
  1872
sl@0
  1873
    default:
sl@0
  1874
sl@0
  1875
      return -1;
sl@0
  1876
    }
sl@0
  1877
  }
sl@0
  1878
sl@0
  1879
  return totalbytesread;
sl@0
  1880
}
sl@0
  1881
sl@0
  1882
sl@0
  1883
/*
sl@0
  1884
 * Function:
sl@0
  1885
 *
sl@0
  1886
 *   mp4_i32 readDREF(MP4HandleImp handle,
sl@0
  1887
 *                    dataReferenceAtom *dref)
sl@0
  1888
 *
sl@0
  1889
 * Description:
sl@0
  1890
 *
sl@0
  1891
 *   This function parses one DREF atom.
sl@0
  1892
 *
sl@0
  1893
 * Parameters:
sl@0
  1894
 *
sl@0
  1895
 *   handle             MP4 library handle
sl@0
  1896
 *   dref               DREF pointer
sl@0
  1897
 *
sl@0
  1898
 * Return value:
sl@0
  1899
 *
sl@0
  1900
 *   Negative integer   Error
sl@0
  1901
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1902
 *
sl@0
  1903
 */
sl@0
  1904
mp4_i32 readDREF(MP4HandleImp handle, dataReferenceAtom *dref)
sl@0
  1905
{
sl@0
  1906
  mp4_i32 bytesread;
sl@0
  1907
  mp4_i32 totalbytesread = 0;
sl@0
  1908
sl@0
  1909
sl@0
  1910
  if ((dref->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1911
    return -100;
sl@0
  1912
sl@0
  1913
  bytesread = readFullAtomHeader(handle, dref->atomhdr);
sl@0
  1914
  if (bytesread < 0)
sl@0
  1915
    return -1;
sl@0
  1916
  totalbytesread += bytesread;
sl@0
  1917
sl@0
  1918
  if (dref->atomhdr->type != ATOMTYPE_DREF)
sl@0
  1919
    return -1;
sl@0
  1920
sl@0
  1921
sl@0
  1922
  bytesread = readData(handle, handle->buf, 4);
sl@0
  1923
  if (bytesread < 0)
sl@0
  1924
    return -1;
sl@0
  1925
  dref->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  1926
  totalbytesread += bytesread;
sl@0
  1927
sl@0
  1928
  if (dref->entryCount != 1)
sl@0
  1929
    return -1;
sl@0
  1930
sl@0
  1931
  while ((mp4_u32)totalbytesread < dref->atomhdr->size)
sl@0
  1932
  {
sl@0
  1933
    bytesread = readUnknown(handle);
sl@0
  1934
    if (bytesread < 0)
sl@0
  1935
      return -1;
sl@0
  1936
    totalbytesread += bytesread;
sl@0
  1937
  }
sl@0
  1938
  return totalbytesread;
sl@0
  1939
}
sl@0
  1940
sl@0
  1941
sl@0
  1942
/*
sl@0
  1943
 * Function:
sl@0
  1944
 *
sl@0
  1945
 *   mp4_i32 readURL(MP4HandleImp handle,
sl@0
  1946
 *                   dataEntryURLAtom *url)
sl@0
  1947
 *
sl@0
  1948
 * Description:
sl@0
  1949
 *
sl@0
  1950
 *   This function parses one URL atom.
sl@0
  1951
 *
sl@0
  1952
 * Parameters:
sl@0
  1953
 *
sl@0
  1954
 *   handle             MP4 library handle
sl@0
  1955
 *   url                URL pointer
sl@0
  1956
 *
sl@0
  1957
 * Return value:
sl@0
  1958
 *
sl@0
  1959
 *   Negative integer   Error
sl@0
  1960
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  1961
 *
sl@0
  1962
 */
sl@0
  1963
mp4_i32 readURL(MP4HandleImp handle, dataEntryURLAtom *url)
sl@0
  1964
{
sl@0
  1965
  mp4_i32 bytesread;
sl@0
  1966
  mp4_i32 totalbytesread = 0;
sl@0
  1967
sl@0
  1968
sl@0
  1969
  if ((url->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  1970
    return -100;
sl@0
  1971
sl@0
  1972
  bytesread = readFullAtomHeader(handle, url->atomhdr);
sl@0
  1973
  if (bytesread < 0)
sl@0
  1974
    return -1;
sl@0
  1975
  totalbytesread += bytesread;
sl@0
  1976
sl@0
  1977
  if (url->atomhdr->type != ATOMTYPE_URL)
sl@0
  1978
    return -1;
sl@0
  1979
sl@0
  1980
sl@0
  1981
  if (!(url->atomhdr->flags[0] == 0x00 &&
sl@0
  1982
        url->atomhdr->flags[1] == 0x00 &&
sl@0
  1983
        url->atomhdr->flags[2] == 0x01))
sl@0
  1984
    return -1;
sl@0
  1985
sl@0
  1986
  return totalbytesread;
sl@0
  1987
}
sl@0
  1988
sl@0
  1989
sl@0
  1990
/*
sl@0
  1991
 * Function:
sl@0
  1992
 *
sl@0
  1993
 *   mp4_i32 readURN(MP4HandleImp handle,
sl@0
  1994
 *                   dataEntryURNAtom *urn)
sl@0
  1995
 *
sl@0
  1996
 * Description:
sl@0
  1997
 *
sl@0
  1998
 *   This function parses one URN atom.
sl@0
  1999
 *
sl@0
  2000
 * Parameters:
sl@0
  2001
 *
sl@0
  2002
 *   handle             MP4 library handle
sl@0
  2003
 *   urn                URN pointer
sl@0
  2004
 *
sl@0
  2005
 * Return value:
sl@0
  2006
 *
sl@0
  2007
 *   Negative integer   Error
sl@0
  2008
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2009
 *
sl@0
  2010
 */
sl@0
  2011
mp4_i32 readURN(MP4HandleImp handle, dataEntryURNAtom *urn)
sl@0
  2012
{
sl@0
  2013
  mp4_i32 bytesread;
sl@0
  2014
  mp4_i32 totalbytesread = 0;
sl@0
  2015
sl@0
  2016
sl@0
  2017
  if ((urn->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2018
    return -100;
sl@0
  2019
sl@0
  2020
  bytesread = readFullAtomHeader(handle, urn->atomhdr);
sl@0
  2021
  if (bytesread < 0)
sl@0
  2022
    return -1;
sl@0
  2023
  totalbytesread += bytesread;
sl@0
  2024
sl@0
  2025
  if (urn->atomhdr->type != ATOMTYPE_URN)
sl@0
  2026
    return -1;
sl@0
  2027
sl@0
  2028
sl@0
  2029
  if (!(urn->atomhdr->flags[0] == 0x00 &&
sl@0
  2030
        urn->atomhdr->flags[1] == 0x00 &&
sl@0
  2031
        urn->atomhdr->flags[2] == 0x01))
sl@0
  2032
    return -1;
sl@0
  2033
sl@0
  2034
  return totalbytesread;
sl@0
  2035
}
sl@0
  2036
sl@0
  2037
sl@0
  2038
/*
sl@0
  2039
 * Function:
sl@0
  2040
 *
sl@0
  2041
 *   mp4_i32 readSTBL(MP4HandleImp handle,
sl@0
  2042
 *                    sampleTableAtom *stbl)
sl@0
  2043
 *
sl@0
  2044
 * Description:
sl@0
  2045
 *
sl@0
  2046
 *   This function parses one STBL atom.
sl@0
  2047
 *
sl@0
  2048
 * Parameters:
sl@0
  2049
 *
sl@0
  2050
 *   handle             MP4 library handle
sl@0
  2051
 *   stbl               STBL pointer
sl@0
  2052
 *
sl@0
  2053
 * Return value:
sl@0
  2054
 *
sl@0
  2055
 *   Negative integer   Error
sl@0
  2056
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2057
 *
sl@0
  2058
 */
sl@0
  2059
mp4_i32 readSTBL(MP4HandleImp handle, sampleTableAtom *stbl)
sl@0
  2060
{
sl@0
  2061
  mp4_i32 bytesread;
sl@0
  2062
  mp4_i32 totalbytesread = 0;
sl@0
  2063
sl@0
  2064
sl@0
  2065
  if ((stbl->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2066
    return -100;
sl@0
  2067
sl@0
  2068
  bytesread = readAtomHeader(handle, stbl->atomhdr);
sl@0
  2069
  if (bytesread < 0)
sl@0
  2070
    return -1;
sl@0
  2071
  totalbytesread += bytesread;
sl@0
  2072
sl@0
  2073
  if (stbl->atomhdr->type != ATOMTYPE_STBL)
sl@0
  2074
    return -1;
sl@0
  2075
sl@0
  2076
sl@0
  2077
  while ((mp4_u32)totalbytesread < stbl->atomhdr->size)
sl@0
  2078
  {
sl@0
  2079
    mp4_u32 type;
sl@0
  2080
sl@0
  2081
sl@0
  2082
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  2083
      return -1;
sl@0
  2084
sl@0
  2085
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  2086
sl@0
  2087
    switch (type)
sl@0
  2088
    {
sl@0
  2089
    case ATOMTYPE_STTS:
sl@0
  2090
sl@0
  2091
      if (stbl->stts) /* STTS has already been read, more than one is not allowed */
sl@0
  2092
        return -1;
sl@0
  2093
sl@0
  2094
      if ((stbl->stts = (timeToSampleAtom *)mp4malloc(sizeof(timeToSampleAtom))) == NULL)
sl@0
  2095
        return -100;
sl@0
  2096
sl@0
  2097
      bytesread = readSTTS(handle, stbl->stts);
sl@0
  2098
      if (bytesread < 0)
sl@0
  2099
        return -1;
sl@0
  2100
      totalbytesread += bytesread;
sl@0
  2101
sl@0
  2102
      break;
sl@0
  2103
sl@0
  2104
    case ATOMTYPE_CTTS:
sl@0
  2105
sl@0
  2106
      if (stbl->ctts) /* CTTS has already been read, more than one is not allowed */
sl@0
  2107
        return -1;
sl@0
  2108
sl@0
  2109
      if ((stbl->ctts = (compositionTimeToSampleAtom *)mp4malloc(sizeof(compositionTimeToSampleAtom))) == NULL)
sl@0
  2110
        return -100;
sl@0
  2111
sl@0
  2112
      bytesread = readCTTS(handle, stbl->ctts);
sl@0
  2113
      if (bytesread < 0)
sl@0
  2114
        return -1;
sl@0
  2115
      totalbytesread += bytesread;
sl@0
  2116
sl@0
  2117
      break;
sl@0
  2118
sl@0
  2119
    case ATOMTYPE_STSS:
sl@0
  2120
sl@0
  2121
      if (stbl->stss) /* STSS has already been read, more than one is not allowed */
sl@0
  2122
        return -1;
sl@0
  2123
sl@0
  2124
      if ((stbl->stss = (syncSampleAtom *)mp4malloc(sizeof(syncSampleAtom))) == NULL)
sl@0
  2125
        return -100;
sl@0
  2126
sl@0
  2127
      bytesread = readSTSS(handle, stbl->stss);
sl@0
  2128
      if (bytesread < 0)
sl@0
  2129
        return -1;
sl@0
  2130
      totalbytesread += bytesread;
sl@0
  2131
sl@0
  2132
      break;
sl@0
  2133
sl@0
  2134
    case ATOMTYPE_STSD:
sl@0
  2135
sl@0
  2136
      if (stbl->stsd) /* STSD has already been read, more than one is not allowed */
sl@0
  2137
        return -1;
sl@0
  2138
sl@0
  2139
      if ((stbl->stsd = (sampleDescriptionAtom *)mp4malloc(sizeof(sampleDescriptionAtom))) == NULL)
sl@0
  2140
        return -100;
sl@0
  2141
sl@0
  2142
      bytesread = readSTSD(handle, stbl->stsd);
sl@0
  2143
      if (bytesread < 0)
sl@0
  2144
        return -1;
sl@0
  2145
      totalbytesread += bytesread;
sl@0
  2146
sl@0
  2147
      break;
sl@0
  2148
sl@0
  2149
    case ATOMTYPE_STSZ:
sl@0
  2150
sl@0
  2151
      if (stbl->stsz) /* STSZ or STZ2 has already been read, more than one is not allowed */
sl@0
  2152
        return -1;
sl@0
  2153
sl@0
  2154
      if ((stbl->stsz = (sampleSizeAtom *)mp4malloc(sizeof(sampleSizeAtom))) == NULL)
sl@0
  2155
        return -100;
sl@0
  2156
sl@0
  2157
      bytesread = readSTSZ(handle, stbl->stsz);
sl@0
  2158
      if (bytesread < 0)
sl@0
  2159
        return -1;
sl@0
  2160
      totalbytesread += bytesread;
sl@0
  2161
sl@0
  2162
      break;
sl@0
  2163
sl@0
  2164
    case ATOMTYPE_STZ2:
sl@0
  2165
sl@0
  2166
      if (stbl->stsz) /* STSZ or STZ2 has already been read, more than one is not allowed */
sl@0
  2167
        return -1;
sl@0
  2168
sl@0
  2169
      if ((stbl->stsz = (sampleSizeAtom *)mp4malloc(sizeof(sampleSizeAtom))) == NULL)
sl@0
  2170
        return -100;
sl@0
  2171
sl@0
  2172
      bytesread = readSTZ2(handle, stbl->stsz);
sl@0
  2173
      if (bytesread < 0)
sl@0
  2174
        return -1;
sl@0
  2175
      totalbytesread += bytesread;
sl@0
  2176
sl@0
  2177
      break;
sl@0
  2178
sl@0
  2179
    case ATOMTYPE_STSC:
sl@0
  2180
sl@0
  2181
      if (stbl->stsc) /* STSC has already been read, more than one is not allowed */
sl@0
  2182
        return -1;
sl@0
  2183
sl@0
  2184
      if ((stbl->stsc = (sampleToChunkAtom *)mp4malloc(sizeof(sampleToChunkAtom))) == NULL)
sl@0
  2185
        return -100;
sl@0
  2186
sl@0
  2187
      bytesread = readSTSC(handle, stbl->stsc);
sl@0
  2188
      if (bytesread < 0)
sl@0
  2189
        return -1;
sl@0
  2190
      totalbytesread += bytesread;
sl@0
  2191
sl@0
  2192
      break;
sl@0
  2193
sl@0
  2194
    case ATOMTYPE_STCO:
sl@0
  2195
sl@0
  2196
      if (stbl->stco) /* STCO or CO64 has already been read, more than one is not allowed */
sl@0
  2197
        return -1;
sl@0
  2198
sl@0
  2199
      if ((stbl->stco = (chunkOffsetAtom *)mp4malloc(sizeof(chunkOffsetAtom))) == NULL)
sl@0
  2200
        return -100;
sl@0
  2201
      
sl@0
  2202
      stbl->is32BitOffsets = ETrue;
sl@0
  2203
      bytesread = readSTCO(handle, stbl->stco);
sl@0
  2204
      if (bytesread < 0)
sl@0
  2205
        return -1;
sl@0
  2206
      totalbytesread += bytesread;
sl@0
  2207
sl@0
  2208
      break;
sl@0
  2209
sl@0
  2210
    case ATOMTYPE_CO64:
sl@0
  2211
sl@0
  2212
      if (stbl->stco64) /* STCO or CO64 has already been read, more than one is not allowed */
sl@0
  2213
        return -1;
sl@0
  2214
sl@0
  2215
      if ((stbl->stco64 = (chunkOffset64Atom *)mp4malloc(sizeof(chunkOffset64Atom))) == NULL)
sl@0
  2216
        return -100;
sl@0
  2217
      
sl@0
  2218
      stbl->is32BitOffsets = EFalse;
sl@0
  2219
      bytesread = readCO64(handle, stbl->stco64);
sl@0
  2220
      if (bytesread < 0)
sl@0
  2221
        return -1;
sl@0
  2222
      totalbytesread += bytesread;
sl@0
  2223
sl@0
  2224
      break;
sl@0
  2225
sl@0
  2226
    case ATOMTYPE_SDTP:
sl@0
  2227
      if (stbl->sdtp) /* SDTP has already been read, more than one is not allowed */
sl@0
  2228
        return -1;
sl@0
  2229
      
sl@0
  2230
      if ((stbl->sdtp = (sampleDependencyAtom *)mp4malloc(sizeof(sampleDependencyAtom))) == NULL)
sl@0
  2231
        return -100;
sl@0
  2232
sl@0
  2233
      if (!stbl->stsz)
sl@0
  2234
    	  {
sl@0
  2235
    	  return -1;
sl@0
  2236
    	  }
sl@0
  2237
sl@0
  2238
	  // sample_count of SDTP is taken from the sample_count in the Sample Size Box ('stsz') or
sl@0
  2239
	  // Compact Sample Size Box (‘stz2’). 
sl@0
  2240
	  bytesread = readSDTP(handle, stbl->sdtp, stbl->stsz->sampleCount);
sl@0
  2241
    	  
sl@0
  2242
      if (bytesread < 0)
sl@0
  2243
        return -1;
sl@0
  2244
      totalbytesread += bytesread;
sl@0
  2245
      break;
sl@0
  2246
sl@0
  2247
    default: /* Other atoms are not needed */
sl@0
  2248
sl@0
  2249
      bytesread = readUnknown(handle);
sl@0
  2250
      if (bytesread < 0)
sl@0
  2251
        return -1;
sl@0
  2252
      totalbytesread += bytesread;
sl@0
  2253
sl@0
  2254
      break;
sl@0
  2255
    }
sl@0
  2256
  }
sl@0
  2257
sl@0
  2258
  return totalbytesread;
sl@0
  2259
}
sl@0
  2260
sl@0
  2261
sl@0
  2262
/*
sl@0
  2263
 * Function:
sl@0
  2264
 *
sl@0
  2265
 *   mp4_i32 readSTTS(MP4HandleImp handle,
sl@0
  2266
 *                    timeToSampleAtom *stts)
sl@0
  2267
 *
sl@0
  2268
 * Description:
sl@0
  2269
 *
sl@0
  2270
 *   This function parses one STTS atom.
sl@0
  2271
 *
sl@0
  2272
 * Parameters:
sl@0
  2273
 *
sl@0
  2274
 *   handle             MP4 library handle
sl@0
  2275
 *   stts               STTS pointer
sl@0
  2276
 *
sl@0
  2277
 * Return value:
sl@0
  2278
 *
sl@0
  2279
 *   Negative integer   Error
sl@0
  2280
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2281
 *
sl@0
  2282
 */
sl@0
  2283
mp4_i32 readSTTS(MP4HandleImp handle, timeToSampleAtom *stts)
sl@0
  2284
{
sl@0
  2285
  mp4_i32 bytesread;
sl@0
  2286
  mp4_i32 totalbytesread = 0;
sl@0
  2287
  mp4_u32 i;
sl@0
  2288
sl@0
  2289
sl@0
  2290
  if ((stts->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2291
    return -100;
sl@0
  2292
sl@0
  2293
  bytesread = readFullAtomHeader(handle, stts->atomhdr);
sl@0
  2294
  if (bytesread < 0)
sl@0
  2295
    return -1;
sl@0
  2296
  totalbytesread += bytesread;
sl@0
  2297
sl@0
  2298
  if (stts->atomhdr->type != ATOMTYPE_STTS)
sl@0
  2299
    return -1;
sl@0
  2300
sl@0
  2301
sl@0
  2302
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2303
  if (bytesread < 0)
sl@0
  2304
    return -1;
sl@0
  2305
  stts->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2306
  totalbytesread += bytesread;
sl@0
  2307
  
sl@0
  2308
  if ( stts->entryCount )
sl@0
  2309
  {
sl@0
  2310
	  stts->sampleCount = (mp4_u32 *)mp4malloc(stts->entryCount * sizeof(mp4_u32));
sl@0
  2311
	  if (stts->sampleCount == NULL)
sl@0
  2312
	    return -1;
sl@0
  2313
	  stts->sampleDelta = (mp4_i32 *)mp4malloc(stts->entryCount * sizeof(mp4_i32));
sl@0
  2314
	  if (stts->sampleDelta == NULL)
sl@0
  2315
	    return -1;
sl@0
  2316
sl@0
  2317
	  for (i = 0; i < stts->entryCount; i++)
sl@0
  2318
	  {
sl@0
  2319
	    bytesread = readData(handle, handle->buf, 8);
sl@0
  2320
	    if (bytesread < 0)
sl@0
  2321
	      return -1;
sl@0
  2322
sl@0
  2323
	    stts->sampleCount[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2324
	    stts->sampleDelta[i] = i32endian(*((mp4_i32 *)(handle->buf+4)));
sl@0
  2325
sl@0
  2326
	    totalbytesread += bytesread;
sl@0
  2327
	  }
sl@0
  2328
  }
sl@0
  2329
sl@0
  2330
  return totalbytesread;
sl@0
  2331
}
sl@0
  2332
sl@0
  2333
sl@0
  2334
/*
sl@0
  2335
 * Function:
sl@0
  2336
 *
sl@0
  2337
 *   mp4_i32 readCTTS(MP4HandleImp handle,
sl@0
  2338
 *                    compositionTimeToSampleAtom *ctts)
sl@0
  2339
 *
sl@0
  2340
 * Description:
sl@0
  2341
 *
sl@0
  2342
 *   This function parses one CTTS atom.
sl@0
  2343
 *
sl@0
  2344
 * Parameters:
sl@0
  2345
 *
sl@0
  2346
 *   handle             MP4 library handle
sl@0
  2347
 *   ctts               CTTS pointer
sl@0
  2348
 *
sl@0
  2349
 * Return value:
sl@0
  2350
 *
sl@0
  2351
 *   Negative integer   Error
sl@0
  2352
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2353
 *
sl@0
  2354
 */
sl@0
  2355
mp4_i32 readCTTS(MP4HandleImp handle, compositionTimeToSampleAtom *ctts)
sl@0
  2356
{
sl@0
  2357
  mp4_i32 bytesread;
sl@0
  2358
  mp4_i32 totalbytesread = 0;
sl@0
  2359
  mp4_u32 i;
sl@0
  2360
sl@0
  2361
sl@0
  2362
  if ((ctts->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2363
    return -100;
sl@0
  2364
sl@0
  2365
  bytesread = readFullAtomHeader(handle, ctts->atomhdr);
sl@0
  2366
  if (bytesread < 0)
sl@0
  2367
    return -1;
sl@0
  2368
  totalbytesread += bytesread;
sl@0
  2369
sl@0
  2370
  if (ctts->atomhdr->type != ATOMTYPE_CTTS)
sl@0
  2371
    return -1;
sl@0
  2372
sl@0
  2373
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2374
  if (bytesread < 0)
sl@0
  2375
    return -1;
sl@0
  2376
  ctts->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2377
  totalbytesread += bytesread;
sl@0
  2378
sl@0
  2379
  if ( ctts->entryCount )
sl@0
  2380
  {
sl@0
  2381
	  ctts->sampleCount = (mp4_u32 *)mp4malloc(ctts->entryCount * sizeof(mp4_u32));
sl@0
  2382
	  if (ctts->sampleCount == NULL)
sl@0
  2383
	    return -1;
sl@0
  2384
	  ctts->sampleOffset = (mp4_u32 *)mp4malloc(ctts->entryCount * sizeof(mp4_u32));
sl@0
  2385
	  if (ctts->sampleOffset == NULL)
sl@0
  2386
	    return -1;
sl@0
  2387
sl@0
  2388
	  for (i = 0; i < ctts->entryCount; i++)
sl@0
  2389
	  {
sl@0
  2390
	    bytesread = readData(handle, handle->buf, 8);
sl@0
  2391
	    if (bytesread < 0)
sl@0
  2392
	      return -1;
sl@0
  2393
sl@0
  2394
	    ctts->sampleCount[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2395
	    ctts->sampleOffset[i] = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  2396
sl@0
  2397
	    totalbytesread += bytesread;
sl@0
  2398
	  }
sl@0
  2399
  }
sl@0
  2400
  return totalbytesread;
sl@0
  2401
}
sl@0
  2402
sl@0
  2403
sl@0
  2404
/*
sl@0
  2405
 * Function:
sl@0
  2406
 *
sl@0
  2407
 *   mp4_i32 readSTSS(MP4HandleImp handle,
sl@0
  2408
 *                    syncSampleAtom *stss)
sl@0
  2409
 *
sl@0
  2410
 * Description:
sl@0
  2411
 *
sl@0
  2412
 *   This function parses one STSS atom.
sl@0
  2413
 *
sl@0
  2414
 * Parameters:
sl@0
  2415
 *
sl@0
  2416
 *   handle             MP4 library handle
sl@0
  2417
 *   stss               STSS pointer
sl@0
  2418
 *
sl@0
  2419
 * Return value:
sl@0
  2420
 *
sl@0
  2421
 *   Negative integer   Error
sl@0
  2422
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2423
 *
sl@0
  2424
 */
sl@0
  2425
mp4_i32 readSTSS(MP4HandleImp handle, syncSampleAtom *stss)
sl@0
  2426
{
sl@0
  2427
  mp4_i32 bytesread;
sl@0
  2428
  mp4_i32 totalbytesread = 0;
sl@0
  2429
  mp4_u32 i;
sl@0
  2430
sl@0
  2431
sl@0
  2432
  if ((stss->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2433
    return -100;
sl@0
  2434
sl@0
  2435
  bytesread = readFullAtomHeader(handle, stss->atomhdr);
sl@0
  2436
  if (bytesread < 0)
sl@0
  2437
    return -1;
sl@0
  2438
  totalbytesread += bytesread;
sl@0
  2439
sl@0
  2440
  if (stss->atomhdr->type != ATOMTYPE_STSS)
sl@0
  2441
    return -1;
sl@0
  2442
sl@0
  2443
sl@0
  2444
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2445
  if (bytesread < 0)
sl@0
  2446
    return -1;
sl@0
  2447
  stss->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2448
  totalbytesread += bytesread;
sl@0
  2449
sl@0
  2450
  if ( stss->entryCount )
sl@0
  2451
  {
sl@0
  2452
	  stss->sampleNumber = (mp4_u32 *)mp4malloc(stss->entryCount * sizeof(mp4_u32));
sl@0
  2453
	  if (stss->sampleNumber == NULL)
sl@0
  2454
	    return -1;
sl@0
  2455
sl@0
  2456
	  for (i = 0; i < stss->entryCount; i++)
sl@0
  2457
	  {
sl@0
  2458
	    bytesread = readData(handle, handle->buf, 4);
sl@0
  2459
	    if (bytesread < 0)
sl@0
  2460
	      return -1;
sl@0
  2461
sl@0
  2462
	    stss->sampleNumber[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2463
sl@0
  2464
	    totalbytesread += bytesread;
sl@0
  2465
	  }
sl@0
  2466
  }
sl@0
  2467
sl@0
  2468
  return totalbytesread;
sl@0
  2469
}
sl@0
  2470
sl@0
  2471
sl@0
  2472
/*
sl@0
  2473
 * Function:
sl@0
  2474
 *
sl@0
  2475
 *   mp4_i32 readSTSD(MP4HandleImp handle,
sl@0
  2476
 *                    sampleDescriptionAtom *stsd)
sl@0
  2477
 *
sl@0
  2478
 * Description:
sl@0
  2479
 *
sl@0
  2480
 *   This function parses one STSD atom.
sl@0
  2481
 *
sl@0
  2482
 * Parameters:
sl@0
  2483
 *
sl@0
  2484
 *   handle             MP4 library handle
sl@0
  2485
 *   stsd               STSD pointer
sl@0
  2486
 *
sl@0
  2487
 * Return value:
sl@0
  2488
 *
sl@0
  2489
 *   Negative integer   Error
sl@0
  2490
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2491
 *
sl@0
  2492
 */
sl@0
  2493
mp4_i32 readSTSD(MP4HandleImp handle, sampleDescriptionAtom *stsd)
sl@0
  2494
	{
sl@0
  2495
	mp4_i32 bytesread;
sl@0
  2496
	mp4_i32 totalbytesread = 0;
sl@0
  2497
	mp4_u32 totalsampleentriesread = 0;
sl@0
  2498
	mp4_u32 unknownsampleentriesread = 0;
sl@0
  2499
	mp4_bool skipentries = 0;
sl@0
  2500
sl@0
  2501
	if ((stsd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2502
        {
sl@0
  2503
        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2504
        stsd->entryCount = totalsampleentriesread;
sl@0
  2505
	    return -100;
sl@0
  2506
        }
sl@0
  2507
sl@0
  2508
	bytesread = readFullAtomHeader(handle, stsd->atomhdr);
sl@0
  2509
	if (bytesread < 0)
sl@0
  2510
	    {
sl@0
  2511
	    // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2512
	    stsd->entryCount = totalsampleentriesread;
sl@0
  2513
	    return -1;
sl@0
  2514
	    }
sl@0
  2515
	totalbytesread += bytesread;
sl@0
  2516
sl@0
  2517
	if (stsd->atomhdr->type != ATOMTYPE_STSD)
sl@0
  2518
	    {
sl@0
  2519
	    // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2520
	    stsd->entryCount = totalsampleentriesread;
sl@0
  2521
	    return -1;
sl@0
  2522
	    }
sl@0
  2523
sl@0
  2524
	bytesread = readData(handle, handle->buf, 4);
sl@0
  2525
	if (bytesread < 0)
sl@0
  2526
	    {
sl@0
  2527
	    // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2528
	    stsd->entryCount = totalsampleentriesread;
sl@0
  2529
	    return -1;
sl@0
  2530
	    }
sl@0
  2531
	stsd->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2532
	totalbytesread += bytesread;
sl@0
  2533
sl@0
  2534
	mp4_u32 type;
sl@0
  2535
	while ((mp4_u32)totalbytesread < stsd->atomhdr->size)
sl@0
  2536
		{	
sl@0
  2537
		// if the number of entries read already surpasses the number of entries specified 
sl@0
  2538
		// within the STSD atom, the file is corrupted.
sl@0
  2539
		if ((totalsampleentriesread + unknownsampleentriesread) >= stsd->entryCount)
sl@0
  2540
			{
sl@0
  2541
			// for memory cleanup set entrycount to allocated num of entries.
sl@0
  2542
			stsd->entryCount = totalsampleentriesread;
sl@0
  2543
  	  		return -1;    	    	
sl@0
  2544
			}
sl@0
  2545
sl@0
  2546
		// read the next sample type
sl@0
  2547
		if (peekData(handle, handle->buf, 8) < 0)
sl@0
  2548
	        {
sl@0
  2549
	        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2550
	        stsd->entryCount = totalsampleentriesread;
sl@0
  2551
		    return -1;
sl@0
  2552
	        }
sl@0
  2553
		type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  2554
    
sl@0
  2555
		// if the max sample entiries supported by the library has been reached 
sl@0
  2556
		if ((stsd->entryCount > STSDMAXSAMPLEENTRYCOUNT) && (totalsampleentriesread == STSDMAXSAMPLEENTRYCOUNT))
sl@0
  2557
			{
sl@0
  2558
			// skip reading the rest of the entries to make sure no more than max count of sample entries 
sl@0
  2559
			// will be processed, so that cleanup will always work. 
sl@0
  2560
			type = 0;
sl@0
  2561
			skipentries = 1;
sl@0
  2562
			}
sl@0
  2563
sl@0
  2564
		switch (type)
sl@0
  2565
			{
sl@0
  2566
			case ATOMTYPE_MP4V:
sl@0
  2567
				{
sl@0
  2568
				if (stsd->mp4v[totalsampleentriesread]) /* MP4V[totalsampleentriesread] has already been read, more than one is not allowed */ 
sl@0
  2569
			        {
sl@0
  2570
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2571
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2572
				    return -1;
sl@0
  2573
			        }
sl@0
  2574
		
sl@0
  2575
				if ((stsd->mp4v[totalsampleentriesread] = (visualSampleEntry *)mp4malloc(sizeof(visualSampleEntry))) == NULL)
sl@0
  2576
			        {
sl@0
  2577
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2578
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2579
				    return -100;
sl@0
  2580
			        }
sl@0
  2581
		
sl@0
  2582
				bytesread = readMP4V(handle, stsd->mp4v[totalsampleentriesread]);
sl@0
  2583
				totalsampleentriesread++;
sl@0
  2584
				if (bytesread < 0)
sl@0
  2585
			        {
sl@0
  2586
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2587
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2588
				    return -1;
sl@0
  2589
			        }
sl@0
  2590
				totalbytesread += bytesread;
sl@0
  2591
				break;
sl@0
  2592
				}
sl@0
  2593
sl@0
  2594
			case ATOMTYPE_MP4A:
sl@0
  2595
				{	
sl@0
  2596
				if (stsd->mp4a[totalsampleentriesread]) /* MP4A[totalsampleentriesread] has already been read, more than one is not allowed */
sl@0
  2597
			        {
sl@0
  2598
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2599
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2600
				    return -1;
sl@0
  2601
			        }
sl@0
  2602
sl@0
  2603
				if ((stsd->mp4a[totalsampleentriesread] = (audioSampleEntry *)mp4malloc(sizeof(audioSampleEntry))) == NULL)
sl@0
  2604
			        {
sl@0
  2605
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2606
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2607
				    return -100;
sl@0
  2608
			        }
sl@0
  2609
sl@0
  2610
				bytesread = readMP4A(handle, stsd->mp4a[totalsampleentriesread]);
sl@0
  2611
				totalsampleentriesread++;
sl@0
  2612
				if (bytesread < 0)
sl@0
  2613
			        {
sl@0
  2614
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2615
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2616
				    return -1;
sl@0
  2617
			        }
sl@0
  2618
				totalbytesread += bytesread;
sl@0
  2619
				break;
sl@0
  2620
				}
sl@0
  2621
sl@0
  2622
			case ATOMTYPE_MP4S:
sl@0
  2623
				{
sl@0
  2624
				if (stsd->mp4s[totalsampleentriesread]) /* MP4S has already been read, more than one is not allowed */
sl@0
  2625
			        {
sl@0
  2626
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2627
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2628
				    return -1;
sl@0
  2629
			        }
sl@0
  2630
sl@0
  2631
				if ((stsd->mp4s[totalsampleentriesread] = (mpegSampleEntry *)mp4malloc(sizeof(mpegSampleEntry))) == NULL)
sl@0
  2632
			        {
sl@0
  2633
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2634
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2635
				    return -100;
sl@0
  2636
			        }
sl@0
  2637
sl@0
  2638
				bytesread = readMP4S(handle, stsd->mp4s[totalsampleentriesread]);
sl@0
  2639
				totalsampleentriesread++;
sl@0
  2640
				if (bytesread < 0)
sl@0
  2641
			        {
sl@0
  2642
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2643
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2644
				    return -1;
sl@0
  2645
			        }
sl@0
  2646
				totalbytesread += bytesread;
sl@0
  2647
				}
sl@0
  2648
				break;
sl@0
  2649
sl@0
  2650
			case ATOMTYPE_S263:
sl@0
  2651
				{
sl@0
  2652
				if (stsd->s263[totalsampleentriesread]) /* MP4S has already been read, more than one is not allowed */
sl@0
  2653
			        {
sl@0
  2654
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2655
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2656
				    return -1;
sl@0
  2657
			        }
sl@0
  2658
sl@0
  2659
				if ((stsd->s263[totalsampleentriesread] = (h263SampleEntry *)mp4malloc(sizeof(h263SampleEntry))) == NULL)
sl@0
  2660
			        {
sl@0
  2661
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2662
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2663
				    return -100;
sl@0
  2664
			        }
sl@0
  2665
sl@0
  2666
				bytesread = readS263(handle, stsd->s263[totalsampleentriesread]);
sl@0
  2667
				totalsampleentriesread++;
sl@0
  2668
				if (bytesread < 0)
sl@0
  2669
			        {
sl@0
  2670
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2671
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2672
				    return -1;
sl@0
  2673
			        }
sl@0
  2674
				totalbytesread += bytesread;
sl@0
  2675
				}
sl@0
  2676
				break;
sl@0
  2677
sl@0
  2678
			case ATOMTYPE_SAMR:
sl@0
  2679
				{
sl@0
  2680
				if (stsd->samr[totalsampleentriesread]) /* SAMR has already been read, more than one is not allowed */
sl@0
  2681
			        {
sl@0
  2682
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2683
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2684
				    return -1;
sl@0
  2685
			        }
sl@0
  2686
sl@0
  2687
				if ((stsd->samr[totalsampleentriesread] = (amrSampleEntry *)mp4malloc(sizeof(amrSampleEntry))) == NULL)
sl@0
  2688
			        {
sl@0
  2689
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2690
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2691
				    return -100;
sl@0
  2692
			        }
sl@0
  2693
sl@0
  2694
				bytesread = readSAMR(handle, stsd->samr[totalsampleentriesread]);
sl@0
  2695
				totalsampleentriesread++;
sl@0
  2696
				if (bytesread < 0)
sl@0
  2697
			        {
sl@0
  2698
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2699
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2700
				    return -1;
sl@0
  2701
			        }
sl@0
  2702
				totalbytesread += bytesread;
sl@0
  2703
				}
sl@0
  2704
				break;
sl@0
  2705
sl@0
  2706
			case ATOMTYPE_SAWB:
sl@0
  2707
				{
sl@0
  2708
				if (stsd->sawb[totalsampleentriesread]) /* SAWB has already been read, more than one is not allowed */
sl@0
  2709
			        {
sl@0
  2710
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2711
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2712
				    return -1;
sl@0
  2713
			        }
sl@0
  2714
sl@0
  2715
				if ((stsd->sawb[totalsampleentriesread] = (amrSampleEntry *)mp4malloc(sizeof(amrSampleEntry))) == NULL)
sl@0
  2716
			        {
sl@0
  2717
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2718
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2719
				    return -100;
sl@0
  2720
			        }
sl@0
  2721
sl@0
  2722
				bytesread = readSAWB(handle, stsd->sawb[totalsampleentriesread]);
sl@0
  2723
				totalsampleentriesread++;
sl@0
  2724
				if (bytesread < 0)
sl@0
  2725
			        {
sl@0
  2726
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2727
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2728
				    return -1;
sl@0
  2729
			        }
sl@0
  2730
				totalbytesread += bytesread;
sl@0
  2731
				}
sl@0
  2732
				break;
sl@0
  2733
sl@0
  2734
			case ATOMTYPE_AVC1:
sl@0
  2735
				{
sl@0
  2736
				if (stsd->avc1[totalsampleentriesread]) /* AVC1 has already been read, more than one is not allowed */
sl@0
  2737
					{
sl@0
  2738
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2739
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2740
				    return -1;
sl@0
  2741
					}
sl@0
  2742
				if ((stsd->avc1[totalsampleentriesread] = (avcSampleEntry *)mp4malloc(sizeof(avcSampleEntry))) == NULL)
sl@0
  2743
			        {
sl@0
  2744
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2745
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2746
				    return -100;
sl@0
  2747
			        }
sl@0
  2748
sl@0
  2749
				bytesread = readAVC1(handle, stsd->avc1[totalsampleentriesread]);
sl@0
  2750
				totalsampleentriesread++;
sl@0
  2751
				if (bytesread < 0)
sl@0
  2752
					{
sl@0
  2753
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2754
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2755
				    return -1;
sl@0
  2756
			        }
sl@0
  2757
				totalbytesread += bytesread;
sl@0
  2758
				}
sl@0
  2759
				break;
sl@0
  2760
sl@0
  2761
			case ATOMTYPE_SQCP:
sl@0
  2762
				{
sl@0
  2763
				if (stsd->sqcp[totalsampleentriesread]) /* SQCP has already been read, more than one is not allowed */
sl@0
  2764
			        {
sl@0
  2765
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2766
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2767
				    return -1;
sl@0
  2768
			        }
sl@0
  2769
				if ((stsd->sqcp[totalsampleentriesread] = (qcelpSampleEntry *)mp4malloc(sizeof(qcelpSampleEntry))) == NULL)
sl@0
  2770
			        {
sl@0
  2771
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2772
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2773
				    return -100;
sl@0
  2774
			        }
sl@0
  2775
sl@0
  2776
				bytesread = readSQCP(handle, stsd->sqcp[totalsampleentriesread]);
sl@0
  2777
				totalsampleentriesread++;
sl@0
  2778
				if (bytesread < 0)
sl@0
  2779
					{
sl@0
  2780
			        // for memory cleanup set entrycount to allocated num of entries.
sl@0
  2781
			        stsd->entryCount = totalsampleentriesread;
sl@0
  2782
				    return -1;
sl@0
  2783
			        }
sl@0
  2784
				totalbytesread += bytesread;
sl@0
  2785
				}
sl@0
  2786
				break;
sl@0
  2787
sl@0
  2788
			default: /* Other atoms are not needed */
sl@0
  2789
				// no need to increment totalsampleentriesread as no memory is allocated for unsupported 
sl@0
  2790
				// or unrecognized sample types.  Alternatively, increment the count of unknown samples.   
sl@0
  2791
				// This is for ensure if a non-audio/video track can properly be parsed without being 
sl@0
  2792
				// recongized as an invalid format file.
sl@0
  2793
				unknownsampleentriesread++;
sl@0
  2794
				bytesread = readUnknown(handle);
sl@0
  2795
				if (bytesread < 0)
sl@0
  2796
		    		{
sl@0
  2797
		    		// for memory cleanup set entrycount to allocated num of entries.
sl@0
  2798
		    		stsd->entryCount = totalsampleentriesread;
sl@0
  2799
		    		return -1;
sl@0
  2800
		    		}
sl@0
  2801
				totalbytesread += bytesread;
sl@0
  2802
				break;
sl@0
  2803
			}
sl@0
  2804
		}
sl@0
  2805
sl@0
  2806
	// if the STSD atom's entry count is NOT the same as the number (supported & unsupported) entries parsed,
sl@0
  2807
	// the atom is likely a corrupted one. 
sl@0
  2808
	if ((totalsampleentriesread + unknownsampleentriesread) != stsd->entryCount)
sl@0
  2809
		{
sl@0
  2810
		// for memory cleanup set entrycount to allocated num of entries.
sl@0
  2811
		stsd->entryCount = totalsampleentriesread;
sl@0
  2812
		return -1;
sl@0
  2813
		}
sl@0
  2814
	else 
sl@0
  2815
		{
sl@0
  2816
		// if the STSD atom's entry count is the same as the number of (supported & unsupported) entries 
sl@0
  2817
		// parsed, check if some entries are skipped because the max sample entry count has been reached  
sl@0
  2818
		if (skipentries) 
sl@0
  2819
			{
sl@0
  2820
			// if STSDMAXSAMPLEENTRYCOUNT was reached edit entrycount to make sure cleanup works.
sl@0
  2821
			stsd->entryCount = STSDMAXSAMPLEENTRYCOUNT;
sl@0
  2822
			}
sl@0
  2823
		else if (unknownsampleentriesread > 0)
sl@0
  2824
			{
sl@0
  2825
			// unknown (unsupported) sample entries present, set the STSD entry count to the actual 
sl@0
  2826
			// number of supported sample entries detected
sl@0
  2827
			stsd->entryCount = totalsampleentriesread;
sl@0
  2828
			}
sl@0
  2829
		}
sl@0
  2830
  
sl@0
  2831
	return totalbytesread;
sl@0
  2832
	}
sl@0
  2833
sl@0
  2834
sl@0
  2835
/*
sl@0
  2836
 * Function:
sl@0
  2837
 *
sl@0
  2838
 *   mp4_i32 readSTSZ(MP4HandleImp handle,
sl@0
  2839
 *                    sampleSizeAtom *stsz)
sl@0
  2840
 *
sl@0
  2841
 * Description:
sl@0
  2842
 *
sl@0
  2843
 *   This function parses one STSZ atom.
sl@0
  2844
 *
sl@0
  2845
 * Parameters:
sl@0
  2846
 *
sl@0
  2847
 *   handle             MP4 library handle
sl@0
  2848
 *   stsz               STSZ pointer
sl@0
  2849
 *
sl@0
  2850
 * Return value:
sl@0
  2851
 *
sl@0
  2852
 *   Negative integer   Error
sl@0
  2853
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2854
 *
sl@0
  2855
 */
sl@0
  2856
mp4_i32 readSTSZ(MP4HandleImp handle, sampleSizeAtom *stsz)
sl@0
  2857
{
sl@0
  2858
  mp4_i32 bytesread;
sl@0
  2859
  mp4_i32 totalbytesread = 0;
sl@0
  2860
sl@0
  2861
sl@0
  2862
  if ((stsz->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2863
    return -100;
sl@0
  2864
sl@0
  2865
  bytesread = readFullAtomHeader(handle, stsz->atomhdr);
sl@0
  2866
  if (bytesread < 0)
sl@0
  2867
    return -1;
sl@0
  2868
  totalbytesread += bytesread;
sl@0
  2869
sl@0
  2870
  if (stsz->atomhdr->type != ATOMTYPE_STSZ)
sl@0
  2871
    return -1;
sl@0
  2872
sl@0
  2873
sl@0
  2874
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2875
  if (bytesread < 0)
sl@0
  2876
    return -1;
sl@0
  2877
  stsz->sampleSize = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2878
  totalbytesread += bytesread;
sl@0
  2879
sl@0
  2880
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2881
  if (bytesread < 0)
sl@0
  2882
    return -1;
sl@0
  2883
  stsz->sampleCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2884
  totalbytesread += bytesread;
sl@0
  2885
sl@0
  2886
  // zero size samplesize means samples have different sizes, and those sizes are stored in sampleSizeEntries.
sl@0
  2887
  if ((stsz->sampleCount) && (stsz->sampleSize == 0))
sl@0
  2888
  {
sl@0
  2889
    mp4_u32 i;
sl@0
  2890
sl@0
  2891
    // check validity of stsz->sampleCount before allocating entrysize table.
sl@0
  2892
    if ( handle->moov->mvhd )
sl@0
  2893
        {
sl@0
  2894
        if ( handle->moov->mvhd->timeScale > 0 )
sl@0
  2895
            {
sl@0
  2896
            TUint magicNumberMaxSamplesInSec = MAXSAMPLESPERSECOND;
sl@0
  2897
            TUint maxSampleCount;
sl@0
  2898
sl@0
  2899
            if ( handle->moov->mvhd->atomhdr->version == 1 ) // 64bit duration
sl@0
  2900
                {
sl@0
  2901
                maxSampleCount = I64INT(handle->moov->mvhd->duration64 / TUint(handle->moov->mvhd->timeScale) + 1) * magicNumberMaxSamplesInSec;
sl@0
  2902
                }
sl@0
  2903
            else    // 32bit duration
sl@0
  2904
                {
sl@0
  2905
                maxSampleCount = TUint((TUint( handle->moov->mvhd->duration  ) / TUint(handle->moov->mvhd->timeScale) + 1)) * magicNumberMaxSamplesInSec;
sl@0
  2906
                }
sl@0
  2907
sl@0
  2908
            if ( maxSampleCount < stsz->sampleCount )
sl@0
  2909
                {
sl@0
  2910
                // corrupted 
sl@0
  2911
                return -1;
sl@0
  2912
                }
sl@0
  2913
            }
sl@0
  2914
        }
sl@0
  2915
sl@0
  2916
    // allocate stsz->entrySize table
sl@0
  2917
    stsz->entrySize = (mp4_u32 *)mp4malloc(stsz->sampleCount * sizeof(mp4_u32));
sl@0
  2918
    if (stsz->entrySize == NULL)
sl@0
  2919
      return -1;
sl@0
  2920
sl@0
  2921
    for (i = 0; i < stsz->sampleCount; i++)
sl@0
  2922
    {
sl@0
  2923
      bytesread = readData(handle, handle->buf, 4);
sl@0
  2924
      if (bytesread < 0)
sl@0
  2925
        return -1;
sl@0
  2926
sl@0
  2927
      stsz->entrySize[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2928
sl@0
  2929
      totalbytesread += bytesread;
sl@0
  2930
    }
sl@0
  2931
  }
sl@0
  2932
sl@0
  2933
  return totalbytesread;
sl@0
  2934
}
sl@0
  2935
sl@0
  2936
sl@0
  2937
/*
sl@0
  2938
 * Function:
sl@0
  2939
 *
sl@0
  2940
 *   mp4_i32 readSTZ2(MP4HandleImp handle,
sl@0
  2941
 *                    sampleSizeAtom *stsz)
sl@0
  2942
 *
sl@0
  2943
 * Description:
sl@0
  2944
 *
sl@0
  2945
 *   This function parses one STZ2 atom.
sl@0
  2946
 *
sl@0
  2947
 *   The result is placed in STSZ structure.
sl@0
  2948
 *
sl@0
  2949
 * Parameters:
sl@0
  2950
 *
sl@0
  2951
 *   handle             MP4 library handle
sl@0
  2952
 *   stsz               STSZ pointer
sl@0
  2953
 *
sl@0
  2954
 * Return value:
sl@0
  2955
 *
sl@0
  2956
 *   Negative integer   Error
sl@0
  2957
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  2958
 *
sl@0
  2959
 */
sl@0
  2960
mp4_i32 readSTZ2(MP4HandleImp handle, sampleSizeAtom *stsz)
sl@0
  2961
{
sl@0
  2962
  mp4_i32 bytesread;
sl@0
  2963
  mp4_i32 totalbytesread = 0;
sl@0
  2964
  mp4_u8  fieldsize;
sl@0
  2965
sl@0
  2966
sl@0
  2967
  if ((stsz->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  2968
    return -100;
sl@0
  2969
sl@0
  2970
  bytesread = readFullAtomHeader(handle, stsz->atomhdr);
sl@0
  2971
  if (bytesread < 0)
sl@0
  2972
    return -1;
sl@0
  2973
  totalbytesread += bytesread;
sl@0
  2974
sl@0
  2975
  if (stsz->atomhdr->type != ATOMTYPE_STZ2)
sl@0
  2976
    return -1;
sl@0
  2977
sl@0
  2978
sl@0
  2979
  bytesread = discardData(handle, 3);
sl@0
  2980
  if (bytesread < 0)
sl@0
  2981
    return -1;
sl@0
  2982
  totalbytesread += bytesread;
sl@0
  2983
sl@0
  2984
  bytesread = readData(handle, handle->buf, 1);
sl@0
  2985
  if (bytesread < 0)
sl@0
  2986
    return -1;
sl@0
  2987
  fieldsize = handle->buf[0];
sl@0
  2988
  totalbytesread += bytesread;
sl@0
  2989
sl@0
  2990
  bytesread = readData(handle, handle->buf, 4);
sl@0
  2991
  if (bytesread < 0)
sl@0
  2992
    return -1;
sl@0
  2993
  stsz->sampleCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  2994
  totalbytesread += bytesread;
sl@0
  2995
sl@0
  2996
  switch (fieldsize)
sl@0
  2997
  {
sl@0
  2998
  case 4: /* Two entries in each byte */
sl@0
  2999
sl@0
  3000
    {
sl@0
  3001
      mp4_u32 i;
sl@0
  3002
sl@0
  3003
      stsz->entrySize = (mp4_u32 *)mp4malloc(stsz->sampleCount * sizeof(mp4_u32));
sl@0
  3004
      if (stsz->entrySize == NULL)
sl@0
  3005
        return -1;
sl@0
  3006
sl@0
  3007
      for (i = 0; i < (stsz->sampleCount + 1) / 2; i++)
sl@0
  3008
      {
sl@0
  3009
        bytesread = readData(handle, handle->buf, 1);
sl@0
  3010
        if (bytesread < 0)
sl@0
  3011
          return -1;
sl@0
  3012
sl@0
  3013
        totalbytesread += bytesread;
sl@0
  3014
sl@0
  3015
        stsz->entrySize[i * 2] = (mp4_u32)(handle->buf[0] >> 4);
sl@0
  3016
sl@0
  3017
        if (stsz->sampleCount % 2 == 0) /* Even number of samples */
sl@0
  3018
        {
sl@0
  3019
          stsz->entrySize[i * 2 + 1] = (mp4_u32)(handle->buf[0] & 0x0f);
sl@0
  3020
          continue;
sl@0
  3021
        }
sl@0
  3022
sl@0
  3023
        /* This condition is needed to avoid writing after the table */
sl@0
  3024
sl@0
  3025
        if (i == (stsz->sampleCount + 1) / 2 - 1) /* Last sample */
sl@0
  3026
        {
sl@0
  3027
        }
sl@0
  3028
        else
sl@0
  3029
          stsz->entrySize[i * 2 + 1] = (mp4_u32)(handle->buf[0] & 0x0f);
sl@0
  3030
      }
sl@0
  3031
    }
sl@0
  3032
sl@0
  3033
    break;
sl@0
  3034
sl@0
  3035
  case 8: /* One entry for each byte */
sl@0
  3036
sl@0
  3037
    {
sl@0
  3038
      mp4_u32 i;
sl@0
  3039
sl@0
  3040
      stsz->entrySize = (mp4_u32 *)mp4malloc(stsz->sampleCount * sizeof(mp4_u32));
sl@0
  3041
      if (stsz->entrySize == NULL)
sl@0
  3042
        return -1;
sl@0
  3043
sl@0
  3044
      for (i = 0; i < stsz->sampleCount; i++)
sl@0
  3045
      {
sl@0
  3046
        bytesread = readData(handle, handle->buf, 1);
sl@0
  3047
        if (bytesread < 0)
sl@0
  3048
          return -1;
sl@0
  3049
sl@0
  3050
        stsz->entrySize[i] = (mp4_u32)handle->buf[0];
sl@0
  3051
sl@0
  3052
        totalbytesread += bytesread;
sl@0
  3053
      }
sl@0
  3054
    }
sl@0
  3055
sl@0
  3056
    break;
sl@0
  3057
sl@0
  3058
  case 16: /* Each entry in 2 bytes */
sl@0
  3059
sl@0
  3060
    {
sl@0
  3061
      mp4_u32 i;
sl@0
  3062
sl@0
  3063
      stsz->entrySize = (mp4_u32 *)mp4malloc(stsz->sampleCount * sizeof(mp4_u32));
sl@0
  3064
      if (stsz->entrySize == NULL)
sl@0
  3065
        return -1;
sl@0
  3066
sl@0
  3067
      for (i = 0; i < stsz->sampleCount; i++)
sl@0
  3068
      {
sl@0
  3069
        bytesread = readData(handle, handle->buf, 2);
sl@0
  3070
        if (bytesread < 0)
sl@0
  3071
          return -1;
sl@0
  3072
sl@0
  3073
        stsz->entrySize[i] = (mp4_u32)u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3074
sl@0
  3075
        totalbytesread += bytesread;
sl@0
  3076
      }
sl@0
  3077
    }
sl@0
  3078
sl@0
  3079
    break;
sl@0
  3080
sl@0
  3081
  default: /* Illegal fieldsize */
sl@0
  3082
sl@0
  3083
    return -1;
sl@0
  3084
  }
sl@0
  3085
sl@0
  3086
sl@0
  3087
  return totalbytesread;
sl@0
  3088
}
sl@0
  3089
sl@0
  3090
sl@0
  3091
/*
sl@0
  3092
 * Function:
sl@0
  3093
 *
sl@0
  3094
 *   mp4_i32 readSTSC(MP4HandleImp handle,
sl@0
  3095
 *                    sampleToChunkAtom *stsc)
sl@0
  3096
 *
sl@0
  3097
 * Description:
sl@0
  3098
 *
sl@0
  3099
 *   This function parses one STSC atom.
sl@0
  3100
 *
sl@0
  3101
 * Parameters:
sl@0
  3102
 *
sl@0
  3103
 *   handle             MP4 library handle
sl@0
  3104
 *   stsc               STSC pointer
sl@0
  3105
 *
sl@0
  3106
 * Return value:
sl@0
  3107
 *
sl@0
  3108
 *   Negative integer   Error
sl@0
  3109
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3110
 *
sl@0
  3111
 */
sl@0
  3112
mp4_i32 readSTSC(MP4HandleImp handle, sampleToChunkAtom *stsc)
sl@0
  3113
{
sl@0
  3114
  mp4_i32 bytesread;
sl@0
  3115
  mp4_i32 totalbytesread = 0;
sl@0
  3116
  mp4_u32 i;
sl@0
  3117
sl@0
  3118
sl@0
  3119
  if ((stsc->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3120
    return -100;
sl@0
  3121
sl@0
  3122
  bytesread = readFullAtomHeader(handle, stsc->atomhdr);
sl@0
  3123
  if (bytesread < 0)
sl@0
  3124
    return -1;
sl@0
  3125
  totalbytesread += bytesread;
sl@0
  3126
sl@0
  3127
  if (stsc->atomhdr->type != ATOMTYPE_STSC)
sl@0
  3128
    return -1;
sl@0
  3129
sl@0
  3130
sl@0
  3131
  bytesread = readData(handle, handle->buf, 4);
sl@0
  3132
  if (bytesread < 0)
sl@0
  3133
    return -1;
sl@0
  3134
  stsc->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  3135
  totalbytesread += bytesread;
sl@0
  3136
sl@0
  3137
  if (stsc->entryCount)
sl@0
  3138
  {
sl@0
  3139
	  stsc->firstChunk = (mp4_u32 *)mp4malloc(stsc->entryCount * sizeof(mp4_u32));
sl@0
  3140
	  if (stsc->firstChunk == NULL)
sl@0
  3141
	    return -1;
sl@0
  3142
	  stsc->samplesPerChunk = (mp4_u32 *)mp4malloc(stsc->entryCount * sizeof(mp4_u32));
sl@0
  3143
	  if (stsc->samplesPerChunk == NULL)
sl@0
  3144
	    return -1;
sl@0
  3145
	  stsc->sampleDescriptionIndex = (mp4_u32 *)mp4malloc(stsc->entryCount * sizeof(mp4_u32));
sl@0
  3146
	  if (stsc->sampleDescriptionIndex == NULL)
sl@0
  3147
	  {
sl@0
  3148
		return -1;	  	
sl@0
  3149
	  }
sl@0
  3150
sl@0
  3151
	  for (i = 0; i < stsc->entryCount; i++)
sl@0
  3152
	  {
sl@0
  3153
	    bytesread = readData(handle, handle->buf, 12);
sl@0
  3154
	    if (bytesread < 0)
sl@0
  3155
	      return -1;
sl@0
  3156
sl@0
  3157
	    stsc->firstChunk[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  3158
	    stsc->samplesPerChunk[i] = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  3159
	    stsc->sampleDescriptionIndex[i] = u32endian(*((mp4_u32 *)(handle->buf+8)));
sl@0
  3160
	    if ( stsc->sampleDescriptionIndex[i] > stsc->entryCount)
sl@0
  3161
	    {
sl@0
  3162
	    	return -1;
sl@0
  3163
	    }
sl@0
  3164
sl@0
  3165
	    totalbytesread += bytesread;
sl@0
  3166
	  }
sl@0
  3167
  }
sl@0
  3168
  return totalbytesread;
sl@0
  3169
}
sl@0
  3170
sl@0
  3171
sl@0
  3172
/*
sl@0
  3173
 * Function:
sl@0
  3174
 *
sl@0
  3175
 *   mp4_i32 readSTCO(MP4HandleImp handle,
sl@0
  3176
 *                    chunkOffsetAtom *stco)
sl@0
  3177
 *
sl@0
  3178
 * Description:
sl@0
  3179
 *
sl@0
  3180
 *   This function parses one STCO atom.
sl@0
  3181
 *
sl@0
  3182
 * Parameters:
sl@0
  3183
 *
sl@0
  3184
 *   handle             MP4 library handle
sl@0
  3185
 *   stco               STCO pointer
sl@0
  3186
 *
sl@0
  3187
 * Return value:
sl@0
  3188
 *
sl@0
  3189
 *   Negative integer   Error
sl@0
  3190
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3191
 *
sl@0
  3192
 */
sl@0
  3193
mp4_i32 readSTCO(MP4HandleImp handle, chunkOffsetAtom *stco)
sl@0
  3194
{
sl@0
  3195
  mp4_i32 bytesread;
sl@0
  3196
  mp4_i32 totalbytesread = 0;
sl@0
  3197
  mp4_u32  i;
sl@0
  3198
sl@0
  3199
sl@0
  3200
  if ((stco->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3201
    return -100;
sl@0
  3202
sl@0
  3203
  bytesread = readFullAtomHeader(handle, stco->atomhdr);
sl@0
  3204
  if (bytesread < 0)
sl@0
  3205
    return -1;
sl@0
  3206
  totalbytesread += bytesread;
sl@0
  3207
sl@0
  3208
  if (stco->atomhdr->type != ATOMTYPE_STCO)
sl@0
  3209
    return -1;
sl@0
  3210
sl@0
  3211
sl@0
  3212
  bytesread = readData(handle, handle->buf, 4);
sl@0
  3213
  if (bytesread < 0)
sl@0
  3214
    return -1;
sl@0
  3215
  stco->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  3216
  totalbytesread += bytesread;
sl@0
  3217
sl@0
  3218
  if (stco->entryCount)
sl@0
  3219
  {
sl@0
  3220
	  // validate stco->entryCount before allocating chunkOffsetTable
sl@0
  3221
	  if ( handle->moov->mvhd )
sl@0
  3222
	    {
sl@0
  3223
	    if ( handle->moov->mvhd->timeScale > 0 )
sl@0
  3224
	        {
sl@0
  3225
	        TUint magicNumberMaxSamplesInSec = MAXSAMPLESPERSECOND;
sl@0
  3226
	        TUint maxSampleCount;
sl@0
  3227
sl@0
  3228
	        if ( handle->moov->mvhd->atomhdr->version == 1 ) // 64bit duration
sl@0
  3229
	            {
sl@0
  3230
	            maxSampleCount = I64INT(handle->moov->mvhd->duration64 / TUint(handle->moov->mvhd->timeScale) + 1) * magicNumberMaxSamplesInSec;
sl@0
  3231
	            }
sl@0
  3232
	        else    // 32bit duration
sl@0
  3233
	            {
sl@0
  3234
	            maxSampleCount = TUint((TUint( handle->moov->mvhd->duration  ) / TUint(handle->moov->mvhd->timeScale) + 1)) * magicNumberMaxSamplesInSec;
sl@0
  3235
	            }
sl@0
  3236
sl@0
  3237
	        if ( maxSampleCount < stco->entryCount )
sl@0
  3238
	            {
sl@0
  3239
	            // corrupted 
sl@0
  3240
	            return -1;
sl@0
  3241
	            }
sl@0
  3242
	        }
sl@0
  3243
	    }
sl@0
  3244
sl@0
  3245
	  stco->chunkOffset = (mp4_u32 *)mp4malloc(stco->entryCount * sizeof(mp4_u32));
sl@0
  3246
	  if (stco->chunkOffset == NULL)
sl@0
  3247
	    return -1;
sl@0
  3248
sl@0
  3249
	  for (i = 0; i < stco->entryCount; i++)
sl@0
  3250
	  {
sl@0
  3251
	    bytesread = readData(handle, handle->buf, 4);
sl@0
  3252
	    if (bytesread < 0)
sl@0
  3253
	      return -1;
sl@0
  3254
sl@0
  3255
	    stco->chunkOffset[i] = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  3256
sl@0
  3257
	    totalbytesread += bytesread;
sl@0
  3258
	  }
sl@0
  3259
  }
sl@0
  3260
  return totalbytesread;
sl@0
  3261
}
sl@0
  3262
sl@0
  3263
sl@0
  3264
/*
sl@0
  3265
 * Function:
sl@0
  3266
 *
sl@0
  3267
 *   mp4_i32 readCO64(MP4HandleImp handle,
sl@0
  3268
 *                    chunkOffset64Atom *stco64)
sl@0
  3269
 *
sl@0
  3270
 * Description:
sl@0
  3271
 *
sl@0
  3272
 *   This function parses one CO64 atom.
sl@0
  3273
 *
sl@0
  3274
 * Parameters:
sl@0
  3275
 *
sl@0
  3276
 *   handle             MP4 library handle
sl@0
  3277
 *   stco64               CO64 pointer
sl@0
  3278
 *
sl@0
  3279
 * Return value:
sl@0
  3280
 *
sl@0
  3281
 *   Negative integer   Error
sl@0
  3282
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3283
 *
sl@0
  3284
 */
sl@0
  3285
mp4_i32 readCO64(MP4HandleImp handle, chunkOffset64Atom *stco64)
sl@0
  3286
{
sl@0
  3287
  mp4_i32 bytesread;
sl@0
  3288
  mp4_i32 totalbytesread = 0;
sl@0
  3289
  mp4_u32 i;
sl@0
  3290
sl@0
  3291
sl@0
  3292
  if ((stco64->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3293
    return -100;
sl@0
  3294
sl@0
  3295
  bytesread = readFullAtomHeader(handle, stco64->atomhdr);
sl@0
  3296
  if (bytesread < 0)
sl@0
  3297
    return -1;
sl@0
  3298
  totalbytesread += bytesread;
sl@0
  3299
sl@0
  3300
  if (stco64->atomhdr->type != ATOMTYPE_CO64)
sl@0
  3301
    return -1;
sl@0
  3302
sl@0
  3303
sl@0
  3304
  bytesread = readData(handle, handle->buf, 4);
sl@0
  3305
  if (bytesread < 0)
sl@0
  3306
    return -1;
sl@0
  3307
  stco64->entryCount = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  3308
  totalbytesread += bytesread;
sl@0
  3309
sl@0
  3310
  if ( stco64->entryCount )
sl@0
  3311
  {
sl@0
  3312
	  stco64->chunkOffset = (mp4_u64 *)mp4malloc(stco64->entryCount * sizeof(mp4_u64));
sl@0
  3313
	  if (stco64->chunkOffset == NULL)
sl@0
  3314
	    return -1;
sl@0
  3315
sl@0
  3316
	  for (i = 0; i < stco64->entryCount; i++)
sl@0
  3317
	  {
sl@0
  3318
	    bytesread = readData(handle, handle->buf, 8);
sl@0
  3319
	    if (bytesread < 0)
sl@0
  3320
	      return -1;
sl@0
  3321
	    
sl@0
  3322
	    stco64->chunkOffset[i] = u64endian(*((mp4_u64 *)(handle->buf)));
sl@0
  3323
sl@0
  3324
	    totalbytesread += bytesread;
sl@0
  3325
	  }
sl@0
  3326
  }
sl@0
  3327
  return totalbytesread;
sl@0
  3328
}
sl@0
  3329
sl@0
  3330
sl@0
  3331
/*
sl@0
  3332
 * Function:
sl@0
  3333
 *
sl@0
  3334
 *   mp4_i32 readMP4V(MP4HandleImp handle,
sl@0
  3335
 *                    visualSampleEntry *mp4v)
sl@0
  3336
 *
sl@0
  3337
 * Description:
sl@0
  3338
 *
sl@0
  3339
 *   This function parses one MP4V atom.
sl@0
  3340
 *
sl@0
  3341
 * Parameters:
sl@0
  3342
 *
sl@0
  3343
 *   handle             MP4 library handle
sl@0
  3344
 *   mp4v               MP4V pointer
sl@0
  3345
 *
sl@0
  3346
 * Return value:
sl@0
  3347
 *
sl@0
  3348
 *   Negative integer   Error
sl@0
  3349
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3350
 *
sl@0
  3351
 */
sl@0
  3352
mp4_i32 readMP4V(MP4HandleImp handle, visualSampleEntry *mp4v)
sl@0
  3353
{
sl@0
  3354
  mp4_i32 bytesread;
sl@0
  3355
  mp4_i32 totalbytesread = 0;
sl@0
  3356
sl@0
  3357
sl@0
  3358
  if ((mp4v->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3359
    return -100;
sl@0
  3360
sl@0
  3361
  bytesread = readAtomHeader(handle, mp4v->atomhdr);
sl@0
  3362
  if (bytesread < 0)
sl@0
  3363
    return -1;
sl@0
  3364
  totalbytesread += bytesread;
sl@0
  3365
sl@0
  3366
  if (mp4v->atomhdr->type != ATOMTYPE_MP4V)
sl@0
  3367
    return -1;
sl@0
  3368
sl@0
  3369
sl@0
  3370
  bytesread = discardData(handle, 6);
sl@0
  3371
  if (bytesread < 0)
sl@0
  3372
    return -1;
sl@0
  3373
  totalbytesread += bytesread;
sl@0
  3374
sl@0
  3375
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3376
  if (bytesread < 0)
sl@0
  3377
    return -1;
sl@0
  3378
  mp4v->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3379
  totalbytesread += bytesread;
sl@0
  3380
sl@0
  3381
  bytesread = discardData(handle, 16);
sl@0
  3382
  if (bytesread < 0)
sl@0
  3383
    return -1;
sl@0
  3384
  totalbytesread += bytesread;
sl@0
  3385
sl@0
  3386
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3387
  if (bytesread < 0)
sl@0
  3388
    return -1;
sl@0
  3389
  mp4v->width = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3390
  totalbytesread += bytesread;
sl@0
  3391
sl@0
  3392
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3393
  if (bytesread < 0)
sl@0
  3394
    return -1;
sl@0
  3395
  mp4v->height = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3396
  totalbytesread += bytesread;
sl@0
  3397
sl@0
  3398
  bytesread = discardData(handle, 50);
sl@0
  3399
  if (bytesread < 0)
sl@0
  3400
    return -1;
sl@0
  3401
  totalbytesread += bytesread;
sl@0
  3402
sl@0
  3403
  if ((mp4v->esd = (ESDAtom *)mp4malloc(sizeof(ESDAtom))) == NULL)
sl@0
  3404
    return -100;
sl@0
  3405
sl@0
  3406
  bytesread = readESD(handle, mp4v->esd);
sl@0
  3407
  if (bytesread < 0)
sl@0
  3408
    return -1;
sl@0
  3409
  totalbytesread += bytesread;
sl@0
  3410
  
sl@0
  3411
  if ( totalbytesread < mp4v->atomhdr->size )
sl@0
  3412
  	{
sl@0
  3413
    bytesread = discardData(handle, mp4v->atomhdr->size - totalbytesread );
sl@0
  3414
  	if (bytesread < 0)
sl@0
  3415
  		{
sl@0
  3416
    	return -1;	  		
sl@0
  3417
  		}
sl@0
  3418
  	totalbytesread += bytesread;
sl@0
  3419
  	}  
sl@0
  3420
sl@0
  3421
  return totalbytesread;
sl@0
  3422
}
sl@0
  3423
sl@0
  3424
sl@0
  3425
/*
sl@0
  3426
 * Function:
sl@0
  3427
 *
sl@0
  3428
 *   mp4_i32 readMP4A(MP4HandleImp handle,
sl@0
  3429
 *                    audioSampleEntry *mp4a)
sl@0
  3430
 *
sl@0
  3431
 * Description:
sl@0
  3432
 *
sl@0
  3433
 *   This function parses one MP4A atom.
sl@0
  3434
 *
sl@0
  3435
 * Parameters:
sl@0
  3436
 *
sl@0
  3437
 *   handle             MP4 library handle
sl@0
  3438
 *   mp4a               MP4A pointer
sl@0
  3439
 *
sl@0
  3440
 * Return value:
sl@0
  3441
 *
sl@0
  3442
 *   Negative integer   Error
sl@0
  3443
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3444
 *
sl@0
  3445
 */
sl@0
  3446
mp4_i32 readMP4A(MP4HandleImp handle, audioSampleEntry *mp4a)
sl@0
  3447
{
sl@0
  3448
  mp4_i32 bytesread;
sl@0
  3449
  mp4_i32 totalbytesread = 0;
sl@0
  3450
sl@0
  3451
sl@0
  3452
  if ((mp4a->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3453
    return -100;
sl@0
  3454
sl@0
  3455
  bytesread = readAtomHeader(handle, mp4a->atomhdr);
sl@0
  3456
  if (bytesread < 0)
sl@0
  3457
    return -1;
sl@0
  3458
  totalbytesread += bytesread;
sl@0
  3459
sl@0
  3460
  if (mp4a->atomhdr->type != ATOMTYPE_MP4A)
sl@0
  3461
    return -1;
sl@0
  3462
sl@0
  3463
sl@0
  3464
  bytesread = discardData(handle, 6);
sl@0
  3465
  if (bytesread < 0)
sl@0
  3466
    return -1;
sl@0
  3467
  totalbytesread += bytesread;
sl@0
  3468
sl@0
  3469
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3470
  if (bytesread < 0)
sl@0
  3471
    return -1;
sl@0
  3472
  mp4a->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3473
  totalbytesread += bytesread;
sl@0
  3474
sl@0
  3475
  bytesread = discardData(handle, 16);
sl@0
  3476
  if (bytesread < 0)
sl@0
  3477
    return -1;
sl@0
  3478
  totalbytesread += bytesread;
sl@0
  3479
sl@0
  3480
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3481
  if (bytesread < 0)
sl@0
  3482
    return -1;
sl@0
  3483
  mp4a->timeScale = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3484
  totalbytesread += bytesread;
sl@0
  3485
sl@0
  3486
  bytesread = discardData(handle, 2);
sl@0
  3487
  if (bytesread < 0)
sl@0
  3488
    return -1;
sl@0
  3489
  totalbytesread += bytesread;
sl@0
  3490
sl@0
  3491
  if ((mp4a->esd = (ESDAtom *)mp4malloc(sizeof(ESDAtom))) == NULL)
sl@0
  3492
    return -100;
sl@0
  3493
sl@0
  3494
  bytesread = readESD(handle, mp4a->esd);
sl@0
  3495
  if (bytesread < 0)
sl@0
  3496
    return -1;
sl@0
  3497
  totalbytesread += bytesread;
sl@0
  3498
  
sl@0
  3499
  if ( totalbytesread < mp4a->atomhdr->size )
sl@0
  3500
  	{
sl@0
  3501
    bytesread = discardData(handle, mp4a->atomhdr->size - totalbytesread );
sl@0
  3502
  	if (bytesread < 0)
sl@0
  3503
  		{
sl@0
  3504
    	return -1;	  		
sl@0
  3505
  		}
sl@0
  3506
  	totalbytesread += bytesread;
sl@0
  3507
  	}
sl@0
  3508
sl@0
  3509
  return totalbytesread;
sl@0
  3510
}
sl@0
  3511
sl@0
  3512
sl@0
  3513
/*
sl@0
  3514
 * Function:
sl@0
  3515
 *
sl@0
  3516
 *   mp4_i32 readMP4S(MP4HandleImp handle,
sl@0
  3517
 *                    mpegSampleEntry *mp4s)
sl@0
  3518
 *
sl@0
  3519
 * Description:
sl@0
  3520
 *
sl@0
  3521
 *   This function parses one MP4S atom.
sl@0
  3522
 *
sl@0
  3523
 * Parameters:
sl@0
  3524
 *
sl@0
  3525
 *   handle             MP4 library handle
sl@0
  3526
 *   mp4s               MP4S pointer
sl@0
  3527
 *
sl@0
  3528
 * Return value:
sl@0
  3529
 *
sl@0
  3530
 *   Negative integer   Error
sl@0
  3531
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3532
 *
sl@0
  3533
 */
sl@0
  3534
mp4_i32 readMP4S(MP4HandleImp handle, mpegSampleEntry *mp4s)
sl@0
  3535
{
sl@0
  3536
  mp4_i32 bytesread;
sl@0
  3537
  mp4_i32 totalbytesread = 0;
sl@0
  3538
sl@0
  3539
sl@0
  3540
  if ((mp4s->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3541
    return -100;
sl@0
  3542
sl@0
  3543
  bytesread = readAtomHeader(handle, mp4s->atomhdr);
sl@0
  3544
  if (bytesread < 0)
sl@0
  3545
    return -1;
sl@0
  3546
  totalbytesread += bytesread;
sl@0
  3547
sl@0
  3548
  if (mp4s->atomhdr->type != ATOMTYPE_MP4S)
sl@0
  3549
    return -1;
sl@0
  3550
sl@0
  3551
sl@0
  3552
  bytesread = discardData(handle, 6);
sl@0
  3553
  if (bytesread < 0)
sl@0
  3554
    return -1;
sl@0
  3555
  totalbytesread += bytesread;
sl@0
  3556
sl@0
  3557
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3558
  if (bytesread < 0)
sl@0
  3559
    return -1;
sl@0
  3560
  mp4s->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3561
  totalbytesread += bytesread;
sl@0
  3562
sl@0
  3563
  if ((mp4s->esd = (ESDAtom *)mp4malloc(sizeof(ESDAtom))) == NULL)
sl@0
  3564
    return -100;
sl@0
  3565
sl@0
  3566
  bytesread = readESD(handle, mp4s->esd);
sl@0
  3567
  if (bytesread < 0)
sl@0
  3568
    return -1;
sl@0
  3569
  totalbytesread += bytesread;
sl@0
  3570
  
sl@0
  3571
  if ( totalbytesread < mp4s->atomhdr->size )
sl@0
  3572
  	{
sl@0
  3573
    bytesread = discardData(handle, mp4s->atomhdr->size - totalbytesread );
sl@0
  3574
  	if (bytesread < 0)
sl@0
  3575
  		{
sl@0
  3576
    	return -1;	  		
sl@0
  3577
  		}
sl@0
  3578
  	totalbytesread += bytesread;
sl@0
  3579
  	}    
sl@0
  3580
sl@0
  3581
  return totalbytesread;
sl@0
  3582
}
sl@0
  3583
sl@0
  3584
sl@0
  3585
/*
sl@0
  3586
 * Function:
sl@0
  3587
 *
sl@0
  3588
 *   mp4_i32 readS263(MP4HandleImp handle,
sl@0
  3589
 *                    h263SampleEntry *s263)
sl@0
  3590
 *
sl@0
  3591
 * Description:
sl@0
  3592
 *
sl@0
  3593
 *   This function parses one S263 atom.
sl@0
  3594
 *
sl@0
  3595
 * Parameters:
sl@0
  3596
 *
sl@0
  3597
 *   handle             MP4 library handle
sl@0
  3598
 *   s263               S263 pointer
sl@0
  3599
 *
sl@0
  3600
 * Return value:
sl@0
  3601
 *
sl@0
  3602
 *   Negative integer   Error
sl@0
  3603
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3604
 *
sl@0
  3605
 */
sl@0
  3606
mp4_i32 readS263(MP4HandleImp handle, h263SampleEntry *s263)
sl@0
  3607
{
sl@0
  3608
  mp4_i32 bytesread;
sl@0
  3609
  mp4_i32 totalbytesread = 0;
sl@0
  3610
sl@0
  3611
sl@0
  3612
  if ((s263->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3613
    return -100;
sl@0
  3614
sl@0
  3615
  bytesread = readAtomHeader(handle, s263->atomhdr);
sl@0
  3616
  if (bytesread < 0)
sl@0
  3617
    return -1;
sl@0
  3618
  totalbytesread += bytesread;
sl@0
  3619
sl@0
  3620
  if (s263->atomhdr->type != ATOMTYPE_S263)
sl@0
  3621
    return -1;
sl@0
  3622
sl@0
  3623
sl@0
  3624
  bytesread = discardData(handle, 6);
sl@0
  3625
  if (bytesread < 0)
sl@0
  3626
    return -1;
sl@0
  3627
  totalbytesread += bytesread;
sl@0
  3628
sl@0
  3629
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3630
  if (bytesread < 0)
sl@0
  3631
    return -1;
sl@0
  3632
  s263->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3633
  totalbytesread += bytesread;
sl@0
  3634
sl@0
  3635
  bytesread = discardData(handle, 16);
sl@0
  3636
  if (bytesread < 0)
sl@0
  3637
    return -1;
sl@0
  3638
  totalbytesread += bytesread;
sl@0
  3639
sl@0
  3640
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3641
  if (bytesread < 0)
sl@0
  3642
    return -1;
sl@0
  3643
  s263->width = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3644
  totalbytesread += bytesread;
sl@0
  3645
sl@0
  3646
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3647
  if (bytesread < 0)
sl@0
  3648
    return -1;
sl@0
  3649
  s263->height = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3650
  totalbytesread += bytesread;
sl@0
  3651
sl@0
  3652
  bytesread = discardData(handle, 50);
sl@0
  3653
  if (bytesread < 0)
sl@0
  3654
    return -1;
sl@0
  3655
  totalbytesread += bytesread;
sl@0
  3656
sl@0
  3657
  if ((s263->d263 = (h263SpecificAtom *)mp4malloc(sizeof(h263SpecificAtom))) == NULL)
sl@0
  3658
    return -100;
sl@0
  3659
sl@0
  3660
  bytesread = readD263(handle, s263->d263);
sl@0
  3661
  if (bytesread < 0)
sl@0
  3662
    return -1;
sl@0
  3663
  totalbytesread += bytesread;
sl@0
  3664
  
sl@0
  3665
  if ( totalbytesread < s263->atomhdr->size )
sl@0
  3666
  	{
sl@0
  3667
    bytesread = discardData(handle, s263->atomhdr->size - totalbytesread );
sl@0
  3668
  	if (bytesread < 0)
sl@0
  3669
  		{
sl@0
  3670
    	return -1;	  		
sl@0
  3671
  		}
sl@0
  3672
  	totalbytesread += bytesread;
sl@0
  3673
  	}      
sl@0
  3674
sl@0
  3675
  return totalbytesread;
sl@0
  3676
}
sl@0
  3677
sl@0
  3678
sl@0
  3679
/*
sl@0
  3680
 * Function:
sl@0
  3681
 *
sl@0
  3682
 *   mp4_i32 readSAMR(MP4HandleImp handle,
sl@0
  3683
 *                    amrSampleEntry *samr)
sl@0
  3684
 *
sl@0
  3685
 * Description:
sl@0
  3686
 *
sl@0
  3687
 *   This function parses one SAMR atom.
sl@0
  3688
 *
sl@0
  3689
 * Parameters:
sl@0
  3690
 *
sl@0
  3691
 *   handle             MP4 library handle
sl@0
  3692
 *   samr               SAMR pointer
sl@0
  3693
 *
sl@0
  3694
 * Return value:
sl@0
  3695
 *
sl@0
  3696
 *   Negative integer   Error
sl@0
  3697
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3698
 *
sl@0
  3699
 */
sl@0
  3700
mp4_i32 readSAMR(MP4HandleImp handle, amrSampleEntry *samr)
sl@0
  3701
{
sl@0
  3702
  mp4_i32 bytesread;
sl@0
  3703
  mp4_i32 totalbytesread = 0;
sl@0
  3704
sl@0
  3705
sl@0
  3706
  if ((samr->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3707
    return -100;
sl@0
  3708
sl@0
  3709
  bytesread = readAtomHeader(handle, samr->atomhdr);
sl@0
  3710
  if (bytesread < 0)
sl@0
  3711
    return -1;
sl@0
  3712
  totalbytesread += bytesread;
sl@0
  3713
sl@0
  3714
  if (samr->atomhdr->type != ATOMTYPE_SAMR)
sl@0
  3715
    return -1;
sl@0
  3716
sl@0
  3717
sl@0
  3718
  bytesread = discardData(handle, 6);
sl@0
  3719
  if (bytesread < 0)
sl@0
  3720
    return -1;
sl@0
  3721
  totalbytesread += bytesread;
sl@0
  3722
sl@0
  3723
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3724
  if (bytesread < 0)
sl@0
  3725
    return -1;
sl@0
  3726
  samr->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3727
  totalbytesread += bytesread;
sl@0
  3728
sl@0
  3729
  bytesread = discardData(handle, 16);
sl@0
  3730
  if (bytesread < 0)
sl@0
  3731
    return -1;
sl@0
  3732
  totalbytesread += bytesread;
sl@0
  3733
sl@0
  3734
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3735
  if (bytesread < 0)
sl@0
  3736
    return -1;
sl@0
  3737
  samr->timeScale = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3738
  totalbytesread += bytesread;
sl@0
  3739
sl@0
  3740
  bytesread = discardData(handle, 2);
sl@0
  3741
  if (bytesread < 0)
sl@0
  3742
    return -1;
sl@0
  3743
  totalbytesread += bytesread;
sl@0
  3744
sl@0
  3745
  if ((samr->damr = (amrDecSpecStruc *)mp4malloc(sizeof(amrDecSpecStruc))) == NULL)
sl@0
  3746
    return -100;
sl@0
  3747
sl@0
  3748
  bytesread = readDAMR(handle, samr->damr);
sl@0
  3749
  if (bytesread < 0)
sl@0
  3750
    return -1;
sl@0
  3751
  totalbytesread += bytesread;
sl@0
  3752
  
sl@0
  3753
  if ( totalbytesread < samr->atomhdr->size )
sl@0
  3754
  	{
sl@0
  3755
    bytesread = discardData(handle, samr->atomhdr->size - totalbytesread );
sl@0
  3756
  	if (bytesread < 0)
sl@0
  3757
  		{
sl@0
  3758
    	return -1;	  		
sl@0
  3759
  		}
sl@0
  3760
  	totalbytesread += bytesread;
sl@0
  3761
  	}      
sl@0
  3762
sl@0
  3763
  return totalbytesread;
sl@0
  3764
}
sl@0
  3765
sl@0
  3766
sl@0
  3767
/*
sl@0
  3768
 * Function:
sl@0
  3769
 *
sl@0
  3770
 *   mp4_i32 readSAWB(MP4HandleImp handle,
sl@0
  3771
 *                    amrSampleEntry *sawb)
sl@0
  3772
 *
sl@0
  3773
 * Description:
sl@0
  3774
 *
sl@0
  3775
 *   This function parses one SAWB atom.
sl@0
  3776
 *
sl@0
  3777
 * Parameters:
sl@0
  3778
 *
sl@0
  3779
 *   handle             MP4 library handle
sl@0
  3780
 *   sawb               SAWB pointer
sl@0
  3781
 *
sl@0
  3782
 * Return value:
sl@0
  3783
 *
sl@0
  3784
 *   Negative integer   Error
sl@0
  3785
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3786
 *
sl@0
  3787
 */
sl@0
  3788
mp4_i32 readSAWB(MP4HandleImp handle, amrSampleEntry *sawb)
sl@0
  3789
{
sl@0
  3790
  mp4_i32 bytesread;
sl@0
  3791
  mp4_i32 totalbytesread = 0;
sl@0
  3792
sl@0
  3793
sl@0
  3794
  if ((sawb->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3795
    return -100;
sl@0
  3796
sl@0
  3797
  bytesread = readAtomHeader(handle, sawb->atomhdr);
sl@0
  3798
  if (bytesread < 0)
sl@0
  3799
    return -1;
sl@0
  3800
  totalbytesread += bytesread;
sl@0
  3801
sl@0
  3802
  if (sawb->atomhdr->type != ATOMTYPE_SAWB)
sl@0
  3803
    return -1;
sl@0
  3804
sl@0
  3805
sl@0
  3806
  bytesread = discardData(handle, 6);
sl@0
  3807
  if (bytesread < 0)
sl@0
  3808
    return -1;
sl@0
  3809
  totalbytesread += bytesread;
sl@0
  3810
sl@0
  3811
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3812
  if (bytesread < 0)
sl@0
  3813
    return -1;
sl@0
  3814
  sawb->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3815
  totalbytesread += bytesread;
sl@0
  3816
sl@0
  3817
  bytesread = discardData(handle, 16);
sl@0
  3818
  if (bytesread < 0)
sl@0
  3819
    return -1;
sl@0
  3820
  totalbytesread += bytesread;
sl@0
  3821
sl@0
  3822
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3823
  if (bytesread < 0)
sl@0
  3824
    return -1;
sl@0
  3825
  sawb->timeScale = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3826
  totalbytesread += bytesread;
sl@0
  3827
sl@0
  3828
  bytesread = discardData(handle, 2);
sl@0
  3829
  if (bytesread < 0)
sl@0
  3830
    return -1;
sl@0
  3831
  totalbytesread += bytesread;
sl@0
  3832
sl@0
  3833
  if ((sawb->damr = (amrDecSpecStruc *)mp4malloc(sizeof(amrDecSpecStruc))) == NULL)
sl@0
  3834
    return -100;
sl@0
  3835
sl@0
  3836
  bytesread = readDAMR(handle, sawb->damr);
sl@0
  3837
  if (bytesread < 0)
sl@0
  3838
    return -1;
sl@0
  3839
  totalbytesread += bytesread;
sl@0
  3840
  
sl@0
  3841
  if ( totalbytesread < sawb->atomhdr->size )
sl@0
  3842
  	{
sl@0
  3843
    bytesread = discardData(handle, sawb->atomhdr->size - totalbytesread );
sl@0
  3844
  	if (bytesread < 0)
sl@0
  3845
  		{
sl@0
  3846
    	return -1;	  		
sl@0
  3847
  		}
sl@0
  3848
  	totalbytesread += bytesread;
sl@0
  3849
  	}      
sl@0
  3850
sl@0
  3851
  return totalbytesread;
sl@0
  3852
}
sl@0
  3853
sl@0
  3854
sl@0
  3855
/*
sl@0
  3856
 * Function:
sl@0
  3857
 *
sl@0
  3858
 *   mp4_i32 readESD(MP4HandleImp handle,
sl@0
  3859
 *                   ESDAtom *esd)
sl@0
  3860
 *
sl@0
  3861
 * Description:
sl@0
  3862
 *
sl@0
  3863
 *   This function parses one ESD atom.
sl@0
  3864
 *
sl@0
  3865
 * Parameters:
sl@0
  3866
 *
sl@0
  3867
 *   handle             MP4 library handle
sl@0
  3868
 *   esd                ESD pointer
sl@0
  3869
 *
sl@0
  3870
 * Return value:
sl@0
  3871
 *
sl@0
  3872
 *   Negative integer   Error
sl@0
  3873
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  3874
 *
sl@0
  3875
 */
sl@0
  3876
mp4_i32 readESD(MP4HandleImp handle, ESDAtom *esd)
sl@0
  3877
{
sl@0
  3878
  mp4_i32 bytesread;
sl@0
  3879
  mp4_i32 totalbytesread = 0;
sl@0
  3880
  mp4_i32 decConfDescrBytesRead = 0;
sl@0
  3881
sl@0
  3882
sl@0
  3883
  if ((esd->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  3884
    return -100;
sl@0
  3885
sl@0
  3886
  bytesread = readFullAtomHeader(handle, esd->atomhdr);
sl@0
  3887
  if (bytesread < 0)
sl@0
  3888
    return -1;
sl@0
  3889
  totalbytesread += bytesread;
sl@0
  3890
sl@0
  3891
  if (esd->atomhdr->type != ATOMTYPE_ESD)
sl@0
  3892
    return -1;
sl@0
  3893
sl@0
  3894
sl@0
  3895
  bytesread = readData(handle, handle->buf, 1);
sl@0
  3896
  if (bytesread < 0)
sl@0
  3897
    return -1;
sl@0
  3898
  esd->esDescrTag = handle->buf[0];
sl@0
  3899
  totalbytesread += bytesread;
sl@0
  3900
  if (esd->esDescrTag != 3) /* ES_DescrTag == 3 */
sl@0
  3901
    return -1;
sl@0
  3902
sl@0
  3903
  esd->size = 0;
sl@0
  3904
  do
sl@0
  3905
  {
sl@0
  3906
    mp4_u8 c;
sl@0
  3907
sl@0
  3908
    bytesread = readData(handle, handle->buf, 1);
sl@0
  3909
    if (bytesread < 0)
sl@0
  3910
      return -1;
sl@0
  3911
    c = (mp4_u8)(handle->buf[0] & 0x7f);
sl@0
  3912
    esd->size = (esd->size << 7) | c;
sl@0
  3913
    totalbytesread += bytesread;
sl@0
  3914
  }
sl@0
  3915
  while (handle->buf[0] & 0x80);
sl@0
  3916
sl@0
  3917
  bytesread = readData(handle, handle->buf, 2);
sl@0
  3918
  if (bytesread < 0)
sl@0
  3919
    return -1;
sl@0
  3920
  esd->ESID = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3921
  totalbytesread += bytesread;
sl@0
  3922
sl@0
  3923
  bytesread = readData(handle, handle->buf, 1);
sl@0
  3924
  if (bytesread < 0)
sl@0
  3925
    return -1;
sl@0
  3926
  esd->flags = handle->buf[0];
sl@0
  3927
  totalbytesread += bytesread;
sl@0
  3928
sl@0
  3929
  if (esd->flags & 0x80) /* Stream Dependence flag has been set */
sl@0
  3930
  {
sl@0
  3931
    bytesread = readData(handle, handle->buf, 2);
sl@0
  3932
    if (bytesread < 0)
sl@0
  3933
      return -1;
sl@0
  3934
    esd->dependsOnESID = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3935
    totalbytesread += bytesread;
sl@0
  3936
  }
sl@0
  3937
sl@0
  3938
  if (esd->flags & 0x40) /* URL flag has been set */
sl@0
  3939
  {
sl@0
  3940
    bytesread = readData(handle, handle->buf, 1);
sl@0
  3941
    if (bytesread < 0)
sl@0
  3942
      return -1;
sl@0
  3943
    esd->URLLength = handle->buf[0];
sl@0
  3944
    totalbytesread += bytesread;
sl@0
  3945
sl@0
  3946
    bytesread = discardData(handle, esd->URLLength);
sl@0
  3947
    if (bytesread < 0)
sl@0
  3948
      return -1;
sl@0
  3949
    totalbytesread += bytesread;
sl@0
  3950
  }
sl@0
  3951
sl@0
  3952
  if (esd->flags & 0x20) /* OCR stream flag has been set */
sl@0
  3953
  {
sl@0
  3954
    bytesread = readData(handle, handle->buf, 2);
sl@0
  3955
    if (bytesread < 0)
sl@0
  3956
      return -1;
sl@0
  3957
    esd->OCRESID = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  3958
    totalbytesread += bytesread;
sl@0
  3959
  }
sl@0
  3960
sl@0
  3961
  bytesread = readData(handle, handle->buf, 1);
sl@0
  3962
  if (bytesread < 0)
sl@0
  3963
    return -1;
sl@0
  3964
  esd->decConfDescrTag = handle->buf[0];
sl@0
  3965
  totalbytesread += bytesread;
sl@0
  3966
  if (esd->decConfDescrTag != 4) /* DecoderConfigDescrTag == 4 */
sl@0
  3967
    return -1;
sl@0
  3968
sl@0
  3969
  esd->decConfDescrSize = 0;
sl@0
  3970
  do
sl@0
  3971
  {
sl@0
  3972
    mp4_u8 c;
sl@0
  3973
sl@0
  3974
    bytesread = readData(handle, handle->buf, 1);
sl@0
  3975
    if (bytesread < 0)
sl@0
  3976
      return -1;
sl@0
  3977
    c = (mp4_u8)(handle->buf[0] & 0x7f);
sl@0
  3978
    esd->decConfDescrSize = (esd->decConfDescrSize << 7) | c;
sl@0
  3979
    totalbytesread += bytesread;
sl@0
  3980
  }
sl@0
  3981
  while (handle->buf[0] & 0x80);
sl@0
  3982
sl@0
  3983
  bytesread = readData(handle, handle->buf, 1);
sl@0
  3984
  if (bytesread < 0)
sl@0
  3985
    return -1;
sl@0
  3986
  esd->objectTypeIndication = handle->buf[0];
sl@0
  3987
  totalbytesread += bytesread;
sl@0
  3988
  decConfDescrBytesRead += bytesread;
sl@0
  3989
sl@0
  3990
  bytesread = readData(handle, handle->buf, 1);
sl@0
  3991
  if (bytesread < 0)
sl@0
  3992
    return -1;
sl@0
  3993
  esd->stream = handle->buf[0];
sl@0
  3994
  totalbytesread += bytesread;
sl@0
  3995
  decConfDescrBytesRead += bytesread;
sl@0
  3996
sl@0
  3997
  bytesread = readData(handle, handle->buf, 3);
sl@0
  3998
  if (bytesread < 0)
sl@0
  3999
    return -1;
sl@0
  4000
  esd->bufferSizeDB = ((mp4_u32)handle->buf[0]) << 16 |
sl@0
  4001
                      ((mp4_u32)handle->buf[1]) << 8 |
sl@0
  4002
                      ((mp4_u32)handle->buf[2]);
sl@0
  4003
  totalbytesread += bytesread;
sl@0
  4004
  decConfDescrBytesRead += bytesread;
sl@0
  4005
sl@0
  4006
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4007
  if (bytesread < 0)
sl@0
  4008
    return -1;
sl@0
  4009
  esd->maxBitrate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4010
  totalbytesread += bytesread;
sl@0
  4011
  decConfDescrBytesRead += bytesread;
sl@0
  4012
sl@0
  4013
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4014
  if (bytesread < 0)
sl@0
  4015
    return -1;
sl@0
  4016
  esd->avgBitrate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4017
  totalbytesread += bytesread;
sl@0
  4018
  decConfDescrBytesRead += bytesread;
sl@0
  4019
sl@0
  4020
  if ((mp4_u32)decConfDescrBytesRead < esd->decConfDescrSize)
sl@0
  4021
  {
sl@0
  4022
    bytesread = readData(handle, handle->buf, 1);
sl@0
  4023
    if (bytesread < 0)
sl@0
  4024
      return -1;
sl@0
  4025
    esd->decSpecificInfoTag = handle->buf[0];
sl@0
  4026
    totalbytesread += bytesread;
sl@0
  4027
    decConfDescrBytesRead += bytesread;
sl@0
  4028
    if (esd->decSpecificInfoTag != 5) /* DecSpecificInfoTag == 5 */
sl@0
  4029
    {
sl@0
  4030
      bytesread = discardData(handle, esd->decConfDescrSize - decConfDescrBytesRead);
sl@0
  4031
      if (bytesread < 0)
sl@0
  4032
        return -1;
sl@0
  4033
      totalbytesread += bytesread;
sl@0
  4034
    }
sl@0
  4035
    else
sl@0
  4036
    {
sl@0
  4037
      esd->decSpecificInfoSize = 0;
sl@0
  4038
      do
sl@0
  4039
      {
sl@0
  4040
        mp4_u8 c;
sl@0
  4041
sl@0
  4042
        bytesread = readData(handle, handle->buf, 1);
sl@0
  4043
        if (bytesread < 0)
sl@0
  4044
          return -1;
sl@0
  4045
        c = (mp4_u8)(handle->buf[0] & 0x7f);
sl@0
  4046
        esd->decSpecificInfoSize = (esd->decSpecificInfoSize << 7) | c;
sl@0
  4047
        totalbytesread += bytesread;
sl@0
  4048
      }
sl@0
  4049
      while (handle->buf[0] & 0x80);
sl@0
  4050
sl@0
  4051
      if(esd->decSpecificInfoSize)
sl@0
  4052
      {
sl@0
  4053
        if ((esd->decSpecificInfo = (mp4_u8 *)mp4malloc(esd->decSpecificInfoSize)) == NULL)
sl@0
  4054
          return -100;
sl@0
  4055
sl@0
  4056
        bytesread = readData(handle, esd->decSpecificInfo, esd->decSpecificInfoSize);
sl@0
  4057
        if (bytesread < 0)
sl@0
  4058
          return -1;
sl@0
  4059
        totalbytesread += bytesread;
sl@0
  4060
      }
sl@0
  4061
    }
sl@0
  4062
  }
sl@0
  4063
sl@0
  4064
  bytesread = discardData(handle, esd->atomhdr->size - totalbytesread);
sl@0
  4065
  if (bytesread < 0)
sl@0
  4066
    return -1;
sl@0
  4067
  totalbytesread += bytesread;
sl@0
  4068
sl@0
  4069
  return totalbytesread;
sl@0
  4070
}
sl@0
  4071
sl@0
  4072
sl@0
  4073
/*
sl@0
  4074
 * Function:
sl@0
  4075
 *
sl@0
  4076
 *   mp4_i32 readD263(MP4HandleImp handle,
sl@0
  4077
 *                    h263SpecificAtom *d263)
sl@0
  4078
 *
sl@0
  4079
 * Description:
sl@0
  4080
 *
sl@0
  4081
 *   This function parses one D263 atom.
sl@0
  4082
 *
sl@0
  4083
 * Parameters:
sl@0
  4084
 *
sl@0
  4085
 *   handle             MP4 library handle
sl@0
  4086
 *   d263               D263 pointer
sl@0
  4087
 *
sl@0
  4088
 * Return value:
sl@0
  4089
 *
sl@0
  4090
 *   Negative integer   Error
sl@0
  4091
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  4092
 *
sl@0
  4093
 */
sl@0
  4094
mp4_i32 readD263(MP4HandleImp handle, h263SpecificAtom *d263)
sl@0
  4095
{
sl@0
  4096
  mp4_i32 bytesread;
sl@0
  4097
  mp4_i32 totalbytesread = 0;
sl@0
  4098
sl@0
  4099
sl@0
  4100
  if ((d263->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  4101
    return -100;
sl@0
  4102
sl@0
  4103
  bytesread = readAtomHeader(handle, d263->atomhdr);
sl@0
  4104
  if (bytesread < 0)
sl@0
  4105
    return -1;
sl@0
  4106
  totalbytesread += bytesread;
sl@0
  4107
sl@0
  4108
  if (d263->atomhdr->type != ATOMTYPE_D263)
sl@0
  4109
    return -1;
sl@0
  4110
sl@0
  4111
sl@0
  4112
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4113
  if (bytesread < 0)
sl@0
  4114
    return -1;
sl@0
  4115
  d263->vendor = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4116
  totalbytesread += bytesread;
sl@0
  4117
sl@0
  4118
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4119
  if (bytesread < 0)
sl@0
  4120
    return -1;
sl@0
  4121
  d263->decoderVersion = handle->buf[0];
sl@0
  4122
  totalbytesread += bytesread;
sl@0
  4123
sl@0
  4124
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4125
  if (bytesread < 0)
sl@0
  4126
    return -1;
sl@0
  4127
  d263->h263Level = handle->buf[0];
sl@0
  4128
  totalbytesread += bytesread;
sl@0
  4129
sl@0
  4130
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4131
  if (bytesread < 0)
sl@0
  4132
    return -1;
sl@0
  4133
  d263->h263Profile = handle->buf[0];
sl@0
  4134
  totalbytesread += bytesread;
sl@0
  4135
sl@0
  4136
  /* Check for the bitrate atom */
sl@0
  4137
sl@0
  4138
  while ((mp4_u32)totalbytesread < d263->atomhdr->size)
sl@0
  4139
  {
sl@0
  4140
    mp4_u32 type;
sl@0
  4141
sl@0
  4142
sl@0
  4143
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  4144
      return -1;
sl@0
  4145
sl@0
  4146
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  4147
sl@0
  4148
    switch (type)
sl@0
  4149
    {
sl@0
  4150
    case ATOMTYPE_BITR:
sl@0
  4151
sl@0
  4152
      if (d263->bitr) /* BITR has already been read, more than one is not allowed */
sl@0
  4153
        return -1;
sl@0
  4154
sl@0
  4155
      if ((d263->bitr = (bitrateAtom *)mp4malloc(sizeof(bitrateAtom))) == NULL)
sl@0
  4156
        return -100;
sl@0
  4157
sl@0
  4158
      bytesread = readBITR(handle, d263->bitr);
sl@0
  4159
      if (bytesread < 0)
sl@0
  4160
        return -1;
sl@0
  4161
      totalbytesread += bytesread;
sl@0
  4162
sl@0
  4163
      break;
sl@0
  4164
sl@0
  4165
    default: /* Other atoms are not needed */
sl@0
  4166
sl@0
  4167
      bytesread = readUnknown(handle);
sl@0
  4168
      if (bytesread < 0)
sl@0
  4169
        return -1;
sl@0
  4170
      totalbytesread += bytesread;
sl@0
  4171
sl@0
  4172
      break;
sl@0
  4173
    }
sl@0
  4174
  }
sl@0
  4175
sl@0
  4176
  return totalbytesread;
sl@0
  4177
}
sl@0
  4178
sl@0
  4179
sl@0
  4180
/*
sl@0
  4181
 * Function:
sl@0
  4182
 *
sl@0
  4183
 *   mp4_i32 readBITR(MP4HandleImp handle,
sl@0
  4184
 *                    bitrateAtom *d263)
sl@0
  4185
 *
sl@0
  4186
 * Description:
sl@0
  4187
 *
sl@0
  4188
 *   This function parses one BITR atom.
sl@0
  4189
 *
sl@0
  4190
 * Parameters:
sl@0
  4191
 *
sl@0
  4192
 *   handle             MP4 library handle
sl@0
  4193
 *   bitr               BITR pointer
sl@0
  4194
 *
sl@0
  4195
 * Return value:
sl@0
  4196
 *
sl@0
  4197
 *   Negative integer   Error
sl@0
  4198
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  4199
 *
sl@0
  4200
 */
sl@0
  4201
mp4_i32 readBITR(MP4HandleImp handle, bitrateAtom *bitr)
sl@0
  4202
{
sl@0
  4203
  mp4_i32 bytesread;
sl@0
  4204
  mp4_i32 totalbytesread = 0;
sl@0
  4205
sl@0
  4206
sl@0
  4207
  if ((bitr->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  4208
    return -100;
sl@0
  4209
sl@0
  4210
  bytesread = readAtomHeader(handle, bitr->atomhdr);
sl@0
  4211
  if (bytesread < 0)
sl@0
  4212
    return -1;
sl@0
  4213
  totalbytesread += bytesread;
sl@0
  4214
sl@0
  4215
  if (bitr->atomhdr->type != ATOMTYPE_BITR)
sl@0
  4216
    return -1;
sl@0
  4217
sl@0
  4218
sl@0
  4219
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4220
  if (bytesread < 0)
sl@0
  4221
    return -1;
sl@0
  4222
  bitr->avgBitrate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4223
  totalbytesread += bytesread;
sl@0
  4224
sl@0
  4225
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4226
  if (bytesread < 0)
sl@0
  4227
    return -1;
sl@0
  4228
  bitr->maxBitrate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4229
  totalbytesread += bytesread;
sl@0
  4230
sl@0
  4231
  return totalbytesread;
sl@0
  4232
}
sl@0
  4233
sl@0
  4234
sl@0
  4235
/*
sl@0
  4236
 * Function:
sl@0
  4237
 *
sl@0
  4238
 *   mp4_i32 readDAMR(MP4HandleImp handle,
sl@0
  4239
 *                    amrDecSpecStruc *damr)
sl@0
  4240
 *
sl@0
  4241
 * Description:
sl@0
  4242
 *
sl@0
  4243
 *   This function parses one DAMR atom.
sl@0
  4244
 *
sl@0
  4245
 * Parameters:
sl@0
  4246
 *
sl@0
  4247
 *   handle             MP4 library handle
sl@0
  4248
 *   damr               DAMR pointer
sl@0
  4249
 *
sl@0
  4250
 * Return value:
sl@0
  4251
 *
sl@0
  4252
 *   Negative integer   Error
sl@0
  4253
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  4254
 *
sl@0
  4255
 */
sl@0
  4256
mp4_i32 readDAMR(MP4HandleImp handle, amrDecSpecStruc *damr)
sl@0
  4257
{
sl@0
  4258
  mp4_i32 bytesread;
sl@0
  4259
  mp4_i32 totalbytesread = 0;
sl@0
  4260
sl@0
  4261
sl@0
  4262
  if ((damr->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  4263
    return -100;
sl@0
  4264
sl@0
  4265
  bytesread = readAtomHeader(handle, damr->atomhdr);
sl@0
  4266
  if (bytesread < 0)
sl@0
  4267
    return -1;
sl@0
  4268
  totalbytesread += bytesread;
sl@0
  4269
sl@0
  4270
  if (damr->atomhdr->type != ATOMTYPE_DAMR)
sl@0
  4271
    return -1;
sl@0
  4272
sl@0
  4273
sl@0
  4274
  bytesread = readData(handle, handle->buf, 4);
sl@0
  4275
  if (bytesread < 0)
sl@0
  4276
    return -1;
sl@0
  4277
  damr->vendor = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  4278
  totalbytesread += bytesread;
sl@0
  4279
sl@0
  4280
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4281
  if (bytesread < 0)
sl@0
  4282
    return -1;
sl@0
  4283
  damr->decoderVersion = handle->buf[0];
sl@0
  4284
  totalbytesread += bytesread;
sl@0
  4285
sl@0
  4286
  bytesread = readData(handle, handle->buf, 2);
sl@0
  4287
  if (bytesread < 0)
sl@0
  4288
    return -1;
sl@0
  4289
  damr->modeSet = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  4290
  totalbytesread += bytesread;
sl@0
  4291
sl@0
  4292
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4293
  if (bytesread < 0)
sl@0
  4294
    return -1;
sl@0
  4295
  damr->modeChangePeriod = handle->buf[0];
sl@0
  4296
  totalbytesread += bytesread;
sl@0
  4297
sl@0
  4298
  bytesread = readData(handle, handle->buf, 1);
sl@0
  4299
  if (bytesread < 0)
sl@0
  4300
    return -1;
sl@0
  4301
  damr->framesPerSample = handle->buf[0];
sl@0
  4302
  totalbytesread += bytesread;
sl@0
  4303
sl@0
  4304
  return totalbytesread;
sl@0
  4305
}
sl@0
  4306
sl@0
  4307
sl@0
  4308
/*
sl@0
  4309
 * Function:
sl@0
  4310
 *
sl@0
  4311
 *   mp4_i32 freeFTYP(MP4HandleImp handle)
sl@0
  4312
 *
sl@0
  4313
 * Description:
sl@0
  4314
 *
sl@0
  4315
 *   This function frees memory for FTYP atom.
sl@0
  4316
 *
sl@0
  4317
 * Parameters:
sl@0
  4318
 *
sl@0
  4319
 *   ftyp       FTYP atom pointer
sl@0
  4320
 *
sl@0
  4321
 * Return value:
sl@0
  4322
 *
sl@0
  4323
 *   0          Success
sl@0
  4324
 *   Negative   Error
sl@0
  4325
 *
sl@0
  4326
 */
sl@0
  4327
mp4_i32 freeFTYP(fileTypeAtom *ftyp)
sl@0
  4328
{
sl@0
  4329
  if (ftyp)
sl@0
  4330
  {
sl@0
  4331
    if (freeAtomHeader(ftyp->atomhdr) < 0)
sl@0
  4332
      return -1;
sl@0
  4333
    if (ftyp->compatibleBrands)
sl@0
  4334
      mp4free(ftyp->compatibleBrands);
sl@0
  4335
sl@0
  4336
    mp4free(ftyp);
sl@0
  4337
  }
sl@0
  4338
sl@0
  4339
  return 0;
sl@0
  4340
}
sl@0
  4341
sl@0
  4342
sl@0
  4343
/*
sl@0
  4344
 * Function:
sl@0
  4345
 *
sl@0
  4346
 *   mp4_i32 freeMOOV(movieAtom *moov)
sl@0
  4347
 *
sl@0
  4348
 * Description:
sl@0
  4349
 *
sl@0
  4350
 *   This function frees memory for MOOV atom.
sl@0
  4351
 *
sl@0
  4352
 * Parameters:
sl@0
  4353
 *
sl@0
  4354
 *   moov       MOOV atom pointer
sl@0
  4355
 *
sl@0
  4356
 * Return value:
sl@0
  4357
 *
sl@0
  4358
 *   0          Success
sl@0
  4359
 *   Negative   Error
sl@0
  4360
 *
sl@0
  4361
 */
sl@0
  4362
mp4_i32 freeMOOV(movieAtom *moov)
sl@0
  4363
{
sl@0
  4364
  if (moov)
sl@0
  4365
  {
sl@0
  4366
    if (freeAtomHeader(moov->atomhdr) < 0)
sl@0
  4367
      return -1;
sl@0
  4368
    if (freeMVHD(moov->mvhd) < 0)
sl@0
  4369
      return -1;
sl@0
  4370
    if (freeTRAK(moov->trakAudio) < 0)
sl@0
  4371
      return -1;
sl@0
  4372
    if (freeTRAK(moov->trakVideo) < 0)
sl@0
  4373
      return -1;
sl@0
  4374
    if (freeIODS(moov->iods) < 0)
sl@0
  4375
      return -1;
sl@0
  4376
    if (freeUDTA(moov->udta) < 0)
sl@0
  4377
      return -1;
sl@0
  4378
    if (freeMETA(moov->meta) < 0)
sl@0
  4379
      return -1;
sl@0
  4380
sl@0
  4381
    mp4free(moov);
sl@0
  4382
  }
sl@0
  4383
sl@0
  4384
  return 0;
sl@0
  4385
}
sl@0
  4386
sl@0
  4387
sl@0
  4388
/*
sl@0
  4389
 * Function:
sl@0
  4390
 *
sl@0
  4391
 *   mp4_i32 freeAtomHeader(atomHeader *atomhdr)
sl@0
  4392
 *
sl@0
  4393
 * Description:
sl@0
  4394
 *
sl@0
  4395
 *   This function frees memory for atom header.
sl@0
  4396
 *
sl@0
  4397
 * Parameters:
sl@0
  4398
 *
sl@0
  4399
 *   atomhdr    atom header pointer
sl@0
  4400
 *
sl@0
  4401
 * Return value:
sl@0
  4402
 *
sl@0
  4403
 *   0          Success
sl@0
  4404
 *   Negative   Error
sl@0
  4405
 *
sl@0
  4406
 */
sl@0
  4407
mp4_i32 freeAtomHeader(atomHeader *atomhdr)
sl@0
  4408
{
sl@0
  4409
  if (atomhdr)
sl@0
  4410
    mp4free(atomhdr);
sl@0
  4411
sl@0
  4412
  return 0;
sl@0
  4413
}
sl@0
  4414
sl@0
  4415
sl@0
  4416
/*
sl@0
  4417
 * Function:
sl@0
  4418
 *
sl@0
  4419
 *   mp4_i32 freeMVHD(movieHeaderAtom *mvhd)
sl@0
  4420
 *
sl@0
  4421
 * Description:
sl@0
  4422
 *
sl@0
  4423
 *   This function frees memory for MVHD atom.
sl@0
  4424
 *
sl@0
  4425
 * Parameters:
sl@0
  4426
 *
sl@0
  4427
 *   mvhd       MVHD atom pointer
sl@0
  4428
 *
sl@0
  4429
 * Return value:
sl@0
  4430
 *
sl@0
  4431
 *   0          Success
sl@0
  4432
 *   Negative   Error
sl@0
  4433
 *
sl@0
  4434
 */
sl@0
  4435
mp4_i32 freeMVHD(movieHeaderAtom *mvhd)
sl@0
  4436
{
sl@0
  4437
  if (mvhd)
sl@0
  4438
  {
sl@0
  4439
    if (freeAtomHeader(mvhd->atomhdr) < 0)
sl@0
  4440
      return -1;
sl@0
  4441
sl@0
  4442
    mp4free(mvhd);
sl@0
  4443
  }
sl@0
  4444
sl@0
  4445
  return 0;
sl@0
  4446
}
sl@0
  4447
sl@0
  4448
sl@0
  4449
/*
sl@0
  4450
 * Function:
sl@0
  4451
 *
sl@0
  4452
 *   mp4_i32 freeTRAK(trackAtom *trak)
sl@0
  4453
 *
sl@0
  4454
 * Description:
sl@0
  4455
 *
sl@0
  4456
 *   This function frees memory for TRAK atom.
sl@0
  4457
 *
sl@0
  4458
 * Parameters:
sl@0
  4459
 *
sl@0
  4460
 *   trak       TRAK atom pointer
sl@0
  4461
 *
sl@0
  4462
 * Return value:
sl@0
  4463
 *
sl@0
  4464
 *   0          Success
sl@0
  4465
 *   Negative   Error
sl@0
  4466
 *
sl@0
  4467
 */
sl@0
  4468
mp4_i32 freeTRAK(trackAtom *trak)
sl@0
  4469
{
sl@0
  4470
  if (trak)
sl@0
  4471
  {
sl@0
  4472
    if (freeAtomHeader(trak->atomhdr) < 0)
sl@0
  4473
      return -1;
sl@0
  4474
    if (freeTKHD(trak->tkhd) < 0)
sl@0
  4475
      return -1;
sl@0
  4476
    if (freeTREF(trak->tref) < 0)
sl@0
  4477
      return -1;
sl@0
  4478
    if (freeEDTS(trak->edts) < 0)
sl@0
  4479
      return -1;
sl@0
  4480
    if (freeMDIA(trak->mdia) < 0)
sl@0
  4481
      return -1;
sl@0
  4482
    if (freeUDTA(trak->udta) < 0)
sl@0
  4483
      return -1;
sl@0
  4484
sl@0
  4485
    mp4free(trak);
sl@0
  4486
  }
sl@0
  4487
sl@0
  4488
  return 0;
sl@0
  4489
}
sl@0
  4490
sl@0
  4491
sl@0
  4492
/*
sl@0
  4493
 * Function:
sl@0
  4494
 *
sl@0
  4495
 *   mp4_i32 freeTKHD(trackHeaderAtom *tkhd)
sl@0
  4496
 *
sl@0
  4497
 * Description:
sl@0
  4498
 *
sl@0
  4499
 *   This function frees memory for TKHD atom.
sl@0
  4500
 *
sl@0
  4501
 * Parameters:
sl@0
  4502
 *
sl@0
  4503
 *   tkhd       TKHD atom pointer
sl@0
  4504
 *
sl@0
  4505
 * Return value:
sl@0
  4506
 *
sl@0
  4507
 *   0          Success
sl@0
  4508
 *   Negative   Error
sl@0
  4509
 *
sl@0
  4510
 */
sl@0
  4511
mp4_i32 freeTKHD(trackHeaderAtom *tkhd)
sl@0
  4512
{
sl@0
  4513
  if (tkhd)
sl@0
  4514
  {
sl@0
  4515
    if (freeAtomHeader(tkhd->atomhdr) < 0)
sl@0
  4516
      return -1;
sl@0
  4517
sl@0
  4518
    mp4free(tkhd);
sl@0
  4519
  }
sl@0
  4520
sl@0
  4521
  return 0;
sl@0
  4522
}
sl@0
  4523
sl@0
  4524
sl@0
  4525
/*
sl@0
  4526
 * Function:
sl@0
  4527
 *
sl@0
  4528
 *   mp4_i32 freeTREF(trackReferenceAtom *tref)
sl@0
  4529
 *
sl@0
  4530
 * Description:
sl@0
  4531
 *
sl@0
  4532
 *   This function frees memory for TREF atom.
sl@0
  4533
 *
sl@0
  4534
 * Parameters:
sl@0
  4535
 *
sl@0
  4536
 *   tref       TREF atom pointer
sl@0
  4537
 *
sl@0
  4538
 * Return value:
sl@0
  4539
 *
sl@0
  4540
 *   0          Success
sl@0
  4541
 *   Negative   Error
sl@0
  4542
 *
sl@0
  4543
 */
sl@0
  4544
mp4_i32 freeTREF(trackReferenceAtom *tref)
sl@0
  4545
{
sl@0
  4546
  if (tref)
sl@0
  4547
  {
sl@0
  4548
    if (freeAtomHeader(tref->atomhdr) < 0)
sl@0
  4549
      return -1;
sl@0
  4550
sl@0
  4551
    mp4free(tref);
sl@0
  4552
  }
sl@0
  4553
sl@0
  4554
  return 0;
sl@0
  4555
}
sl@0
  4556
sl@0
  4557
sl@0
  4558
/*
sl@0
  4559
 * Function:
sl@0
  4560
 *
sl@0
  4561
 *   mp4_i32 freeEDTS(editListContainerAtom *edts)
sl@0
  4562
 *
sl@0
  4563
 * Description:
sl@0
  4564
 *
sl@0
  4565
 *   This function frees memory for EDTS atom.
sl@0
  4566
 *
sl@0
  4567
 * Parameters:
sl@0
  4568
 *
sl@0
  4569
 *   edts       EDTS atom pointer
sl@0
  4570
 *
sl@0
  4571
 * Return value:
sl@0
  4572
 *
sl@0
  4573
 *   0          Success
sl@0
  4574
 *   Negative   Error
sl@0
  4575
 *
sl@0
  4576
 */
sl@0
  4577
mp4_i32 freeEDTS(editListContainerAtom *edts)
sl@0
  4578
{
sl@0
  4579
  if (edts)
sl@0
  4580
  {
sl@0
  4581
    if (freeAtomHeader(edts->atomhdr) < 0)
sl@0
  4582
      return -1;
sl@0
  4583
sl@0
  4584
    mp4free(edts);
sl@0
  4585
  }
sl@0
  4586
sl@0
  4587
  return 0;
sl@0
  4588
}
sl@0
  4589
sl@0
  4590
sl@0
  4591
/*
sl@0
  4592
 * Function:
sl@0
  4593
 *
sl@0
  4594
 *   mp4_i32 freeMDIA(mediaAtom *mdia)
sl@0
  4595
 *
sl@0
  4596
 * Description:
sl@0
  4597
 *
sl@0
  4598
 *   This function frees memory for MDIA atom.
sl@0
  4599
 *
sl@0
  4600
 * Parameters:
sl@0
  4601
 *
sl@0
  4602
 *   mdia       MDIA atom pointer
sl@0
  4603
 *
sl@0
  4604
 * Return value:
sl@0
  4605
 *
sl@0
  4606
 *   0          Success
sl@0
  4607
 *   Negative   Error
sl@0
  4608
 *
sl@0
  4609
 */
sl@0
  4610
mp4_i32 freeMDIA(mediaAtom *mdia)
sl@0
  4611
{
sl@0
  4612
  if (mdia)
sl@0
  4613
  {
sl@0
  4614
    if (freeAtomHeader(mdia->atomhdr) < 0)
sl@0
  4615
      return -1;
sl@0
  4616
    if (freeMDHD(mdia->mdhd) < 0)
sl@0
  4617
      return -1;
sl@0
  4618
    if (freeHDLR(mdia->hdlr) < 0)
sl@0
  4619
      return -1;
sl@0
  4620
    if (freeMINF(mdia->minf) < 0)
sl@0
  4621
      return -1;
sl@0
  4622
sl@0
  4623
    mp4free(mdia);
sl@0
  4624
  }
sl@0
  4625
sl@0
  4626
  return 0;
sl@0
  4627
}
sl@0
  4628
sl@0
  4629
sl@0
  4630
/*
sl@0
  4631
 * Function:
sl@0
  4632
 *
sl@0
  4633
 *   mp4_i32 freeMDHD(mediaHeaderAtom *mdhd)
sl@0
  4634
 *
sl@0
  4635
 * Description:
sl@0
  4636
 *
sl@0
  4637
 *   This function frees memory for MDHD atom.
sl@0
  4638
 *
sl@0
  4639
 * Parameters:
sl@0
  4640
 *
sl@0
  4641
 *   mdhd       MDHD atom pointer
sl@0
  4642
 *
sl@0
  4643
 * Return value:
sl@0
  4644
 *
sl@0
  4645
 *   0          Success
sl@0
  4646
 *   Negative   Error
sl@0
  4647
 *
sl@0
  4648
 */
sl@0
  4649
mp4_i32 freeMDHD(mediaHeaderAtom *mdhd)
sl@0
  4650
{
sl@0
  4651
  if (mdhd)
sl@0
  4652
  {
sl@0
  4653
    if (freeAtomHeader(mdhd->atomhdr) < 0)
sl@0
  4654
      return -1;
sl@0
  4655
sl@0
  4656
    mp4free(mdhd);
sl@0
  4657
  }
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 freeHDLR(handlerAtom *hdlr)
sl@0
  4667
 *
sl@0
  4668
 * Description:
sl@0
  4669
 *
sl@0
  4670
 *   This function frees memory for HDLR atom.
sl@0
  4671
 *
sl@0
  4672
 * Parameters:
sl@0
  4673
 *
sl@0
  4674
 *   hdlr       HDLR atom pointer
sl@0
  4675
 *
sl@0
  4676
 * Return value:
sl@0
  4677
 *
sl@0
  4678
 *   0          Success
sl@0
  4679
 *   Negative   Error
sl@0
  4680
 *
sl@0
  4681
 */
sl@0
  4682
mp4_i32 freeHDLR(handlerAtom *hdlr)
sl@0
  4683
{
sl@0
  4684
  if (hdlr)
sl@0
  4685
  {
sl@0
  4686
    if (freeAtomHeader(hdlr->atomhdr) < 0)
sl@0
  4687
      return -1;
sl@0
  4688
    if (hdlr->name)
sl@0
  4689
      mp4free(hdlr->name);
sl@0
  4690
sl@0
  4691
    mp4free(hdlr);
sl@0
  4692
  }
sl@0
  4693
sl@0
  4694
  return 0;
sl@0
  4695
}
sl@0
  4696
sl@0
  4697
sl@0
  4698
/*
sl@0
  4699
 * Function:
sl@0
  4700
 *
sl@0
  4701
 *   mp4_i32 freeMINF(mediaInformationAtom *minf)
sl@0
  4702
 *
sl@0
  4703
 * Description:
sl@0
  4704
 *
sl@0
  4705
 *   This function frees memory for MINF atom.
sl@0
  4706
 *
sl@0
  4707
 * Parameters:
sl@0
  4708
 *
sl@0
  4709
 *   minf       MINF atom pointer
sl@0
  4710
 *
sl@0
  4711
 * Return value:
sl@0
  4712
 *
sl@0
  4713
 *   0          Success
sl@0
  4714
 *   Negative   Error
sl@0
  4715
 *
sl@0
  4716
 */
sl@0
  4717
mp4_i32 freeMINF(mediaInformationAtom *minf)
sl@0
  4718
{
sl@0
  4719
  if (minf)
sl@0
  4720
  {
sl@0
  4721
    if (freeAtomHeader(minf->atomhdr) < 0)
sl@0
  4722
      return -1;
sl@0
  4723
    if (freeVMHD(minf->vmhd) < 0)
sl@0
  4724
      return -1;
sl@0
  4725
    if (freeSMHD(minf->smhd) < 0)
sl@0
  4726
      return -1;
sl@0
  4727
    if (freeDINF(minf->dinf) < 0)
sl@0
  4728
      return -1;
sl@0
  4729
    if (freeSTBL(minf->stbl) < 0)
sl@0
  4730
      return -1;
sl@0
  4731
sl@0
  4732
    mp4free(minf);
sl@0
  4733
  }
sl@0
  4734
sl@0
  4735
  return 0;
sl@0
  4736
}
sl@0
  4737
sl@0
  4738
sl@0
  4739
/*
sl@0
  4740
 * Function:
sl@0
  4741
 *
sl@0
  4742
 *   mp4_i32 freeVMHD(videoMediaHeaderAtom *vmhd)
sl@0
  4743
 *
sl@0
  4744
 * Description:
sl@0
  4745
 *
sl@0
  4746
 *   This function frees memory for VMHD atom.
sl@0
  4747
 *
sl@0
  4748
 * Parameters:
sl@0
  4749
 *
sl@0
  4750
 *   vmhd       VMHD atom pointer
sl@0
  4751
 *
sl@0
  4752
 * Return value:
sl@0
  4753
 *
sl@0
  4754
 *   0          Success
sl@0
  4755
 *   Negative   Error
sl@0
  4756
 *
sl@0
  4757
 */
sl@0
  4758
mp4_i32 freeVMHD(videoMediaHeaderAtom *vmhd)
sl@0
  4759
{
sl@0
  4760
  if (vmhd)
sl@0
  4761
  {
sl@0
  4762
    if (freeAtomHeader(vmhd->atomhdr) < 0)
sl@0
  4763
      return -1;
sl@0
  4764
sl@0
  4765
    mp4free(vmhd);
sl@0
  4766
  }
sl@0
  4767
sl@0
  4768
  return 0;
sl@0
  4769
}
sl@0
  4770
sl@0
  4771
sl@0
  4772
/*
sl@0
  4773
 * Function:
sl@0
  4774
 *
sl@0
  4775
 *   mp4_i32 freeSMHD(soundMediaHeaderAtom *smhd)
sl@0
  4776
 *
sl@0
  4777
 * Description:
sl@0
  4778
 *
sl@0
  4779
 *   This function frees memory for SMHD atom.
sl@0
  4780
 *
sl@0
  4781
 * Parameters:
sl@0
  4782
 *
sl@0
  4783
 *   smhd       SMHD atom pointer
sl@0
  4784
 *
sl@0
  4785
 * Return value:
sl@0
  4786
 *
sl@0
  4787
 *   0          Success
sl@0
  4788
 *   Negative   Error
sl@0
  4789
 *
sl@0
  4790
 */
sl@0
  4791
mp4_i32 freeSMHD(soundMediaHeaderAtom *smhd)
sl@0
  4792
{
sl@0
  4793
  if (smhd)
sl@0
  4794
  {
sl@0
  4795
    if (freeAtomHeader(smhd->atomhdr) < 0)
sl@0
  4796
      return -1;
sl@0
  4797
sl@0
  4798
    mp4free(smhd);
sl@0
  4799
  }
sl@0
  4800
sl@0
  4801
  return 0;
sl@0
  4802
}
sl@0
  4803
sl@0
  4804
sl@0
  4805
/*
sl@0
  4806
 * Function:
sl@0
  4807
 *
sl@0
  4808
 *   mp4_i32 freeDINF(dataInformationAtom *dinf)
sl@0
  4809
 *
sl@0
  4810
 * Description:
sl@0
  4811
 *
sl@0
  4812
 *   This function frees memory for DINF atom.
sl@0
  4813
 *
sl@0
  4814
 * Parameters:
sl@0
  4815
 *
sl@0
  4816
 *   dinf       DINF atom pointer
sl@0
  4817
 *
sl@0
  4818
 * Return value:
sl@0
  4819
 *
sl@0
  4820
 *   0          Success
sl@0
  4821
 *   Negative   Error
sl@0
  4822
 *
sl@0
  4823
 */
sl@0
  4824
mp4_i32 freeDINF(dataInformationAtom *dinf)
sl@0
  4825
{
sl@0
  4826
  if (dinf)
sl@0
  4827
  {
sl@0
  4828
    if (freeAtomHeader(dinf->atomhdr) < 0)
sl@0
  4829
      return -1;
sl@0
  4830
    if (freeDREF(dinf->dref) < 0)
sl@0
  4831
      return -1;
sl@0
  4832
sl@0
  4833
    mp4free(dinf);
sl@0
  4834
  }
sl@0
  4835
sl@0
  4836
  return 0;
sl@0
  4837
}
sl@0
  4838
sl@0
  4839
sl@0
  4840
/*
sl@0
  4841
 * Function:
sl@0
  4842
 *
sl@0
  4843
 *   mp4_i32 freeDREF(dataReferenceAtom *dref)
sl@0
  4844
 *
sl@0
  4845
 * Description:
sl@0
  4846
 *
sl@0
  4847
 *   This function frees memory for DREF atom.
sl@0
  4848
 *
sl@0
  4849
 * Parameters:
sl@0
  4850
 *
sl@0
  4851
 *   dref       DREF atom pointer
sl@0
  4852
 *
sl@0
  4853
 * Return value:
sl@0
  4854
 *
sl@0
  4855
 *   0          Success
sl@0
  4856
 *   Negative   Error
sl@0
  4857
 *
sl@0
  4858
 */
sl@0
  4859
mp4_i32 freeDREF(dataReferenceAtom *dref)
sl@0
  4860
{
sl@0
  4861
  if (dref)
sl@0
  4862
  {
sl@0
  4863
    if (freeAtomHeader(dref->atomhdr) < 0)
sl@0
  4864
      return -1;
sl@0
  4865
    if (freeURL(dref->url) < 0)
sl@0
  4866
      return -1;
sl@0
  4867
    if (freeURN(dref->urn) < 0)
sl@0
  4868
      return -1;
sl@0
  4869
sl@0
  4870
    mp4free(dref);
sl@0
  4871
  }
sl@0
  4872
sl@0
  4873
  return 0;
sl@0
  4874
}
sl@0
  4875
sl@0
  4876
sl@0
  4877
/*
sl@0
  4878
 * Function:
sl@0
  4879
 *
sl@0
  4880
 *   mp4_i32 freeURL(dataEntryURLAtom *url)
sl@0
  4881
 *
sl@0
  4882
 * Description:
sl@0
  4883
 *
sl@0
  4884
 *   This function frees memory for URL atom.
sl@0
  4885
 *
sl@0
  4886
 * Parameters:
sl@0
  4887
 *
sl@0
  4888
 *   url        URL atom pointer
sl@0
  4889
 *
sl@0
  4890
 * Return value:
sl@0
  4891
 *
sl@0
  4892
 *   0          Success
sl@0
  4893
 *   Negative   Error
sl@0
  4894
 *
sl@0
  4895
 */
sl@0
  4896
mp4_i32 freeURL(dataEntryURLAtom *url)
sl@0
  4897
{
sl@0
  4898
  if (url)
sl@0
  4899
  {
sl@0
  4900
    if (freeAtomHeader(url->atomhdr) < 0)
sl@0
  4901
      return -1;
sl@0
  4902
sl@0
  4903
    mp4free(url);
sl@0
  4904
  }
sl@0
  4905
sl@0
  4906
  return 0;
sl@0
  4907
}
sl@0
  4908
sl@0
  4909
sl@0
  4910
/*
sl@0
  4911
 * Function:
sl@0
  4912
 *
sl@0
  4913
 *   mp4_i32 freeURN(dataEntryURNAtom *urn)
sl@0
  4914
 *
sl@0
  4915
 * Description:
sl@0
  4916
 *
sl@0
  4917
 *   This function frees memory for URN atom.
sl@0
  4918
 *
sl@0
  4919
 * Parameters:
sl@0
  4920
 *
sl@0
  4921
 *   urn        URN atom pointer
sl@0
  4922
 *
sl@0
  4923
 * Return value:
sl@0
  4924
 *
sl@0
  4925
 *   0          Success
sl@0
  4926
 *   Negative   Error
sl@0
  4927
 *
sl@0
  4928
 */
sl@0
  4929
mp4_i32 freeURN(dataEntryURNAtom *urn)
sl@0
  4930
{
sl@0
  4931
  if (urn)
sl@0
  4932
  {
sl@0
  4933
    if (freeAtomHeader(urn->atomhdr) < 0)
sl@0
  4934
      return -1;
sl@0
  4935
sl@0
  4936
    mp4free(urn);
sl@0
  4937
  }
sl@0
  4938
sl@0
  4939
  return 0;
sl@0
  4940
}
sl@0
  4941
sl@0
  4942
sl@0
  4943
/*
sl@0
  4944
 * Function:
sl@0
  4945
 *
sl@0
  4946
 *   mp4_i32 freeSTBL(sampleTableAtom *stbl)
sl@0
  4947
 *
sl@0
  4948
 * Description:
sl@0
  4949
 *
sl@0
  4950
 *   This function frees memory for STBL atom.
sl@0
  4951
 *
sl@0
  4952
 * Parameters:
sl@0
  4953
 *
sl@0
  4954
 *   stbl       STBL atom pointer
sl@0
  4955
 *
sl@0
  4956
 * Return value:
sl@0
  4957
 *
sl@0
  4958
 *   0          Success
sl@0
  4959
 *   Negative   Error
sl@0
  4960
 *
sl@0
  4961
 */
sl@0
  4962
mp4_i32 freeSTBL(sampleTableAtom *stbl)
sl@0
  4963
{
sl@0
  4964
  if (stbl)
sl@0
  4965
  {
sl@0
  4966
    if (freeAtomHeader(stbl->atomhdr) < 0)
sl@0
  4967
      return -1;
sl@0
  4968
    if (freeSTTS(stbl->stts) < 0)
sl@0
  4969
      return -1;
sl@0
  4970
    if (freeCTTS(stbl->ctts) < 0)
sl@0
  4971
      return -1;
sl@0
  4972
    if (freeSTSD(stbl->stsd) < 0)
sl@0
  4973
      return -1;
sl@0
  4974
    if (freeSTSZ(stbl->stsz) < 0)
sl@0
  4975
      return -1;
sl@0
  4976
    if (freeSTSC(stbl->stsc) < 0)
sl@0
  4977
      return -1;
sl@0
  4978
    if (stbl->is32BitOffsets)
sl@0
  4979
    {
sl@0
  4980
    
sl@0
  4981
      if (freeSTCO(stbl->stco) < 0)
sl@0
  4982
        return -1;
sl@0
  4983
    }
sl@0
  4984
    else
sl@0
  4985
    {
sl@0
  4986
    
sl@0
  4987
      if (freeSTCO64(stbl->stco64) < 0)
sl@0
  4988
        return -1;
sl@0
  4989
    }
sl@0
  4990
    if (freeSTSS(stbl->stss) < 0)
sl@0
  4991
      return -1;
sl@0
  4992
    if (freeSTSH(stbl->stsh) < 0)
sl@0
  4993
      return -1;
sl@0
  4994
    if (freeSDTP(stbl->sdtp) < 0)
sl@0
  4995
      return -1;
sl@0
  4996
sl@0
  4997
    mp4free(stbl);
sl@0
  4998
  }
sl@0
  4999
sl@0
  5000
  return 0;
sl@0
  5001
}
sl@0
  5002
sl@0
  5003
sl@0
  5004
/*
sl@0
  5005
 * Function:
sl@0
  5006
 *
sl@0
  5007
 *   mp4_i32 freeSTTS(timeToSampleAtom *stts)
sl@0
  5008
 *
sl@0
  5009
 * Description:
sl@0
  5010
 *
sl@0
  5011
 *   This function frees memory for STTS atom.
sl@0
  5012
 *
sl@0
  5013
 * Parameters:
sl@0
  5014
 *
sl@0
  5015
 *   stts       STTS atom pointer
sl@0
  5016
 *
sl@0
  5017
 * Return value:
sl@0
  5018
 *
sl@0
  5019
 *   0          Success
sl@0
  5020
 *   Negative   Error
sl@0
  5021
 *
sl@0
  5022
 */
sl@0
  5023
mp4_i32 freeSTTS(timeToSampleAtom *stts)
sl@0
  5024
{
sl@0
  5025
  if (stts)
sl@0
  5026
  {
sl@0
  5027
    if (freeAtomHeader(stts->atomhdr) < 0)
sl@0
  5028
      return -1;
sl@0
  5029
    if (stts->sampleCount)
sl@0
  5030
      mp4free(stts->sampleCount);
sl@0
  5031
    if (stts->sampleDelta)
sl@0
  5032
      mp4free(stts->sampleDelta);
sl@0
  5033
sl@0
  5034
    mp4free(stts);
sl@0
  5035
  }
sl@0
  5036
sl@0
  5037
  return 0;
sl@0
  5038
}
sl@0
  5039
sl@0
  5040
sl@0
  5041
/*
sl@0
  5042
 * Function:
sl@0
  5043
 *
sl@0
  5044
 *   mp4_i32 freeCTTS(compositionTimeToSampleAtom *ctts)
sl@0
  5045
 *
sl@0
  5046
 * Description:
sl@0
  5047
 *
sl@0
  5048
 *   This function frees memory for CTTS atom.
sl@0
  5049
 *
sl@0
  5050
 * Parameters:
sl@0
  5051
 *
sl@0
  5052
 *   ctts       CTTS atom pointer
sl@0
  5053
 *
sl@0
  5054
 * Return value:
sl@0
  5055
 *
sl@0
  5056
 *   0          Success
sl@0
  5057
 *   Negative   Error
sl@0
  5058
 *
sl@0
  5059
 */
sl@0
  5060
mp4_i32 freeCTTS(compositionTimeToSampleAtom *ctts)
sl@0
  5061
{
sl@0
  5062
  if (ctts)
sl@0
  5063
  {
sl@0
  5064
    if (freeAtomHeader(ctts->atomhdr) < 0)
sl@0
  5065
      return -1;
sl@0
  5066
    if (ctts->sampleCount)
sl@0
  5067
      mp4free(ctts->sampleCount);
sl@0
  5068
    if (ctts->sampleOffset)
sl@0
  5069
      mp4free(ctts->sampleOffset);
sl@0
  5070
sl@0
  5071
    mp4free(ctts);
sl@0
  5072
  }
sl@0
  5073
sl@0
  5074
  return 0;
sl@0
  5075
}
sl@0
  5076
sl@0
  5077
sl@0
  5078
/*
sl@0
  5079
 * Function:
sl@0
  5080
 *
sl@0
  5081
 *   mp4_i32 freeSTSD(sampleDescriptionAtom *stsd)
sl@0
  5082
 *
sl@0
  5083
 * Description:
sl@0
  5084
 *
sl@0
  5085
 *   This function frees memory for STSD atom.
sl@0
  5086
 *
sl@0
  5087
 * Parameters:
sl@0
  5088
 *
sl@0
  5089
 *   stsd       STSD atom pointer
sl@0
  5090
 *
sl@0
  5091
 * Return value:
sl@0
  5092
 *
sl@0
  5093
 *   0          Success
sl@0
  5094
 *   Negative   Error
sl@0
  5095
 *
sl@0
  5096
 */
sl@0
  5097
mp4_i32 freeSTSD(sampleDescriptionAtom *stsd)
sl@0
  5098
{
sl@0
  5099
  mp4_u32 sampleentrycount = 0;
sl@0
  5100
  mp4_u32 entryindex;
sl@0
  5101
  
sl@0
  5102
  if (stsd)
sl@0
  5103
  {
sl@0
  5104
	sampleentrycount = stsd->entryCount;
sl@0
  5105
sl@0
  5106
    if (freeAtomHeader(stsd->atomhdr) < 0)
sl@0
  5107
      return -1;
sl@0
  5108
	for (entryindex = 0; entryindex < sampleentrycount; entryindex++)
sl@0
  5109
	{
sl@0
  5110
		if (freeMP4V(stsd->mp4v[entryindex]) < 0)
sl@0
  5111
		  return -1;
sl@0
  5112
		if (freeMP4A(stsd->mp4a[entryindex]) < 0)
sl@0
  5113
		  return -1;
sl@0
  5114
		if (freeMP4S(stsd->mp4s[entryindex]) < 0)
sl@0
  5115
		  return -1;
sl@0
  5116
		if (freeS263(stsd->s263[entryindex]) < 0)
sl@0
  5117
		  return -1;
sl@0
  5118
		if (freeSAMR(stsd->samr[entryindex]) < 0)
sl@0
  5119
		  return -1;
sl@0
  5120
		if (freeSAWB(stsd->sawb[entryindex]) < 0)
sl@0
  5121
		  return -1;
sl@0
  5122
		if (freeAVC1(stsd->avc1[entryindex]) < 0)
sl@0
  5123
			return -1;
sl@0
  5124
        if (freeSQCP(stsd->sqcp[entryindex]) < 0)
sl@0
  5125
          return -1;
sl@0
  5126
	}
sl@0
  5127
    mp4free(stsd);
sl@0
  5128
  }
sl@0
  5129
sl@0
  5130
  return 0;
sl@0
  5131
}
sl@0
  5132
sl@0
  5133
sl@0
  5134
/*
sl@0
  5135
 * Function:
sl@0
  5136
 *
sl@0
  5137
 *   mp4_i32 freeMP4V(visualSampleEntry *mp4v)
sl@0
  5138
 *
sl@0
  5139
 * Description:
sl@0
  5140
 *
sl@0
  5141
 *   This function frees memory for MP4V atom.
sl@0
  5142
 *
sl@0
  5143
 * Parameters:
sl@0
  5144
 *
sl@0
  5145
 *   mp4v       MP4V atom pointer
sl@0
  5146
 *
sl@0
  5147
 * Return value:
sl@0
  5148
 *
sl@0
  5149
 *   0          Success
sl@0
  5150
 *   Negative   Error
sl@0
  5151
 *
sl@0
  5152
 */
sl@0
  5153
mp4_i32 freeMP4V(visualSampleEntry *mp4v)
sl@0
  5154
{
sl@0
  5155
  if (mp4v)
sl@0
  5156
  {
sl@0
  5157
    if (freeAtomHeader(mp4v->atomhdr) < 0)
sl@0
  5158
      return -1;
sl@0
  5159
    if (freeESD(mp4v->esd) < 0)
sl@0
  5160
      return -1;
sl@0
  5161
sl@0
  5162
    mp4free(mp4v);
sl@0
  5163
  }
sl@0
  5164
sl@0
  5165
  return 0;
sl@0
  5166
}
sl@0
  5167
sl@0
  5168
sl@0
  5169
/*
sl@0
  5170
 * Function:
sl@0
  5171
 *
sl@0
  5172
 *   mp4_i32 freeESD(ESDAtom *esd)
sl@0
  5173
 *
sl@0
  5174
 * Description:
sl@0
  5175
 *
sl@0
  5176
 *   This function frees memory for ESD atom.
sl@0
  5177
 *
sl@0
  5178
 * Parameters:
sl@0
  5179
 *
sl@0
  5180
 *   esd        ESD atom pointer
sl@0
  5181
 *
sl@0
  5182
 * Return value:
sl@0
  5183
 *
sl@0
  5184
 *   0          Success
sl@0
  5185
 *   Negative   Error
sl@0
  5186
 *
sl@0
  5187
 */
sl@0
  5188
mp4_i32 freeESD(ESDAtom *esd)
sl@0
  5189
{
sl@0
  5190
  if (esd)
sl@0
  5191
  {
sl@0
  5192
    if (freeAtomHeader(esd->atomhdr) < 0)
sl@0
  5193
      return -1;
sl@0
  5194
    if (esd->URLString)
sl@0
  5195
      mp4free(esd->URLString);
sl@0
  5196
    if (esd->decSpecificInfo)
sl@0
  5197
      mp4free(esd->decSpecificInfo);
sl@0
  5198
sl@0
  5199
    mp4free(esd);
sl@0
  5200
  }
sl@0
  5201
sl@0
  5202
  return 0;
sl@0
  5203
}
sl@0
  5204
sl@0
  5205
sl@0
  5206
/*
sl@0
  5207
 * Function:
sl@0
  5208
 *
sl@0
  5209
 *   mp4_i32 freeMP4A(audioSampleEntry *mp4a)
sl@0
  5210
 *
sl@0
  5211
 * Description:
sl@0
  5212
 *
sl@0
  5213
 *   This function frees memory for MP4A atom.
sl@0
  5214
 *
sl@0
  5215
 * Parameters:
sl@0
  5216
 *
sl@0
  5217
 *   mp4a       MP4A atom pointer
sl@0
  5218
 *
sl@0
  5219
 * Return value:
sl@0
  5220
 *
sl@0
  5221
 *   0          Success
sl@0
  5222
 *   Negative   Error
sl@0
  5223
 *
sl@0
  5224
 */
sl@0
  5225
mp4_i32 freeMP4A(audioSampleEntry *mp4a)
sl@0
  5226
{
sl@0
  5227
  if (mp4a)
sl@0
  5228
  {
sl@0
  5229
    if (freeAtomHeader(mp4a->atomhdr) < 0)
sl@0
  5230
      return -1;
sl@0
  5231
    if (freeESD(mp4a->esd) < 0)
sl@0
  5232
      return -1;
sl@0
  5233
sl@0
  5234
    mp4free(mp4a);
sl@0
  5235
  }
sl@0
  5236
sl@0
  5237
  return 0;
sl@0
  5238
}
sl@0
  5239
sl@0
  5240
sl@0
  5241
/*
sl@0
  5242
 * Function:
sl@0
  5243
 *
sl@0
  5244
 *   mp4_i32 freeMP4S(mpegSampleEntry *mp4s)
sl@0
  5245
 *
sl@0
  5246
 * Description:
sl@0
  5247
 *
sl@0
  5248
 *   This function frees memory for MP4S atom.
sl@0
  5249
 *
sl@0
  5250
 * Parameters:
sl@0
  5251
 *
sl@0
  5252
 *   mp4s       MP4S atom pointer
sl@0
  5253
 *
sl@0
  5254
 * Return value:
sl@0
  5255
 *
sl@0
  5256
 *   0          Success
sl@0
  5257
 *   Negative   Error
sl@0
  5258
 *
sl@0
  5259
 */
sl@0
  5260
mp4_i32 freeMP4S(mpegSampleEntry *mp4s)
sl@0
  5261
{
sl@0
  5262
  if (mp4s)
sl@0
  5263
  {
sl@0
  5264
    if (freeAtomHeader(mp4s->atomhdr) < 0)
sl@0
  5265
      return -1;
sl@0
  5266
    if (freeESD(mp4s->esd) < 0)
sl@0
  5267
      return -1;
sl@0
  5268
sl@0
  5269
    mp4free(mp4s);
sl@0
  5270
  }
sl@0
  5271
sl@0
  5272
  return 0;
sl@0
  5273
}
sl@0
  5274
sl@0
  5275
sl@0
  5276
/*
sl@0
  5277
 * Function:
sl@0
  5278
 *
sl@0
  5279
 *   mp4_i32 freeS263(h263SampleEntry *s263)
sl@0
  5280
 *
sl@0
  5281
 * Description:
sl@0
  5282
 *
sl@0
  5283
 *   This function frees memory for S263 atom.
sl@0
  5284
 *
sl@0
  5285
 * Parameters:
sl@0
  5286
 *
sl@0
  5287
 *   s263       S263 atom pointer
sl@0
  5288
 *
sl@0
  5289
 * Return value:
sl@0
  5290
 *
sl@0
  5291
 *   0          Success
sl@0
  5292
 *   Negative   Error
sl@0
  5293
 *
sl@0
  5294
 */
sl@0
  5295
mp4_i32 freeS263(h263SampleEntry *s263)
sl@0
  5296
{
sl@0
  5297
  if (s263)
sl@0
  5298
  {
sl@0
  5299
    if (freeAtomHeader(s263->atomhdr) < 0)
sl@0
  5300
      return -1;
sl@0
  5301
    if (freeD263(s263->d263) < 0)
sl@0
  5302
      return -1;
sl@0
  5303
sl@0
  5304
    mp4free(s263);
sl@0
  5305
  }
sl@0
  5306
sl@0
  5307
  return 0;
sl@0
  5308
}
sl@0
  5309
sl@0
  5310
sl@0
  5311
/*
sl@0
  5312
 * Function:
sl@0
  5313
 *
sl@0
  5314
 *   mp4_i32 freeD263(h263SpecificAtom *d263)
sl@0
  5315
 *
sl@0
  5316
 * Description:
sl@0
  5317
 *
sl@0
  5318
 *   This function frees memory for D263 atom.
sl@0
  5319
 *
sl@0
  5320
 * Parameters:
sl@0
  5321
 *
sl@0
  5322
 *   d263       D263 atom pointer
sl@0
  5323
 *
sl@0
  5324
 * Return value:
sl@0
  5325
 *
sl@0
  5326
 *   0          Success
sl@0
  5327
 *   Negative   Error
sl@0
  5328
 *
sl@0
  5329
 */
sl@0
  5330
mp4_i32 freeD263(h263SpecificAtom *d263)
sl@0
  5331
{
sl@0
  5332
  if (d263)
sl@0
  5333
  {
sl@0
  5334
    if (freeAtomHeader(d263->atomhdr) < 0)
sl@0
  5335
      return -1;
sl@0
  5336
    if (freeBITR(d263->bitr) < 0)
sl@0
  5337
      return -1;
sl@0
  5338
sl@0
  5339
    mp4free(d263);
sl@0
  5340
  }
sl@0
  5341
sl@0
  5342
  return 0;
sl@0
  5343
}
sl@0
  5344
sl@0
  5345
sl@0
  5346
/*
sl@0
  5347
 * Function:
sl@0
  5348
 *
sl@0
  5349
 *   mp4_i32 freeBITR(BitrateAtom *bitr)
sl@0
  5350
 *
sl@0
  5351
 * Description:
sl@0
  5352
 *
sl@0
  5353
 *   This function frees memory for BITR atom.
sl@0
  5354
 *
sl@0
  5355
 * Parameters:
sl@0
  5356
 *
sl@0
  5357
 *   bitr       BITR atom pointer
sl@0
  5358
 *
sl@0
  5359
 * Return value:
sl@0
  5360
 *
sl@0
  5361
 *   0          Success
sl@0
  5362
 *   Negative   Error
sl@0
  5363
 *
sl@0
  5364
 */
sl@0
  5365
mp4_i32 freeBITR(bitrateAtom *bitr)
sl@0
  5366
{
sl@0
  5367
  if (bitr)
sl@0
  5368
  {
sl@0
  5369
    if (freeAtomHeader(bitr->atomhdr) < 0)
sl@0
  5370
      return -1;
sl@0
  5371
sl@0
  5372
    mp4free(bitr);
sl@0
  5373
  }
sl@0
  5374
sl@0
  5375
  return 0;
sl@0
  5376
}
sl@0
  5377
sl@0
  5378
sl@0
  5379
/*
sl@0
  5380
 * Function:
sl@0
  5381
 *
sl@0
  5382
 *   mp4_i32 freeSAMR(amrSampleEntry *samr)
sl@0
  5383
 *
sl@0
  5384
 * Description:
sl@0
  5385
 *
sl@0
  5386
 *   This function frees memory for SAMR atom.
sl@0
  5387
 *
sl@0
  5388
 * Parameters:
sl@0
  5389
 *
sl@0
  5390
 *   samr       SAMR atom pointer
sl@0
  5391
 *
sl@0
  5392
 * Return value:
sl@0
  5393
 *
sl@0
  5394
 *   0          Success
sl@0
  5395
 *   Negative   Error
sl@0
  5396
 *
sl@0
  5397
 */
sl@0
  5398
mp4_i32 freeSAMR(amrSampleEntry *samr)
sl@0
  5399
{
sl@0
  5400
  if (samr)
sl@0
  5401
  {
sl@0
  5402
    if (freeAtomHeader(samr->atomhdr) < 0)
sl@0
  5403
      return -1;
sl@0
  5404
    if (freeDAMR(samr->damr) < 0)
sl@0
  5405
      return -1;
sl@0
  5406
sl@0
  5407
    mp4free(samr);
sl@0
  5408
  }
sl@0
  5409
sl@0
  5410
  return 0;
sl@0
  5411
}
sl@0
  5412
sl@0
  5413
sl@0
  5414
/*
sl@0
  5415
 * Function:
sl@0
  5416
 *
sl@0
  5417
 *   mp4_i32 freeSAWB(amrSampleEntry *sawb)
sl@0
  5418
 *
sl@0
  5419
 * Description:
sl@0
  5420
 *
sl@0
  5421
 *   This function frees memory for SAWB atom.
sl@0
  5422
 *
sl@0
  5423
 * Parameters:
sl@0
  5424
 *
sl@0
  5425
 *   sawb       SAWB atom pointer
sl@0
  5426
 *
sl@0
  5427
 * Return value:
sl@0
  5428
 *
sl@0
  5429
 *   0          Success
sl@0
  5430
 *   Negative   Error
sl@0
  5431
 *
sl@0
  5432
 */
sl@0
  5433
mp4_i32 freeSAWB(amrSampleEntry *sawb)
sl@0
  5434
{
sl@0
  5435
  if (sawb)
sl@0
  5436
  {
sl@0
  5437
    if (freeAtomHeader(sawb->atomhdr) < 0)
sl@0
  5438
      return -1;
sl@0
  5439
    if (freeDAMR(sawb->damr) < 0)
sl@0
  5440
      return -1;
sl@0
  5441
sl@0
  5442
    mp4free(sawb);
sl@0
  5443
  }
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 freeDAMR(amrDecSpecStruc *damr)
sl@0
  5453
 *
sl@0
  5454
 * Description:
sl@0
  5455
 *
sl@0
  5456
 *   This function frees memory for DAMR atom.
sl@0
  5457
 *
sl@0
  5458
 * Parameters:
sl@0
  5459
 *
sl@0
  5460
 *   damr       DAMR atom pointer
sl@0
  5461
 *
sl@0
  5462
 * Return value:
sl@0
  5463
 *
sl@0
  5464
 *   0          Success
sl@0
  5465
 *   Negative   Error
sl@0
  5466
 *
sl@0
  5467
 */
sl@0
  5468
mp4_i32 freeDAMR(amrDecSpecStruc *damr)
sl@0
  5469
{
sl@0
  5470
  if (damr)
sl@0
  5471
  {
sl@0
  5472
    if (freeAtomHeader(damr->atomhdr) < 0)
sl@0
  5473
      return -1;
sl@0
  5474
sl@0
  5475
    mp4free(damr);
sl@0
  5476
  }
sl@0
  5477
sl@0
  5478
  return 0;
sl@0
  5479
}
sl@0
  5480
sl@0
  5481
sl@0
  5482
/*
sl@0
  5483
 * Function:
sl@0
  5484
 *
sl@0
  5485
 *   mp4_i32 freeSTSZ(sampleSizeAtom *stsz)
sl@0
  5486
 *
sl@0
  5487
 * Description:
sl@0
  5488
 *
sl@0
  5489
 *   This function frees memory for STSZ atom.
sl@0
  5490
 *
sl@0
  5491
 * Parameters:
sl@0
  5492
 *
sl@0
  5493
 *   stsz       STSZ atom pointer
sl@0
  5494
 *
sl@0
  5495
 * Return value:
sl@0
  5496
 *
sl@0
  5497
 *   0          Success
sl@0
  5498
 *   Negative   Error
sl@0
  5499
 *
sl@0
  5500
 */
sl@0
  5501
mp4_i32 freeSTSZ(sampleSizeAtom *stsz)
sl@0
  5502
{
sl@0
  5503
  if (stsz)
sl@0
  5504
  {
sl@0
  5505
    if (freeAtomHeader(stsz->atomhdr) < 0)
sl@0
  5506
      return -1;
sl@0
  5507
    if (stsz->entrySize)
sl@0
  5508
      mp4free(stsz->entrySize);
sl@0
  5509
sl@0
  5510
    mp4free(stsz);
sl@0
  5511
  }
sl@0
  5512
sl@0
  5513
  return 0;
sl@0
  5514
}
sl@0
  5515
sl@0
  5516
sl@0
  5517
/*
sl@0
  5518
 * Function:
sl@0
  5519
 *
sl@0
  5520
 *   mp4_i32 freeSTSC(sampleToChunkAtom *stsc)
sl@0
  5521
 *
sl@0
  5522
 * Description:
sl@0
  5523
 *
sl@0
  5524
 *   This function frees memory for STSC atom.
sl@0
  5525
 *
sl@0
  5526
 * Parameters:
sl@0
  5527
 *
sl@0
  5528
 *   stsc       STSC atom pointer
sl@0
  5529
 *
sl@0
  5530
 * Return value:
sl@0
  5531
 *
sl@0
  5532
 *   0          Success
sl@0
  5533
 *   Negative   Error
sl@0
  5534
 *
sl@0
  5535
 */
sl@0
  5536
mp4_i32 freeSTSC(sampleToChunkAtom *stsc)
sl@0
  5537
{
sl@0
  5538
  if (stsc)
sl@0
  5539
  {
sl@0
  5540
    if (freeAtomHeader(stsc->atomhdr) < 0)
sl@0
  5541
      return -1;
sl@0
  5542
    if (stsc->firstChunk)
sl@0
  5543
      mp4free(stsc->firstChunk);
sl@0
  5544
    if (stsc->samplesPerChunk)
sl@0
  5545
      mp4free(stsc->samplesPerChunk);
sl@0
  5546
    if (stsc->sampleDescriptionIndex)
sl@0
  5547
      mp4free(stsc->sampleDescriptionIndex);
sl@0
  5548
sl@0
  5549
    mp4free(stsc);
sl@0
  5550
  }
sl@0
  5551
sl@0
  5552
  return 0;
sl@0
  5553
}
sl@0
  5554
sl@0
  5555
sl@0
  5556
/*
sl@0
  5557
 * Function:
sl@0
  5558
 *
sl@0
  5559
 *   mp4_i32 freeSTCO(chunkOffsetAtom *stco)
sl@0
  5560
 *
sl@0
  5561
 * Description:
sl@0
  5562
 *
sl@0
  5563
 *   This function frees memory for STCO atom.
sl@0
  5564
 *
sl@0
  5565
 * Parameters:
sl@0
  5566
 *
sl@0
  5567
 *   stco       STCO atom pointer
sl@0
  5568
 *
sl@0
  5569
 * Return value:
sl@0
  5570
 *
sl@0
  5571
 *   0          Success
sl@0
  5572
 *   Negative   Error
sl@0
  5573
 *
sl@0
  5574
 */
sl@0
  5575
mp4_i32 freeSTCO(chunkOffsetAtom *stco)
sl@0
  5576
{
sl@0
  5577
  if (stco)
sl@0
  5578
  {
sl@0
  5579
    if (freeAtomHeader(stco->atomhdr) < 0)
sl@0
  5580
      return -1;
sl@0
  5581
    if (stco->chunkOffset)
sl@0
  5582
      mp4free(stco->chunkOffset);
sl@0
  5583
sl@0
  5584
    mp4free(stco);
sl@0
  5585
  }
sl@0
  5586
sl@0
  5587
  return 0;
sl@0
  5588
}
sl@0
  5589
sl@0
  5590
/*
sl@0
  5591
 * Function:
sl@0
  5592
 *
sl@0
  5593
 *   mp4_i32 freeSTCO64(chunkOffset64Atom *stco64)
sl@0
  5594
 *
sl@0
  5595
 * Description:
sl@0
  5596
 *
sl@0
  5597
 *   This function frees memory for STCO64 atom.
sl@0
  5598
 *
sl@0
  5599
 * Parameters:
sl@0
  5600
 *
sl@0
  5601
 *   stco64       STCO64 atom pointer
sl@0
  5602
 *
sl@0
  5603
 * Return value:
sl@0
  5604
 *
sl@0
  5605
 *   0          Success
sl@0
  5606
 *   Negative   Error
sl@0
  5607
 *
sl@0
  5608
 */
sl@0
  5609
mp4_i32 freeSTCO64(chunkOffset64Atom *stco64)
sl@0
  5610
{
sl@0
  5611
  if (stco64)
sl@0
  5612
  {
sl@0
  5613
    if (freeAtomHeader(stco64->atomhdr) < 0)
sl@0
  5614
      return -1;
sl@0
  5615
    if (stco64->chunkOffset)
sl@0
  5616
      mp4free(stco64->chunkOffset);
sl@0
  5617
sl@0
  5618
    mp4free(stco64);
sl@0
  5619
  }
sl@0
  5620
sl@0
  5621
  return 0;
sl@0
  5622
}
sl@0
  5623
sl@0
  5624
sl@0
  5625
/*
sl@0
  5626
 * Function:
sl@0
  5627
 *
sl@0
  5628
 *   mp4_i32 freeSTSS(syncSampleAtom *stss)
sl@0
  5629
 *
sl@0
  5630
 * Description:
sl@0
  5631
 *
sl@0
  5632
 *   This function frees memory for STSS atom.
sl@0
  5633
 *
sl@0
  5634
 * Parameters:
sl@0
  5635
 *
sl@0
  5636
 *   stss       STSS atom pointer
sl@0
  5637
 *
sl@0
  5638
 * Return value:
sl@0
  5639
 *
sl@0
  5640
 *   0          Success
sl@0
  5641
 *   Negative   Error
sl@0
  5642
 *
sl@0
  5643
 */
sl@0
  5644
mp4_i32 freeSTSS(syncSampleAtom *stss)
sl@0
  5645
{
sl@0
  5646
  if (stss)
sl@0
  5647
  {
sl@0
  5648
    if (freeAtomHeader(stss->atomhdr) < 0)
sl@0
  5649
      return -1;
sl@0
  5650
    if (stss->sampleNumber)
sl@0
  5651
      mp4free(stss->sampleNumber);
sl@0
  5652
sl@0
  5653
    mp4free(stss);
sl@0
  5654
  }
sl@0
  5655
sl@0
  5656
  return 0;
sl@0
  5657
}
sl@0
  5658
sl@0
  5659
sl@0
  5660
/*
sl@0
  5661
 * Function:
sl@0
  5662
 *
sl@0
  5663
 *   mp4_i32 freeSTSH(shadowSyncSampleAtom *stsh)
sl@0
  5664
 *
sl@0
  5665
 * Description:
sl@0
  5666
 *
sl@0
  5667
 *   This function frees memory for STSH atom.
sl@0
  5668
 *
sl@0
  5669
 * Parameters:
sl@0
  5670
 *
sl@0
  5671
 *   stsh       STSH atom pointer
sl@0
  5672
 *
sl@0
  5673
 * Return value:
sl@0
  5674
 *
sl@0
  5675
 *   0          Success
sl@0
  5676
 *   Negative   Error
sl@0
  5677
 *
sl@0
  5678
 */
sl@0
  5679
mp4_i32 freeSTSH(shadowSyncSampleAtom *stsh)
sl@0
  5680
{
sl@0
  5681
  if (stsh)
sl@0
  5682
  {
sl@0
  5683
    if (freeAtomHeader(stsh->atomhdr) < 0)
sl@0
  5684
      return -1;
sl@0
  5685
sl@0
  5686
    mp4free(stsh);
sl@0
  5687
  }
sl@0
  5688
sl@0
  5689
  return 0;
sl@0
  5690
}
sl@0
  5691
sl@0
  5692
sl@0
  5693
/*
sl@0
  5694
 * Function:
sl@0
  5695
 *
sl@0
  5696
 *   mp4_i32 freeSDTP(sampleDependencyAtom *sdtp)
sl@0
  5697
 *
sl@0
  5698
 * Description:
sl@0
  5699
 *
sl@0
  5700
 *   This function frees memory for SDTP atom.
sl@0
  5701
 *
sl@0
  5702
 * Parameters:
sl@0
  5703
 *
sl@0
  5704
 *   sdtp       SDTP atom pointer
sl@0
  5705
 *
sl@0
  5706
 * Return value:
sl@0
  5707
 *
sl@0
  5708
 *   0          Success
sl@0
  5709
 *   Negative   Error
sl@0
  5710
 *
sl@0
  5711
 */
sl@0
  5712
mp4_i32 freeSDTP(sampleDependencyAtom *sdtp)
sl@0
  5713
	{
sl@0
  5714
	if (sdtp)
sl@0
  5715
		{
sl@0
  5716
		if (freeAtomHeader(sdtp->atomhdr) < 0)
sl@0
  5717
			{
sl@0
  5718
			return -1;
sl@0
  5719
			}
sl@0
  5720
sl@0
  5721
		if (sdtp->dep)
sl@0
  5722
			{
sl@0
  5723
			mp4free(sdtp->dep);
sl@0
  5724
			}		
sl@0
  5725
    
sl@0
  5726
		mp4free(sdtp);
sl@0
  5727
		}
sl@0
  5728
sl@0
  5729
  	return 0;
sl@0
  5730
	}
sl@0
  5731
sl@0
  5732
/*
sl@0
  5733
 * Function:
sl@0
  5734
 *
sl@0
  5735
 *   mp4_i32 freeIODS(objectDescriptorAtom *iods)
sl@0
  5736
 *
sl@0
  5737
 * Description:
sl@0
  5738
 *
sl@0
  5739
 *   This function frees memory for IODS atom.
sl@0
  5740
 *
sl@0
  5741
 * Parameters:
sl@0
  5742
 *
sl@0
  5743
 *   iods       IODS atom pointer
sl@0
  5744
 *
sl@0
  5745
 * Return value:
sl@0
  5746
 *
sl@0
  5747
 *   0          Success
sl@0
  5748
 *   Negative   Error
sl@0
  5749
 *
sl@0
  5750
 */
sl@0
  5751
mp4_i32 freeIODS(objectDescriptorAtom *iods)
sl@0
  5752
{
sl@0
  5753
  if (iods)
sl@0
  5754
  {
sl@0
  5755
    if (freeAtomHeader(iods->atomhdr) < 0)
sl@0
  5756
      return -1;
sl@0
  5757
sl@0
  5758
    mp4free(iods);
sl@0
  5759
  }
sl@0
  5760
sl@0
  5761
  return 0;
sl@0
  5762
}
sl@0
  5763
sl@0
  5764
sl@0
  5765
/*
sl@0
  5766
 * Function:
sl@0
  5767
 *
sl@0
  5768
 *   mp4_i32 readUDTA(MP4HandleImp handle,
sl@0
  5769
 *                    userDataAtom *udta)
sl@0
  5770
 *
sl@0
  5771
 * Description:
sl@0
  5772
 *
sl@0
  5773
 *   This function parses one UDTA atom.
sl@0
  5774
 *
sl@0
  5775
 * Parameters:
sl@0
  5776
 *
sl@0
  5777
 *   handle             MP4 library handle
sl@0
  5778
 *   udta               UDTA pointer
sl@0
  5779
 *
sl@0
  5780
 * Return value:
sl@0
  5781
 *
sl@0
  5782
 *   Negative integer   Error
sl@0
  5783
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  5784
 *
sl@0
  5785
 */
sl@0
  5786
mp4_i32 readUDTA(MP4HandleImp handle, userDataAtom *udta)
sl@0
  5787
{
sl@0
  5788
  mp4_i32 bytesread;
sl@0
  5789
  mp4_i32 totalbytesread = 0;
sl@0
  5790
sl@0
  5791
  if ((udta->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  5792
    return -100;
sl@0
  5793
sl@0
  5794
  bytesread = readAtomHeader(handle, udta->atomhdr);
sl@0
  5795
  if (bytesread < 0)
sl@0
  5796
    return -1;
sl@0
  5797
  totalbytesread += bytesread;
sl@0
  5798
sl@0
  5799
  if (udta->atomhdr->type != ATOMTYPE_UDTA)
sl@0
  5800
    return -1;
sl@0
  5801
sl@0
  5802
  if ( handle->file )
sl@0
  5803
      {
sl@0
  5804
      udta->atomcontentloc = handle->diskReadBufStart + handle->diskReadBufPos;
sl@0
  5805
      }
sl@0
  5806
  else
sl@0
  5807
      {
sl@0
  5808
      udta->atomcontentloc = handle->absPosition;
sl@0
  5809
      }
sl@0
  5810
sl@0
  5811
  if ( udta->atomhdr->size == 1 )
sl@0
  5812
      {
sl@0
  5813
      udta->atomcontentsize = I64INT(udta->atomhdr->largeSize) - (TInt)totalbytesread;
sl@0
  5814
      }
sl@0
  5815
  else
sl@0
  5816
      {
sl@0
  5817
      udta->atomcontentsize = (TInt)(udta->atomhdr->size - totalbytesread);
sl@0
  5818
      }
sl@0
  5819
sl@0
  5820
  if ( handle->file )
sl@0
  5821
  {
sl@0
  5822
  	if ( seekFile(handle, udta->atomhdr->size - totalbytesread) < 0 )
sl@0
  5823
  	{
sl@0
  5824
  	   return -1;	
sl@0
  5825
  	}
sl@0
  5826
  	else
sl@0
  5827
  	{
sl@0
  5828
  	   return udta->atomhdr->size;	
sl@0
  5829
  	}
sl@0
  5830
  }
sl@0
  5831
  else
sl@0
  5832
  {
sl@0
  5833
	  bytesread = discardData(handle, udta->atomhdr->size - totalbytesread);
sl@0
  5834
	  if (bytesread < 0)
sl@0
  5835
	    return -1;
sl@0
  5836
	  totalbytesread += bytesread;
sl@0
  5837
  }
sl@0
  5838
  return totalbytesread;
sl@0
  5839
}
sl@0
  5840
sl@0
  5841
/*
sl@0
  5842
 * Function:
sl@0
  5843
 *
sl@0
  5844
 *   mp4_i32 freeUDTA(userDataAtom *udta)
sl@0
  5845
 *
sl@0
  5846
 * Description:
sl@0
  5847
 *
sl@0
  5848
 *   This function frees memory for UDTA atom.
sl@0
  5849
 *
sl@0
  5850
 * Parameters:
sl@0
  5851
 *
sl@0
  5852
 *   udta       UDTA atom pointer
sl@0
  5853
 *
sl@0
  5854
 * Return value:
sl@0
  5855
 *
sl@0
  5856
 *   0          Success
sl@0
  5857
 *   Negative   Error
sl@0
  5858
 *
sl@0
  5859
 */
sl@0
  5860
mp4_i32 freeUDTA(userDataAtom *udta)
sl@0
  5861
{
sl@0
  5862
  if (udta)
sl@0
  5863
  {
sl@0
  5864
    if (freeAtomHeader(udta->atomhdr) < 0)
sl@0
  5865
      return -1;
sl@0
  5866
    mp4free(udta);
sl@0
  5867
  }
sl@0
  5868
sl@0
  5869
  return 0;
sl@0
  5870
}
sl@0
  5871
sl@0
  5872
sl@0
  5873
/*
sl@0
  5874
 * Function:
sl@0
  5875
 *
sl@0
  5876
 *   mp4_i32 determineVideoLength(MP4HandleImp handle,
sl@0
  5877
 *                                mp4_u32 *videolength)
sl@0
  5878
 *
sl@0
  5879
 * Description:
sl@0
  5880
 *
sl@0
  5881
 *   This function determines the length of video in milliseconds.
sl@0
  5882
 *
sl@0
  5883
 * Parameters:
sl@0
  5884
 *
sl@0
  5885
 *   handle       MP4 library handle
sl@0
  5886
 *   videolength  Video length is returned here
sl@0
  5887
 *
sl@0
  5888
 * Return value:
sl@0
  5889
 *
sl@0
  5890
 *   0            Success
sl@0
  5891
 *   Negative     Error
sl@0
  5892
 *
sl@0
  5893
 */
sl@0
  5894
mp4_i32 determineVideoLength(MP4HandleImp handle, mp4_u32 *videolength)
sl@0
  5895
{
sl@0
  5896
  if (!handle->moov)
sl@0
  5897
    return -1;
sl@0
  5898
sl@0
  5899
  if (!handle->moov->mvhd)
sl@0
  5900
    return -1;
sl@0
  5901
sl@0
  5902
  if (!handle->moov->trakVideo)
sl@0
  5903
    return -1;
sl@0
  5904
sl@0
  5905
  if (!handle->moov->trakVideo->tkhd)
sl@0
  5906
    return -1;
sl@0
  5907
sl@0
  5908
  /* Is timescale set? */
sl@0
  5909
  if (handle->moov->mvhd->timeScale == 0)
sl@0
  5910
    return -1;
sl@0
  5911
sl@0
  5912
  *videolength = (mp4_u32)(((mp4_double)handle->moov->trakVideo->tkhd->duration / (mp4_double)handle->moov->mvhd->timeScale) * (mp4_double)1000);
sl@0
  5913
sl@0
  5914
  return 0;
sl@0
  5915
}
sl@0
  5916
sl@0
  5917
sl@0
  5918
/*
sl@0
  5919
 * Function:
sl@0
  5920
 *
sl@0
  5921
 *   mp4_i32 determineFrameRate(MP4HandleImp handle,
sl@0
  5922
 *                              mp4_double *framerate)
sl@0
  5923
 *
sl@0
  5924
 * Description:
sl@0
  5925
 *
sl@0
  5926
 *   This function determines the frame rate of video.
sl@0
  5927
 *
sl@0
  5928
 *   Frame rate is calculated as the average frame rate of the entire video.
sl@0
  5929
 *
sl@0
  5930
 * Parameters:
sl@0
  5931
 *
sl@0
  5932
 *   handle     MP4 library handle
sl@0
  5933
 *   framerate  Frame rate is returned here
sl@0
  5934
 *
sl@0
  5935
 * Return value:
sl@0
  5936
 *
sl@0
  5937
 *   0          Success
sl@0
  5938
 *   Negative   Error
sl@0
  5939
 *
sl@0
  5940
 */
sl@0
  5941
mp4_i32 determineFrameRate(MP4HandleImp handle, mp4_double *framerate)
sl@0
  5942
{
sl@0
  5943
  mp4_double numberofframes;
sl@0
  5944
  mp4_double length;
sl@0
  5945
sl@0
  5946
sl@0
  5947
  if (!handle)
sl@0
  5948
    return -1;
sl@0
  5949
  if (!handle->moov)
sl@0
  5950
    return -1;
sl@0
  5951
  if (!handle->moov->trakVideo)
sl@0
  5952
    return -1;
sl@0
  5953
  if (!handle->moov->trakVideo->mdia)
sl@0
  5954
    return -1;
sl@0
  5955
  if (!handle->moov->trakVideo->mdia->minf)
sl@0
  5956
    return -1;
sl@0
  5957
  if (!handle->moov->trakVideo->mdia->minf->stbl)
sl@0
  5958
    return -1;
sl@0
  5959
  if (!handle->moov->trakVideo->mdia->minf->stbl->stsz)
sl@0
  5960
    return -1;
sl@0
  5961
  if (!handle->moov->trakVideo->mdia->mdhd)
sl@0
  5962
    return -1;
sl@0
  5963
sl@0
  5964
sl@0
  5965
  	if (handle->moov->trakVideo->mdia->mdhd->timeScale == 0)
sl@0
  5966
    	return -1;
sl@0
  5967
  	
sl@0
  5968
  	if (handle->moov->trakVideo->mdia->mdhd->duration == 0)
sl@0
  5969
  		{
sl@0
  5970
  		*framerate = 0;
sl@0
  5971
  		}
sl@0
  5972
	else
sl@0
  5973
		{
sl@0
  5974
  		numberofframes = (mp4_double)handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount;
sl@0
  5975
  		length = (mp4_double)handle->moov->trakVideo->mdia->mdhd->duration /
sl@0
  5976
           		 (mp4_double)handle->moov->trakVideo->mdia->mdhd->timeScale;
sl@0
  5977
sl@0
  5978
  		*framerate = numberofframes / length;			
sl@0
  5979
		}    
sl@0
  5980
sl@0
  5981
  	return 0;
sl@0
  5982
	}
sl@0
  5983
sl@0
  5984
sl@0
  5985
/*
sl@0
  5986
 * Function:
sl@0
  5987
 *
sl@0
  5988
 *   mp4_i32 determineVideoType(MP4HandleImp handle,
sl@0
  5989
 *                              mp4_u32 *videotype)
sl@0
  5990
 *
sl@0
  5991
 * Description:
sl@0
  5992
 *
sl@0
  5993
 *   This function determines the video type of the MP4.
sl@0
  5994
 *
sl@0
  5995
 * Parameters:
sl@0
  5996
 *
sl@0
  5997
 *   handle     MP4 library handle
sl@0
  5998
 *   videotype  Video type is returned here
sl@0
  5999
 *
sl@0
  6000
 * Return value:
sl@0
  6001
 *
sl@0
  6002
 *   0          Success
sl@0
  6003
 *   -1			Error
sl@0
  6004
 *	 -2			Unknown video type
sl@0
  6005
 *
sl@0
  6006
 */
sl@0
  6007
mp4_i32 determineVideoType(MP4HandleImp handle, mp4_u32 *videotype)
sl@0
  6008
{
sl@0
  6009
  *videotype = MP4_TYPE_NONE;
sl@0
  6010
sl@0
  6011
  if (!handle->moov)
sl@0
  6012
    return -1;
sl@0
  6013
sl@0
  6014
  if (!handle->moov->trakVideo)
sl@0
  6015
    return -1;
sl@0
  6016
sl@0
  6017
  if (!handle->moov->trakVideo->mdia)
sl@0
  6018
    return -1;
sl@0
  6019
sl@0
  6020
  if (!handle->moov->trakVideo->mdia->minf)
sl@0
  6021
    return -1;
sl@0
  6022
sl@0
  6023
  if (!handle->moov->trakVideo->mdia->minf->stbl)
sl@0
  6024
    return -1;
sl@0
  6025
sl@0
  6026
  if (!handle->moov->trakVideo->mdia->minf->stbl->stsd)
sl@0
  6027
    return -1;
sl@0
  6028
  
sl@0
  6029
  if (handle->moov->trakVideo->mdia->minf->stbl->stsd->entryCount == 0)
sl@0
  6030
    return -1;  
sl@0
  6031
sl@0
  6032
/* Assume that the video type is the same for all sample entries. Just get the video type from the first one */
sl@0
  6033
sl@0
  6034
  if (handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0])
sl@0
  6035
  {
sl@0
  6036
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0]->esd)
sl@0
  6037
      return -1;
sl@0
  6038
sl@0
  6039
    if ((handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0]->esd->objectTypeIndication == 0x20) &&
sl@0
  6040
        ((handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0]->esd->stream >> 2) == 0x04))
sl@0
  6041
      *videotype = MP4_TYPE_MPEG4_VIDEO;
sl@0
  6042
  }
sl@0
  6043
  else
sl@0
  6044
  if (handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0])
sl@0
  6045
  {
sl@0
  6046
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->d263)
sl@0
  6047
      return -1;
sl@0
  6048
sl@0
  6049
    switch (handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->d263->h263Profile)
sl@0
  6050
    {
sl@0
  6051
    case 0:
sl@0
  6052
      *videotype = MP4_TYPE_H263_PROFILE_0;
sl@0
  6053
      break;
sl@0
  6054
    case 3:
sl@0
  6055
      *videotype = MP4_TYPE_H263_PROFILE_3;
sl@0
  6056
      break;
sl@0
  6057
    default:
sl@0
  6058
      break;
sl@0
  6059
    }
sl@0
  6060
  }
sl@0
  6061
  else
sl@0
  6062
   if (handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0])
sl@0
  6063
   {
sl@0
  6064
	   if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc)
sl@0
  6065
		   return -1;
sl@0
  6066
sl@0
  6067
	   if (handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfigSize == 0)
sl@0
  6068
		   return -1;
sl@0
  6069
sl@0
  6070
	   /* AVC profile is in the second byte of the avcconfigrecord */
sl@0
  6071
	   switch((mp4_u8)handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfig[1]) 
sl@0
  6072
	   {
sl@0
  6073
	   case 66:
sl@0
  6074
		   *videotype = MP4_TYPE_AVC_PROFILE_BASELINE;
sl@0
  6075
		   break;
sl@0
  6076
	   case 77:
sl@0
  6077
		   *videotype = MP4_TYPE_AVC_PROFILE_MAIN;
sl@0
  6078
		   break;
sl@0
  6079
	   case 88:
sl@0
  6080
		   *videotype = MP4_TYPE_AVC_PROFILE_EXTENDED;
sl@0
  6081
		   break;
sl@0
  6082
       case 100:
sl@0
  6083
          *videotype = MP4_TYPE_AVC_PROFILE_HIGH;
sl@0
  6084
           break;
sl@0
  6085
	   default:
sl@0
  6086
		   {
sl@0
  6087
		   mp4_u8 constraintByte = (mp4_u8)handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->avcc->avcConfig[2];
sl@0
  6088
		   if ( (constraintByte & 0x80) || (constraintByte & 0x10) )
sl@0
  6089
			   {
sl@0
  6090
			   *videotype = MP4_TYPE_AVC_PROFILE_BASELINE;	
sl@0
  6091
			   }
sl@0
  6092
		   else if (constraintByte & 0x40)
sl@0
  6093
			   {
sl@0
  6094
			   *videotype = MP4_TYPE_AVC_PROFILE_MAIN;	
sl@0
  6095
			   }
sl@0
  6096
		   else if (constraintByte & 0x20)
sl@0
  6097
			   {
sl@0
  6098
			   *videotype = MP4_TYPE_AVC_PROFILE_EXTENDED;
sl@0
  6099
			   }
sl@0
  6100
		   // NOTE: Cannot reliably determine higher profiles from
sl@0
  6101
		   // the constraint flags.
sl@0
  6102
		   break;	   	
sl@0
  6103
		   }
sl@0
  6104
	   }
sl@0
  6105
	}
sl@0
  6106
   else
sl@0
  6107
       {}
sl@0
  6108
   /* Note: Read the AVC level and recreate the actual AVC profile and level in the future! */
sl@0
  6109
  if (*videotype == MP4_TYPE_NONE)
sl@0
  6110
    return -2;
sl@0
  6111
sl@0
  6112
  return 0;
sl@0
  6113
}
sl@0
  6114
sl@0
  6115
sl@0
  6116
/*
sl@0
  6117
 * Function:
sl@0
  6118
 *
sl@0
  6119
 *   mp4_i32 determineVideoResolution(MP4HandleImp handle,
sl@0
  6120
 *                                    mp4_u32 *videowidth,
sl@0
  6121
 *                                    mp4_u32 *videoheight)
sl@0
  6122
 *
sl@0
  6123
 * Description:
sl@0
  6124
 *
sl@0
  6125
 *   This function finds out the video width and height from the atom
sl@0
  6126
 *   structure.
sl@0
  6127
 *
sl@0
  6128
 * Parameters:
sl@0
  6129
 *
sl@0
  6130
 *   handle       MP4 library handle
sl@0
  6131
 *   videowidth   Video width is returned here
sl@0
  6132
 *   videoheight  Video height is returned here
sl@0
  6133
 *
sl@0
  6134
 * Return value:
sl@0
  6135
 *
sl@0
  6136
 *   0            Success
sl@0
  6137
 *   Negative     Error
sl@0
  6138
 *
sl@0
  6139
 */
sl@0
  6140
mp4_i32 determineVideoResolution(MP4HandleImp handle, mp4_u32 *videowidth, mp4_u32 *videoheight)
sl@0
  6141
{
sl@0
  6142
  mp4_u32 videotype = MP4_TYPE_NONE;
sl@0
  6143
sl@0
  6144
sl@0
  6145
  if (determineVideoType(handle, &videotype) < 0)
sl@0
  6146
    return -1;
sl@0
  6147
sl@0
  6148
  if (videotype == MP4_TYPE_NONE)
sl@0
  6149
    return -1;
sl@0
  6150
sl@0
  6151
  if (!handle->moov)
sl@0
  6152
    return -1;
sl@0
  6153
sl@0
  6154
  if (!handle->moov->trakVideo)
sl@0
  6155
    return -1;
sl@0
  6156
sl@0
  6157
  if (!handle->moov->trakVideo->mdia)
sl@0
  6158
    return -1;
sl@0
  6159
sl@0
  6160
  if (!handle->moov->trakVideo->mdia->minf)
sl@0
  6161
    return -1;
sl@0
  6162
sl@0
  6163
  if (!handle->moov->trakVideo->mdia->minf->stbl)
sl@0
  6164
    return -1;
sl@0
  6165
sl@0
  6166
  if (!handle->moov->trakVideo->mdia->minf->stbl->stsd)
sl@0
  6167
    return -1;
sl@0
  6168
sl@0
  6169
  if (handle->moov->trakVideo->mdia->minf->stbl->stsd->entryCount == 0)
sl@0
  6170
    return -1;  
sl@0
  6171
  
sl@0
  6172
/* Assume that the video characteristics for all the video sample entries are the same. Just get them from the first one */
sl@0
  6173
sl@0
  6174
  if (videotype == MP4_TYPE_H263_PROFILE_0 ||
sl@0
  6175
      videotype == MP4_TYPE_H263_PROFILE_3)
sl@0
  6176
  {
sl@0
  6177
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0])
sl@0
  6178
      return -1;
sl@0
  6179
sl@0
  6180
    *videowidth  = handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->width;
sl@0
  6181
    *videoheight = handle->moov->trakVideo->mdia->minf->stbl->stsd->s263[0]->height;
sl@0
  6182
  }
sl@0
  6183
  else if (videotype == MP4_TYPE_MPEG4_VIDEO)
sl@0
  6184
  {
sl@0
  6185
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0])
sl@0
  6186
      return -1;
sl@0
  6187
sl@0
  6188
    *videowidth  = handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0]->width;
sl@0
  6189
    *videoheight = handle->moov->trakVideo->mdia->minf->stbl->stsd->mp4v[0]->height;
sl@0
  6190
  }
sl@0
  6191
  else if ( isAvcVideo(videotype) )
sl@0
  6192
  {
sl@0
  6193
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0])
sl@0
  6194
      return -1;
sl@0
  6195
sl@0
  6196
    *videowidth  = handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->width;
sl@0
  6197
    *videoheight = handle->moov->trakVideo->mdia->minf->stbl->stsd->avc1[0]->height;
sl@0
  6198
  }
sl@0
  6199
  else
sl@0
  6200
  {
sl@0
  6201
  }
sl@0
  6202
sl@0
  6203
  return 0;
sl@0
  6204
}
sl@0
  6205
sl@0
  6206
sl@0
  6207
/*
sl@0
  6208
 * Function:
sl@0
  6209
 *
sl@0
  6210
 *   mp4_i32 determineVideoTimeScale(MP4HandleImp handle,
sl@0
  6211
 *                                   mp4_u32 *timescale)
sl@0
  6212
 *
sl@0
  6213
 * Description:
sl@0
  6214
 *
sl@0
  6215
 *   This function determines the timescale of video track.
sl@0
  6216
 *
sl@0
  6217
 * Parameters:
sl@0
  6218
 *
sl@0
  6219
 *   handle     MP4 library handle
sl@0
  6220
 *   timescale  Timescale of video track is returned here
sl@0
  6221
 *
sl@0
  6222
 * Return value:
sl@0
  6223
 *
sl@0
  6224
 *   0          Success
sl@0
  6225
 *   Negative   Error
sl@0
  6226
 *
sl@0
  6227
 */
sl@0
  6228
mp4_i32 determineVideoTimeScale(MP4HandleImp handle, mp4_u32 *timescale)
sl@0
  6229
{
sl@0
  6230
  if (timescale == NULL)
sl@0
  6231
    return 0;
sl@0
  6232
sl@0
  6233
  if (!handle)
sl@0
  6234
    return -1;
sl@0
  6235
  if (!handle->moov)
sl@0
  6236
    return -1;
sl@0
  6237
  if (!handle->moov->trakVideo)
sl@0
  6238
    return -1;
sl@0
  6239
  if (!handle->moov->trakVideo->mdia)
sl@0
  6240
    return -1;
sl@0
  6241
  if (!handle->moov->trakVideo->mdia->mdhd)
sl@0
  6242
    return -1;
sl@0
  6243
  if (handle->moov->trakVideo->mdia->mdhd->timeScale == 0)
sl@0
  6244
    return -1;
sl@0
  6245
sl@0
  6246
  *timescale = handle->moov->trakVideo->mdia->mdhd->timeScale;
sl@0
  6247
sl@0
  6248
  return 0;
sl@0
  6249
}
sl@0
  6250
sl@0
  6251
sl@0
  6252
/*
sl@0
  6253
 * Function:
sl@0
  6254
 *
sl@0
  6255
 *   mp4_i32 determineAudioLength(MP4HandleImp handle,
sl@0
  6256
 *                                mp4_u32 *audiolength)
sl@0
  6257
 *
sl@0
  6258
 * Description:
sl@0
  6259
 *
sl@0
  6260
 *   This function determines the length of audio in milliseconds.
sl@0
  6261
 *
sl@0
  6262
 * Parameters:
sl@0
  6263
 *
sl@0
  6264
 *   handle       MP4 library handle
sl@0
  6265
 *   audiolength  Audio length is returned here
sl@0
  6266
 *
sl@0
  6267
 * Return value:
sl@0
  6268
 *
sl@0
  6269
 *   0            Success
sl@0
  6270
 *   Negative     Error
sl@0
  6271
 *
sl@0
  6272
 */
sl@0
  6273
mp4_i32 determineAudioLength(MP4HandleImp handle, mp4_u32 *audiolength)
sl@0
  6274
{
sl@0
  6275
  if (!handle->moov)
sl@0
  6276
    return -1;
sl@0
  6277
sl@0
  6278
  if (!handle->moov->mvhd)
sl@0
  6279
    return -1;
sl@0
  6280
sl@0
  6281
  if (!handle->moov->trakAudio)
sl@0
  6282
    return -1;
sl@0
  6283
sl@0
  6284
  if (!handle->moov->trakAudio->tkhd)
sl@0
  6285
    return -1;
sl@0
  6286
sl@0
  6287
  /* Is timescale set? */
sl@0
  6288
  if (handle->moov->mvhd->timeScale == 0)
sl@0
  6289
    return -1;
sl@0
  6290
sl@0
  6291
  *audiolength = (mp4_u32)(((mp4_double)handle->moov->trakAudio->tkhd->duration / (mp4_double)handle->moov->mvhd->timeScale) * (mp4_double)1000);
sl@0
  6292
sl@0
  6293
  return 0;
sl@0
  6294
}
sl@0
  6295
sl@0
  6296
sl@0
  6297
/*
sl@0
  6298
 * Function:
sl@0
  6299
 *
sl@0
  6300
 *   mp4_i32 determineAudioType(MP4HandleImp handle,
sl@0
  6301
 *                              mp4_u32 *audiotype)
sl@0
  6302
 *
sl@0
  6303
 * Description:
sl@0
  6304
 *
sl@0
  6305
 *   This function determines the audio type of the MP4.
sl@0
  6306
 *
sl@0
  6307
 * Parameters:
sl@0
  6308
 *
sl@0
  6309
 *   handle     MP4 library handle
sl@0
  6310
 *   audiotype  Audio type is returned here
sl@0
  6311
 *
sl@0
  6312
 * Return value:
sl@0
  6313
 *
sl@0
  6314
 *   0          Success
sl@0
  6315
 *   -1   		Error
sl@0
  6316
 *   -2			Unknown audiotrack
sl@0
  6317
 *
sl@0
  6318
 */
sl@0
  6319
mp4_i32 determineAudioType(MP4HandleImp handle, mp4_u32 *audiotype)
sl@0
  6320
{
sl@0
  6321
  *audiotype = MP4_TYPE_NONE;
sl@0
  6322
sl@0
  6323
sl@0
  6324
  if (!handle->moov)
sl@0
  6325
    return -1;
sl@0
  6326
sl@0
  6327
  if (!handle->moov->trakAudio)
sl@0
  6328
    return -1;
sl@0
  6329
sl@0
  6330
  if (!handle->moov->trakAudio->mdia)
sl@0
  6331
    return -1;
sl@0
  6332
sl@0
  6333
  if (!handle->moov->trakAudio->mdia->minf)
sl@0
  6334
    return -1;
sl@0
  6335
sl@0
  6336
  if (!handle->moov->trakAudio->mdia->minf->stbl)
sl@0
  6337
    return -1;
sl@0
  6338
sl@0
  6339
  if (!handle->moov->trakAudio->mdia->minf->stbl->stsd)
sl@0
  6340
    return -1;
sl@0
  6341
  
sl@0
  6342
  if (handle->moov->trakAudio->mdia->minf->stbl->stsd->entryCount == 0)
sl@0
  6343
    return -1;  
sl@0
  6344
sl@0
  6345
/* Assume that the audio type is the same for all sample entries. Just get the audio type from the first one */
sl@0
  6346
  if (handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0])
sl@0
  6347
  {
sl@0
  6348
    if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0]->esd)
sl@0
  6349
      return -1;
sl@0
  6350
sl@0
  6351
    if ((handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0]->esd->objectTypeIndication == 0x40) &&
sl@0
  6352
        ((handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0]->esd->stream >> 2) == 0x05))
sl@0
  6353
      *audiotype = MP4_TYPE_MPEG4_AUDIO;
sl@0
  6354
sl@0
  6355
   if ((handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0]->esd->objectTypeIndication == 0xE1) &&
sl@0
  6356
     ((handle->moov->trakAudio->mdia->minf->stbl->stsd->mp4a[0]->esd->stream >> 2) == 0x05))  
sl@0
  6357
   {
sl@0
  6358
      *audiotype = MP4_TYPE_QCELP_13K;
sl@0
  6359
      handle->qcelpStoredAsMPEGAudio = MP4TRUE;
sl@0
  6360
   }
sl@0
  6361
  }
sl@0
  6362
  else if (handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[0])
sl@0
  6363
    *audiotype = MP4_TYPE_AMR_NB;
sl@0
  6364
  else if (handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[0])
sl@0
  6365
    *audiotype = MP4_TYPE_AMR_WB;
sl@0
  6366
  else if (handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[0])
sl@0
  6367
  {
sl@0
  6368
    *audiotype = MP4_TYPE_QCELP_13K;
sl@0
  6369
    handle->qcelpStoredAsMPEGAudio = MP4FALSE;
sl@0
  6370
  }
sl@0
  6371
  else
sl@0
  6372
  {
sl@0
  6373
  }
sl@0
  6374
sl@0
  6375
  if (*audiotype == MP4_TYPE_NONE)
sl@0
  6376
    return -2;
sl@0
  6377
sl@0
  6378
  return 0;
sl@0
  6379
}
sl@0
  6380
sl@0
  6381
sl@0
  6382
/*
sl@0
  6383
 * Function:
sl@0
  6384
 *
sl@0
  6385
 *   mp4_i32 determineAudioFramesPerSample(MP4HandleImp handle,
sl@0
  6386
 *                                         mp4_u8 *framespersample)
sl@0
  6387
 *
sl@0
  6388
 * Description:
sl@0
  6389
 *
sl@0
  6390
 *   This function determines the number of audio frames in each sample.
sl@0
  6391
 *   The function works with AMR audio type only.
sl@0
  6392
 *
sl@0
  6393
 * Parameters:
sl@0
  6394
 *
sl@0
  6395
 *   handle           MP4 library handle
sl@0
  6396
 *   framespersample  Number of frames in each sample
sl@0
  6397
 *
sl@0
  6398
 * Return value:
sl@0
  6399
 *
sl@0
  6400
 *   0                Success
sl@0
  6401
 *   Negative         Error
sl@0
  6402
 *
sl@0
  6403
 */
sl@0
  6404
mp4_i32 determineAudioFramesPerSample(MP4HandleImp handle, mp4_u8 *framespersample)
sl@0
  6405
{
sl@0
  6406
  mp4_i8 sampleentryindex;
sl@0
  6407
  
sl@0
  6408
  *framespersample = 0;
sl@0
  6409
sl@0
  6410
sl@0
  6411
  if (!((handle->type & MP4_TYPE_AMR_NB) ||
sl@0
  6412
        (handle->type & MP4_TYPE_AMR_WB) ||
sl@0
  6413
        ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio))))
sl@0
  6414
  {
sl@0
  6415
    *framespersample = 1;
sl@0
  6416
sl@0
  6417
    return 0;
sl@0
  6418
  }
sl@0
  6419
sl@0
  6420
sl@0
  6421
  if (!handle->moov)
sl@0
  6422
    return -1;
sl@0
  6423
sl@0
  6424
  if (!handle->moov->trakAudio)
sl@0
  6425
    return -1;
sl@0
  6426
sl@0
  6427
  if (!handle->moov->trakAudio->mdia)
sl@0
  6428
    return -1;
sl@0
  6429
sl@0
  6430
  if (!handle->moov->trakAudio->mdia->minf)
sl@0
  6431
    return -1;
sl@0
  6432
sl@0
  6433
  if (!handle->moov->trakAudio->mdia->minf->stbl)
sl@0
  6434
    return -1;
sl@0
  6435
sl@0
  6436
  if (!handle->moov->trakAudio->mdia->minf->stbl->stsd)
sl@0
  6437
    return -1;
sl@0
  6438
sl@0
  6439
  if (handle->type & MP4_TYPE_AMR_NB)
sl@0
  6440
  {
sl@0
  6441
/* Now, framespersample returns the maximum frames_per_sample listed in the AMR sample entries*/
sl@0
  6442
	for (sampleentryindex = 0; (mp4_u8) sampleentryindex < handle->moov->trakAudio->mdia->minf->stbl->stsd->entryCount; sampleentryindex++)
sl@0
  6443
	{
sl@0
  6444
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[sampleentryindex])
sl@0
  6445
		  return -1;
sl@0
  6446
sl@0
  6447
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[sampleentryindex]->damr)
sl@0
  6448
		  return -1;
sl@0
  6449
sl@0
  6450
		if (*framespersample < handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[sampleentryindex]->damr->framesPerSample)
sl@0
  6451
			*framespersample = handle->moov->trakAudio->mdia->minf->stbl->stsd->samr[sampleentryindex]->damr->framesPerSample;
sl@0
  6452
	}
sl@0
  6453
  }
sl@0
  6454
  else if (handle->type & MP4_TYPE_AMR_WB)
sl@0
  6455
  {
sl@0
  6456
/* Now, framespersample returns the maximum frames_per_sample listed in the AMR sample entries*/
sl@0
  6457
	for (sampleentryindex = 0; (mp4_u8)sampleentryindex < handle->moov->trakAudio->mdia->minf->stbl->stsd->entryCount; sampleentryindex++)
sl@0
  6458
	{
sl@0
  6459
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[sampleentryindex])
sl@0
  6460
		  return -1;
sl@0
  6461
sl@0
  6462
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[sampleentryindex]->damr)
sl@0
  6463
		  return -1;
sl@0
  6464
sl@0
  6465
		if (*framespersample < handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[sampleentryindex]->damr->framesPerSample)
sl@0
  6466
 		  *framespersample = handle->moov->trakAudio->mdia->minf->stbl->stsd->sawb[sampleentryindex]->damr->framesPerSample;
sl@0
  6467
	}
sl@0
  6468
  }
sl@0
  6469
  else if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio))
sl@0
  6470
  {
sl@0
  6471
/* Now, framespersample returns the maximum frames_per_sample listed in the QCELP-13K sample entries*/
sl@0
  6472
	for (sampleentryindex = 0; (mp4_u8)sampleentryindex < handle->moov->trakAudio->mdia->minf->stbl->stsd->entryCount; sampleentryindex++)
sl@0
  6473
	{
sl@0
  6474
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[sampleentryindex])
sl@0
  6475
		  return -1;
sl@0
  6476
sl@0
  6477
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[sampleentryindex]->dqcp)
sl@0
  6478
		  return -1;
sl@0
  6479
sl@0
  6480
		if (*framespersample < handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[sampleentryindex]->dqcp->framesPerSample)
sl@0
  6481
		  *framespersample = handle->moov->trakAudio->mdia->minf->stbl->stsd->sqcp[sampleentryindex]->dqcp->framesPerSample;
sl@0
  6482
	}
sl@0
  6483
  }
sl@0
  6484
  else
sl@0
  6485
  {
sl@0
  6486
  }
sl@0
  6487
sl@0
  6488
  return 0;
sl@0
  6489
}
sl@0
  6490
sl@0
  6491
sl@0
  6492
/*
sl@0
  6493
 * Function:
sl@0
  6494
 *
sl@0
  6495
 *   mp4_i32 determineAudioTimeScale(MP4HandleImp handle,
sl@0
  6496
 *                                   mp4_u32 *timescale)
sl@0
  6497
 *
sl@0
  6498
 * Description:
sl@0
  6499
 *
sl@0
  6500
 *   This function determines the timescale of audio track.
sl@0
  6501
 *
sl@0
  6502
 * Parameters:
sl@0
  6503
 *
sl@0
  6504
 *   handle     MP4 library handle
sl@0
  6505
 *   timescale  Timescale of audio track is returned here
sl@0
  6506
 *
sl@0
  6507
 * Return value:
sl@0
  6508
 *
sl@0
  6509
 *   0          Success
sl@0
  6510
 *   Negative   Error
sl@0
  6511
 *
sl@0
  6512
 */
sl@0
  6513
mp4_i32 determineAudioTimeScale(MP4HandleImp handle, mp4_u32 *timescale)
sl@0
  6514
{
sl@0
  6515
  if (timescale == NULL)
sl@0
  6516
    return 0;
sl@0
  6517
sl@0
  6518
  if (!handle)
sl@0
  6519
    return -1;
sl@0
  6520
  if (!handle->moov)
sl@0
  6521
    return -1;
sl@0
  6522
  if (!handle->moov->trakAudio)
sl@0
  6523
    return -1;
sl@0
  6524
  if (!handle->moov->trakAudio->mdia)
sl@0
  6525
    return -1;
sl@0
  6526
  if (!handle->moov->trakAudio->mdia->mdhd)
sl@0
  6527
    return -1;
sl@0
  6528
sl@0
  6529
sl@0
  6530
  if (handle->moov->trakAudio->mdia->mdhd->timeScale == 0)
sl@0
  6531
    return -1;
sl@0
  6532
sl@0
  6533
  *timescale = handle->moov->trakAudio->mdia->mdhd->timeScale;
sl@0
  6534
sl@0
  6535
  return 0;
sl@0
  6536
}
sl@0
  6537
sl@0
  6538
sl@0
  6539
/*
sl@0
  6540
 * Function:
sl@0
  6541
 *
sl@0
  6542
 *   mp4_i32 determineAudioAverageBitRate(MP4HandleImp handle,
sl@0
  6543
 *                                        mp4_u32 *averagebitrate)
sl@0
  6544
 *
sl@0
  6545
 * Description:
sl@0
  6546
 *
sl@0
  6547
 *   This function determines the average bitrate of the audio in bits per
sl@0
  6548
 *   second.
sl@0
  6549
 *
sl@0
  6550
 *   The average is calculated so that the audio data length is divided by
sl@0
  6551
 *   the length of the  audio track.
sl@0
  6552
 *
sl@0
  6553
 * Parameters:
sl@0
  6554
 *
sl@0
  6555
 *   handle                MP4 library handle
sl@0
  6556
 *   averagebitrate        Result is returned here
sl@0
  6557
 *
sl@0
  6558
 * Return value:
sl@0
  6559
 *
sl@0
  6560
 *   0           Success
sl@0
  6561
 *   Negative    Error
sl@0
  6562
 *
sl@0
  6563
 */
sl@0
  6564
mp4_i32 determineAudioAverageBitRate(MP4HandleImp handle, mp4_u32 *averagebitrate)
sl@0
  6565
	{
sl@0
  6566
	mp4_u32 audiosize = 0;
sl@0
  6567
sl@0
  6568
  	if (!handle->moov)
sl@0
  6569
  		{
sl@0
  6570
  		return -1;	
sl@0
  6571
  		}
sl@0
  6572
    	
sl@0
  6573
  	if (handle->moov->trakAudio)
sl@0
  6574
  		{
sl@0
  6575
		if (!handle->moov->trakAudio->mdia)
sl@0
  6576
			{
sl@0
  6577
			return -1;		
sl@0
  6578
			}
sl@0
  6579
					
sl@0
  6580
		if (!handle->moov->trakAudio->mdia->minf)
sl@0
  6581
			{
sl@0
  6582
			return -1;	
sl@0
  6583
			}
sl@0
  6584
		
sl@0
  6585
		if (!handle->moov->trakAudio->mdia->minf->stbl)
sl@0
  6586
			{
sl@0
  6587
			return -1;				
sl@0
  6588
			}
sl@0
  6589
sl@0
  6590
		if (!handle->moov->trakAudio->mdia->minf->stbl->stsz)
sl@0
  6591
			{
sl@0
  6592
			return -1;				
sl@0
  6593
			}
sl@0
  6594
sl@0
  6595
		if (handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleSize != 0)
sl@0
  6596
			{
sl@0
  6597
			audiosize += (handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleCount *
sl@0
  6598
	                   	 handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleSize);			
sl@0
  6599
			}
sl@0
  6600
	    else
sl@0
  6601
	    	{
sl@0
  6602
	      	mp4_u32 i;
sl@0
  6603
	      	for (i = 0; i < handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleCount; i++)
sl@0
  6604
	      		{
sl@0
  6605
	        	audiosize += handle->moov->trakAudio->mdia->minf->stbl->stsz->entrySize[i];      			
sl@0
  6606
	      		}
sl@0
  6607
	    	}
sl@0
  6608
	  	}
sl@0
  6609
	else
sl@0
  6610
		{
sl@0
  6611
		return -1;  		
sl@0
  6612
		}
sl@0
  6613
sl@0
  6614
  	if (!handle->moov->trakAudio->mdia->mdhd)
sl@0
  6615
  		{
sl@0
  6616
    	return -1;  			
sl@0
  6617
  		}
sl@0
  6618
  	
sl@0
  6619
  	if (!handle->moov->trakAudio->mdia->mdhd->timeScale)
sl@0
  6620
  		{
sl@0
  6621
		return -1;  			
sl@0
  6622
  		}
sl@0
  6623
sl@0
  6624
  	if (handle->moov->trakAudio->mdia->mdhd->duration == 0)
sl@0
  6625
  		{
sl@0
  6626
  		*averagebitrate = 0;
sl@0
  6627
  		}
sl@0
  6628
	else
sl@0
  6629
		{
sl@0
  6630
		*averagebitrate = (mp4_u32)((mp4_double)8 *
sl@0
  6631
		                  (mp4_double)audiosize /
sl@0
  6632
		                  ((mp4_double)handle->moov->trakAudio->mdia->mdhd->duration /
sl@0
  6633
		                  (mp4_double)handle->moov->trakAudio->mdia->mdhd->timeScale));
sl@0
  6634
		}  	
sl@0
  6635
sl@0
  6636
  	return 0;
sl@0
  6637
	}
sl@0
  6638
sl@0
  6639
sl@0
  6640
/*
sl@0
  6641
 * Function:
sl@0
  6642
 *
sl@0
  6643
 *   mp4_i32 determineStreamSize(MP4HandleImp handle,
sl@0
  6644
 *                              mp4_u32 *streamsize)
sl@0
  6645
 *
sl@0
  6646
 * Description:
sl@0
  6647
 *
sl@0
  6648
 *   This function determines the size of media data in MP4 file/stream.
sl@0
  6649
 *
sl@0
  6650
 * Parameters:
sl@0
  6651
 *
sl@0
  6652
 *   handle      MP4 library handle
sl@0
  6653
 *   streamsize  Size of data
sl@0
  6654
 *
sl@0
  6655
 * Return value:
sl@0
  6656
 *
sl@0
  6657
 *   0           Success
sl@0
  6658
 *   Negative    Error
sl@0
  6659
 *
sl@0
  6660
 */
sl@0
  6661
mp4_i32 determineStreamSize(MP4HandleImp handle, mp4_u32 *streamsize)
sl@0
  6662
{
sl@0
  6663
  *streamsize = 0;
sl@0
  6664
sl@0
  6665
  if (!handle->moov)
sl@0
  6666
    return -1;
sl@0
  6667
sl@0
  6668
  if ((!handle->moov->trakAudio) && (!handle->moov->trakVideo))
sl@0
  6669
    return -1;
sl@0
  6670
sl@0
  6671
  if (handle->moov->trakAudio)
sl@0
  6672
  {
sl@0
  6673
    if (!handle->moov->trakAudio->mdia)
sl@0
  6674
      return -1;
sl@0
  6675
sl@0
  6676
    if (!handle->moov->trakAudio->mdia->minf)
sl@0
  6677
      return -1;
sl@0
  6678
sl@0
  6679
    if (!handle->moov->trakAudio->mdia->minf->stbl)
sl@0
  6680
      return -1;
sl@0
  6681
sl@0
  6682
    if (!handle->moov->trakAudio->mdia->minf->stbl->stsz)
sl@0
  6683
      return -1;
sl@0
  6684
sl@0
  6685
    if (handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleSize != 0)
sl@0
  6686
      *streamsize += handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleCount *
sl@0
  6687
                     handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleSize;
sl@0
  6688
    else
sl@0
  6689
    {
sl@0
  6690
      mp4_u32 i;
sl@0
  6691
sl@0
  6692
      for (i = 0; i < handle->moov->trakAudio->mdia->minf->stbl->stsz->sampleCount; i++)
sl@0
  6693
        *streamsize += handle->moov->trakAudio->mdia->minf->stbl->stsz->entrySize[i];
sl@0
  6694
    }
sl@0
  6695
  }
sl@0
  6696
sl@0
  6697
  if (handle->moov->trakVideo)
sl@0
  6698
  {
sl@0
  6699
    if (!handle->moov->trakVideo->mdia)
sl@0
  6700
      return -1;
sl@0
  6701
sl@0
  6702
    if (!handle->moov->trakVideo->mdia->minf)
sl@0
  6703
      return -1;
sl@0
  6704
sl@0
  6705
    if (!handle->moov->trakVideo->mdia->minf->stbl)
sl@0
  6706
      return -1;
sl@0
  6707
sl@0
  6708
    if (!handle->moov->trakVideo->mdia->minf->stbl->stsz)
sl@0
  6709
      return -1;
sl@0
  6710
sl@0
  6711
    if (handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleSize != 0)
sl@0
  6712
      *streamsize += handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount *
sl@0
  6713
                     handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleSize;
sl@0
  6714
    else
sl@0
  6715
    {
sl@0
  6716
      mp4_u32 i;
sl@0
  6717
sl@0
  6718
      for (i = 0; i < handle->moov->trakVideo->mdia->minf->stbl->stsz->sampleCount; i++)
sl@0
  6719
        *streamsize += handle->moov->trakVideo->mdia->minf->stbl->stsz->entrySize[i];
sl@0
  6720
    }
sl@0
  6721
  }
sl@0
  6722
sl@0
  6723
  return 0;
sl@0
  6724
}
sl@0
  6725
sl@0
  6726
sl@0
  6727
/*
sl@0
  6728
 * Function:
sl@0
  6729
 *
sl@0
  6730
 *   mp4_i32 determineStreamAverageBitRate(MP4HandleImp handle,
sl@0
  6731
 *                                         mp4_u32 *streamaveragebitrate,
sl@0
  6732
 *                                         mp4_u32 streamsize)
sl@0
  6733
 *
sl@0
  6734
 * Description:
sl@0
  6735
 *
sl@0
  6736
 *   This function determines the average bitrate of the stream in bits per
sl@0
  6737
 *   second.
sl@0
  6738
 *
sl@0
  6739
 *   The average is calculated so that the media data length is divided by
sl@0
  6740
 *   the length of the presentation.
sl@0
  6741
 *
sl@0
  6742
 * Parameters:
sl@0
  6743
 *
sl@0
  6744
 *   handle                MP4 library handle
sl@0
  6745
 *   streamaveragebitrate  Result is returned here
sl@0
  6746
 *   streamsize            Size of media data in bytes
sl@0
  6747
 *
sl@0
  6748
 * Return value:
sl@0
  6749
 *
sl@0
  6750
 *   0           Success
sl@0
  6751
 *   Negative    Error
sl@0
  6752
 *
sl@0
  6753
 */
sl@0
  6754
mp4_i32 determineStreamAverageBitRate(MP4HandleImp handle, mp4_u32 *streamaveragebitrate, mp4_u32 streamsize)
sl@0
  6755
{
sl@0
  6756
  if (!handle->moov)
sl@0
  6757
    return -1;
sl@0
  6758
sl@0
  6759
  if (!handle->moov->mvhd)
sl@0
  6760
    return -1;
sl@0
  6761
sl@0
  6762
  if (!handle->moov->mvhd->timeScale)
sl@0
  6763
    return -1;
sl@0
  6764
sl@0
  6765
  if (handle->moov->mvhd->atomhdr->version == 1) /* 64 bit */
sl@0
  6766
      {
sl@0
  6767
      if (!handle->moov->mvhd->duration64)
sl@0
  6768
        return -1;
sl@0
  6769
     
sl@0
  6770
      *streamaveragebitrate = (mp4_u32)((mp4_double)8 * (mp4_double)streamsize /
sl@0
  6771
                                        ((mp4_double)handle->moov->mvhd->duration64 / handle->moov->mvhd->timeScale));      
sl@0
  6772
      }
sl@0
  6773
  else /* 32 bit */
sl@0
  6774
      {
sl@0
  6775
      if (!handle->moov->mvhd->duration)
sl@0
  6776
        return -1;
sl@0
  6777
sl@0
  6778
      *streamaveragebitrate = (mp4_u32)((mp4_double)8 * (mp4_double)streamsize /
sl@0
  6779
                                        ((mp4_double)handle->moov->mvhd->duration / handle->moov->mvhd->timeScale));      
sl@0
  6780
      }
sl@0
  6781
sl@0
  6782
  return 0;
sl@0
  6783
}
sl@0
  6784
sl@0
  6785
sl@0
  6786
/*
sl@0
  6787
 * Function:
sl@0
  6788
 *
sl@0
  6789
 *   mp4_i32 advanceVideoFrame(MP4HandleImp handle,
sl@0
  6790
 *                             trackAtom *trak)
sl@0
  6791
 *
sl@0
  6792
 * Description:
sl@0
  6793
 *
sl@0
  6794
 *   This function Advances one video frame and finds the frame offset
sl@0
  6795
 *   and size.
sl@0
  6796
 *
sl@0
  6797
 * Parameters:
sl@0
  6798
 *
sl@0
  6799
 *   handle    MP4 library handle
sl@0
  6800
 *   trak      TRAK atom pointer
sl@0
  6801
 *
sl@0
  6802
 * Return value:
sl@0
  6803
 *
sl@0
  6804
 *   0         Success
sl@0
  6805
 *   Negative  Error
sl@0
  6806
 *
sl@0
  6807
 */
sl@0
  6808
mp4_i32 advanceVideoFrame(MP4HandleImp handle, trackAtom *trak)
sl@0
  6809
{
sl@0
  6810
  if (!trak->mdia)
sl@0
  6811
    return -1;
sl@0
  6812
  if (!trak->mdia->minf)
sl@0
  6813
    return -1;
sl@0
  6814
  if (!trak->mdia->minf->stbl)
sl@0
  6815
    return -1;
sl@0
  6816
  if (!trak->mdia->minf->stbl->stsz)
sl@0
  6817
    return -1;
sl@0
  6818
sl@0
  6819
  /* Are there frames (samples) left? */
sl@0
  6820
sl@0
  6821
  if (trak->mdia->minf->stbl->stsz->sampleCount > handle->videoSampleNum)
sl@0
  6822
    handle->videoSampleNum++;
sl@0
  6823
  else
sl@0
  6824
    return -2;
sl@0
  6825
sl@0
  6826
  /* Find the size of the frame (sample) */
sl@0
  6827
sl@0
  6828
  if (resolveVideoSampleSize(handle, trak->mdia->minf->stbl->stsz) < 0)
sl@0
  6829
    return -1;
sl@0
  6830
sl@0
  6831
  /* Find the offset of the frame (sample) */
sl@0
  6832
sl@0
  6833
  if (resolveVideoSampleOffset(handle, trak->mdia->minf->stbl) < 0)
sl@0
  6834
    return -1;
sl@0
  6835
sl@0
  6836
sl@0
  6837
  return 0;
sl@0
  6838
}
sl@0
  6839
sl@0
  6840
sl@0
  6841
/*
sl@0
  6842
 * Function:
sl@0
  6843
 *
sl@0
  6844
 *   mp4_i32 resolveVideoSampleOffset(MP4HandleImp handle,
sl@0
  6845
 *                                    sampleTableAtom *stbl)
sl@0
  6846
 *
sl@0
  6847
 * Description:
sl@0
  6848
 *
sl@0
  6849
 *   This function finds the offset of the current video sample.
sl@0
  6850
 *   The result is stored in handle->videoFrameOffset.
sl@0
  6851
 *
sl@0
  6852
 * Parameters:
sl@0
  6853
 *
sl@0
  6854
 *   handle    MP4 library handle
sl@0
  6855
 *   stbl      STBL atom pointer
sl@0
  6856
 *
sl@0
  6857
 * Return value:
sl@0
  6858
 *
sl@0
  6859
 *   0         Success
sl@0
  6860
 *   Negative  Error
sl@0
  6861
 *
sl@0
  6862
 */
sl@0
  6863
mp4_i32 resolveVideoSampleOffset(MP4HandleImp handle, sampleTableAtom *stbl)
sl@0
  6864
	{
sl@0
  6865
	mp4_u32  chunk;            /* Current chunk number */
sl@0
  6866
	mp4_u32  sample;           /* Number of samples before this run of chunks */
sl@0
  6867
	mp4_u32  entry;            /* Current entry in sample to chunk */
sl@0
  6868
	mp4_u32  chunksInThisRun;  /* Number of chunks in this run */
sl@0
  6869
	mp4_u32  sampleNrInChunk = 0;	/* Sample number in the chunk */
sl@0
  6870
sl@0
  6871
	if (!stbl->stsc || stbl->stsc->entryCount == 0)
sl@0
  6872
		{
sl@0
  6873
		return -1;
sl@0
  6874
		}
sl@0
  6875
	
sl@0
  6876
	if (!stbl->stco || stbl->stco->entryCount == 0)
sl@0
  6877
		{
sl@0
  6878
		return -1;
sl@0
  6879
		}
sl@0
  6880
sl@0
  6881
	chunk = 0;
sl@0
  6882
	sample = 0;
sl@0
  6883
	entry = 0;
sl@0
  6884
sl@0
  6885
  for (;;)
sl@0
  6886
		{
sl@0
  6887
		/* Find how many chunks there are in this run */
sl@0
  6888
		
sl@0
  6889
		if (stbl->stsc->entryCount > entry + 1) /* Not last chunk run */
sl@0
  6890
			{
sl@0
  6891
			chunksInThisRun = stbl->stsc->firstChunk[entry + 1] - stbl->stsc->firstChunk[entry];
sl@0
  6892
			}
sl@0
  6893
		else
sl@0
  6894
			{
sl@0
  6895
			chunksInThisRun = stbl->stco->entryCount - chunk + 1;
sl@0
  6896
			}
sl@0
  6897
sl@0
  6898
		if (handle->videoSampleNum <= chunksInThisRun * stbl->stsc->samplesPerChunk[entry] + sample)
sl@0
  6899
			{
sl@0
  6900
			chunk += (handle->videoSampleNum - sample + stbl->stsc->samplesPerChunk[entry] - 1) / stbl->stsc->samplesPerChunk[entry];
sl@0
  6901
			sampleNrInChunk = (handle->videoSampleNum - sample + stbl->stsc->samplesPerChunk[entry] - 1) % stbl->stsc->samplesPerChunk[entry];
sl@0
  6902
	  
sl@0
  6903
			/* The following functions are needed for multiple sample entry support */
sl@0
  6904
			handle->videoSampleEntryIndex = stbl->stsc->sampleDescriptionIndex[entry];
sl@0
  6905
sl@0
  6906
			break; /* We know the chunk number and sample number in chunk AND the sample entry index of the current sample*/
sl@0
  6907
			}
sl@0
  6908
		else
sl@0
  6909
			{
sl@0
  6910
			chunk += chunksInThisRun;
sl@0
  6911
			sample += chunksInThisRun * stbl->stsc->samplesPerChunk[entry];
sl@0
  6912
			}
sl@0
  6913
sl@0
  6914
	    entry++;
sl@0
  6915
		}
sl@0
  6916
sl@0
  6917
	if (chunk > stbl->stco->entryCount)
sl@0
  6918
		{
sl@0
  6919
		return -1;
sl@0
  6920
		}
sl@0
  6921
sl@0
  6922
	handle->videoFrameOffset = getChunkOffset(stbl, chunk - 1);
sl@0
  6923
sl@0
  6924
	if (sampleNrInChunk)
sl@0
  6925
		{
sl@0
  6926
		if (stbl->stsz->sampleSize)
sl@0
  6927
			{
sl@0
  6928
			handle->videoFrameOffset += stbl->stsz->sampleSize * sampleNrInChunk;
sl@0
  6929
			}
sl@0
  6930
		else
sl@0
  6931
			{
sl@0
  6932
			if (stbl->stsz->sampleCount == 0)
sl@0
  6933
				{
sl@0
  6934
				return -1;
sl@0
  6935
				}
sl@0
  6936
			while (sampleNrInChunk)
sl@0
  6937
				{
sl@0
  6938
				handle->videoFrameOffset += stbl->stsz->entrySize[handle->videoSampleNum - sampleNrInChunk - 1];
sl@0
  6939
				sampleNrInChunk--;
sl@0
  6940
				}
sl@0
  6941
			}
sl@0
  6942
		}
sl@0
  6943
		
sl@0
  6944
		
sl@0
  6945
	//PRINT((_L("videoFrameOffset %Lu"), handle->videoFrameOffset));
sl@0
  6946
	return 0;
sl@0
  6947
	}
sl@0
  6948
sl@0
  6949
sl@0
  6950
/*
sl@0
  6951
 * Function:
sl@0
  6952
 *
sl@0
  6953
 *   mp4_i32 resolveVideoSampleSize(MP4HandleImp handle,
sl@0
  6954
 *                                  sampleSizeAtom *stsz)
sl@0
  6955
 *
sl@0
  6956
 * Description:
sl@0
  6957
 *
sl@0
  6958
 *   This function finds the size of the current video sample.
sl@0
  6959
 *   The result is stored in handle->videoFrameSize.
sl@0
  6960
 *
sl@0
  6961
 * Parameters:
sl@0
  6962
 *
sl@0
  6963
 *   handle    MP4 library handle
sl@0
  6964
 *   stsz      STSZ atom pointer
sl@0
  6965
 *
sl@0
  6966
 * Return value:
sl@0
  6967
 *
sl@0
  6968
 *   0         Success
sl@0
  6969
 *   Negative  Error
sl@0
  6970
 *
sl@0
  6971
 */
sl@0
  6972
mp4_i32 resolveVideoSampleSize(MP4HandleImp handle, sampleSizeAtom *stsz)
sl@0
  6973
	{
sl@0
  6974
	if (stsz->sampleSize)
sl@0
  6975
		{
sl@0
  6976
		handle->videoFrameSize = stsz->sampleSize;
sl@0
  6977
		return 0;
sl@0
  6978
		}
sl@0
  6979
sl@0
  6980
	if (stsz->sampleCount == 0)
sl@0
  6981
		{
sl@0
  6982
		return -1;
sl@0
  6983
		}
sl@0
  6984
	handle->videoFrameSize = stsz->entrySize[handle->videoSampleNum - 1];
sl@0
  6985
sl@0
  6986
	return 0;
sl@0
  6987
	}
sl@0
  6988
sl@0
  6989
sl@0
  6990
/*
sl@0
  6991
 * Function:
sl@0
  6992
 *
sl@0
  6993
 *   mp4_i32 fetchVideoFrame(MP4HandleImp handle,
sl@0
  6994
 *                           trackAtom *trak,
sl@0
  6995
 *                           mp4_u8 *buffer,
sl@0
  6996
 *                           mp4_u32 buffersize,
sl@0
  6997
 *                           mp4_u32 *framesize,
sl@0
  6998
 *                           mp4_u32 *timestamp,
sl@0
  6999
 *                           mp4_bool *keyframe,
sl@0
  7000
 *                           mp4_u32 *timestamp2)
sl@0
  7001
 *
sl@0
  7002
 * Description:
sl@0
  7003
 *
sl@0
  7004
 *   This function fetches one video frame from a file.
sl@0
  7005
 *
sl@0
  7006
 * Parameters:
sl@0
  7007
 *
sl@0
  7008
 *   handle       MP4 library handle
sl@0
  7009
 *   trak         TRAK atom pointer
sl@0
  7010
 *   buffer       Video frame is retuned here
sl@0
  7011
 *   buffersize   Size of buffer
sl@0
  7012
 *   framesize    Size of returned frame in bytes
sl@0
  7013
 *   timestamp    Frame time in milliseconds (from the beginning of the
sl@0
  7014
 *                presentation)
sl@0
  7015
 *   keyframe     True if intra frame, false otherwise
sl@0
  7016
 *   timestamp2   Frame time in timescale (from the beginning of the
sl@0
  7017
 *                presentation)
sl@0
  7018
 *
sl@0
  7019
 * Return value:
sl@0
  7020
 *
sl@0
  7021
 *   0            Success
sl@0
  7022
 *   Negative     Error
sl@0
  7023
 *
sl@0
  7024
 */
sl@0
  7025
mp4_i32 fetchVideoFrame(MP4HandleImp handle,
sl@0
  7026
                        trackAtom *trak,
sl@0
  7027
                        mp4_u8 *buffer,
sl@0
  7028
                        mp4_u32 buffersize,
sl@0
  7029
                        mp4_u32 *framesize,
sl@0
  7030
                        mp4_u32 *timestamp,
sl@0
  7031
                        mp4_bool *keyframe,
sl@0
  7032
                        mp4_u32 *timestamp2)
sl@0
  7033
{
sl@0
  7034
  mp4_i32 bytesread;
sl@0
  7035
sl@0
  7036
sl@0
  7037
  if (!trak->mdia)
sl@0
  7038
    return -1;
sl@0
  7039
sl@0
  7040
  if (handle->file) /* Input is in a file */
sl@0
  7041
  {
sl@0
  7042
    if (seekFileAbs(handle, handle->videoFrameOffset) != 0)
sl@0
  7043
      return -4;
sl@0
  7044
  }
sl@0
  7045
  else /* Input is a stream */
sl@0
  7046
  {
sl@0
  7047
      if (handle->videoFrameOffset + handle->videoFrameSize <= getCumulativeBufferedBytes(handle))
sl@0
  7048
      {
sl@0
  7049
          handle->absPosition = handle->videoFrameOffset;
sl@0
  7050
      }
sl@0
  7051
      else
sl@0
  7052
        return -3;
sl@0
  7053
  }
sl@0
  7054
sl@0
  7055
  if (handle->videoFrameSize > buffersize)
sl@0
  7056
  {
sl@0
  7057
    *framesize = handle->videoFrameSize;
sl@0
  7058
    return -2;
sl@0
  7059
  }
sl@0
  7060
sl@0
  7061
  bytesread = readData(handle, buffer, handle->videoFrameSize);
sl@0
  7062
  switch (bytesread)
sl@0
  7063
  {
sl@0
  7064
    case -1:
sl@0
  7065
      return -1;
sl@0
  7066
    case -2:
sl@0
  7067
      return -4;
sl@0
  7068
    case -10:
sl@0
  7069
      return -3;
sl@0
  7070
    default:
sl@0
  7071
      break;
sl@0
  7072
  }
sl@0
  7073
sl@0
  7074
  if (handle->file)
sl@0
  7075
    if (handle->videoFrameOffset + handle->videoFrameSize - 1 > handle->lastAccessedPosInFile)
sl@0
  7076
      handle->lastAccessedPosInFile = handle->videoFrameOffset + handle->videoFrameSize - 1;
sl@0
  7077
sl@0
  7078
  *framesize = handle->videoFrameSize;
sl@0
  7079
sl@0
  7080
  if (convertVideoSampleToTime(handle, trak->mdia, timestamp, timestamp2) < 0)
sl@0
  7081
    return -1;
sl@0
  7082
sl@0
  7083
  if (isVideoFrameKeyFrame(handle, trak, keyframe) < 0)
sl@0
  7084
    return -1;
sl@0
  7085
sl@0
  7086
  return 0;
sl@0
  7087
}
sl@0
  7088
sl@0
  7089
/*
sl@0
  7090
 * Function:
sl@0
  7091
 *
sl@0
  7092
 *   mp4_i32 fetchVideoFrameAsync(MP4HandleImp handle,
sl@0
  7093
 *                           	  trackAtom *trak,
sl@0
  7094
 *                           	  mp4_u8 *buffer,
sl@0
  7095
 *                           	  mp4_u32 buffersize,
sl@0
  7096
 *
sl@0
  7097
 * Description:
sl@0
  7098
 *
sl@0
  7099
 *   This function fetches one video frame from a file asyncronously.
sl@0
  7100
 *
sl@0
  7101
 * Parameters:
sl@0
  7102
 *
sl@0
  7103
 *   handle       MP4 library handle
sl@0
  7104
 *   trak         TRAK atom pointer
sl@0
  7105
 *   buffer       Video frame is retuned here
sl@0
  7106
 *   buffersize   Size of buffer
sl@0
  7107
 *
sl@0
  7108
 * Return value:
sl@0
  7109
 *
sl@0
  7110
 *   0            Success
sl@0
  7111
 *   Negative     Error
sl@0
  7112
 *
sl@0
  7113
 */
sl@0
  7114
mp4_i32 fetchVideoFrameAsync(MP4HandleImp handle,
sl@0
  7115
                        trackAtom *trak,
sl@0
  7116
                        mp4_u8 *buffer,
sl@0
  7117
                        mp4_u32 *buffersize)
sl@0
  7118
{
sl@0
  7119
  if (trak)
sl@0
  7120
	{
sl@0
  7121
	if (!trak->mdia)
sl@0
  7122
		return -1;
sl@0
  7123
	}
sl@0
  7124
  else
sl@0
  7125
    {
sl@0
  7126
	return -1;
sl@0
  7127
    }
sl@0
  7128
  
sl@0
  7129
  if (handle->videoFrameSize > *buffersize)
sl@0
  7130
  {
sl@0
  7131
    *buffersize = handle->videoFrameSize;
sl@0
  7132
    return -2;
sl@0
  7133
  }
sl@0
  7134
  
sl@0
  7135
  if ( handle->asyncReader == NULL )
sl@0
  7136
  	{
sl@0
  7137
	TRAPD(error, handle->asyncReader = CFileAsyncParser::NewL( handle, (RFile64&)handle->rfile ));
sl@0
  7138
	if ( error != KErrNone )
sl@0
  7139
		{
sl@0
  7140
		if (error == KErrNoMemory )
sl@0
  7141
			{
sl@0
  7142
			return MP4_OUT_OF_MEMORY;    		
sl@0
  7143
			}
sl@0
  7144
		else
sl@0
  7145
			{
sl@0
  7146
			return -1;
sl@0
  7147
			}
sl@0
  7148
		}  	
sl@0
  7149
  	}
sl@0
  7150
  
sl@0
  7151
  return handle->asyncReader->ReadVideoFrame( buffer, handle->videoFrameOffset, handle->videoFrameSize);
sl@0
  7152
}
sl@0
  7153
sl@0
  7154
/*
sl@0
  7155
 * Function:
sl@0
  7156
 *
sl@0
  7157
 *   mp4_i32 isVideoFrameKeyFrame(MP4HandleImp handle,
sl@0
  7158
 *                                trackAtom *trak,
sl@0
  7159
 *                                mp4_bool *keyframe)
sl@0
  7160
 *
sl@0
  7161
 * Description:
sl@0
  7162
 *
sl@0
  7163
 *   This function determines if the current frame is a keyframe (intra)
sl@0
  7164
 *   or not.
sl@0
  7165
 *
sl@0
  7166
 * Parameters:
sl@0
  7167
 *
sl@0
  7168
 *   handle       MP4 library handle
sl@0
  7169
 *   trak         TRAK atom pointer
sl@0
  7170
 *   keyframe     Has a value of MP4TRUE if current frame is a keyframe
sl@0
  7171
 *                (intra) or MP4FALSE otherwise
sl@0
  7172
 *
sl@0
  7173
 * Return value:
sl@0
  7174
 *
sl@0
  7175
 *   0            Success
sl@0
  7176
 *   Negative     Error
sl@0
  7177
 *
sl@0
  7178
 */
sl@0
  7179
mp4_i32 isVideoFrameKeyFrame(MP4HandleImp handle, trackAtom *trak, mp4_bool *keyframe)
sl@0
  7180
{
sl@0
  7181
  mp4_u32  i;
sl@0
  7182
sl@0
  7183
sl@0
  7184
  *keyframe = MP4FALSE;
sl@0
  7185
sl@0
  7186
  if (!trak->mdia)
sl@0
  7187
    return -1;
sl@0
  7188
sl@0
  7189
  if (!trak->mdia->minf)
sl@0
  7190
    return -1;
sl@0
  7191
sl@0
  7192
  if (!trak->mdia->minf->stbl)
sl@0
  7193
    return -1;
sl@0
  7194
sl@0
  7195
  if (!trak->mdia->minf->stbl->stss)
sl@0
  7196
  {
sl@0
  7197
    *keyframe = MP4TRUE;
sl@0
  7198
sl@0
  7199
    return 0;
sl@0
  7200
  }
sl@0
  7201
sl@0
  7202
  for (i = 0; i < trak->mdia->minf->stbl->stss->entryCount; i++)
sl@0
  7203
  {
sl@0
  7204
    if (trak->mdia->minf->stbl->stss->sampleNumber[i] == handle->videoSampleNum)
sl@0
  7205
    {
sl@0
  7206
      *keyframe = MP4TRUE;
sl@0
  7207
      break;
sl@0
  7208
    }
sl@0
  7209
  }
sl@0
  7210
sl@0
  7211
  return 0;
sl@0
  7212
}
sl@0
  7213
sl@0
  7214
sl@0
  7215
/*
sl@0
  7216
 * Function:
sl@0
  7217
 *
sl@0
  7218
 *   mp4_i32 convertVideoSampleToTime(MP4HandleImp handle,
sl@0
  7219
 *                                    mediaAtom *mdia,
sl@0
  7220
 *                                    mp4_u32 *timestamp,
sl@0
  7221
 *                                    mp4_u32 *timestamp2)
sl@0
  7222
 *
sl@0
  7223
 * Description:
sl@0
  7224
 *
sl@0
  7225
 *   This function converts a video sample to corresponding time.
sl@0
  7226
 *
sl@0
  7227
 * Parameters:
sl@0
  7228
 *
sl@0
  7229
 *   handle       MP4 library handle
sl@0
  7230
 *   mdia         MDIA atom pointer
sl@0
  7231
 *   timestamp    Time in milliseconds is returned here
sl@0
  7232
 *   timestamp2   Time in timescale is returned here
sl@0
  7233
 *
sl@0
  7234
 * Return value:
sl@0
  7235
 *
sl@0
  7236
 *   0            Success
sl@0
  7237
 *   Negative     Error
sl@0
  7238
 *
sl@0
  7239
 */
sl@0
  7240
mp4_i32 convertVideoSampleToTime(MP4HandleImp handle,
sl@0
  7241
                                 mediaAtom *mdia,
sl@0
  7242
                                 mp4_u32 *timestamp,
sl@0
  7243
                                 mp4_u32 *timestamp2)
sl@0
  7244
	{
sl@0
  7245
	mp4_u32      tmptime;
sl@0
  7246
	mp4_double   tmptime2;
sl@0
  7247
	mp4_u32      sample;
sl@0
  7248
	mp4_u32      entry;
sl@0
  7249
sl@0
  7250
	if (!mdia->mdhd)
sl@0
  7251
		{
sl@0
  7252
		return -1;
sl@0
  7253
		}
sl@0
  7254
	if (!mdia->minf)
sl@0
  7255
		{
sl@0
  7256
		return -1;
sl@0
  7257
		}
sl@0
  7258
	if (!mdia->minf->stbl)
sl@0
  7259
		{
sl@0
  7260
		return -1;
sl@0
  7261
		}
sl@0
  7262
	if (!mdia->minf->stbl->stts)
sl@0
  7263
		{
sl@0
  7264
		return -1;
sl@0
  7265
		}
sl@0
  7266
	if (mdia->minf->stbl->stts->entryCount == 0)
sl@0
  7267
		{
sl@0
  7268
		return -1;
sl@0
  7269
		}
sl@0
  7270
sl@0
  7271
	tmptime = 0;
sl@0
  7272
	sample = 0;
sl@0
  7273
	entry = 0;
sl@0
  7274
sl@0
  7275
	for (;;)
sl@0
  7276
		{
sl@0
  7277
		if (sample + mdia->minf->stbl->stts->sampleCount[entry] < handle->videoSampleNum)
sl@0
  7278
			{
sl@0
  7279
			sample += mdia->minf->stbl->stts->sampleCount[entry];
sl@0
  7280
			tmptime += (mdia->minf->stbl->stts->sampleCount[entry] * mdia->minf->stbl->stts->sampleDelta[entry]);
sl@0
  7281
			entry++;
sl@0
  7282
			if (entry == mdia->minf->stbl->stts->entryCount)
sl@0
  7283
				{
sl@0
  7284
				return -1;
sl@0
  7285
				}
sl@0
  7286
			}
sl@0
  7287
		else
sl@0
  7288
			{
sl@0
  7289
			tmptime += ((handle->videoSampleNum - sample - 1) * mdia->minf->stbl->stts->sampleDelta[entry]);
sl@0
  7290
			break;
sl@0
  7291
			}
sl@0
  7292
		}
sl@0
  7293
	
sl@0
  7294
  	if (mdia->mdhd->timeScale == 0)
sl@0
  7295
  		{
sl@0
  7296
  		return -1;
sl@0
  7297
  		}
sl@0
  7298
sl@0
  7299
  	if (timestamp2)
sl@0
  7300
  		{
sl@0
  7301
  		*timestamp2 = tmptime;
sl@0
  7302
  		}
sl@0
  7303
sl@0
  7304
  	tmptime2 = (mp4_double)tmptime * (mp4_double)1000 / (mp4_double)mdia->mdhd->timeScale + (mp4_double)0.5;
sl@0
  7305
sl@0
  7306
  	*timestamp = (mp4_u32)tmptime2;
sl@0
  7307
sl@0
  7308
  	return 0;
sl@0
  7309
	}
sl@0
  7310
sl@0
  7311
sl@0
  7312
/*
sl@0
  7313
 * Function:
sl@0
  7314
 *
sl@0
  7315
 *   mp4_i32 advanceAudioSample(MP4HandleImp handle,
sl@0
  7316
 *                              trackAtom *trak)
sl@0
  7317
 *
sl@0
  7318
 * Description:
sl@0
  7319
 *
sl@0
  7320
 *   This function advances one audio sample and finds the sample
sl@0
  7321
 *   offset and sample size.
sl@0
  7322
 *
sl@0
  7323
 * Parameters:
sl@0
  7324
 *
sl@0
  7325
 *   handle    MP4 library handle
sl@0
  7326
 *   trak      TRAK atom pointer
sl@0
  7327
 *
sl@0
  7328
 * Return value:
sl@0
  7329
 *
sl@0
  7330
 *   0         Success
sl@0
  7331
 *   Negative  Error
sl@0
  7332
 *
sl@0
  7333
 */
sl@0
  7334
mp4_i32 advanceAudioSample(MP4HandleImp handle,
sl@0
  7335
                           trackAtom *trak)
sl@0
  7336
{
sl@0
  7337
  if (!trak->mdia)
sl@0
  7338
    return -1;
sl@0
  7339
  if (!trak->mdia->minf)
sl@0
  7340
    return -1;
sl@0
  7341
  if (!trak->mdia->minf->stbl)
sl@0
  7342
    return -1;
sl@0
  7343
  if (!trak->mdia->minf->stbl->stsz)
sl@0
  7344
    return -1;
sl@0
  7345
sl@0
  7346
sl@0
  7347
  /* Are there samples left? */
sl@0
  7348
sl@0
  7349
  if (trak->mdia->minf->stbl->stsz->sampleCount > handle->audioSampleNum)
sl@0
  7350
    handle->audioSampleNum++;
sl@0
  7351
  else
sl@0
  7352
    return -2;
sl@0
  7353
sl@0
  7354
  /* Find the size of the sample */
sl@0
  7355
sl@0
  7356
  if (resolveAudioSampleSize(handle, trak->mdia->minf->stbl->stsz) < 0)
sl@0
  7357
    return -1;
sl@0
  7358
sl@0
  7359
  /* Find the offset of the sample */
sl@0
  7360
sl@0
  7361
  if (resolveAudioSampleOffset(handle, trak->mdia->minf->stbl) < 0)
sl@0
  7362
    return -1;
sl@0
  7363
sl@0
  7364
sl@0
  7365
  return 0;
sl@0
  7366
}
sl@0
  7367
sl@0
  7368
sl@0
  7369
/*
sl@0
  7370
 * Function:
sl@0
  7371
 *
sl@0
  7372
 *   mp4_i32 resolveAudioSampleOffset(MP4HandleImp handle,
sl@0
  7373
 *                                    sampleTableAtom *stbl)
sl@0
  7374
 *
sl@0
  7375
 * Description:
sl@0
  7376
 *
sl@0
  7377
 *   This function finds the offset of the current audio sample.
sl@0
  7378
 *   The result is stored in handle->audioSampleOffset.
sl@0
  7379
 *
sl@0
  7380
 * Parameters:
sl@0
  7381
 *
sl@0
  7382
 *   handle    MP4 library handle
sl@0
  7383
 *   stbl      STBL atom pointer
sl@0
  7384
 *
sl@0
  7385
 * Return value:
sl@0
  7386
 *
sl@0
  7387
 *   0         Success
sl@0
  7388
 *   Negative  Error
sl@0
  7389
 *
sl@0
  7390
 */
sl@0
  7391
mp4_i32 resolveAudioSampleOffset(MP4HandleImp handle, sampleTableAtom *stbl)
sl@0
  7392
{
sl@0
  7393
  mp4_u32  chunk;            /* Current chunk number */
sl@0
  7394
  mp4_u32  sample;            /* Number of samples before this run of chunks */
sl@0
  7395
  mp4_u32  entry;            /* Current entry in sample to chunk */
sl@0
  7396
  mp4_u32 chunksInThisRun;  /* Number of chunks in this run */
sl@0
  7397
  mp4_u32  sampleNrInChunk;  /* Sample number in the chunk */
sl@0
  7398
sl@0
  7399
sl@0
  7400
  if (!stbl->stsc || stbl->stsc->entryCount == 0)
sl@0
  7401
    return -1;
sl@0
  7402
  if (!stbl->stco || stbl->stco->entryCount == 0)
sl@0
  7403
    return -1;
sl@0
  7404
sl@0
  7405
  chunk = 0;
sl@0
  7406
  sample = 0;
sl@0
  7407
  entry = 0;
sl@0
  7408
sl@0
  7409
  for (;;)
sl@0
  7410
  {
sl@0
  7411
    /* Find how many chunks there are in this run */
sl@0
  7412
sl@0
  7413
    if (stbl->stsc->entryCount > entry + 1) /* Not last chunk run */
sl@0
  7414
    {
sl@0
  7415
      chunksInThisRun = stbl->stsc->firstChunk[entry + 1] -
sl@0
  7416
                        stbl->stsc->firstChunk[entry];
sl@0
  7417
    }
sl@0
  7418
    else
sl@0
  7419
      chunksInThisRun = stbl->stco->entryCount - chunk + 1;
sl@0
  7420
sl@0
  7421
sl@0
  7422
    if (handle->audioSampleNum <= chunksInThisRun * stbl->stsc->samplesPerChunk[entry] + sample)
sl@0
  7423
    {
sl@0
  7424
      chunk += (handle->audioSampleNum - sample + stbl->stsc->samplesPerChunk[entry] - 1) / stbl->stsc->samplesPerChunk[entry];
sl@0
  7425
      sampleNrInChunk = (handle->audioSampleNum - sample + stbl->stsc->samplesPerChunk[entry] - 1) % stbl->stsc->samplesPerChunk[entry];
sl@0
  7426
sl@0
  7427
	  /* The following functions are needed for multiple sample entry support */
sl@0
  7428
	  handle->audioSampleEntryIndex = stbl->stsc->sampleDescriptionIndex[entry];
sl@0
  7429
sl@0
  7430
      break; /* We know the chunk number and sample number in chunk AND the sample entry index of the current sample*/
sl@0
  7431
    }
sl@0
  7432
    else
sl@0
  7433
    {
sl@0
  7434
      chunk += chunksInThisRun;
sl@0
  7435
      sample += chunksInThisRun * stbl->stsc->samplesPerChunk[entry];
sl@0
  7436
    }
sl@0
  7437
sl@0
  7438
    entry++;
sl@0
  7439
  }
sl@0
  7440
sl@0
  7441
  if (chunk > stbl->stco->entryCount)
sl@0
  7442
    return -1;
sl@0
  7443
sl@0
  7444
  handle->audioSampleOffset = getChunkOffset(stbl, chunk - 1);
sl@0
  7445
sl@0
  7446
  	if (sampleNrInChunk)
sl@0
  7447
  		{
sl@0
  7448
  		if (stbl->stsz->sampleSize)
sl@0
  7449
  			{
sl@0
  7450
  			handle->audioSampleOffset += stbl->stsz->sampleSize * sampleNrInChunk;
sl@0
  7451
  			}
sl@0
  7452
  		else
sl@0
  7453
  			{
sl@0
  7454
  			if (stbl->stsz->sampleCount == 0)
sl@0
  7455
  				{
sl@0
  7456
  				// ensure there are entries in the entrySize array
sl@0
  7457
  				return -1;
sl@0
  7458
  				}
sl@0
  7459
    
sl@0
  7460
  			while (sampleNrInChunk)
sl@0
  7461
  				{
sl@0
  7462
  				handle->audioSampleOffset += stbl->stsz->entrySize[handle->audioSampleNum - sampleNrInChunk - 1];
sl@0
  7463
  				sampleNrInChunk--;
sl@0
  7464
  				}
sl@0
  7465
  			}
sl@0
  7466
  		}
sl@0
  7467
  		
sl@0
  7468
  //PRINT((_L("audioSampleOffset %Lu"), handle->audioSampleOffset));
sl@0
  7469
  return 0;
sl@0
  7470
}
sl@0
  7471
sl@0
  7472
sl@0
  7473
/*
sl@0
  7474
 * Function:
sl@0
  7475
 *
sl@0
  7476
 *   mp4_i32 resolveAudioSampleSize(MP4HandleImp handle,
sl@0
  7477
 *                                  sampleSizeAtom *stsz)
sl@0
  7478
 *
sl@0
  7479
 * Description:
sl@0
  7480
 *
sl@0
  7481
 *   This function finds the size of the current audio sample.
sl@0
  7482
 *   The result is stored in handle->audioSampleSize.
sl@0
  7483
 *
sl@0
  7484
 * Parameters:
sl@0
  7485
 *
sl@0
  7486
 *   handle    MP4 library handle
sl@0
  7487
 *   stsz      STSZ atom pointer
sl@0
  7488
 *
sl@0
  7489
 * Return value:
sl@0
  7490
 *
sl@0
  7491
 *   0         Success
sl@0
  7492
 *   Negative  Error
sl@0
  7493
 *
sl@0
  7494
 */
sl@0
  7495
mp4_i32 resolveAudioSampleSize(MP4HandleImp handle, sampleSizeAtom *stsz)
sl@0
  7496
	{
sl@0
  7497
	if (stsz->sampleSize)
sl@0
  7498
		{
sl@0
  7499
		handle->audioSampleSize = stsz->sampleSize;
sl@0
  7500
		return 0;
sl@0
  7501
		}
sl@0
  7502
sl@0
  7503
	if (stsz->sampleCount == 0)
sl@0
  7504
		{
sl@0
  7505
		return -1;
sl@0
  7506
		}
sl@0
  7507
	handle->audioSampleSize = stsz->entrySize[handle->audioSampleNum - 1];
sl@0
  7508
sl@0
  7509
	return 0;
sl@0
  7510
	}
sl@0
  7511
sl@0
  7512
sl@0
  7513
/*
sl@0
  7514
 * Function:
sl@0
  7515
 *
sl@0
  7516
 *   mp4_i32 fetchAudioSample(MP4HandleImp handle,
sl@0
  7517
 *                            trackAtom *trak,
sl@0
  7518
 *                            mp4_u8 *buffer,
sl@0
  7519
 *                            mp4_u32 buffersize,
sl@0
  7520
 *                            mp4_u32 *framesize,
sl@0
  7521
 *                            mp4_u32 *timestamp,
sl@0
  7522
 *                            mp4_u32 *returnedframes,
sl@0
  7523
 *                            mp4_u32 *timestamp2)
sl@0
  7524
 *
sl@0
  7525
 * Description:
sl@0
  7526
 *
sl@0
  7527
 *   This function fetches one audio sample from a file.
sl@0
  7528
 *
sl@0
  7529
 *   Note: returnedframes may differ from the correct value when accessing
sl@0
  7530
 *         the last audio sample.
sl@0
  7531
 *
sl@0
  7532
 * Parameters:
sl@0
  7533
 *
sl@0
  7534
 *   handle           MP4 library handle
sl@0
  7535
 *   trak             TRAK atom pointer
sl@0
  7536
 *   buffer           Audio frame is retuned here
sl@0
  7537
 *   buffersize       Size of buffer
sl@0
  7538
 *   framesize        Size of returned frame in bytes
sl@0
  7539
 *   timestamp        Frame time in milliseconds (from the beginning of the
sl@0
  7540
 *                    presentation)
sl@0
  7541
 *   returnedframes   Number of frames returned, of 0 if not known
sl@0
  7542
 *   timestamp2       Frame time in timescale (from the beginning of the
sl@0
  7543
 *                    presentation)
sl@0
  7544
 *
sl@0
  7545
 * Return value:
sl@0
  7546
 *
sl@0
  7547
 *   0                Success
sl@0
  7548
 *   Negative         Error
sl@0
  7549
 *
sl@0
  7550
 */
sl@0
  7551
mp4_i32 fetchAudioSample(MP4HandleImp handle,
sl@0
  7552
                         trackAtom *trak,
sl@0
  7553
                         mp4_u8 *buffer,
sl@0
  7554
                         mp4_u32 buffersize,
sl@0
  7555
                         mp4_u32 *framesize,
sl@0
  7556
                         mp4_u32 *timestamp,
sl@0
  7557
                         mp4_u32 *returnedframes,
sl@0
  7558
                         mp4_u32 *timestamp2)
sl@0
  7559
{
sl@0
  7560
  mp4_i32 bytesread;
sl@0
  7561
  mp4_i32 frameLength;
sl@0
  7562
  mp4_u32 numOfFrames;
sl@0
  7563
  mp4_u8 *framepointer;
sl@0
  7564
  mp4_u32 rawAmrFrameLength[16] = {13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1};
sl@0
  7565
sl@0
  7566
  if (!trak->mdia)
sl@0
  7567
    return -1;
sl@0
  7568
sl@0
  7569
  if (handle->file) /* Input is in a file */
sl@0
  7570
  {
sl@0
  7571
    if (seekFileAbs(handle, handle->audioSampleOffset) != 0)
sl@0
  7572
      return -4;
sl@0
  7573
  }
sl@0
  7574
  else /* Input is a stream */
sl@0
  7575
  {
sl@0
  7576
      if (handle->audioSampleOffset + handle->audioSampleSize <= getCumulativeBufferedBytes(handle))
sl@0
  7577
      {
sl@0
  7578
          handle->absPosition = handle->audioSampleOffset;
sl@0
  7579
      }
sl@0
  7580
      else
sl@0
  7581
        return -3;
sl@0
  7582
  }
sl@0
  7583
sl@0
  7584
  if (handle->audioSampleSize > buffersize)
sl@0
  7585
  {
sl@0
  7586
    *framesize = handle->audioSampleSize;
sl@0
  7587
    return -2;
sl@0
  7588
  }
sl@0
  7589
sl@0
  7590
  bytesread = readData(handle, buffer, handle->audioSampleSize);
sl@0
  7591
  switch (bytesread)
sl@0
  7592
  {
sl@0
  7593
    case -1:
sl@0
  7594
      return -1;
sl@0
  7595
    case -2:
sl@0
  7596
      return -4;
sl@0
  7597
    case -10:
sl@0
  7598
      return -3;
sl@0
  7599
    default:
sl@0
  7600
      break;
sl@0
  7601
  }
sl@0
  7602
sl@0
  7603
  if (handle->file)
sl@0
  7604
    if (handle->audioSampleOffset + handle->audioSampleSize - 1 > handle->lastAccessedPosInFile)
sl@0
  7605
      handle->lastAccessedPosInFile = handle->audioSampleOffset + handle->audioSampleSize - 1;
sl@0
  7606
sl@0
  7607
  *framesize = handle->audioSampleSize;
sl@0
  7608
  if (convertAudioSampleToTime(handle, trak->mdia, timestamp, timestamp2) < 0)
sl@0
  7609
    return -1;
sl@0
  7610
sl@0
  7611
  *returnedframes = 0;
sl@0
  7612
sl@0
  7613
  /* AMR */
sl@0
  7614
  if (trak->mdia->minf)
sl@0
  7615
    if (trak->mdia->minf->stbl)
sl@0
  7616
      if (trak->mdia->minf->stbl->stsd)
sl@0
  7617
        if (handle->type & MP4_TYPE_AMR_NB)
sl@0
  7618
        {
sl@0
  7619
            framepointer = buffer;
sl@0
  7620
            numOfFrames = 0;
sl@0
  7621
            while ( bytesread > 0 )
sl@0
  7622
            {
sl@0
  7623
                frameLength = rawAmrFrameLength[(TInt)(((*framepointer) & 0x78) >> 3)];
sl@0
  7624
                if ( frameLength == 0)
sl@0
  7625
                {
sl@0
  7626
                    return -4;
sl@0
  7627
                }
sl@0
  7628
                bytesread -= frameLength;
sl@0
  7629
                framepointer += frameLength;
sl@0
  7630
                numOfFrames++;
sl@0
  7631
            }
sl@0
  7632
            *returnedframes = numOfFrames;
sl@0
  7633
sl@0
  7634
		  /* Return the number of sample entries listed for this particular sample entry index 
sl@0
  7635
          if (trak->mdia->minf->stbl->stsd->samr[handle->audioSampleEntryIndex - 1])
sl@0
  7636
            if (trak->mdia->minf->stbl->stsd->samr[handle->audioSampleEntryIndex - 1]->damr)
sl@0
  7637
              *returnedframes = trak->mdia->minf->stbl->stsd->samr[handle->audioSampleEntryIndex - 1]->damr->framesPerSample;*/
sl@0
  7638
        }
sl@0
  7639
        else if (handle->type & MP4_TYPE_AMR_WB)
sl@0
  7640
        {
sl@0
  7641
		  /* Return the number of sample entries listed for this particular sample entry index */
sl@0
  7642
          if (trak->mdia->minf->stbl->stsd->sawb[handle->audioSampleEntryIndex - 1])
sl@0
  7643
            if (trak->mdia->minf->stbl->stsd->sawb[handle->audioSampleEntryIndex - 1]->damr)
sl@0
  7644
              *returnedframes = trak->mdia->minf->stbl->stsd->sawb[handle->audioSampleEntryIndex - 1]->damr->framesPerSample;
sl@0
  7645
        }
sl@0
  7646
        else
sl@0
  7647
        {
sl@0
  7648
        }
sl@0
  7649
sl@0
  7650
  /* MPEG-4 audio */
sl@0
  7651
  if (trak->mdia->minf)
sl@0
  7652
    if (trak->mdia->minf->stbl)
sl@0
  7653
      if (trak->mdia->minf->stbl->stsd)
sl@0
  7654
        if (trak->mdia->minf->stbl->stsd->mp4a[handle->audioSampleEntryIndex - 1])
sl@0
  7655
          *returnedframes = 1;
sl@0
  7656
sl@0
  7657
  /* QCELP 13K as QCELPSampleEntry*/
sl@0
  7658
  if (trak->mdia->minf)
sl@0
  7659
    if (trak->mdia->minf->stbl)
sl@0
  7660
      if (trak->mdia->minf->stbl->stsd)
sl@0
  7661
        if ((handle->type & MP4_TYPE_QCELP_13K) && (!handle->qcelpStoredAsMPEGAudio))
sl@0
  7662
        {
sl@0
  7663
		  /* Return the number of sample entries listed for this particular sample entry index */
sl@0
  7664
          if (trak->mdia->minf->stbl->stsd->sqcp[handle->audioSampleEntryIndex - 1])
sl@0
  7665
            if (trak->mdia->minf->stbl->stsd->sqcp[handle->audioSampleEntryIndex - 1]->dqcp)
sl@0
  7666
              *returnedframes = trak->mdia->minf->stbl->stsd->sqcp[handle->audioSampleEntryIndex - 1]->dqcp->framesPerSample;
sl@0
  7667
        }
sl@0
  7668
sl@0
  7669
  /* QCELP 13K as MPEG-4 audio */
sl@0
  7670
  if (trak->mdia->minf)
sl@0
  7671
    if (trak->mdia->minf->stbl)
sl@0
  7672
      if (trak->mdia->minf->stbl->stsd)
sl@0
  7673
        if (trak->mdia->minf->stbl->stsd->mp4a[handle->audioSampleEntryIndex - 1])
sl@0
  7674
          *returnedframes = 1;
sl@0
  7675
sl@0
  7676
  return 0;
sl@0
  7677
}
sl@0
  7678
sl@0
  7679
/*
sl@0
  7680
 * Function:
sl@0
  7681
 *
sl@0
  7682
 *   mp4_i32 fetchAudioSampleAsync(MP4HandleImp handle,
sl@0
  7683
 *                            trackAtom *trak,
sl@0
  7684
 *                            mp4_u8 *buffer,
sl@0
  7685
 *                            mp4_u32 buffersize,
sl@0
  7686
 *
sl@0
  7687
 * Description:
sl@0
  7688
 *
sl@0
  7689
 *   This function fetches one audio sample from a file asyncronously.
sl@0
  7690
 *
sl@0
  7691
 * Parameters:
sl@0
  7692
 *
sl@0
  7693
 *   handle           MP4 library handle
sl@0
  7694
 *   trak             TRAK atom pointer
sl@0
  7695
 *   buffer           Audio frame is retuned here
sl@0
  7696
 *   buffersize       Size of buffer
sl@0
  7697
 *
sl@0
  7698
 * Return value:
sl@0
  7699
 *
sl@0
  7700
 *   0                Success
sl@0
  7701
 *   Negative         Error
sl@0
  7702
 *
sl@0
  7703
 */
sl@0
  7704
mp4_i32 fetchAudioSampleAsync(MP4HandleImp handle,
sl@0
  7705
                         	  trackAtom *trak,
sl@0
  7706
                         	  mp4_u8 *buffer,
sl@0
  7707
                         	  mp4_u32 *buffersize)
sl@0
  7708
{
sl@0
  7709
  if (trak)
sl@0
  7710
	{
sl@0
  7711
	if (!trak->mdia)
sl@0
  7712
		return -1;
sl@0
  7713
	}
sl@0
  7714
  else
sl@0
  7715
    {
sl@0
  7716
	return -1;
sl@0
  7717
    }
sl@0
  7718
  
sl@0
  7719
  if (handle->audioSampleSize > *buffersize)
sl@0
  7720
		{
sl@0
  7721
		*buffersize = handle->audioSampleSize;
sl@0
  7722
		return -2;
sl@0
  7723
		}
sl@0
  7724
  
sl@0
  7725
  if (!handle->file) // Other input than file is not supported
sl@0
  7726
	  {
sl@0
  7727
	  return -1;
sl@0
  7728
	  }
sl@0
  7729
  
sl@0
  7730
  if ( handle->asyncReader == NULL )
sl@0
  7731
  	{
sl@0
  7732
	TRAPD(error, handle->asyncReader = CFileAsyncParser::NewL( handle, (RFile64&)handle->rfile ));
sl@0
  7733
	if ( error != KErrNone )
sl@0
  7734
		{
sl@0
  7735
		if (error == KErrNoMemory )
sl@0
  7736
			{
sl@0
  7737
			return MP4_OUT_OF_MEMORY;    		
sl@0
  7738
			}
sl@0
  7739
		else
sl@0
  7740
			{
sl@0
  7741
			return -1;
sl@0
  7742
			}
sl@0
  7743
		}  	
sl@0
  7744
  	}
sl@0
  7745
    
sl@0
  7746
  return handle->asyncReader->ReadAudioFrames( buffer, handle->audioSampleOffset, handle->audioSampleSize);
sl@0
  7747
}
sl@0
  7748
sl@0
  7749
/*
sl@0
  7750
 * Function:
sl@0
  7751
 *
sl@0
  7752
 *   mp4_i32 convertAudioSampleToTime(MP4HandleImp handle,
sl@0
  7753
 *                                    mediaAtom *mdia,
sl@0
  7754
 *                                    mp4_u32 *timestamp,
sl@0
  7755
 *                                    mp4_u32 *timestamp2)
sl@0
  7756
 *
sl@0
  7757
 * Description:
sl@0
  7758
 *
sl@0
  7759
 *   This function converts an audio sample to corresponding time.
sl@0
  7760
 *
sl@0
  7761
 * Parameters:
sl@0
  7762
 *
sl@0
  7763
 *   handle       MP4 library handle
sl@0
  7764
 *   mdia         MDIA atom pointer
sl@0
  7765
 *   timestamp    Time in milliseconds is returned here
sl@0
  7766
 *   timestamp2   Time in timescale is returned here
sl@0
  7767
 *
sl@0
  7768
 * Return value:
sl@0
  7769
 *
sl@0
  7770
 *   0            Success
sl@0
  7771
 *   Negative     Error
sl@0
  7772
 *
sl@0
  7773
 */
sl@0
  7774
mp4_i32 convertAudioSampleToTime(MP4HandleImp handle,
sl@0
  7775
                                 mediaAtom *mdia,
sl@0
  7776
                                 mp4_u32 *timestamp,
sl@0
  7777
                                 mp4_u32 *timestamp2)
sl@0
  7778
	{
sl@0
  7779
	mp4_u32      tmptime;
sl@0
  7780
	mp4_double  tmptime2;
sl@0
  7781
	mp4_u32      sample;
sl@0
  7782
	mp4_u32      entry;
sl@0
  7783
sl@0
  7784
  	if (!mdia->mdhd)
sl@0
  7785
  		{
sl@0
  7786
  		return -1;
sl@0
  7787
  		}
sl@0
  7788
  	if (!mdia->minf)
sl@0
  7789
  		{
sl@0
  7790
  		return -1;
sl@0
  7791
  		}
sl@0
  7792
  	if (!mdia->minf->stbl)
sl@0
  7793
  		{
sl@0
  7794
  		return -1;
sl@0
  7795
  		}
sl@0
  7796
  	if (!mdia->minf->stbl->stts)
sl@0
  7797
  		{
sl@0
  7798
  		return -1;
sl@0
  7799
  		}
sl@0
  7800
  	if (mdia->minf->stbl->stts->entryCount == 0)
sl@0
  7801
  		{
sl@0
  7802
  		return -1;
sl@0
  7803
  		}
sl@0
  7804
sl@0
  7805
  	tmptime = 0;
sl@0
  7806
  	sample = 0;
sl@0
  7807
  	entry = 0;
sl@0
  7808
sl@0
  7809
  	for (;;)
sl@0
  7810
  		{
sl@0
  7811
  		if (sample + mdia->minf->stbl->stts->sampleCount[entry] < handle->audioSampleNum)
sl@0
  7812
  			{
sl@0
  7813
  			sample += mdia->minf->stbl->stts->sampleCount[entry];
sl@0
  7814
  			tmptime += mdia->minf->stbl->stts->sampleCount[entry] *
sl@0
  7815
                 	mdia->minf->stbl->stts->sampleDelta[entry];
sl@0
  7816
  			entry++;
sl@0
  7817
  			
sl@0
  7818
  			if (entry == mdia->minf->stbl->stts->entryCount)
sl@0
  7819
  				return -1;
sl@0
  7820
  			}
sl@0
  7821
  		else
sl@0
  7822
  			{
sl@0
  7823
  			tmptime += (handle->audioSampleNum - sample - 1) * mdia->minf->stbl->stts->sampleDelta[entry];
sl@0
  7824
  			break;
sl@0
  7825
  			}
sl@0
  7826
  		}
sl@0
  7827
sl@0
  7828
  	if (mdia->mdhd->timeScale == 0)
sl@0
  7829
  		{
sl@0
  7830
  		return -1;
sl@0
  7831
  		}
sl@0
  7832
sl@0
  7833
  	if (timestamp2)
sl@0
  7834
  		{
sl@0
  7835
  		*timestamp2 = tmptime;
sl@0
  7836
  		}
sl@0
  7837
sl@0
  7838
  	tmptime2 = (mp4_double)tmptime * (mp4_double)1000 / (mp4_double)mdia->mdhd->timeScale + (mp4_double)0.5;
sl@0
  7839
sl@0
  7840
  	*timestamp = (mp4_u32)tmptime2;
sl@0
  7841
sl@0
  7842
  	return 0;
sl@0
  7843
	}
sl@0
  7844
sl@0
  7845
sl@0
  7846
/*
sl@0
  7847
 * Function:
sl@0
  7848
 *
sl@0
  7849
 *   mp4_i32 convertTimeToSample(MP4HandleImp handle,
sl@0
  7850
 *                               trackAtom *trak,
sl@0
  7851
 *                               mp4_u32 position,
sl@0
  7852
 *                               mp4_u32 *sample)
sl@0
  7853
 *
sl@0
  7854
 * Description:
sl@0
  7855
 *
sl@0
  7856
 *   This function converts time to corresponding sample number.
sl@0
  7857
 *
sl@0
  7858
 * Parameters:
sl@0
  7859
 *
sl@0
  7860
 *   handle       MP4 library handle
sl@0
  7861
 *   trak         trackAtom pointer
sl@0
  7862
 *   position     Time in milliseconds
sl@0
  7863
 *   sample       Sample number is returned here
sl@0
  7864
 *
sl@0
  7865
 * Return value:
sl@0
  7866
 *
sl@0
  7867
 *   0            Success
sl@0
  7868
 *   Negative     Error
sl@0
  7869
 *
sl@0
  7870
 */
sl@0
  7871
mp4_i32 convertTimeToSample(MP4HandleImp handle,
sl@0
  7872
                            trackAtom *trak,
sl@0
  7873
                            mp4_u32 position,
sl@0
  7874
                            mp4_u32 *sample)
sl@0
  7875
{
sl@0
  7876
  mp4_u32 pos;      /* Target position in media timescale */
sl@0
  7877
  mp4_u32 tmppos;   /* Temporary position counter */
sl@0
  7878
  mp4_u32 i;
sl@0
  7879
sl@0
  7880
sl@0
  7881
  if (!handle)
sl@0
  7882
    return -1;
sl@0
  7883
  if (!trak)
sl@0
  7884
    return -1;
sl@0
  7885
  if (!trak->mdia)
sl@0
  7886
    return -1;
sl@0
  7887
  if (!trak->mdia->mdhd)
sl@0
  7888
    return -1;
sl@0
  7889
  if (!trak->mdia->minf)
sl@0
  7890
    return -1;
sl@0
  7891
  if (!trak->mdia->minf->stbl)
sl@0
  7892
    return -1;
sl@0
  7893
  if (!trak->mdia->minf->stbl->stts)
sl@0
  7894
    return -1;
sl@0
  7895
  if (trak->mdia->minf->stbl->stts->entryCount == 0)
sl@0
  7896
    return -1;
sl@0
  7897
sl@0
  7898
  *sample = 1;
sl@0
  7899
  tmppos = 0;
sl@0
  7900
sl@0
  7901
  pos = (mp4_u32)((mp4_double)position / (mp4_double)1000 * (mp4_double)trak->mdia->mdhd->timeScale + (mp4_double)0.5);
sl@0
  7902
sl@0
  7903
  for (i = 0; i < trak->mdia->minf->stbl->stts->entryCount; i++)
sl@0
  7904
  {
sl@0
  7905
    if (pos >= (tmppos + trak->mdia->minf->stbl->stts->sampleCount[i] *
sl@0
  7906
                         trak->mdia->minf->stbl->stts->sampleDelta[i]))
sl@0
  7907
    {
sl@0
  7908
      *sample += trak->mdia->minf->stbl->stts->sampleCount[i];
sl@0
  7909
      tmppos += (trak->mdia->minf->stbl->stts->sampleCount[i] *
sl@0
  7910
                 trak->mdia->minf->stbl->stts->sampleDelta[i]);
sl@0
  7911
sl@0
  7912
      if (i == trak->mdia->minf->stbl->stts->entryCount - 1) /* Last entry */
sl@0
  7913
        *sample = *sample - 1;
sl@0
  7914
    }
sl@0
  7915
    else
sl@0
  7916
    {
sl@0
  7917
      if (trak->mdia->minf->stbl->stts->sampleDelta[i] == 0)
sl@0
  7918
        return -1;
sl@0
  7919
sl@0
  7920
      *sample += ((pos - tmppos) / trak->mdia->minf->stbl->stts->sampleDelta[i]);
sl@0
  7921
sl@0
  7922
      break;
sl@0
  7923
    }
sl@0
  7924
  }
sl@0
  7925
sl@0
  7926
  return 0;
sl@0
  7927
}
sl@0
  7928
sl@0
  7929
sl@0
  7930
/*
sl@0
  7931
 * Function:
sl@0
  7932
 *
sl@0
  7933
 *   mp4_i32 goToVideoSample(MP4HandleImp handle,
sl@0
  7934
 *                           trackAtom *trak,
sl@0
  7935
 *                           mp4_u32 sample)
sl@0
  7936
 *
sl@0
  7937
 * Description:
sl@0
  7938
 *
sl@0
  7939
 *   This function moves to video sample indicated by sample and finds the
sl@0
  7940
 *   sample offset and sample size.
sl@0
  7941
 *
sl@0
  7942
 * Parameters:
sl@0
  7943
 *
sl@0
  7944
 *   handle    MP4 library handle
sl@0
  7945
 *   trak      TRAK atom pointer
sl@0
  7946
 *   sample    Sample to go to
sl@0
  7947
 *
sl@0
  7948
 * Return value:
sl@0
  7949
 *
sl@0
  7950
 *   0         Success
sl@0
  7951
 *   Negative  Error
sl@0
  7952
 *
sl@0
  7953
 */
sl@0
  7954
mp4_i32 goToVideoSample(MP4HandleImp handle,
sl@0
  7955
                        trackAtom *trak,
sl@0
  7956
                        mp4_u32 sample)
sl@0
  7957
{
sl@0
  7958
  if (!trak->mdia)
sl@0
  7959
    return -1;
sl@0
  7960
  if (!trak->mdia->minf)
sl@0
  7961
    return -1;
sl@0
  7962
  if (!trak->mdia->minf->stbl)
sl@0
  7963
    return -1;
sl@0
  7964
  if (!trak->mdia->minf->stbl->stsz)
sl@0
  7965
    return -1;
sl@0
  7966
sl@0
  7967
sl@0
  7968
  /* Is the sample valid? */
sl@0
  7969
sl@0
  7970
  if (sample <= trak->mdia->minf->stbl->stsz->sampleCount)
sl@0
  7971
    handle->videoSampleNum = sample;
sl@0
  7972
  else
sl@0
  7973
    return -1;
sl@0
  7974
sl@0
  7975
  /* Find the size of the sample */
sl@0
  7976
sl@0
  7977
  if (resolveVideoSampleSize(handle, trak->mdia->minf->stbl->stsz) < 0)
sl@0
  7978
    return -1;
sl@0
  7979
sl@0
  7980
  /* Find the offset of the sample */
sl@0
  7981
sl@0
  7982
  if (resolveVideoSampleOffset(handle, trak->mdia->minf->stbl) < 0)
sl@0
  7983
    return -1;
sl@0
  7984
sl@0
  7985
sl@0
  7986
  return 0;
sl@0
  7987
}
sl@0
  7988
sl@0
  7989
sl@0
  7990
/*
sl@0
  7991
 * Function:
sl@0
  7992
 *
sl@0
  7993
 *   mp4_i32 goToAudioSample(MP4HandleImp handle,
sl@0
  7994
 *                           trackAtom *trak,
sl@0
  7995
 *                           mp4_u32 sample)
sl@0
  7996
 *
sl@0
  7997
 * Description:
sl@0
  7998
 *
sl@0
  7999
 *   This function moves to audio sample indicated by sample and finds the
sl@0
  8000
 *   sample offset and sample size.
sl@0
  8001
 *
sl@0
  8002
 * Parameters:
sl@0
  8003
 *
sl@0
  8004
 *   handle    MP4 library handle
sl@0
  8005
 *   trak      TRAK atom pointer
sl@0
  8006
 *   sample    Sample to go to
sl@0
  8007
 *
sl@0
  8008
 * Return value:
sl@0
  8009
 *
sl@0
  8010
 *   0         Success
sl@0
  8011
 *   Negative  Error
sl@0
  8012
 *
sl@0
  8013
 */
sl@0
  8014
mp4_i32 goToAudioSample(MP4HandleImp handle,
sl@0
  8015
                        trackAtom *trak,
sl@0
  8016
                        mp4_u32 sample)
sl@0
  8017
{
sl@0
  8018
  if (!trak->mdia)
sl@0
  8019
    return -1;
sl@0
  8020
  if (!trak->mdia->minf)
sl@0
  8021
    return -1;
sl@0
  8022
  if (!trak->mdia->minf->stbl)
sl@0
  8023
    return -1;
sl@0
  8024
  if (!trak->mdia->minf->stbl->stsz)
sl@0
  8025
    return -1;
sl@0
  8026
sl@0
  8027
sl@0
  8028
  /* Is the sample valid? */
sl@0
  8029
sl@0
  8030
  if (sample <= trak->mdia->minf->stbl->stsz->sampleCount)
sl@0
  8031
    handle->audioSampleNum = sample;
sl@0
  8032
  else
sl@0
  8033
    return -1;
sl@0
  8034
sl@0
  8035
  /* Find the size of the sample */
sl@0
  8036
sl@0
  8037
  if (resolveAudioSampleSize(handle, trak->mdia->minf->stbl->stsz) < 0)
sl@0
  8038
    return -1;
sl@0
  8039
sl@0
  8040
  /* Find the offset of the sample */
sl@0
  8041
sl@0
  8042
  if (resolveAudioSampleOffset(handle, trak->mdia->minf->stbl) < 0)
sl@0
  8043
    return -1;
sl@0
  8044
sl@0
  8045
sl@0
  8046
  return 0;
sl@0
  8047
}
sl@0
  8048
sl@0
  8049
sl@0
  8050
/*
sl@0
  8051
 * Function:
sl@0
  8052
 *
sl@0
  8053
 *   mp4_i32 findVideoKeyFrame(MP4HandleImp handle,
sl@0
  8054
 *                             trackAtom *trak,
sl@0
  8055
 *                             mp4_u32 sample,
sl@0
  8056
 *                             mp4_u32 *newsample)
sl@0
  8057
 *
sl@0
  8058
 * Description:
sl@0
  8059
 *
sl@0
  8060
 *   This function finds the video keyframe that is identical to or precedes
sl@0
  8061
 *   the sample indicated by sample.
sl@0
  8062
 *
sl@0
  8063
 * Parameters:
sl@0
  8064
 *
sl@0
  8065
 *   handle       MP4 library handle
sl@0
  8066
 *   trak         TRAK atom pointer
sl@0
  8067
 *   sample       Sample number
sl@0
  8068
 *   newsample    Sample number of found keyframe
sl@0
  8069
 *
sl@0
  8070
 * Return value:
sl@0
  8071
 *
sl@0
  8072
 *   0            Success
sl@0
  8073
 *   Negative     Error
sl@0
  8074
 *
sl@0
  8075
 */
sl@0
  8076
mp4_i32 findVideoKeyFrame(MP4HandleImp handle,
sl@0
  8077
                          trackAtom *trak,
sl@0
  8078
                          mp4_u32 sample,
sl@0
  8079
                          mp4_u32 *newsample)
sl@0
  8080
{
sl@0
  8081
  mp4_i32  i;
sl@0
  8082
sl@0
  8083
sl@0
  8084
  if (!handle)
sl@0
  8085
    return -1;
sl@0
  8086
  if (!trak->mdia)
sl@0
  8087
    return -1;
sl@0
  8088
  if (!trak->mdia->minf)
sl@0
  8089
    return -1;
sl@0
  8090
  if (!trak->mdia->minf->stbl)
sl@0
  8091
    return -1;
sl@0
  8092
sl@0
  8093
  if (!trak->mdia->minf->stbl->stss) /* No sync sample atom => all samples are
sl@0
  8094
                                        random access points */
sl@0
  8095
  {
sl@0
  8096
    *newsample = sample;
sl@0
  8097
sl@0
  8098
    return 0;
sl@0
  8099
  }
sl@0
  8100
  *newsample = 0;
sl@0
  8101
sl@0
  8102
  for (i = trak->mdia->minf->stbl->stss->entryCount - 1; i >= 0; i--)
sl@0
  8103
  {
sl@0
  8104
    if (sample >= trak->mdia->minf->stbl->stss->sampleNumber[i])
sl@0
  8105
    {
sl@0
  8106
      *newsample = trak->mdia->minf->stbl->stss->sampleNumber[i];
sl@0
  8107
      break;
sl@0
  8108
    }
sl@0
  8109
  }
sl@0
  8110
sl@0
  8111
  if (*newsample == 0)
sl@0
  8112
    return -1;
sl@0
  8113
sl@0
  8114
  return 0;
sl@0
  8115
}
sl@0
  8116
sl@0
  8117
sl@0
  8118
/*
sl@0
  8119
 * Function:
sl@0
  8120
 *
sl@0
  8121
 *   mp4_i32 readAVCC(MP4HandleImp handle,
sl@0
  8122
 *                    avcConfigurationAtom *avcc)
sl@0
  8123
 *
sl@0
  8124
 * Description:
sl@0
  8125
 *
sl@0
  8126
 *   This function parses one avcc atom.
sl@0
  8127
 *
sl@0
  8128
 * Parameters:
sl@0
  8129
 *
sl@0
  8130
 *   handle             MP4 library handle
sl@0
  8131
 *   avcc               avcC pointer
sl@0
  8132
 *
sl@0
  8133
 * Return value:
sl@0
  8134
 *
sl@0
  8135
 *   Negative integer   Error
sl@0
  8136
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8137
 *
sl@0
  8138
 */
sl@0
  8139
mp4_i32 readAVCC(MP4HandleImp handle, avcConfigurationAtom *avcc)
sl@0
  8140
{
sl@0
  8141
	mp4_i32 bytesread;
sl@0
  8142
	mp4_i32 totalbytesread = 0;
sl@0
  8143
sl@0
  8144
	avcc->avcConfigSize = 0;
sl@0
  8145
sl@0
  8146
	if ((avcc->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8147
		return -100;
sl@0
  8148
sl@0
  8149
	bytesread = readAtomHeader(handle, avcc->atomhdr);
sl@0
  8150
	if (bytesread < 0)
sl@0
  8151
		return -1;
sl@0
  8152
	totalbytesread +=bytesread;
sl@0
  8153
sl@0
  8154
	if (avcc->atomhdr->type != ATOMTYPE_AVCC)
sl@0
  8155
		return -1;
sl@0
  8156
sl@0
  8157
    /* read the avcDecoderConfigurationRecord */
sl@0
  8158
    if  (avcc->atomhdr->size != 1)
sl@0
  8159
    	avcc->avcConfigSize = avcc->atomhdr->size - 8;
sl@0
  8160
    else
sl@0
  8161
    	avcc->avcConfigSize = (mp4_u32)(I64INT(avcc->atomhdr->largeSize) - 16);
sl@0
  8162
sl@0
  8163
   	avcc->avcConfig = (mp4_u8 *)mp4malloc(avcc->avcConfigSize);
sl@0
  8164
	if (avcc->avcConfig == 0)
sl@0
  8165
		return -100;
sl@0
  8166
	
sl@0
  8167
	bytesread = readData(handle, avcc->avcConfig, avcc->avcConfigSize );
sl@0
  8168
    
sl@0
  8169
	if (bytesread < 0)
sl@0
  8170
		return -1;
sl@0
  8171
	totalbytesread +=bytesread;
sl@0
  8172
	return totalbytesread;
sl@0
  8173
}
sl@0
  8174
sl@0
  8175
sl@0
  8176
/*
sl@0
  8177
 * Function:
sl@0
  8178
 *
sl@0
  8179
 *   mp4_i32 readBTRT(MP4HandleImp handle,
sl@0
  8180
 *                    mpeg4BitrateAtom *btrt)
sl@0
  8181
 *
sl@0
  8182
 * Description:
sl@0
  8183
 *
sl@0
  8184
 *   This function parses one btrt atom.
sl@0
  8185
 *
sl@0
  8186
 * Parameters:
sl@0
  8187
 *
sl@0
  8188
 *   handle             MP4 library handle
sl@0
  8189
 *   btrt					btrt pointer
sl@0
  8190
 *
sl@0
  8191
 * Return value:
sl@0
  8192
 *
sl@0
  8193
 *   Negative integer   Error
sl@0
  8194
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8195
 *
sl@0
  8196
 */
sl@0
  8197
mp4_i32 readBTRT(MP4HandleImp handle, mpeg4BitrateAtom *btrt)
sl@0
  8198
{
sl@0
  8199
	mp4_i32 bytesread;
sl@0
  8200
	mp4_i32 totalbytesread = 0;
sl@0
  8201
sl@0
  8202
sl@0
  8203
	if ((btrt->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8204
		return -100;
sl@0
  8205
sl@0
  8206
	bytesread = readAtomHeader(handle, btrt->atomhdr);
sl@0
  8207
	if (bytesread < 0)
sl@0
  8208
		return -1;
sl@0
  8209
	totalbytesread +=bytesread;
sl@0
  8210
sl@0
  8211
	if (btrt->atomhdr->type != ATOMTYPE_BTRT)
sl@0
  8212
		return -1;
sl@0
  8213
sl@0
  8214
    /* read the mpeg4BitrateAtom */
sl@0
  8215
   bytesread = readData(handle, handle->buf, 4);
sl@0
  8216
   if (bytesread < 0)
sl@0
  8217
	   return -1;
sl@0
  8218
   btrt->bufferSizeDB = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  8219
   totalbytesread +=bytesread;
sl@0
  8220
sl@0
  8221
   bytesread = readData(handle, handle->buf, 4);
sl@0
  8222
   if (bytesread < 0)
sl@0
  8223
	   return -1;
sl@0
  8224
   btrt->maxBitRate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  8225
   totalbytesread +=bytesread;
sl@0
  8226
sl@0
  8227
   bytesread = readData(handle, handle->buf, 4);
sl@0
  8228
   if (bytesread < 0)
sl@0
  8229
	   return -1;
sl@0
  8230
   btrt->avgBitrate = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  8231
   totalbytesread +=bytesread;
sl@0
  8232
sl@0
  8233
	return totalbytesread;
sl@0
  8234
}
sl@0
  8235
sl@0
  8236
/*
sl@0
  8237
 * Function:
sl@0
  8238
 *
sl@0
  8239
 *   mp4_i32 readM4DS(MP4HandleImp handle,
sl@0
  8240
 *                    mpeg4ExtensionDescriptorsAtom *m4ds)
sl@0
  8241
 *
sl@0
  8242
 * Description:
sl@0
  8243
 *
sl@0
  8244
 *   This function parses one m4ds atom.
sl@0
  8245
 *
sl@0
  8246
 * Parameters:
sl@0
  8247
 *
sl@0
  8248
 *   handle             MP4 library handle
sl@0
  8249
 *   m4ds               m4ds pointer
sl@0
  8250
 *
sl@0
  8251
 * Return value:
sl@0
  8252
 *
sl@0
  8253
 *   Negative integer   Error
sl@0
  8254
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8255
 *
sl@0
  8256
 */
sl@0
  8257
mp4_i32 readM4DS(MP4HandleImp handle, mpeg4ExtensionDescriptorsAtom *m4ds)
sl@0
  8258
{
sl@0
  8259
	mp4_i32 bytesread;
sl@0
  8260
	mp4_i32 totalbytesread = 0;
sl@0
  8261
	mp4_u32 i;
sl@0
  8262
sl@0
  8263
	m4ds->descrSize = 0;
sl@0
  8264
sl@0
  8265
	if ((m4ds->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8266
		return -100;
sl@0
  8267
sl@0
  8268
	bytesread = readAtomHeader(handle, m4ds->atomhdr);
sl@0
  8269
	if (bytesread < 0)
sl@0
  8270
		return -1;
sl@0
  8271
	totalbytesread +=bytesread;
sl@0
  8272
sl@0
  8273
	if (m4ds->atomhdr->type != ATOMTYPE_M4DS)
sl@0
  8274
		return -1;
sl@0
  8275
sl@0
  8276
    /* read the avcDecoderConfigurationRecord */
sl@0
  8277
	if  (m4ds->atomhdr->size != 1)
sl@0
  8278
		bytesread = readData(handle, handle->buf, m4ds->atomhdr->size - 8);
sl@0
  8279
	else
sl@0
  8280
        bytesread = readData(handle, handle->buf, (mp4_u32)(I64INT(m4ds->atomhdr->largeSize) - 16) );
sl@0
  8281
sl@0
  8282
	if (bytesread < 0)
sl@0
  8283
		return -1;
sl@0
  8284
	m4ds->descrSize = bytesread;
sl@0
  8285
	m4ds->descr = (mp4_u8 *)mp4malloc(m4ds->descrSize * sizeof(mp4_u8));
sl@0
  8286
	
sl@0
  8287
	/* copy the mpeg4ExtensionDescriptors from the temp. buffer */
sl@0
  8288
	for(i = 0; i <  m4ds->descrSize; i++)
sl@0
  8289
		m4ds->descr[i] = handle->buf[i];
sl@0
  8290
	
sl@0
  8291
	totalbytesread +=bytesread;
sl@0
  8292
sl@0
  8293
	return totalbytesread;
sl@0
  8294
}
sl@0
  8295
sl@0
  8296
/*
sl@0
  8297
 * Function:
sl@0
  8298
 *
sl@0
  8299
 *   mp4_i32 readAVC1(MP4HandleImp handle,
sl@0
  8300
 *                    avcSampleEntry *avc1)
sl@0
  8301
 *
sl@0
  8302
 * Description:
sl@0
  8303
 *
sl@0
  8304
 *   This function parses one avc1 atom.
sl@0
  8305
 *
sl@0
  8306
 * Parameters:
sl@0
  8307
 *
sl@0
  8308
 *   handle             MP4 library handle
sl@0
  8309
 *   avc1               avc1 pointer
sl@0
  8310
 *
sl@0
  8311
 * Return value:
sl@0
  8312
 *
sl@0
  8313
 *   Negative integer   Error
sl@0
  8314
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8315
 *
sl@0
  8316
 */
sl@0
  8317
mp4_i32 readAVC1(MP4HandleImp handle, avcSampleEntry *avc1)
sl@0
  8318
{
sl@0
  8319
  mp4_i32 bytesread;
sl@0
  8320
  mp4_i32 totalbytesread = 0;
sl@0
  8321
sl@0
  8322
  if ((avc1->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8323
    return -100;
sl@0
  8324
sl@0
  8325
  bytesread = readAtomHeader(handle, avc1->atomhdr);
sl@0
  8326
sl@0
  8327
  if (bytesread < 0)
sl@0
  8328
    return -1;
sl@0
  8329
  totalbytesread += bytesread;
sl@0
  8330
sl@0
  8331
  if (avc1->atomhdr->type != ATOMTYPE_AVC1)
sl@0
  8332
    return -1;
sl@0
  8333
sl@0
  8334
  bytesread = discardData(handle, 6);
sl@0
  8335
  if (bytesread < 0)
sl@0
  8336
    return -1;
sl@0
  8337
  totalbytesread += bytesread;
sl@0
  8338
sl@0
  8339
  bytesread = readData(handle, handle->buf, 2);
sl@0
  8340
  if (bytesread < 0)
sl@0
  8341
    return -1;
sl@0
  8342
  avc1->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  8343
  totalbytesread += bytesread;
sl@0
  8344
sl@0
  8345
  bytesread = discardData(handle, 16);
sl@0
  8346
  if (bytesread < 0)
sl@0
  8347
    return -1;
sl@0
  8348
  totalbytesread += bytesread;
sl@0
  8349
sl@0
  8350
  bytesread = readData(handle, handle->buf, 2);
sl@0
  8351
  if (bytesread < 0)
sl@0
  8352
    return -1;
sl@0
  8353
  avc1->width = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  8354
  totalbytesread += bytesread;
sl@0
  8355
sl@0
  8356
  bytesread = readData(handle, handle->buf, 2);
sl@0
  8357
  if (bytesread < 0)
sl@0
  8358
    return -1;
sl@0
  8359
  avc1->height = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  8360
  totalbytesread += bytesread;
sl@0
  8361
sl@0
  8362
  bytesread = discardData(handle, 50);
sl@0
  8363
  if (bytesread < 0)
sl@0
  8364
    return -1;
sl@0
  8365
  totalbytesread += bytesread;
sl@0
  8366
sl@0
  8367
  /* Check for the present atoms */
sl@0
  8368
  while ((mp4_u32)totalbytesread < avc1->atomhdr->size)
sl@0
  8369
  {
sl@0
  8370
    mp4_u32 type;
sl@0
  8371
sl@0
  8372
    if (peekData(handle, handle->buf, 8) < 0)
sl@0
  8373
      return -1;
sl@0
  8374
sl@0
  8375
    type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  8376
sl@0
  8377
    switch (type)
sl@0
  8378
    {
sl@0
  8379
    case ATOMTYPE_AVCC:
sl@0
  8380
sl@0
  8381
		if (avc1->avcc) /* avcC has already been read, more than one is not allowed. */
sl@0
  8382
			return -1;
sl@0
  8383
sl@0
  8384
		if ((avc1->avcc = (avcConfigurationAtom *)mp4malloc(sizeof(avcConfigurationAtom))) == NULL)
sl@0
  8385
			return -100;
sl@0
  8386
sl@0
  8387
		bytesread = readAVCC(handle, avc1->avcc);  
sl@0
  8388
		if(bytesread < 0)
sl@0
  8389
			return -1;
sl@0
  8390
		totalbytesread +=bytesread;
sl@0
  8391
  	    break;
sl@0
  8392
sl@0
  8393
    case ATOMTYPE_BTRT:
sl@0
  8394
sl@0
  8395
		if (avc1->btrt) /* btrt has already been read, more than one is not allowed. */
sl@0
  8396
			return -1;
sl@0
  8397
sl@0
  8398
		if ((avc1->btrt = (mpeg4BitrateAtom *)mp4malloc(sizeof(mpeg4BitrateAtom))) == NULL)
sl@0
  8399
			return -100;
sl@0
  8400
sl@0
  8401
		bytesread = readBTRT(handle, avc1->btrt);  
sl@0
  8402
		if(bytesread < 0)
sl@0
  8403
			return -1;
sl@0
  8404
		totalbytesread +=bytesread;
sl@0
  8405
	    break;
sl@0
  8406
sl@0
  8407
    case ATOMTYPE_M4DS:
sl@0
  8408
sl@0
  8409
		if (avc1->m4ds) /* m4ds has already been read, more than one is not allowed. */
sl@0
  8410
			return -1;
sl@0
  8411
sl@0
  8412
		if ((avc1->m4ds = (mpeg4ExtensionDescriptorsAtom *)mp4malloc(sizeof(mpeg4ExtensionDescriptorsAtom))) == NULL)
sl@0
  8413
			return -100;
sl@0
  8414
sl@0
  8415
		bytesread = readM4DS(handle, avc1->m4ds);  
sl@0
  8416
		if(bytesread < 0)
sl@0
  8417
			return -1;
sl@0
  8418
		totalbytesread +=bytesread;
sl@0
  8419
	    break;
sl@0
  8420
	 
sl@0
  8421
	 default:
sl@0
  8422
sl@0
  8423
        bytesread = readUnknown(handle);
sl@0
  8424
        if (bytesread < 0)
sl@0
  8425
            return -1;
sl@0
  8426
        totalbytesread += bytesread;
sl@0
  8427
sl@0
  8428
        break;
sl@0
  8429
sl@0
  8430
	}
sl@0
  8431
  }
sl@0
  8432
sl@0
  8433
  return totalbytesread;
sl@0
  8434
}
sl@0
  8435
sl@0
  8436
/*
sl@0
  8437
 * Function:
sl@0
  8438
 *
sl@0
  8439
 *   mp4_i32 freeAVCC(avcConfigurationAtom *avcc)
sl@0
  8440
 *
sl@0
  8441
 * Description:
sl@0
  8442
 *
sl@0
  8443
 *   This function frees memory for avcc atom.
sl@0
  8444
 *
sl@0
  8445
 * Parameters:
sl@0
  8446
 *
sl@0
  8447
 *   avcc       avcc atom pointer
sl@0
  8448
 *
sl@0
  8449
 * Return value:
sl@0
  8450
 *
sl@0
  8451
 *   0          Success
sl@0
  8452
 *   Negative   Error
sl@0
  8453
 *
sl@0
  8454
 */
sl@0
  8455
mp4_i32 freeAVCC(avcConfigurationAtom *avcc)
sl@0
  8456
{
sl@0
  8457
  if (avcc)
sl@0
  8458
  {
sl@0
  8459
    if (freeAtomHeader(avcc->atomhdr) < 0)
sl@0
  8460
      return -1;
sl@0
  8461
	if(avcc->avcConfig)
sl@0
  8462
		mp4free(avcc->avcConfig);
sl@0
  8463
sl@0
  8464
    mp4free(avcc);
sl@0
  8465
  }
sl@0
  8466
sl@0
  8467
  return 0;
sl@0
  8468
}
sl@0
  8469
sl@0
  8470
/*
sl@0
  8471
 * Function:
sl@0
  8472
 *
sl@0
  8473
 *   mp4_i32 freeBTRT(mpeg4BitrateAtom *btrt)
sl@0
  8474
 *
sl@0
  8475
 * Description:
sl@0
  8476
 *
sl@0
  8477
 *   This function frees memory for btrt atom.
sl@0
  8478
 *
sl@0
  8479
 * Parameters:
sl@0
  8480
 *
sl@0
  8481
 *   btrt       btrt atom pointer
sl@0
  8482
 *
sl@0
  8483
 * Return value:
sl@0
  8484
 *
sl@0
  8485
 *   0          Success
sl@0
  8486
 *   Negative   Error
sl@0
  8487
 *
sl@0
  8488
 */
sl@0
  8489
mp4_i32 freeBTRT(mpeg4BitrateAtom *btrt)
sl@0
  8490
{
sl@0
  8491
  if (btrt)
sl@0
  8492
  {
sl@0
  8493
    if (freeAtomHeader(btrt->atomhdr) < 0)
sl@0
  8494
      return -1;
sl@0
  8495
sl@0
  8496
    mp4free(btrt);
sl@0
  8497
  }
sl@0
  8498
sl@0
  8499
  return 0;
sl@0
  8500
}
sl@0
  8501
sl@0
  8502
/*
sl@0
  8503
 * Function:
sl@0
  8504
 *
sl@0
  8505
 *   mp4_i32 freeM4DS(mpeg4ExtensionDescriptorsAtom *m4ds)
sl@0
  8506
 *
sl@0
  8507
 * Description:
sl@0
  8508
 *
sl@0
  8509
 *   This function frees memory for m4ds atom.
sl@0
  8510
 *
sl@0
  8511
 * Parameters:
sl@0
  8512
 *
sl@0
  8513
 *   m4ds       m4ds atom pointer
sl@0
  8514
 *
sl@0
  8515
 * Return value:
sl@0
  8516
 *
sl@0
  8517
 *   0          Success
sl@0
  8518
 *   Negative   Error
sl@0
  8519
 *
sl@0
  8520
 */
sl@0
  8521
mp4_i32 freeM4DS(mpeg4ExtensionDescriptorsAtom *m4ds)
sl@0
  8522
{
sl@0
  8523
  if (m4ds)
sl@0
  8524
  {
sl@0
  8525
    if (freeAtomHeader(m4ds->atomhdr) < 0)
sl@0
  8526
      return -1;
sl@0
  8527
	if(m4ds->descr)
sl@0
  8528
		mp4free(m4ds->descr);
sl@0
  8529
sl@0
  8530
    mp4free(m4ds);
sl@0
  8531
  }
sl@0
  8532
sl@0
  8533
  return 0;
sl@0
  8534
}
sl@0
  8535
sl@0
  8536
/*
sl@0
  8537
 * Function:
sl@0
  8538
 *
sl@0
  8539
 *   mp4_i32 freeAVC1(avcSampleEntry *avc1)
sl@0
  8540
 *
sl@0
  8541
 * Description:
sl@0
  8542
 *
sl@0
  8543
 *   This function frees memory for avc1 atom.
sl@0
  8544
 *
sl@0
  8545
 * Parameters:
sl@0
  8546
 *
sl@0
  8547
 *   avc1       avc1 atom pointer
sl@0
  8548
 *
sl@0
  8549
 * Return value:
sl@0
  8550
 *
sl@0
  8551
 *   0          Success
sl@0
  8552
 *   Negative   Error
sl@0
  8553
 *
sl@0
  8554
 */
sl@0
  8555
mp4_i32 freeAVC1(avcSampleEntry *avc1)
sl@0
  8556
{
sl@0
  8557
  if (avc1)
sl@0
  8558
  {
sl@0
  8559
    if (freeAtomHeader(avc1->atomhdr) < 0)
sl@0
  8560
      return -1;
sl@0
  8561
    if (freeAVCC(avc1->avcc) < 0)
sl@0
  8562
      return -1;
sl@0
  8563
	if (freeBTRT(avc1->btrt) < 0)
sl@0
  8564
		return -1;
sl@0
  8565
	if (freeM4DS(avc1->m4ds) < 0)
sl@0
  8566
		return -1;
sl@0
  8567
sl@0
  8568
    mp4free(avc1);
sl@0
  8569
  }
sl@0
  8570
sl@0
  8571
  return 0;
sl@0
  8572
}
sl@0
  8573
sl@0
  8574
/*
sl@0
  8575
 * Function:
sl@0
  8576
 *
sl@0
  8577
 *   mp4_i32 readSQCP(MP4HandleImp handle,
sl@0
  8578
 *                    qcelpSampleEntry *sqcp)
sl@0
  8579
 *
sl@0
  8580
 * Description:
sl@0
  8581
 *
sl@0
  8582
 *   This function parses one SQCP atom.
sl@0
  8583
 *
sl@0
  8584
 * Parameters:
sl@0
  8585
 *
sl@0
  8586
 *   handle             MP4 library handle
sl@0
  8587
 *   sqcp               SQCP pointer
sl@0
  8588
 *
sl@0
  8589
 * Return value:
sl@0
  8590
 *
sl@0
  8591
 *   Negative integer   Error
sl@0
  8592
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8593
 *
sl@0
  8594
 */
sl@0
  8595
mp4_i32 readSQCP(MP4HandleImp handle, qcelpSampleEntry *sqcp)
sl@0
  8596
{
sl@0
  8597
  mp4_i32 bytesread;
sl@0
  8598
  mp4_i32 totalbytesread = 0;
sl@0
  8599
sl@0
  8600
sl@0
  8601
  if ((sqcp->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8602
    return -100;
sl@0
  8603
sl@0
  8604
  bytesread = readAtomHeader(handle, sqcp->atomhdr);
sl@0
  8605
  if (bytesread < 0)
sl@0
  8606
    return -1;
sl@0
  8607
  totalbytesread += bytesread;
sl@0
  8608
sl@0
  8609
  if (sqcp->atomhdr->type != ATOMTYPE_SQCP)
sl@0
  8610
    return -1;
sl@0
  8611
sl@0
  8612
sl@0
  8613
  bytesread = discardData(handle, 6);
sl@0
  8614
  if (bytesread < 0)
sl@0
  8615
    return -1;
sl@0
  8616
  totalbytesread += bytesread;
sl@0
  8617
sl@0
  8618
  bytesread = readData(handle, handle->buf, 2);
sl@0
  8619
  if (bytesread < 0)
sl@0
  8620
    return -1;
sl@0
  8621
  sqcp->dataReferenceIndex = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  8622
  totalbytesread += bytesread;
sl@0
  8623
sl@0
  8624
  bytesread = discardData(handle, 16);
sl@0
  8625
  if (bytesread < 0)
sl@0
  8626
    return -1;
sl@0
  8627
  totalbytesread += bytesread;
sl@0
  8628
sl@0
  8629
  bytesread = readData(handle, handle->buf, 2);
sl@0
  8630
  if (bytesread < 0)
sl@0
  8631
    return -1;
sl@0
  8632
  sqcp->timeScale = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  8633
  totalbytesread += bytesread;
sl@0
  8634
sl@0
  8635
  bytesread = discardData(handle, 2);
sl@0
  8636
  if (bytesread < 0)
sl@0
  8637
    return -1;
sl@0
  8638
  totalbytesread += bytesread;
sl@0
  8639
sl@0
  8640
  if ((sqcp->dqcp = (qcelpDecSpecStruc *)mp4malloc(sizeof(qcelpDecSpecStruc))) == NULL)
sl@0
  8641
    return -100;
sl@0
  8642
sl@0
  8643
  bytesread = readDQCP(handle, sqcp->dqcp);
sl@0
  8644
  if (bytesread < 0)
sl@0
  8645
    return -1;
sl@0
  8646
  totalbytesread += bytesread;
sl@0
  8647
  
sl@0
  8648
  if ( totalbytesread < sqcp->atomhdr->size )
sl@0
  8649
  	{
sl@0
  8650
    bytesread = discardData(handle, sqcp->atomhdr->size - totalbytesread );
sl@0
  8651
  	if (bytesread < 0)
sl@0
  8652
  		{
sl@0
  8653
    	return -1;	  		
sl@0
  8654
  		}
sl@0
  8655
  	totalbytesread += bytesread;
sl@0
  8656
  	}  
sl@0
  8657
sl@0
  8658
  return totalbytesread;
sl@0
  8659
}
sl@0
  8660
sl@0
  8661
/*
sl@0
  8662
 * Function:
sl@0
  8663
 *
sl@0
  8664
 *   mp4_i32 freeSQCP(qcelpSampleEntry *sqcp)
sl@0
  8665
 *
sl@0
  8666
 * Description:
sl@0
  8667
 *
sl@0
  8668
 *   This function frees memory for SQCP atom.
sl@0
  8669
 *
sl@0
  8670
 * Parameters:
sl@0
  8671
 *
sl@0
  8672
 *   sqcp       SQCP atom pointer
sl@0
  8673
 *
sl@0
  8674
 * Return value:
sl@0
  8675
 *
sl@0
  8676
 *   0          Success
sl@0
  8677
 *   Negative   Error
sl@0
  8678
 *
sl@0
  8679
 */
sl@0
  8680
mp4_i32 freeSQCP(qcelpSampleEntry *sqcp)
sl@0
  8681
{
sl@0
  8682
  if (sqcp)
sl@0
  8683
  {
sl@0
  8684
    if (freeAtomHeader(sqcp->atomhdr) < 0)
sl@0
  8685
      return -1;
sl@0
  8686
    if (freeDQCP(sqcp->dqcp) < 0)
sl@0
  8687
      return -1;
sl@0
  8688
sl@0
  8689
    mp4free(sqcp);
sl@0
  8690
  }
sl@0
  8691
sl@0
  8692
  return 0;
sl@0
  8693
}
sl@0
  8694
sl@0
  8695
/*
sl@0
  8696
 * Function:
sl@0
  8697
 *
sl@0
  8698
 *   mp4_i32 readDQCP(MP4HandleImp handle,
sl@0
  8699
 *                    qcelpDecSpecStruc *dqcp)
sl@0
  8700
 *
sl@0
  8701
 * Description:
sl@0
  8702
 *
sl@0
  8703
 *   This function parses one DQCP atom.
sl@0
  8704
 *
sl@0
  8705
 * Parameters:
sl@0
  8706
 *
sl@0
  8707
 *   handle             MP4 library handle
sl@0
  8708
 *   dqcp               DQCP pointer
sl@0
  8709
 *
sl@0
  8710
 * Return value:
sl@0
  8711
 *
sl@0
  8712
 *   Negative integer   Error
sl@0
  8713
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8714
 *
sl@0
  8715
 */
sl@0
  8716
mp4_i32 readDQCP(MP4HandleImp handle, qcelpDecSpecStruc *dqcp)
sl@0
  8717
{
sl@0
  8718
  mp4_i32 bytesread;
sl@0
  8719
  mp4_i32 totalbytesread = 0;
sl@0
  8720
sl@0
  8721
sl@0
  8722
  if ((dqcp->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8723
    return -100;
sl@0
  8724
sl@0
  8725
  bytesread = readAtomHeader(handle, dqcp->atomhdr);
sl@0
  8726
  if (bytesread < 0)
sl@0
  8727
    return -1;
sl@0
  8728
  totalbytesread += bytesread;
sl@0
  8729
sl@0
  8730
  if (dqcp->atomhdr->type != ATOMTYPE_DQCP)
sl@0
  8731
    return -1;
sl@0
  8732
sl@0
  8733
sl@0
  8734
  bytesread = readData(handle, handle->buf, 4);
sl@0
  8735
  if (bytesread < 0)
sl@0
  8736
    return -1;
sl@0
  8737
  dqcp->vendor = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  8738
  totalbytesread += bytesread;
sl@0
  8739
sl@0
  8740
  bytesread = readData(handle, handle->buf, 1);
sl@0
  8741
  if (bytesread < 0)
sl@0
  8742
    return -1;
sl@0
  8743
  dqcp->decoderVersion = handle->buf[0];
sl@0
  8744
  totalbytesread += bytesread;
sl@0
  8745
sl@0
  8746
  bytesread = readData(handle, handle->buf, 1);
sl@0
  8747
  if (bytesread < 0)
sl@0
  8748
    return -1;
sl@0
  8749
  dqcp->framesPerSample = handle->buf[0];
sl@0
  8750
  totalbytesread += bytesread;
sl@0
  8751
sl@0
  8752
  return totalbytesread;
sl@0
  8753
}
sl@0
  8754
sl@0
  8755
/*
sl@0
  8756
 * Function:
sl@0
  8757
 *
sl@0
  8758
 *   mp4_i32 freeDQCP(qcelpDecSpecStruc *dqcp)
sl@0
  8759
 *
sl@0
  8760
 * Description:
sl@0
  8761
 *
sl@0
  8762
 *   This function frees memory for DQCP atom.
sl@0
  8763
 *
sl@0
  8764
 * Parameters:
sl@0
  8765
 *
sl@0
  8766
 *   damr       DQCP atom pointer
sl@0
  8767
 *
sl@0
  8768
 * Return value:
sl@0
  8769
 *
sl@0
  8770
 *   0          Success
sl@0
  8771
 *   Negative   Error
sl@0
  8772
 *
sl@0
  8773
 */
sl@0
  8774
mp4_i32 freeDQCP(qcelpDecSpecStruc *dqcp)
sl@0
  8775
{
sl@0
  8776
  if (dqcp)
sl@0
  8777
  {
sl@0
  8778
    if (freeAtomHeader(dqcp->atomhdr) < 0)
sl@0
  8779
      return -1;
sl@0
  8780
sl@0
  8781
    mp4free(dqcp);
sl@0
  8782
  }
sl@0
  8783
sl@0
  8784
  return 0;
sl@0
  8785
}
sl@0
  8786
sl@0
  8787
/*
sl@0
  8788
 * Function:
sl@0
  8789
 *
sl@0
  8790
 *   mp4_i32 readSDTP(MP4HandleImp handle, sampleDependencyAtom *sdtp, 
sl@0
  8791
 * 				      mp4_i32 sample_count)
sl@0
  8792
 *
sl@0
  8793
 * Description:
sl@0
  8794
 *
sl@0
  8795
 *   This function parses one SDTP atom.
sl@0
  8796
 *
sl@0
  8797
 * Parameters:
sl@0
  8798
 *
sl@0
  8799
 *   handle             MP4 library handle
sl@0
  8800
 *   sdtp               SDTP atom pointer
sl@0
  8801
 *
sl@0
  8802
 * Return value:
sl@0
  8803
 *
sl@0
  8804
 *   Negative integer   Error
sl@0
  8805
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8806
 *
sl@0
  8807
 */
sl@0
  8808
sl@0
  8809
mp4_i32 readSDTP(MP4HandleImp handle, 
sl@0
  8810
				 sampleDependencyAtom *sdtp, 
sl@0
  8811
				 mp4_i32 sample_count)
sl@0
  8812
{
sl@0
  8813
  mp4_i32 bytesread = 0;
sl@0
  8814
  mp4_i32 totalbytesread = 0;
sl@0
  8815
  mp4_u32 i = 0;
sl@0
  8816
sl@0
  8817
  if ((sdtp->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8818
    return -100;
sl@0
  8819
sl@0
  8820
  bytesread = readAtomHeader(handle, sdtp->atomhdr);
sl@0
  8821
  if (bytesread < 0)
sl@0
  8822
    return -1;
sl@0
  8823
  totalbytesread += bytesread;
sl@0
  8824
sl@0
  8825
  if (sdtp->atomhdr->type != ATOMTYPE_SDTP)
sl@0
  8826
    return -1;
sl@0
  8827
  
sl@0
  8828
  bytesread = readData(handle, handle->buf, 1); //Version must be 0
sl@0
  8829
  if (bytesread < 0 || handle->buf[0] != 0)
sl@0
  8830
    return -1;
sl@0
  8831
  totalbytesread += bytesread;
sl@0
  8832
  bytesread = readData(handle, handle->buf, 3); // Flags must be 0
sl@0
  8833
  if (bytesread < 0 || handle->buf[0] != 0 || handle->buf[1] != 0 || handle->buf[2] != 0)
sl@0
  8834
    return -1;
sl@0
  8835
  totalbytesread += bytesread;
sl@0
  8836
sl@0
  8837
  // sample_count == (size_of_atom - 12) ???  12 = size + 'sdtp' + ver + flags = 4 + 4 + 1 + 3 ???
sl@0
  8838
  //
sl@0
  8839
  // sample_count is taken from the sample_count in the Sample Size Box ('stsz') or
sl@0
  8840
  // Compact Sample Size Box (‘stz2’).
sl@0
  8841
  if (sample_count != sdtp->atomhdr->size-12 || sample_count < 0)
sl@0
  8842
	  {
sl@0
  8843
	  // as each byte consititue one entry in the table, the number of remaining bytes in this
sl@0
  8844
	  // atom should match the sample count.  If not, the file is corrupted.
sl@0
  8845
	  return -1;
sl@0
  8846
	  }
sl@0
  8847
  
sl@0
  8848
  if ((sdtp->dep = (sampleDependency *)mp4malloc(sample_count * sizeof(sampleDependency))) == NULL)
sl@0
  8849
    return -100;
sl@0
  8850
  
sl@0
  8851
  for(i=0;i<sample_count;i++)
sl@0
  8852
  {
sl@0
  8853
    bytesread = readData(handle, handle->buf, 1);
sl@0
  8854
    if (bytesread < 0)
sl@0
  8855
      return -1;
sl@0
  8856
    
sl@0
  8857
    sdtp->dep[i].sDependsOn = (handle->buf[0] >> 4) & 0x03; // value from 0 to 3
sl@0
  8858
    sdtp->dep[i].sIsDependentOn = (handle->buf[0] >> 2) & 0x03; // value from 0 to 3
sl@0
  8859
    sdtp->dep[i].sHasRedundancy = handle->buf[0] & 0x03; // value from 0 to 3
sl@0
  8860
    totalbytesread += bytesread;
sl@0
  8861
  }
sl@0
  8862
sl@0
  8863
  sdtp->sampleCount = sample_count;
sl@0
  8864
  return totalbytesread;	
sl@0
  8865
}
sl@0
  8866
sl@0
  8867
/*
sl@0
  8868
 * Function:
sl@0
  8869
 *
sl@0
  8870
 *   mp4_i32 readBoxHeader(MP4HandleImp handle, mp4_i64* size, mp4_u32* type)
sl@0
  8871
 * 				      
sl@0
  8872
 *
sl@0
  8873
 * Description:
sl@0
  8874
 *
sl@0
  8875
 *   This function parses the size and type information for a box. 
sl@0
  8876
 *   Taking into account largesize if needed.
sl@0
  8877
 *
sl@0
  8878
 * Parameters:
sl@0
  8879
 *
sl@0
  8880
 *   handle             MP4 library handle
sl@0
  8881
 *   size               Size of box is returned here
sl@0
  8882
 *   type               Type of the box is returned here
sl@0
  8883
 * Return value:
sl@0
  8884
 *
sl@0
  8885
 *   Negative integer   Error
sl@0
  8886
 *   0               Success.
sl@0
  8887
 *
sl@0
  8888
 */
sl@0
  8889
mp4_i32 readBoxHeader(MP4HandleImp handle, mp4_i64* size, mp4_u32* type)
sl@0
  8890
{
sl@0
  8891
  if (peekData(handle, handle->buf, 8) < 0)
sl@0
  8892
    return -1;
sl@0
  8893
sl@0
  8894
  *size = u32endian(*((mp4_u32 *)handle->buf));
sl@0
  8895
  *type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  8896
sl@0
  8897
  if (*size == 1)
sl@0
  8898
  {
sl@0
  8899
    if (peekData(handle, handle->buf, 16) < 0)
sl@0
  8900
      return -1;
sl@0
  8901
    
sl@0
  8902
    *size = u64endian(*((mp4_u64 *)(handle->buf+8)));
sl@0
  8903
  }
sl@0
  8904
sl@0
  8905
  return 0;
sl@0
  8906
}
sl@0
  8907
sl@0
  8908
/*
sl@0
  8909
 */
sl@0
  8910
sl@0
  8911
mp4_i64 getChunkOffset(sampleTableAtom *stbl, mp4_u32 index)
sl@0
  8912
{
sl@0
  8913
  if (stbl->is32BitOffsets)
sl@0
  8914
  	return (mp4_i64)stbl->stco->chunkOffset[index];
sl@0
  8915
  else
sl@0
  8916
    return stbl->stco64->chunkOffset[index];
sl@0
  8917
}
sl@0
  8918
sl@0
  8919
/*
sl@0
  8920
 * Function:
sl@0
  8921
 *
sl@0
  8922
 *   mp4_i32 readMeta(MP4HandleImp handle,
sl@0
  8923
 *                    metaAtom *meta)
sl@0
  8924
 *
sl@0
  8925
 * Description:
sl@0
  8926
 *
sl@0
  8927
 *   This function parses one META atom.
sl@0
  8928
 *
sl@0
  8929
 * Parameters:
sl@0
  8930
 *
sl@0
  8931
 *   handle             MP4 library handle
sl@0
  8932
 *   meta               META pointer
sl@0
  8933
 *
sl@0
  8934
 * Return value:
sl@0
  8935
 *
sl@0
  8936
 *   Negative integer   Error
sl@0
  8937
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  8938
 *
sl@0
  8939
 */
sl@0
  8940
mp4_i32 readMeta(MP4HandleImp handle, metaAtom *meta)
sl@0
  8941
{
sl@0
  8942
    mp4_i32 bytesread;
sl@0
  8943
    mp4_i32 totalbytesread = 0;
sl@0
  8944
sl@0
  8945
sl@0
  8946
    if ((meta->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  8947
      return -100;
sl@0
  8948
sl@0
  8949
    bytesread = readFullAtomHeader(handle, meta->atomhdr);
sl@0
  8950
    if (bytesread < 0)
sl@0
  8951
      return -1;
sl@0
  8952
    totalbytesread += bytesread;
sl@0
  8953
sl@0
  8954
    if (meta->atomhdr->type != ATOMTYPE_META)
sl@0
  8955
      return -1;
sl@0
  8956
sl@0
  8957
sl@0
  8958
    while ((mp4_u32)totalbytesread < meta->atomhdr->size)
sl@0
  8959
    {
sl@0
  8960
      mp4_u32 type;
sl@0
  8961
sl@0
  8962
sl@0
  8963
      if (peekData(handle, handle->buf, 8) < 0)
sl@0
  8964
        return -1;
sl@0
  8965
      
sl@0
  8966
      type = u32endian(*((mp4_u32 *)(handle->buf+4)));
sl@0
  8967
sl@0
  8968
      switch (type)
sl@0
  8969
      {
sl@0
  8970
      case ATOMTYPE_HDLR:
sl@0
  8971
sl@0
  8972
        if (meta->hdlr) /* HDLR has already been read, more than one is not allowed */
sl@0
  8973
          return -1;
sl@0
  8974
sl@0
  8975
        if ((meta->hdlr = (handlerAtom *)mp4malloc(sizeof(handlerAtom))) == NULL)
sl@0
  8976
          return -100;
sl@0
  8977
sl@0
  8978
        bytesread = readHDLR(handle, meta->hdlr);
sl@0
  8979
        if (bytesread < 0)
sl@0
  8980
          return -1;
sl@0
  8981
        totalbytesread += bytesread;
sl@0
  8982
sl@0
  8983
        break;
sl@0
  8984
          
sl@0
  8985
      case ATOMTYPE_ID32:
sl@0
  8986
          
sl@0
  8987
        if (meta->ID32) /* ID32 has already been read, more than one is not allowed */
sl@0
  8988
          return -1;
sl@0
  8989
sl@0
  8990
        if ((meta->ID32 = (ID32Atom *)mp4malloc(sizeof(ID32Atom))) == NULL)
sl@0
  8991
          return -100;
sl@0
  8992
sl@0
  8993
        bytesread = readID32(handle, meta->ID32);
sl@0
  8994
        if (bytesread < 0)
sl@0
  8995
          return -1;
sl@0
  8996
        totalbytesread += bytesread;
sl@0
  8997
          
sl@0
  8998
        break;
sl@0
  8999
        
sl@0
  9000
      default:
sl@0
  9001
sl@0
  9002
        bytesread = readUnknown(handle);
sl@0
  9003
        if (bytesread < 0)
sl@0
  9004
          return -1;
sl@0
  9005
        totalbytesread += bytesread;
sl@0
  9006
sl@0
  9007
        break;
sl@0
  9008
      }
sl@0
  9009
    }
sl@0
  9010
sl@0
  9011
    return totalbytesread;
sl@0
  9012
}
sl@0
  9013
sl@0
  9014
/*
sl@0
  9015
 * Function:
sl@0
  9016
 *
sl@0
  9017
 *   mp4_i32 readID32(MP4HandleImp handle,
sl@0
  9018
 *                    ID32Atom *ID32)
sl@0
  9019
 *
sl@0
  9020
 * Description:
sl@0
  9021
 *
sl@0
  9022
 *   This function parses one ID32 atom.
sl@0
  9023
 *
sl@0
  9024
 * Parameters:
sl@0
  9025
 *
sl@0
  9026
 *   handle             MP4 library handle
sl@0
  9027
 *   ID32               ID32 pointer
sl@0
  9028
 *
sl@0
  9029
 * Return value:
sl@0
  9030
 *
sl@0
  9031
 *   Negative integer   Error
sl@0
  9032
 *   >= 0               Success. Value tells how many bytes were read.
sl@0
  9033
 *
sl@0
  9034
 */
sl@0
  9035
mp4_i32 readID32(MP4HandleImp handle, ID32Atom *ID32)
sl@0
  9036
{
sl@0
  9037
   mp4_i32 bytesread;
sl@0
  9038
   mp4_i32 totalbytesread = 0;
sl@0
  9039
sl@0
  9040
sl@0
  9041
   if ((ID32->atomhdr = (atomHeader *)mp4malloc(sizeof(atomHeader))) == NULL)
sl@0
  9042
     return -100;
sl@0
  9043
sl@0
  9044
   bytesread = readFullAtomHeader(handle, ID32->atomhdr);
sl@0
  9045
   if (bytesread < 0)
sl@0
  9046
     return -1;
sl@0
  9047
   totalbytesread += bytesread;
sl@0
  9048
sl@0
  9049
   if (ID32->atomhdr->type != ATOMTYPE_ID32)
sl@0
  9050
     return -1;
sl@0
  9051
sl@0
  9052
   // next 2 bytes: top bit is padding, remaining 15 bits is Packed ISO-639-2/T language code 
sl@0
  9053
   bytesread = readData(handle, handle->buf, 2);
sl@0
  9054
   if (bytesread < 0)
sl@0
  9055
     return -1;
sl@0
  9056
   ID32->language = u16endian(*((mp4_u16 *)handle->buf));
sl@0
  9057
   totalbytesread += bytesread;
sl@0
  9058
   
sl@0
  9059
   if ( handle->file )
sl@0
  9060
       {
sl@0
  9061
       ID32->atomcontentloc = handle->diskReadBufStart + handle->diskReadBufPos;
sl@0
  9062
       }
sl@0
  9063
   else
sl@0
  9064
       {
sl@0
  9065
       ID32->atomcontentloc = handle->absPosition;
sl@0
  9066
       }
sl@0
  9067
   
sl@0
  9068
   bytesread = discardData(handle, ID32->atomhdr->size - totalbytesread );
sl@0
  9069
   if (bytesread < 0)
sl@0
  9070
     return -1;
sl@0
  9071
   totalbytesread += bytesread;     
sl@0
  9072
   
sl@0
  9073
   return totalbytesread;
sl@0
  9074
}
sl@0
  9075
sl@0
  9076
/*
sl@0
  9077
 * Function:
sl@0
  9078
 *
sl@0
  9079
 *   mp4_i32 freeMETA(metaAtom *meta)
sl@0
  9080
 *
sl@0
  9081
 * Description:
sl@0
  9082
 *
sl@0
  9083
 *   This function frees memory for META atom.
sl@0
  9084
 *
sl@0
  9085
 * Parameters:
sl@0
  9086
 *
sl@0
  9087
 *   meta       META atom pointer
sl@0
  9088
 *
sl@0
  9089
 * Return value:
sl@0
  9090
 *
sl@0
  9091
 *   0          Success
sl@0
  9092
 *   Negative   Error
sl@0
  9093
 *
sl@0
  9094
 */
sl@0
  9095
mp4_i32 freeMETA(metaAtom *meta)
sl@0
  9096
{
sl@0
  9097
  if (meta)
sl@0
  9098
  {
sl@0
  9099
    if (freeAtomHeader(meta->atomhdr) < 0)
sl@0
  9100
      return -1;
sl@0
  9101
    if (freeHDLR(meta->hdlr) < 0)
sl@0
  9102
       return -1;
sl@0
  9103
    if (freeID32(meta->ID32) < 0)
sl@0
  9104
      return -1;
sl@0
  9105
sl@0
  9106
    mp4free(meta);
sl@0
  9107
  }
sl@0
  9108
sl@0
  9109
  return 0;
sl@0
  9110
}
sl@0
  9111
sl@0
  9112
/*
sl@0
  9113
 * Function:
sl@0
  9114
 *
sl@0
  9115
 *   mp4_i32 freeID32(ID32Atom *ID32)
sl@0
  9116
 *
sl@0
  9117
 * Description:
sl@0
  9118
 *
sl@0
  9119
 *   This function frees memory for ID32 atom.
sl@0
  9120
 *
sl@0
  9121
 * Parameters:
sl@0
  9122
 *
sl@0
  9123
 *   ID32       ID32 atom pointer
sl@0
  9124
 *
sl@0
  9125
 * Return value:
sl@0
  9126
 *
sl@0
  9127
 *   0          Success
sl@0
  9128
 *   Negative   Error
sl@0
  9129
 *
sl@0
  9130
 */
sl@0
  9131
mp4_i32 freeID32(ID32Atom *ID32)
sl@0
  9132
{
sl@0
  9133
  if (ID32)
sl@0
  9134
  {
sl@0
  9135
    if (freeAtomHeader(ID32->atomhdr) < 0)
sl@0
  9136
      return -1;
sl@0
  9137
sl@0
  9138
    mp4free(ID32);
sl@0
  9139
  }
sl@0
  9140
sl@0
  9141
  return 0;
sl@0
  9142
}
sl@0
  9143
// End of File