os/mm/mmplugins/lib3gp/impl/src/asyncfileparser.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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 FILES
sl@0
    17
#include <e32base.h>
sl@0
    18
#include <f32file.h>
sl@0
    19
#include <f32file64.h>
sl@0
    20
#include <3gplibrary/mp4lib.h>
sl@0
    21
#include "mp4atom.h"
sl@0
    22
#include "mp4memwrap.h"
sl@0
    23
#include "asyncfileparser.h"
sl@0
    24
sl@0
    25
// MACROS
sl@0
    26
// Debug print macro
sl@0
    27
#if defined(_DEBUG) && defined(_ASYNCFILEPARSERLOGGING)
sl@0
    28
#include <e32svr.h>
sl@0
    29
#define PRINT(x)
sl@0
    30
#else
sl@0
    31
#define PRINT(x)
sl@0
    32
#endif
sl@0
    33
sl@0
    34
// ============================ MEMBER FUNCTIONS ===============================
sl@0
    35
sl@0
    36
// -----------------------------------------------------------------------------
sl@0
    37
// CFileAsyncParser::CFileAsyncParser
sl@0
    38
// C++ default constructor can NOT contain any code, that
sl@0
    39
// might leave.
sl@0
    40
// -----------------------------------------------------------------------------
sl@0
    41
//
sl@0
    42
CFileAsyncParser::CFileAsyncParser() : CActive( EPriorityHigh ), iDiskBufferPointer(NULL,0)
sl@0
    43
    {
sl@0
    44
    
sl@0
    45
    }
sl@0
    46
sl@0
    47
// -----------------------------------------------------------------------------
sl@0
    48
// CFileAsyncParser::ConstructL
sl@0
    49
// Symbian 2nd phase constructor can leave.
sl@0
    50
// -----------------------------------------------------------------------------
sl@0
    51
//
sl@0
    52
void CFileAsyncParser::ConstructL( MP4HandleStruct* aHandle, RFile64& aFile )
sl@0
    53
    {
sl@0
    54
    PRINT(_L("CFileAsyncParser::ConstructL() IN"));
sl@0
    55
    iError = KErrNone;
sl@0
    56
    iInputFile = &aFile;
sl@0
    57
    iHandle = aHandle;    
sl@0
    58
	iAudioSize = 0;
sl@0
    59
	iReturnedAudioFrames = 0;
sl@0
    60
	iAudioTimeStamp = 0; 		
sl@0
    61
	iAudioTimeStamp2 = 1;   // always fill timestamp2 too (null = dont fill)
sl@0
    62
	iAllDataInMemory = EFalse; 
sl@0
    63
	
sl@0
    64
	if ( iHandle->readBufferSize == 0)
sl@0
    65
	{
sl@0
    66
		iReadBufferSize = READBUFSIZE;
sl@0
    67
	}
sl@0
    68
	else
sl@0
    69
	{
sl@0
    70
		iReadBufferSize = iHandle->readBufferSize;
sl@0
    71
	}	
sl@0
    72
	
sl@0
    73
	iDiskBuffer = HBufC8::NewL(iReadBufferSize);
sl@0
    74
	iCurrentDiskReadPosition = 0;
sl@0
    75
	iCurrentBufferReadPosition = 0;
sl@0
    76
    CActiveScheduler::Add(this);
sl@0
    77
    
sl@0
    78
    PRINT(_L("CFileAsyncParser::ConstructL() OUT"));
sl@0
    79
    }
sl@0
    80
sl@0
    81
// -----------------------------------------------------------------------------
sl@0
    82
// CFileAsyncParser::NewL
sl@0
    83
// Two-phased constructor.
sl@0
    84
// -----------------------------------------------------------------------------
sl@0
    85
//
sl@0
    86
CFileAsyncParser* CFileAsyncParser::NewL( MP4HandleStruct* aHandle, RFile64& aFile )
sl@0
    87
    {
sl@0
    88
    CFileAsyncParser* self = new(ELeave) CFileAsyncParser;
sl@0
    89
    CleanupStack::PushL(self);
sl@0
    90
    self->ConstructL( aHandle, aFile );
sl@0
    91
    CleanupStack::Pop(self);
sl@0
    92
    return self;
sl@0
    93
    }
