multimediacommscontroller/mmccfilesourcesink/src/mccfilesourceimpl_withtimer.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccfilesourcesink/src/mccfilesourceimpl_withtimer.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1438 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    
+*
+*/
+
+
+
+        
+// INCLUDE FILES
+#include <ES_SOCK.H>
+#include <e32std.h>
+#include "MccFileSourceImpl.h"
+#include "MmccCodecInformation.h"
+#include "MccFileSourceLogs.h"
+#include "MccTickVideoObserver.h"
+#include "MccTickAudioObserver.h"
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::NewL
+// Static constructor.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl* CMccFileSourceImpl::NewL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::NewL" )
+    
+    CMccFileSourceImpl* self = new ( ELeave ) CMccFileSourceImpl();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ConstructL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::ConstructL" )
+    }
+    
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl::CMccFileSourceImpl()
+    {
+    iObserver = 0;
+    iVideoLength = 0;
+    iFrameRate = 0;
+    iVideoType = 0;
+    iVideoWidth = 0;
+    iVideoHeight = 0;
+    iVideoTimeScale = 0;
+    iAudioLength = 0;
+    iAudioType = 0;
+    iFramesPerSample = 0;
+    iAudioTimeScale = 0;
+    iAverageBitRate = 0;
+    iStreamSize = 0;
+    iStreamAverageBitRate = 0;
+    iAudioPosition = 0;
+    iVideoPosition = 0;
+    iPosition = 0;
+    iCurrentVideoType = CCMRMediaBuffer::EVideoH263;
+    iCurrentAudioType = CCMRMediaBuffer::EAudioAMRNB;
+    iBufferSize = 0;
+    iAudioSize = 0;
+    iReturnedFrames = 0;
+    iNextFrameType = 0;
+    iKeyFrame = 0;
+    iVideoFrameSize = 0;
+    iLastPosition = 0;
+    iFrameSize.iWidth = 0;
+    iFrameSize.iHeight = 0;
+    iCurrentState = EConstructed;
+    iMP4Handle = NULL;
+    iIsAudioLeft = EFalse;
+    iIsVideoLeft = EFalse;
+    iIsAudio = EFalse;
+    iIsVideo = EFalse;
+	iRecursiveCalls = 0;
+	iIsFirstVideoFrame = EFalse;
+
+	iAudioConsumer = 0;
+	iAudioConsumerBuffer = 0;
+	iVideoConsumer = 0;
+	iVideoConsumerBuffer = 0;    
+    }
+        
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::~CMccFileSourceImpl.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl::~CMccFileSourceImpl()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::~CMccFileSourceImpl" )
+  /*
+    delete iPeriodicVideo;
+    delete iPeriodicVideo;
+   */
+    if ( iMP4Handle )
+	    {
+	    MP4Err error = MP4ParseClose( iMP4Handle );
+	    }
+  
+    iObserver = NULL;
+    iVideoConsumer = NULL;
+    iAudioConsumer = NULL;
+    
+    iAudioFrames.Reset();
+    iAudioFrames.Close();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AddDataSink(MCMRMediaSink* aSink)
+//
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::AddDataSink( MCMRMediaSink* /*aSink*/ )
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AddDataSink" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::OpenFileL(TFileName aFileName)
+//
+// Opens a 3gp file for streaming and reads media descriptions into
+// member variables
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::OpenFileL( TFileName aFileName )
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileL" )
+    
+    __ASSERT_ALWAYS( iCurrentState == EConstructed, User::Leave( KErrNotReady ) );
+
+    TFileName fullFileName;
+    MP4Err error = MP4_OK;
+    
+    RFs fS;
+    User::LeaveIfError( fS.Connect() );
+	CleanupClosePushL( fS );
+    TParse fp;	
+    if ( fS.Parse( aFileName, fp ) != KErrNone )
+        {
+        RDebug::Print(_L("CMccFileSourceImpl::OpenFileL file name parse error!"));
+	    User::Leave( KErrGeneral );
+        }
+	
+    fullFileName = fp.FullName();
+
+  	CleanupStack::PopAndDestroy( &fS ); 
+  	
+  	error = MP4ParseOpen( &iMP4Handle, (wchar_t *) fullFileName.PtrZ() );
+
+    if ( error != MP4_OK )
+	    {
+	    RDebug::Print(_L("CMccFileSourceImpl::OpenFileL parse open error!"));
+        RDebug::Print(_L("CMccFileSourceImpl::OpenFileL parse open error=%d"), error);
+
+	    FileOpenErrorL( error );	
+	    }
+	
+ 	ParseUpdateVideoDescriptions();
+ 	
+ 	ParseUpdateAudioDescriptions();
+
+    if ( ( !iIsAudio ) && ( !iIsVideo ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    
+    error = MP4ParseRequestStreamDescription( iMP4Handle,
+        ( mp4_u32* ) &iStreamSize, ( mp4_u32* ) &iStreamAverageBitRate );
+       
+    __FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::OpenFileL, \
+MP4ParseRequestStreamDescription error=",error)
+    
+  
+	#ifdef TIMESTAMP
+		iReplayTimeStamp = 0;
+		iTimeDifference = 0;
+		iPausedTime = 0;
+	#endif
+
+    iCurrentState = EReady;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::CloseFileL()
+//
+// Closes the 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::CloseFileL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::CloseFileL" )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+    if ( iCurrentState == EPlaying )
+        {
+        TRAP_IGNORE( SourceStopL() );
+        }
+
+    MP4Err error;
+    error = MP4ParseClose( iMP4Handle );
+
+    if ( error != MP4_OK )
+        {
+        User::Leave( KErrGeneral );
+        }
+
+    iCurrentState = EConstructed;
+    iMP4Handle = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetPositionL(TTimeIntervalMicroSeconds aPosition)
+// 
+// Sets a new streaming position
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SetPositionL( TTimeIntervalMicroSeconds aPosition )
+    {
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::SetPositionL", Int64() )
+    
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+    if ( iCurrentState == EStopped ) 
+    	{
+    	return;
+    	}
+
+    MP4Err error;
+
+    TInt64 tempPosition = aPosition.Int64();
+    TUint tempPosition2 = tempPosition; 
+    tempPosition2 = tempPosition2 / 1000; 
+    iLastPosition = iVideoLength;
+
+    TRAP_IGNORE( UpdatePositionL());
+       
+    if ( iLastPosition < iAudioLength )
+        {
+        iLastPosition = iAudioLength;
+        }
+
+    if ( tempPosition2 > iLastPosition )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    error = MP4ParseSeek( iMP4Handle, ( mp4_u32 ) tempPosition2,
+        ( mp4_u32* ) &iAudioPosition, ( mp4_u32* ) &iVideoPosition, MP4TRUE );
+	
+    if ( error != MP4_OK )
+        {   
+        User::Leave( KErrGeneral );
+        }
+
+    #ifdef TIMESTAMP
+		if ( iIsAudioLeft == EFalse && iIsVideoLeft == EFalse)
+			{
+			iPosition = 0;
+			}
+        iTimeDifference = iTimeDifference + iPosition - iVideoPosition;
+        iPosition = iVideoPosition;
+    #endif
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoTypeL()
+// 
+// Returns current video type
+// -----------------------------------------------------------------------------
+//
+CCMRMediaBuffer::TBufferType CMccFileSourceImpl::VideoTypeL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoTypeL" )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+    return iCurrentVideoType;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioTypeL()
+// 
+// Returns current audio type
+// -----------------------------------------------------------------------------
+//
+CCMRMediaBuffer::TBufferType CMccFileSourceImpl::AudioTypeL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioTypeL" )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    
+    return iCurrentAudioType;
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoFrameRateL()
+// 
+// Returns current video frame rate
+// -----------------------------------------------------------------------------
+//
+TReal32 CMccFileSourceImpl::VideoFrameRateL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFrameRateL" )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+    return TReal32 ( iFrameRate );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioBitRateL()
+// 
+// Returns current audio bit rate
+// -----------------------------------------------------------------------------
+//
+TUint CMccFileSourceImpl::AudioBitRateL()
+    {
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::AudioBitRateL", iAverageBitRate )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    
+    return iAverageBitRate;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::DurationL()
+// 
+// Returns duration of current media clip
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileSourceImpl::DurationL()
+    {
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::DurationL", 
+                                iVideoLength * 1000 )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    
+    return TTimeIntervalMicroSeconds( iVideoLength * 1000 );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoFrameSizeL()
+// 
+// Returns current video frame size
+// -----------------------------------------------------------------------------
+//
+TSize CMccFileSourceImpl::VideoFrameSizeL()
+    {        
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoFrameSizeL iWidth", 
+                                iFrameSize.iWidth )
+	__FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::VideoFrameSizeL iHeight",
+								iFrameSize.iHeight )                            
+    
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    
+    return iFrameSize;
+    }
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoBitRateL()
+// 
+// Returns current video bitrate
+// -----------------------------------------------------------------------------
+//
+TUint CMccFileSourceImpl::VideoBitRateL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoBitRateL, videoBitRate" )
+    
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    
+    TUint videoBitRate = iStreamAverageBitRate - iAverageBitRate;
+   
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoBitRateL, videoBitRate", 
+                                videoBitRate )
+    return videoBitRate;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PositionL()
+// 
+// Returns current streaming position
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileSourceImpl::PositionL()
+    {
+    __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::PositionL", 
+                                iPosition * 1000 )
+
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+    return TTimeIntervalMicroSeconds( iPosition * 1000 ); 
+
+    }
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::UpdatePositionL()
+// 
+// Updates the position parameter
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::UpdatePositionL()
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::UpdatePosition" )
+	MP4Err error;
+	
+    error=MP4ParseGetNextVideoTimestamp( iMP4Handle,
+        ( mp4_u32* ) &iPosition, NULL );
+
+    if ( error != MP4_OK )
+        {
+        User::Leave( KErrGeneral );
+        }
+
+    error = MP4ParseSeek( iMP4Handle, ( mp4_u32 ) iPosition,
+        ( mp4_u32* ) &iAudioPosition, ( mp4_u32* ) &iVideoPosition, MP4FALSE );
+	
+     if ( error != MP4_OK )
+        {
+        User::Leave( KErrGeneral );
+        }
+
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ReadAudioFrameL()
+// 
+// Reads the next audio frame from 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ReadAudioFrameL()
+    {
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL" )
+	
+     
+    TBool brokenFrame = EFalse;
+    
+  	if ( iAudioConsumer == NULL)
+  		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+source not available" )
+  		return;
+  		}
+  	else
+  		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer" )  		
+  		}	
+
+	if (!iAudioFrames.Count())
+		{		
+	    MP4Err error;
+
+	    error = MP4ParseIsFrameAvailable( iMP4Handle, MP4_TYPE_AMR_NB );
+	    
+	    if ( error != MP4_OK )
+	        {
+	  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+no audio" ) 
+			iIsAudioLeft = EFalse;
+	        }
+	    else 
+	    	{
+	  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+	audio OK" )
+	    	iIsAudioLeft = ETrue;
+	    	}
+	    	
+	    if ( iIsAudioLeft == EFalse && iIsVideoLeft == EFalse )
+	        {
+	  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+no video & audio available" ) 		
+	        		
+			#ifdef TIMESTAMP
+				iReplayTimeStamp = iReplayTimeStamp + iPosition + 10;
+			#endif
+
+			SetPositionL(  TTimeIntervalMicroSeconds ( 0 ) );
+			SourcePauseL();
+
+	        if ( iObserver )
+	            {
+	            iObserver->EndOfFile( KErrNone );
+	            }
+	        return;
+		    }
+
+		// Timing correction code
+		TTimeIntervalMicroSeconds elapsedTime;
+	    TTime currentTime;
+	    currentTime.HomeTime();
+	    elapsedTime = currentTime.MicroSecondsFrom( iStartTime );
+	    TInt64 tempTime = elapsedTime.Int64();
+	    TInt timeNow = tempTime  / 1000;
+
+		if ( ( timeNow + 500 ) < ( ( TInt ) iAudioPosition + iTimeDifference + iReplayTimeStamp + ( iPausedTime / 1000 ) ) )
+			{
+	  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+Position check, returning" ) 
+	  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, IGNORING" ) 
+	  		//return    				
+			}
+
+		MP4ParseNextFrameSize( iMP4Handle, MP4_TYPE_AMR_NB,
+	        ( mp4_u32* ) &iBufferSize );
+
+	    HBufC8* iMediaBuffer = HBufC8::NewL( iBufferSize );
+	    TPtr8 iMediaSinkBuffer = iMediaBuffer->Des();
+
+	    iMediaSinkBuffer.SetLength( iBufferSize );
+
+	    if ( MP4ParseReadAudioFrames( iMP4Handle,
+	        ( mp4_u8* ) iMediaSinkBuffer.Ptr(),
+	        ( mp4_u32 ) iBufferSize, ( mp4_u32* ) &iAudioSize,
+	        ( mp4_u32* ) &iPosition, ( mp4_u32* ) &iReturnedFrames,
+			NULL ) == MP4_OK )
+			{
+			__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadAudioFrameL, \
+read, time position", iPosition ) 		
+
+			iAudioPosition = iPosition ;
+			brokenFrame = EFalse;
+			
+			TBool areFramesNormal = EFalse;
+		
+			// If brokenFrame = ETrue don't send the frame forward!
+					
+			// Calculate real frame size from sample size
+	        TInt FrameSize = iBufferSize / iReturnedFrames;
+	        TUint Counter = 0;
+	        TInt AddToTimeStamp = 0;
+	        TInt startPosition = 0;
+	        
+	        while (Counter < iReturnedFrames)
+	            {
+	            Counter++;
+
+				if ( areFramesNormal == EFalse )
+					{
+					FrameSize = GetFrameLength( iMediaBuffer->Mid( startPosition ) ); 
+					if ( FrameSize == 0 )
+						{
+						brokenFrame = ETrue;
+						}
+					else 
+						{
+						brokenFrame = EFalse;
+						}
+					}
+
+				
+				TTimeIntervalMicroSeconds timeStamp(0);
+					
+	            // Sets a different timestamp than in file (forward/rewind functionality)
+	            #ifdef TIMESTAMP
+				timeStamp = TTimeIntervalMicroSeconds( ( (iPosition + iTimeDifference + iReplayTimeStamp ) * 1000 ) 
+							+ AddToTimeStamp 
+				#ifdef TIMESTAMPPAUSE			
+							+  iPausedTime 
+				#endif //TIMESTAMPPAUSE
+							); 
+            	#else //TIMESTAMP   
+					timeStamp =TTimeIntervalMicroSeconds( ( iPosition * 1000 ) + AddToTimeStamp ) ;
+            	#endif //TIMESTAMP
+
+				TAudioFrameItem item;
+				item.iFrame = HBufC8::NewL( FrameSize );
+    			item.iFrame->Des().Copy( iMediaBuffer->Mid( startPosition , FrameSize ) );
+    			item.iTimeStamp = timeStamp;
+    			User::LeaveIfError( iAudioFrames.Append(item) );
+	            
+			    AddToTimeStamp += 20000;
+	            startPosition += FrameSize;
+	            }    
+		    delete iMediaBuffer;
+		    iMediaBuffer = NULL; 
+
+			if ( ( timeNow - 500 ) < ( ( TInt ) iAudioPosition + iTimeDifference + iReplayTimeStamp + ( iPausedTime / 1000 ) ) )
+				{
+				__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+Position check, returning" )
+				__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+IGNORING" )
+				//return;
+				}
+
+			}
+		else
+			{
+			__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+reading frames failed" )
+			}
+    	}
+    else
+    	{
+		__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadAudioFrameL, \
+existing frames, count", iAudioFrames.Count() )    		
+    	}
+
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer, copying" ) 
+	CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>(iAudioConsumerBuffer); 		
+	__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer, len", buf->BufferSize() )
+	HBufC8* audioFrame = iAudioFrames[0].iFrame; 
+    buf->Data().Copy( *audioFrame );
+ 	iAudioConsumerBuffer->SetTimeToPlay(iAudioFrames[0].iTimeStamp);
+	iAudioConsumerBuffer->SetLastBuffer(EFalse);
+    iAudioFrames.Remove(0);
+    delete audioFrame;
+      	
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer, complete" ) 
+
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer to sink" )   		
+	iAudioConsumer->BufferFilledL( iAudioConsumerBuffer );
+	iAudioConsumer = 0;
+	iAudioConsumerBuffer = 0;
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadAudioFrameL, \
+writing buffer to sink complete" )  	
+	}
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ReadVideoFrameL()
+// 
+// Reads the next video frame from 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ReadVideoFrameL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL" )
+
+    MP4Err error;
+    
+  	if ( iVideoConsumer == NULL)
+  		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+source not available" ) 
+  		return;
+  		}
+  
+  	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+writing buffer" ) 
+  			
+    
+    error = MP4ParseIsFrameAvailable( iMP4Handle, iVideoType );
+    error = MP4ParseIsFrameAvailable( iMP4Handle, MP4_TYPE_AVC_PROFILE_BASELINE );
+    error = MP4ParseIsFrameAvailable( iMP4Handle, iVideoType );
+    error = MP4ParseIsFrameAvailable( iMP4Handle, MP4_TYPE_AVC_PROFILE_MAIN );
+    error = MP4ParseIsFrameAvailable( iMP4Handle, MP4_TYPE_AVC_PROFILE_EXTENDED );
+    error = MP4ParseIsFrameAvailable( iMP4Handle, iVideoType );
+
+
+	if ( error != MP4_OK )
+        {
+        iIsVideoLeft = EFalse;
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+no video" )  		
+        }
+    else 
+    	{
+    	iIsVideoLeft = ETrue;
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+video available" ) 		
+    	}
+
+    // If no more frames available inform observer and stop playing
+    if ( iIsAudioLeft == EFalse && iIsVideoLeft == EFalse )
+        {
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+no video & audio available" )  		
+
+		#ifdef TIMESTAMP
+			iReplayTimeStamp = iReplayTimeStamp + iPosition + 10;
+		#endif
+		
+		SetPositionL(  TTimeIntervalMicroSeconds ( 0 ) );
+		SourcePauseL();
+
+        if ( iObserver ) 
+        	{
+  			__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, \
+  	sending EOF" ) 
+        	iObserver->EndOfFile( KErrNone );
+        	}
+        return;
+        }
+
+	// Timing correction code
+	TTimeIntervalMicroSeconds elapsedTime;
+    TTime currentTime;
+    currentTime.HomeTime();
+    elapsedTime = currentTime.MicroSecondsFrom( iStartTime );
+    TInt64 tempTime = elapsedTime.Int64();
+    TInt timeNow = tempTime /*.GetTInt()*/ / 1000;
+
+	if ( ( timeNow + 500 ) < ( ( TInt ) iVideoPosition + iTimeDifference + iReplayTimeStamp + ( iPausedTime / 1000 ) ) )
+		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, Position check, returning" ) 
+  		__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadVideoFrameL", (timeNow + 500))
+  		__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadVideoFrameL", 
+  			(( TInt ) iVideoPosition + iTimeDifference + iReplayTimeStamp + ( iPausedTime / 1000 ) ) )  				
+  		__FILESOURCE_CONTROLL_INT4( "CMccFileSourceImpl::ReadVideoFrameL, videoPosition", iVideoPosition, 
+  			                        "TimeDifference", iTimeDifference, 
+  			                        "ReplyTimeStamp", iReplayTimeStamp, 
+  			                        "PausedTime", iPausedTime )  				
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, IGNORING" )   				
+		//return; 
+		}
+
+    // Read the size of next video frame
+  	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, reading frame" ) 
+    MP4ParseNextFrameSize( iMP4Handle, iVideoType,
+        ( mp4_u32* ) &iBufferSize );
+    
+    HBufC8* tempBuff = NULL;
+    if ( IsAVCVideo() && iIsFirstVideoFrame )
+    	{
+    	ExtractH264ParameterSetNALUsL( &tempBuff );
+    	if ( NULL != tempBuff )
+    		{
+    		CleanupStack::PushL( tempBuff );
+    		}
+    	iIsFirstVideoFrame = EFalse;
+    	}
+    // Allocate a buffer big enough for the next video frame
+  	__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadVideoFrameL, reading frame, size", iBufferSize )
+    HBufC8* iMediaBuffer = HBufC8::NewL( iBufferSize );
+    // Pointer descriptor to the buffer	
+    const TUint8* iPtrMediaSinkBuffer = iMediaBuffer->Des().Ptr();
+	   
+    if ( MP4ParseReadVideoFrame( iMP4Handle,
+        ( mp4_u8* ) iPtrMediaSinkBuffer, ( mp4_u32 ) iBufferSize,
+        ( mp4_u32* ) &iVideoFrameSize, ( mp4_u32* ) &iPosition,
+        ( mp4_bool* ) &iKeyFrame, NULL ) == MP4_OK )
+		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, reading frame, OK" )   		
+        TPtr8 iMediaSinkBuffer = iMediaBuffer->Des();
+
+		iVideoPosition = iPosition ;
+		
+
+        iMediaSinkBuffer.SetLength( iBufferSize ); // Sets buffer length
+        if ( IsAVCVideo() )
+        {
+        MarkWithNALUDelimiters( iBufferSize, iMediaSinkBuffer );
+    	}
+
+		TTimeIntervalMicroSeconds timeStamp( 0 );
+		
+        #ifdef TIMESTAMP
+			timeStamp = TTimeIntervalMicroSeconds( ( iPosition + iTimeDifference + iReplayTimeStamp ) * 1000 
+			#ifdef TIMESTAMPPAUSE
+						 + iPausedTime  
+			#endif //TIMESTAMPPAUSE
+				); 
+        	#else //TIMESTAMP
+				timeStamp = TTimeIntervalMicroSeconds ( iPosition * 1000 );
+        	#endif //TIMESTAMP
+   
+            //buffer = new ( ELeave ) CCMRMediaBuffer(
+            //iMediaSinkBuffer, CCMRMediaBuffer::EVideoH263, iBufferSize,
+            //FALSE,  timeStamp );
+             
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer, copying" ) 
+  		CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>(iVideoConsumerBuffer); 		
+  		__FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer, len", buf->BufferSize() )
+  		if( NULL != tempBuff )
+  			{
+  			buf->Data().Copy( *tempBuff );
+  			CleanupStack::PopAndDestroy( tempBuff );
+        	tempBuff = NULL;
+  			}
+  		else
+  			{
+  			buf->Data().Delete( 0, buf->BufferSize() );
+  			}
+        buf->Data().Append( *iMediaBuffer );
+           	
+	 	iVideoConsumerBuffer->SetTimeToPlay(timeStamp);
+		iVideoConsumerBuffer->SetLastBuffer(EFalse);
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer, complete" ) 
+
+        TInt err = KErrNone;
+		if ( err == KErrNone )
+            {
+
+  			__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer to sink" ) 
+  			iVideoConsumer->BufferFilledL( iVideoConsumerBuffer );
+  			iVideoConsumer = 0;
+  			iVideoConsumerBuffer = 0;
+  			__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer to sink complete" )   		
+  			   
+			if ( err != KErrNone )
+            	{
+            	delete iMediaBuffer;
+            	iMediaBuffer = NULL;
+            	User::Leave( KErrGeneral );
+            	}
+            }
+        }
+        else
+	        {
+	        __FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, reading frame, NOT OK" )
+	        }
+   
+    delete iMediaBuffer;
+    iMediaBuffer = NULL;
+
+	if ( ( timeNow - 500 ) < ( ( TInt ) iVideoPosition + iTimeDifference + iReplayTimeStamp + ( iPausedTime / 1000 ) ) )
+		{
+  		__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, Time Check 2, IGNORING" )    						//return;
+		}
+
+  	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ReadVideoFrameL, writing buffer to sink complete" ) 		
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PlayL()
+// 
+// Starts streaming from 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePlayL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePlayL" )
+    
+    __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+    			
+    if ( iCurrentState == EPlaying )
+        {
+        return;
+        }
+
+    #ifdef TIMESTAMP
+        if ( iCurrentState == EPaused ) 
+            {
+            iPauseStopped.HomeTime();
+//#ifdef TIMESTAMPPAUSE
+            TTimeIntervalMicroSeconds differenceTemp1 = 
+            	iPauseStopped.MicroSecondsFrom(iPauseStarted);
+            TInt64 differenceTemp2 = differenceTemp1.Int64();
+            iPausedTime = iPausedTime + differenceTemp2 /*.GetTInt()*/;
+//#endif //TIMESTAMPPAUSE
+            }
+		else
+			{
+			 iStartTime.HomeTime(); // Set start time to current time
+			}
+    #endif
+ /*   
+
+    // Variables for periodic timers
+    // temporary flagged hack for WINS to get timing right
+    TInt iTickIntervalVideo = 1000000;
+    TInt iTickIntervalAudio = 10000;
+
+    if ( iFrameRate != 0 )
+        {
+        // Set interval for video
+        iTickIntervalVideo = ( 1000000 / ( TInt ) iFrameRate  ) ; 
+        }
+        
+
+    TInt ticks = 10000;
+
+	// ROP plays faster so this code was added to help syncronisation
+//	iTickIntervalAudio = TInt (iTickIntervalAudio *  ( ( 100.0 - KPlaybackSync ) / 100.0 )) ;
+	iTickIntervalVideo = TInt (iTickIntervalVideo *  ( ( 100.0 - KPlaybackSync ) / 100.0 )) ;
+    	
+    // Creation and starting of periodic timers
+	 
+    if ( iIsAudio )
+        {
+        if ( !iPeriodicAudio )
+	        {
+	        iPeriodicAudio = CMccPeriodicRunner::NewL( *this );
+	        }
+        
+        iPeriodicAudio->Start( iTickIntervalAudio, 
+                               TCallBack( TickAudioL, this ) );
+        }
+    if ( iIsVideo )
+        {
+        if ( !iPeriodicVideo )
+	        {
+	        iPeriodicVideo = CMccPeriodicRunner::NewL( *this );
+	
+	        }
+        iPeriodicVideo->Start( iTickIntervalVideo,
+                               TCallBack( TickVideoL, this ) );
+        }		
+       
+       */
+    iCurrentState = EPlaying;
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::TickAudioL
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::TickAudioL(  TAny* aObject  )
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::TickAudioL" )
+
+    if ( ( ( CMccFileSourceImpl* ) aObject )->iFramesPerSample <= 2 )
+        {
+        //Reads five frames in one tick 
+        for ( int x = 0 ; x < 5; x++ )
+            {
+            ( ( CMccFileSourceImpl* ) aObject )->ReadAudioFrameL();
+            }
+        }
+
+    if ( ( ( CMccFileSourceImpl* ) aObject )->iFramesPerSample == 3 ||
+         ( ( CMccFileSourceImpl* ) aObject )->iFramesPerSample == 4 )
+         {
+               
+        //Reads two frames in one tick 
+        for ( int x = 0 ; x < 2; x++ )
+            {
+            ( ( CMccFileSourceImpl* ) aObject )->ReadAudioFrameL() ;
+            }
+        }
+
+    if ( ( ( CMccFileSourceImpl* ) aObject )->iFramesPerSample >= 5 ) 
+        {   
+        ( ( CMccFileSourceImpl* ) aObject )->ReadAudioFrameL();
+        }
+        
+    return KErrNone;
+	}
+    
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::TickVideoL
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::TickVideoL( TAny* aObject )
+	{
+	( ( CMccFileSourceImpl* ) aObject )->ReadVideoFrameL();
+	
+	return KErrNone;
+	}
+        
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PauseL()
+// 
+// Pauses streaming by cancelling timers
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePauseL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePauseL" )
+
+    if ( iCurrentState != EPlaying ) 
+    	{
+    	return;
+    	}
+    /*
+    __ASSERT_ALWAYS( iPeriodicAudio, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iPeriodicAudio, User::Leave( KErrArgument ) );
+
+    iPeriodicAudio->Cancel();
+    iPeriodicVideo->Cancel();
+      */  
+    iCurrentState = EPaused;
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::StopL()
+// 
+// Stops streaming
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourceStopL()
+    {
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceStopL" )
+
+    if ( iCurrentState == EConstructed )
+        {
+        return;
+        }
+/*
+    if ( iCurrentState == EPlaying )
+        {   
+        __ASSERT_ALWAYS( iPeriodicAudio, User::Leave( KErrArgument ) );
+        __ASSERT_ALWAYS( iPeriodicAudio, User::Leave( KErrArgument ) );
+
+		iPeriodicAudio->Cancel();
+		iPeriodicVideo->Cancel();
+        }
+*/	
+    SetPositionL(  TTimeIntervalMicroSeconds ( 0 ) );
+
+    iCurrentState = EStopped;
+
+    #ifdef TIMESTAMP
+       
+	if ( iIsAudioLeft == TRUE  && iIsVideoLeft == TRUE  )
+		{
+		iTimeDifference = 0;
+		iPausedTime=0;
+		}
+		
+    iPauseStarted = 0;
+    iPauseStopped = 0;
+        
+    #endif
+
+    }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::GetFrameLenght()
+// 
+// Gets audio frame lenght from given buffer
+// -----------------------------------------------------------------------------
+//
+TUint CMccFileSourceImpl::GetFrameLength( TPtrC8 aData )
+	{
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::GetFrameLength" )
+
+	const TUint8 *ptrData=aData.Ptr();
+	//read FT from data
+	TUint8 fT = (TUint8) ( *ptrData & 0x78 );
+	fT = TUint8 ( fT >> 3 );
+	//return frame length
+	switch ( fT )
+		{
+			case 0: //amr 4.75
+			{
+                return 13;
+            }
+            case 1: //amr 5.15
+			{
+                return 14;
+            }
+			case 2: //amr 5.9
+			{
+				return 16;
+            }
+ 			case 3: //amr 6.7
+            {
+				return 18;
+            }
+			case 4: //amr 7.4
+			{
+				return 20;
+            }
+            case 5: //amr 7.95
+            {
+			    return 21;
+            }
+            case 6: //amr 10.2
+			{
+                return 27;
+            }
+            case 7: //amr 12.2
+            {
+                return 32;
+            }
+			case 8: //amr SID
+			{
+				return 6;
+			}
+
+			case 15: //no data
+				{
+				return 1;
+				}
+            default: //not arm narrowband
+            {
+				return 0;
+            }
+        }
+}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourceDataTypeCode()
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccFileSourceImpl::SourceDataTypeCode( TMediaId aMediaId )
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceDataTypeCode" )
+
+    if ( KUidMediaTypeVideo == aMediaId.iMediaType )
+        {
+        return iVideoFourCC;
+        }
+    else if ( KUidMediaTypeAudio == aMediaId.iMediaType  )
+        {
+        return iAudioFourCC;
+        }
+    else
+        {
+        return TFourCC( NULL );
+        }
+	}
+	
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetSourceDataTypeCode()
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::SetSourceDataTypeCode( 
+	TFourCC aCodec, 
+    TMediaId aMediaId )
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SetSourceDataTypeCode" )
+	
+    if ( ( KUidMediaTypeVideo == aMediaId.iMediaType &&
+    	aCodec == iVideoFourCC ) ||
+    	 ( KUidMediaTypeAudio == aMediaId.iMediaType &&
+    	aCodec == iAudioFourCC ) )
+        {
+        return KErrNone;
+        } 
+    else
+	    {
+	    return KErrNotSupported;
+	    }
+	}	
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourcePrimeL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePrimeL()
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePrimeL" )
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::FillBufferL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::FillBufferL( CMMFBuffer* aBuffer,
+						              MDataSink*  aConsumer,
+						              TMediaId    aMediaId )
+	{
+	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL" )
+
+	if (aMediaId.iMediaType == KUidMediaTypeAudio)
+		{
+    	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, audio" )
+	    iAudioConsumer = aConsumer;
+		iAudioConsumerBuffer = aBuffer;		
+		}
+	else if (aMediaId.iMediaType == KUidMediaTypeVideo )
+		{
+    	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, video" )    
+	    iVideoConsumer = aConsumer;
+		iVideoConsumerBuffer = aBuffer;		
+		}
+	else
+		{
+    	__FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, unknown media " ) 
+		User::Leave( KErrNotSupported );	
+		}
+
+	}	
+	
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::MarkWithNALUDelimiters()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::MarkWithNALUDelimiters( 
+	const TInt aAccessUnitSize, TDes8& aBuffer )
+	{
+    __FILESOURCE_CONTROLL( "CMccFileSourceImpl::MarkWithNALUDelimiters" )
+    
+    TUint8* ptrByte = NULL;
+    TInt indx = 0;
+    TUint32 size;
+    const TUint32 size_field_len = 4;
+    
+    do
+	    {
+    	ptrByte = const_cast<TUint8*> ( aBuffer.Mid( indx ).Ptr() );	// get starting point of NALU size
+    	size = BigEndian::Get32(ptrByte);	// get NALU size
+    	aBuffer[indx+0] = 0x00;
+    	aBuffer[indx+1] = 0x00;
+    	aBuffer[indx+2] = 0x00;
+    	aBuffer[indx+3] = 0x01;
+    	indx = indx + size + size_field_len;
+    	
+	    }while(indx < aAccessUnitSize);
+    
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ExtractH264ParameterSetNALUsL()
+// -----------------------------------------------------------------------------
+//
+
+void CMccFileSourceImpl::ExtractH264ParameterSetNALUsL( HBufC8** aBufferOut )
+	{
+	__FILESOURCE_CONTROLL( "CMccFileSourceImpl::ExtractH264ParameterSetNALUsL" )
+	
+	*aBufferOut = NULL;
+	
+	MP4Err error = MP4_OK;
+	HBufC8* buffer = NULL;
+	HBufC8* bufferOut = NULL;
+	TUint32 decspecinfosize;
+	TUint8* ptrByte;
+	
+	// Query for size
+	error = MP4ParseReadVideoDecoderSpecificInfo( iMP4Handle,
+												  ( mp4_u8* ) NULL,
+												  0,
+												  ( mp4_u32* ) &decspecinfosize
+											 	);
+	if( ( MP4_OK != error ) && ( MP4_BUFFER_TOO_SMALL != error ) )
+		{
+		User::Leave(KErrGeneral);
+		}
+	
+	buffer = HBufC8::NewLC(decspecinfosize);
+	ptrByte = const_cast<TUint8*> ( buffer->Des().Ptr() );
+	
+	error = MP4ParseReadVideoDecoderSpecificInfo( iMP4Handle,
+												  ( mp4_u8* ) ptrByte,
+												  ( mp4_u32 ) buffer->Des().MaxSize(),
+												  ( mp4_u32* ) &decspecinfosize
+											 	);
+	if(MP4_OK != error)
+		{
+		User::Leave(KErrGeneral);
+		}
+	else
+		{
+		buffer->Des().SetLength( decspecinfosize );
+		}
+	
+	bufferOut = HBufC8::NewLC( buffer->Size() * 2 );
+	TPtr8 ptrBufferOut = bufferOut->Des();
+	TPtr8 ptrBuffer = buffer->Des();
+	
+	// find NALUs in decoder info and put in buffer by marking with delimiters
+	
+	TUint8 tmpByte;
+	TUint16 size16;
+	TInt indx = 5;		// skip other info in the beginning
+	TInt numNALUs = 0;
+	TInt lp_indx;
+	
+	// get number of seq. parameter set NALUs
+	tmpByte = ptrBuffer[indx++];
+	numNALUs = tmpByte & 0x1F;		// get rid of reserved '111' bits
+	
+	// extract seq. parameter set NALUs
+	
+	for ( lp_indx = 0; lp_indx < numNALUs; lp_indx++ )
+		{
+		size16 = BigEndian::Get16( ptrBuffer.Mid( indx ).Ptr() );
+		indx += 2;
+		
+		// insert delimiter
+		tmpByte = 0x00;
+		ptrBufferOut.Append( &tmpByte, 1 );
+		ptrBufferOut.Append( &tmpByte, 1 );
+		ptrBufferOut.Append( &tmpByte, 1 );
+		tmpByte = 0x01;
+		ptrBufferOut.Append( &tmpByte, 1 );
+		
+		ptrBufferOut.Append( ptrBuffer.Mid( indx, size16 ) );
+		
+		indx  += size16;
+		}
+	
+	// get number of pic. parameter set NALUs
+	tmpByte = ptrBuffer[indx++];
+	numNALUs = tmpByte;
+	
+	// extract pic. parameter set NALUs
+	
+	for ( lp_indx = 0; lp_indx < numNALUs; lp_indx++ )
+		{
+		size16 = BigEndian::Get16( ptrBuffer.Mid( indx ).Ptr() );
+		indx += 2;
+		
+		// insert delimiter
+		tmpByte = 0x00;
+		ptrBufferOut.Append( &tmpByte, 1 );
+		ptrBufferOut.Append( &tmpByte, 1 );
+		ptrBufferOut.Append( &tmpByte, 1 );
+		tmpByte = 0x01;
+		ptrBufferOut.Append( &tmpByte, 1 );
+		
+		ptrBufferOut.Append( ptrBuffer.Mid( indx, size16 ) );
+		
+		indx  += size16;
+		}
+	
+	CleanupStack::Pop( bufferOut );	
+	CleanupStack::PopAndDestroy( buffer );
+	
+	*aBufferOut = bufferOut;
+	
+	}
+	
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::IsAVCVideo()
+// -----------------------------------------------------------------------------
+//
+
+TBool CMccFileSourceImpl::IsAVCVideo()
+	{
+	if ( ( iVideoType == MP4_TYPE_AVC_PROFILE_BASELINE ) ||
+         ( iVideoType == MP4_TYPE_AVC_PROFILE_MAIN )	 ||
+         ( iVideoType == MP4_TYPE_AVC_PROFILE_EXTENDED )
+       )
+	    {
+	   	return ETrue;
+	    }
+    
+    return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::FileOpenErrorL
+// -----------------------------------------------------------------------------
+//	
+void CMccFileSourceImpl::FileOpenErrorL( MP4Err error )
+	{
+	iMP4Handle = NULL;
+	if ( error == MP4_OUT_OF_MEMORY )
+		{
+		User::Leave( KErrNoMemory );	
+		}
+	else
+		{
+		User::Leave( KErrGeneral );	
+		}
+	}
+	
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ParseUpdateVideoDescriptions
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ParseUpdateVideoDescriptions( )
+	{		
+	if ( MP4ParseRequestVideoDescription( iMP4Handle,
+		 ( mp4_u32* ) &iVideoLength,  &iFrameRate, ( mp4_u32* ) &iVideoType,
+	 	 ( mp4_u32* ) &iVideoWidth,  ( mp4_u32* ) &iVideoHeight,
+         ( mp4_u32* ) &iVideoTimeScale ) 
+         == MP4_OK )
+		{
+		iFrameSize.iWidth = iVideoWidth;
+		iFrameSize.iHeight = iVideoHeight;
+		  
+		if ( iVideoType == MP4_TYPE_H263_PROFILE_0 )
+		    {
+		    RDebug::Print(_L("CMccFileSourceImpl::OpenFileL MP4_TYPE_H263_PROFILE_0"));
+
+		    iCurrentVideoType = CCMRMediaBuffer::EVideoH263;
+		    iIsVideo = ETrue;
+		    iIsVideoLeft = ETrue;
+		 //   iVideoFourCC = TFourCC( KMccFourCCIdAVC );
+		    iVideoFourCC = TFourCC( KMccFourCCIdH263 );
+		    }
+		if ( iVideoType == MP4_TYPE_MPEG4_VIDEO )
+		    {
+		    RDebug::Print(_L("CMccFileSourceImpl::OpenFileL MP4_TYPE_MPEG4_VIDEO!"));
+
+		    iCurrentVideoType = CCMRMediaBuffer::EVideoH263;
+		    iIsVideo = ETrue;
+		    iIsVideoLeft = ETrue;
+		    iVideoFourCC = TFourCC( KMccFourCCIdAVC );
+		    }
+		if ( IsAVCVideo() )
+		    {
+		    RDebug::Print(_L("CMccFileSourceImpl::OpenFileL AVC!"));
+
+		    iCurrentVideoType = CCMRMediaBuffer::EVideoH263;
+		    iIsVideo = ETrue;
+		    iIsVideoLeft = ETrue;
+		    iVideoFourCC = TFourCC( KMccFourCCIdAVC );
+		    iIsFirstVideoFrame = ETrue;
+		    }
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ParseUpdateVideoDescriptions
+// -----------------------------------------------------------------------------
+//	    
+void CMccFileSourceImpl::ParseUpdateAudioDescriptions( )
+	{
+    if ( MP4ParseRequestAudioDescription( iMP4Handle,
+         ( mp4_u32* ) &iAudioLength, ( mp4_u32* ) &iAudioType,
+         ( mp4_u8* ) &iFramesPerSample, ( mp4_u32* ) &iAudioTimeScale,
+         ( mp4_u32* ) &iAverageBitRate )
+         == MP4_OK )
+	    {
+        if ( iAudioType == MP4_TYPE_AMR_NB )
+	        {
+	        RDebug::Print(_L("CMccFileSourceImpl::OpenFileL MP4_TYPE_AMR_NB!"));
+
+	        iCurrentAudioType = CCMRMediaBuffer::EAudioAMRNB;
+	        iIsAudio = ETrue;
+	        iIsAudioLeft = ETrue;
+	        iAudioFourCC = TFourCC( KMccFourCCIdAMRNB );
+	        }	
+	    }
+	}
+
+#ifndef EKA2
+// DLL interface code
+EXPORT_C TInt E32Dll( TDllReason )
+    {
+    return KErrNone;
+    }
+#endif