--- /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