sl@0
    94
sl@0
    95
// -----------------------------------------------------------------------------
sl@0
    96
// Destructor
sl@0
    97
// -----------------------------------------------------------------------------
sl@0
    98
//
sl@0
    99
CFileAsyncParser::~CFileAsyncParser()
sl@0
   100
    {
sl@0
   101
    PRINT(_L("CFileAsyncParser::~CFileAsyncParser() in"));
sl@0
   102
sl@0
   103
    if ( IsActive() )
sl@0
   104
        {
sl@0
   105
        if ( iAsyncReadOngoing )
sl@0
   106
            {
sl@0
   107
            Cancel();
sl@0
   108
            }
sl@0
   109
        }
sl@0
   110
sl@0
   111
    delete iDiskBuffer;
sl@0
   112
    PRINT(_L("CFileAsyncParser::~CFileAsyncParser() out"));
sl@0
   113
    }
sl@0
   114
sl@0
   115
// -----------------------------------------------------------------------------
sl@0
   116
// CFileAsyncParser::ReadAudioFrames(  );
sl@0
   117
// Writes incoming buffer data to internal buffers for writing to disk.
sl@0
   118
// (other items were commented in a header).
sl@0
   119
// -----------------------------------------------------------------------------
sl@0
   120
//
sl@0
   121
