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