TInt CFileAsyncParser::ReadAudioFrames( mp4_u8 *buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
sl@0
   122
	{
sl@0
   123
	PRINT(_L("CFileAsyncParser::ReadAudioFrames()"));
sl@0
   124
	iProcessingAudio = ETrue;
sl@0
   125
	return ReadDataAsync( buffer, aPosition, aBytesToRead );
sl@0
   126
	}
sl@0
   127
sl@0
   128
// -----------------------------------------------------------------------------
sl@0
   129
// CFileAsyncParser::ReadVideoFrame( );
sl@0
   130
// Writes incoming buffer data to internal buffers for writing to disk.
sl@0
   131
// (other items were commented in a header).
sl@0
   132
// -----------------------------------------------------------------------------
sl@0
   133
//
sl@0
   134
TInt CFileAsyncParser::ReadVideoFrame( mp4_u8* buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
sl@0
   135
	{
sl@0
   136
	PRINT(_L("CFileAsyncParser::ReadVideoFrame()"));
sl@0
   137
	iProcessingAudio = EFalse;
sl@0
   138
	return ReadDataAsync( buffer, aPosition, aBytesToRead );
sl@0
   139
	}
sl@0
   140
sl@0
   141
sl@0
   142
// -----------------------------------------------------------------------------
sl@0
   143
// CFileAsyncParser::ReadDataAsync(  );
sl@0
   144
// Reads data from file asynchronously.
sl@0
   145
// (other items were commented in a header).
sl@0
   146
// -----------------------------------------------------------------------------
sl@0
   147
//
sl@0
   148
TInt CFileAsyncParser::ReadDataAsync( mp4_u8 *buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
sl@0
   149
	{
sl@0
   150
	PRINT(_L("CFileAsyncParser::ReadDataAsync() in"));
sl@0
   151
	iBuffer = buffer;
sl@0
   152
	if ( iAsyncReadOngoing )
sl@0
   153
		{
sl@0
   154
		return -1; // only one async read can be ongoing at one time;	
sl@0
   155
		}
sl@0
   156
	if (!iDiskBuffer)
sl@0
   157
		{
sl@0
   158
		return -1;
sl@0
   159
		}
sl@0
   160
		
sl@0
   161
  	// Is the new seek point inside the current disk buffer?
sl@0
   162
  	if ( (iCurrentDiskReadPosition > aPosition) &&  
sl@0
   163
  		 (( iCurrentDiskReadPosition - iDiskBuffer->Length() ) <= aPosition  ))
sl@0
   164
  		{
sl@0
   165
    	// Yes
sl@0
   166
	    iCurrentBufferReadPosition = iDiskBuffer->Length() - (iCurrentDiskReadPosition - aPosition);
sl@0
   167
  		}
sl@0
   168
  	else
sl@0
   169
  		{
sl@0
   170
    	// No, set current position and zero diskbuffer
sl@0
   171
		iCurrentBufferReadPosition = 0;
sl@0
   172
		iCurrentDiskReadPosition = (mp4_i64)aPosition;
sl@0
   173
		iDiskBuffer->Des().SetLength(0);
sl@0
   174
		}
sl@0
   175
		
sl@0
   176
	iBytesToRead = aBytesToRead;
sl@0
   177
	iBytesRead = 0;
sl@0
   178
	TInt available = 0;
sl@0
   179
	
sl@0
   180
	// How much data is available in diskbuffer.
sl@0
   181
	available =  iDiskBuffer->Length() - iCurrentBufferReadPosition;
sl@0
   182
	if (available > iBytesToRead)
sl@0
   183
	{
sl@0
   184
	  available = iBytesToRead;
sl@0
   185
	}
sl@0
   186
sl@0
   187
	// If any available copy it first to output buffer
sl@0
   188
	if (available ) 
sl@0
   189
	{
sl@0
   190
	  memcpy(iBuffer, iDiskBuffer->Ptr() + iCurrentBufferReadPosition, available);
sl@0
   191
	  iCurrentBufferReadPosition += available;
sl@0
   192
	  iBytesRead += available;
sl@0
   193
	}
sl@0
   194
sl@0
   195
	// If we got everything from diskbuffer process it right away
sl@0
   196
	if (iBytesRead == iBytesToRead)
sl@0
   197
	{
sl@0
   198
		PRINT(_L("CFileAsyncParser::ReadDataAsync() Data found in memory, no need to read file - return right away"));
sl@0
   199
		iAllDataInMemory = ETrue;
sl@0
   200
		SetActive();
sl@0
   201
        TRequestStatus* tmp = &iStatus;
sl@0
   202
        User::RequestComplete(tmp, KErrNone);
sl@0
   203
        PRINT(_L("CFileAsyncParser::ReadDataAsync() out"));
sl@0
   204
		return MP4_OK;
sl@0
   205
	}
sl@0
   206
	else
sl@0
   207
	{
sl@0
   208
		// Need to read rest of the requested data from file.
sl@0
   209
		iAllDataInMemory = EFalse;
sl@0
   210
	}
sl@0
   211
sl@0
   212
	// Determine used readbuffer size
sl@0
   213
	if ( iHandle->readBufferSize == 0)
sl@0
   214
	{
sl@0
   215
		iReadBufferSize = READBUFSIZE;
sl@0
   216
	}
sl@0
   217
	else
sl@0
   218
	{
sl@0
   219
		iReadBufferSize = iHandle->readBufferSize;
sl@0
   220
	}
sl@0
   221
	
sl@0
   222
	// Increase disk read buffer size if requested frames are larger than current disk buffer.
sl@0
   223
	if ( (iBytesToRead > iReadBufferSize ) || (iReadBufferSize != iDiskBuffer->Des().MaxLength()) )
sl@0
   224
	{
sl@0
   225
        iReadBufferSize = iBytesToRead;
sl@0
   226
        if (iDiskBuffer)
sl@0
   227
        {
sl@0
   228
            delete iDiskBuffer;
sl@0
   229
            iDiskBuffer = NULL;
sl@0
   230
            TRAPD(memerror, iDiskBuffer = HBufC8::NewL(iReadBufferSize));
sl@0
   231
            if (memerror)
sl@0
   232
            {
sl@0
   233
	            return MP4_OUT_OF_MEMORY;
sl@0
   234
            }
sl@0
   235
            else
sl@0
   236
            {
sl@0
   237
				iCurrentBufferReadPosition = 0;
sl@0
   238
            }
sl@0
   239
        }
sl@0
   240
	}
sl@0
   241
sl@0
   242
	iAsyncReadOngoing = ETrue;
sl@0
   243
	iDiskBufferPointer.Set(iDiskBuffer->Des());
sl@0
   244
	iCurrentDiskReadPosition = aPosition + iBytesRead;
sl@0
   245
	switch (iHandle->sourceType)
sl@0
   246
	  {
sl@0
   247
	    case MP4_SOURCE_RFILE:
sl@0
   248
	    {
sl@0
   249
		  PRINT(_L("CFileAsyncParser::ReadDataAsync() Data not in memory, reading RFile64"));	    
sl@0
   250
	      RFile64* rfile = (RFile64*)iHandle->rfile;
sl@0
   251
	      rfile->Read(iCurrentDiskReadPosition, iDiskBufferPointer, iDiskBufferPointer.MaxLength(), iStatus);
sl@0
   252
	      break;
sl@0
   253
	    }
sl@0
   254
	    case MP4_SOURCE_CAF:
sl@0
   255
	    {
sl@0
   256
		  PRINT(_L("CFileAsyncParser::ReadDataAsync() Data not in memory, reading CAF object"));	    	    
sl@0
   257
	      iHandle->cafError = iHandle->cfile->Read(iCurrentDiskReadPosition, iDiskBufferPointer, iDiskBufferPointer.MaxLength(), iStatus);
sl@0
   258
	      if ( iHandle->cafError != KErrNone)
sl@0
   259
	        return -2;
sl@0
   260
	      break;
sl@0
   261
	    }
sl@0
   262
	    default:
sl@0
   263
	      return -1;
sl@0
   264
	  }
sl@0
   265
sl@0
   266
    if ( !IsActive() )
sl@0
   267
	    {
sl@0
   268
	    SetActive();
sl@0
   269
	    }
sl@0
   270
	PRINT(_L("CFileAsyncParser::ReadDataAsync() out"));
sl@0
   271
	return 0;
sl@0
   272
	}
sl@0
   273
sl@0
   274
sl@0
   275
sl@0
   276
// -----------------------------------------------------------------------------
sl@0
   277
// CFileAsyncParser::DoCancel()
sl@0
   278
// From CActive Cancels async request.
sl@0
   279
// -----------------------------------------------------------------------------
sl@0
   280
//
sl@0
   281
void CFileAsyncParser::DoCancel()
sl@0
   282
    {
sl@0
   283
    PRINT(_L("CFileAsyncParser::DoCancel() in"));
sl@0
   284
    if (iAsyncReadOngoing)
sl@0
   285
    	{
sl@0
   286
    	if (iHandle->sourceType == MP4_SOURCE_RFILE)
sl@0
   287
    	    {
sl@0
   288
    	    // cancel read from file
sl@0
   289
    	    ((RFile64 *)(iHandle->rfile))->ReadCancel();
sl@0
   290
        	}
sl@0
   291
    	else if (iHandle->sourceType == MP4_SOURCE_CAF)
sl@0
   292
        	{
sl@0
   293
        	// cancel read from caf object
sl@0
   294
        	iHandle->cfile->ReadCancel(iStatus);
sl@0
   295
        	}
sl@0
   296
    	iAsyncReadOngoing = EFalse;
sl@0
   297
    	}
sl@0
   298
    
sl@0
   299
    PRINT(_L("CFileAsyncParser::DoCancel() out"));
sl@0
   300
    }
sl@0
   301
sl@0
   302
// -----------------------------------------------------------------------------
sl@0
   303
// CFileAsyncParser::ReturnAudioFrames()
sl@0
   304
// Return audio frames to observer.
sl@0
   305
// -----------------------------------------------------------------------------
sl@0
   306
//
sl@0
   307
void CFileAsyncParser::ReturnAudioFrames()
sl@0
   308
	{
sl@0
   309
	PRINT(_L("CFileAsyncParser::ReturnAudioFrames() in"));
sl@0
   310
	TInt error = KErrNone;
sl@0
   311
	
sl@0
   312
	// Update last accessed position in file pointer
sl@0
   313
    if (iHandle->audioSampleOffset + iHandle->audioSampleSize - 1 > iHandle->lastAccessedPosInFile)
sl@0
   314
	    {
sl@0
   315
	    iHandle->lastAccessedPosInFile = iHandle->audioSampleOffset + iHandle->audioSampleSize - 1;
sl@0
   316
	    }
sl@0
   317
	
sl@0
   318
	// Fill audio frame size
sl@0
   319
	iAudioSize = iHandle->audioSampleSize;
sl@0
   320
	
sl@0
   321
	// Fill audio timestamp information
sl@0
   322
	iAudioTimeStamp = 0;
sl@0
   323
	iAudioTimeStamp2 = 1; // fill also timestamp2 (wont be filled if 0)
sl@0
   324
	error = convertAudioSampleToTime(iHandle, iHandle->moov->trakAudio->mdia, &iAudioTimeStamp, &iAudioTimeStamp2);	
sl@0
   325
	if (error == MP4_OK)
sl@0
   326
		{
sl@0
   327
		// Fill iReturnedAudioFrames
sl@0
   328
		iReturnedAudioFrames = 0;
sl@0
   329
		error = CalculateAudioFrameCount();
sl@0
   330
		}
sl@0
   331
	
sl@0
   332
	// Move forward in audio samples
sl@0
   333
	if (error == MP4_OK)
sl@0
   334
		{
sl@0
   335
		error = advanceAudioSample(iHandle, iHandle->moov->trakAudio);
sl@0
   336
		if ( error == -1)
sl@0
   337
			{
sl@0
   338
			error = MP4_ERROR;
sl@0
   339
			}
sl@0
   340
		else if ( error == -2 )
sl@0
   341
			{
sl@0
   342
			error = MP4_OK;
sl@0
   343
			iHandle->audioLast = MP4TRUE;
sl@0
   344
			}
sl@0
   345
		}
sl@0
   346
sl@0
   347
	iAsyncReadOngoing = EFalse;
sl@0
   348
	iHandle->asyncObserver->M3GPMP4LibAudioFramesAvailable(error, 
sl@0
   349
    													  iAudioSize,
sl@0
   350
    													  iAudioTimeStamp,
sl@0
   351
    													  iReturnedAudioFrames,
sl@0
   352
    										  			  iAudioTimeStamp2);
sl@0
   353
	PRINT(_L("CFileAsyncParser::ReturnAudioFrames() out"));		
sl@0
   354
	}
sl@0
   355
sl@0
   356
// -----------------------------------------------------------------------------
sl@0
   357
// CFileAsyncParser::ReturnVideoFrame()
sl@0
   358
// Return video frame to observer.
sl@0
   359
// -----------------------------------------------------------------------------
sl@0
   360
//
sl@0
   361
void CFileAsyncParser::ReturnVideoFrame()
sl@0
   362
	{
sl@0
   363
	PRINT(_L("CFileAsyncParser::ReturnVideoFrame() in"));
sl@0
   364
	TInt error = KErrNone;
sl@0
   365
	
sl@0
   366
	// Update last accessed position in file pointer
sl@0
   367
    if (iHandle->videoFrameOffset + iHandle->videoFrameSize - 1 > iHandle->lastAccessedPosInFile)
sl@0
   368
	    {
sl@0
   369
	    iHandle->lastAccessedPosInFile = iHandle->videoFrameOffset + iHandle->videoFrameSize - 1;
sl@0
   370
	    }
sl@0
   371
	
sl@0
   372
	// Fill video frame size
sl@0
   373
	iVideoSize = iHandle->videoFrameSize;
sl@0
   374
	
sl@0
   375
	// Fill video timestamp information
sl@0
   376
	iVideoTimeStamp = 0;
sl@0
   377
	iVideoTimeStamp2 = 1; // fill also timestamp2 (wont be filled if 0)
sl@0
   378
	error = convertVideoSampleToTime(iHandle, iHandle->moov->trakVideo->mdia, &iVideoTimeStamp, &iVideoTimeStamp2);	
sl@0
   379
	if (error == MP4_OK)
sl@0
   380
		{
sl@0
   381
		// Fill iKeyFrame
sl@0
   382
		iVideoKeyFrame = 0;
sl@0
   383
		error = isVideoFrameKeyFrame(iHandle, iHandle->moov->trakVideo, &iVideoKeyFrame);
sl@0
   384
		}
sl@0
   385
	
sl@0
   386
	// Move forward in video frames
sl@0
   387
	if (error == MP4_OK)
sl@0
   388
		{
sl@0
   389
		error = advanceVideoFrame(iHandle, iHandle->moov->trakVideo);
sl@0
   390
		if ( error == -1)
sl@0
   391
			{
sl@0
   392
			error = MP4_ERROR;
sl@0
   393
			}
sl@0
   394
		else if ( error == -2 )
sl@0
   395
			{
sl@0
   396
			error = MP4_OK;
sl@0
   397
			iHandle->videoLast = MP4TRUE;
sl@0
   398
			}
sl@0
   399
		}
sl@0
   400
sl@0
   401
	iAsyncReadOngoing = EFalse;
sl@0
   402
	iHandle->asyncObserver->M3GPMP4LibVideoFrameAvailable(error,
sl@0
   403
        										   		  iVideoSize, 
sl@0
   404
        										  		  iVideoTimeStamp, 
sl@0
   405
        										   		  iVideoKeyFrame, 
sl@0
   406
        										   		  iVideoTimeStamp2);
sl@0
   407
	PRINT(_L("CFileAsyncParser::ReturnVideoFrame() out"));		
sl@0
   408
	}
sl@0
   409
sl@0
   410
// -----------------------------------------------------------------------------
sl@0
   411
// CFileAsyncParser::CalculateAudioFrameCount()
sl@0
   412
// Return video frame to observer.
sl@0
   413
// -----------------------------------------------------------------------------
sl@0
   414
//
sl@0
   415
TInt CFileAsyncParser::CalculateAudioFrameCount()
sl@0
   416
	{
sl@0
   417
  	mp4_i32 frameLength = 0;
sl@0
   418
  	mp4_u32 numOfFrames = 0;
sl@0
   419
  	mp4_u8 *framepointer = 0;
sl@0
   420
  	mp4_u32 rawAmrFrameLength[16] = {13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1};	
sl@0
   421
	trackAtom *trak = iHandle->moov->trakAudio;
sl@0
   422
	
sl@0
   423
	if (!trak)
sl@0
   424
		{
sl@0
   425
		return -1;
sl@0
   426
		}
sl@0
   427
sl@0
   428
	/* AMR */
sl@0
   429
	if (trak->mdia->minf)
sl@0
   430
	if (trak->mdia->minf->stbl)
sl@0
   431
	  if (trak->mdia->minf->stbl->stsd)
sl@0
   432
	    if (iHandle->type & MP4_TYPE_AMR_NB)
sl@0
   433
	    {
sl@0
   434
	        framepointer = iBuffer;
sl@0
   435
	        numOfFrames = 0;
sl@0
   436
	        while ( iBytesRead > 0 )
sl@0
   437
	        {
sl@0
   438
	            frameLength = rawAmrFrameLength[(TInt)(((*framepointer) & 0x78) >> 3)];
sl@0
   439
	            if ( frameLength == 0)
sl@0
   440
	            {
sl@0
   441
	                return -4;
sl@0
   442
	            }
sl@0
   443
	            iBytesRead -= frameLength;
sl@0
   444
	            framepointer += frameLength;
sl@0
   445
	            numOfFrames++;
sl@0
   446
	        }
sl@0
   447
	        iReturnedAudioFrames = numOfFrames;
sl@0
   448
	    }
sl@0
   449
	    else if (iHandle->type & MP4_TYPE_AMR_WB)
sl@0
   450
	    {
sl@0
   451
		  /* Return the number of sample entries listed for this particular sample entry index */
sl@0
   452
	      if (trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1])
sl@0
   453
	        if (trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1]->damr)
sl@0
   454
	          iReturnedAudioFrames = trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1]->damr->framesPerSample;
sl@0
   455
	    }
sl@0
   456
	    else
sl@0
   457
	    {
sl@0
   458
	    }
sl@0
   459
sl@0
   460
	/* MPEG-4 audio */
sl@0
   461
	if (trak->mdia->minf)
sl@0
   462
	if (trak->mdia->minf->stbl)
sl@0
   463
	  if (trak->mdia->minf->stbl->stsd)
sl@0
   464
	    if (trak->mdia->minf->stbl->stsd->mp4a[iHandle->audioSampleEntryIndex - 1])
sl@0
   465
	      iReturnedAudioFrames = 1;
sl@0
   466
sl@0
   467
	/* QCELP 13K as QCELPSampleEntry*/
sl@0
   468
	if (trak->mdia->minf)
sl@0
   469
	if (trak->mdia->minf->stbl)
sl@0
   470
	  if (trak->mdia->minf->stbl->stsd)
sl@0
   471
	    if ((iHandle->type & MP4_TYPE_QCELP_13K) && (!iHandle->qcelpStoredAsMPEGAudio))
sl@0
   472
	    {
sl@0
   473
		  /* Return the number of sample entries listed for this particular sample entry index */
sl@0
   474
	      if (trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1])
sl@0
   475
	        if (trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1]->dqcp)
sl@0
   476
	          iReturnedAudioFrames = trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1]->dqcp->framesPerSample;
sl@0
   477
	    }
sl@0
   478
sl@0
   479
	/* QCELP 13K as MPEG-4 audio */
sl@0
   480
	if (trak->mdia->minf)
sl@0
   481
	if (trak->mdia->minf->stbl)
sl@0
   482
	  if (trak->mdia->minf->stbl->stsd)
sl@0
   483
	    if (trak->mdia->minf->stbl->stsd->mp4a[iHandle->audioSampleEntryIndex - 1])
sl@0
   484
	      iReturnedAudioFrames = 1;
sl@0
   485
sl@0
   486
	return MP4_OK;	
sl@0
   487
	}
sl@0
   488
sl@0
   489
// -----------------------------------------------------------------------------
sl@0
   490
// CFileAsyncParser::RunL()
sl@0
   491
// From CActive Called when async request completes.
sl@0
   492
// -----------------------------------------------------------------------------
sl@0
   493
//
sl@0
   494
void CFileAsyncParser::RunL()
sl@0
   495
    {
sl@0
   496
    PRINT(_L("CFileAsyncParser::RunL() in"));
sl@0
   497
    if ( iStatus != KErrNone )
sl@0
   498
        {
sl@0
   499
        PRINT((_L("CFileAsyncParser::RunL() error in previous async: %d "), iStatus.Int() ));
sl@0
   500
        iError = iStatus.Int();
sl@0
   501
		iHandle->asyncObserver->M3GPMP4LibAudioFramesAvailable(MP4_FILE_ERROR,0,0,0,0);
sl@0
   502
        return;
sl@0
   503
        }
sl@0
   504
sl@0
   505
    if (!iAllDataInMemory)
sl@0
   506
	    {
sl@0
   507
		if ((mp4_u32)iDiskBuffer->Length() == 0) // EOF or error
sl@0
   508
		{
sl@0
   509
			iError = MP4_FILE_ERROR; // metadata info doesn't match file -> corrupted clip.
sl@0
   510
		}
sl@0
   511
		
sl@0
   512
		memcpy(iBuffer+iBytesRead, iDiskBuffer->Ptr(), iBytesToRead-iBytesRead);
sl@0
   513
	  	iCurrentBufferReadPosition += iBytesToRead-iBytesRead;
sl@0
   514
	  	iCurrentDiskReadPosition += iDiskBuffer->Length();
sl@0
   515
		iBytesRead = iBytesToRead;
sl@0
   516
	  	
sl@0
   517
	  	// set handle disk buffer sizes to zero just in case.
sl@0
   518
	  	iHandle->diskReadBufPos = 0;
sl@0
   519
		iHandle->diskReadSize = 0;
sl@0
   520
		iHandle->diskReadBufStart = 0;
sl@0
   521
		iHandle->diskReadPos = iCurrentDiskReadPosition;
sl@0
   522
    	}
sl@0
   523
sl@0
   524
	if ( iProcessingAudio )
sl@0
   525
		{
sl@0
   526
		ReturnAudioFrames();
sl@0
   527
		}
sl@0
   528
	else
sl@0
   529
		{
sl@0
   530
		ReturnVideoFrame();	
sl@0
   531
		}
sl@0
   532
    
sl@0
   533
    PRINT(_L("CFileAsyncParser::RunL() out"));
sl@0
   534
    }
sl@0
   535
sl@0
   536
//  End of File