--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccfilesourcesink/src/mccfilesourceimpl.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1096 @@
+/*
+* 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 "mccfileaudio.h"
+#include "mccfilevideo.h"
+#include "mccinternalevents.h"
+#include "mmccinterfacedef.h"
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::NewL
+// Static constructor.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl* CMccFileSourceImpl::NewL(
+ TUint32 aEndpointId,
+ MMccResources* aMccResources )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::NewL" )
+
+ CMccFileSourceImpl* self = new ( ELeave ) CMccFileSourceImpl( aEndpointId );
+ CleanupStack::PushL(self);
+ self->ConstructL( aMccResources );
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ConstructL( MMccResources* aMccResources )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::ConstructL" )
+
+ iFileAudio = CMccFileAudio::NewL( *this );
+ iFileVideo = CMccFileVideo::NewL( *this, aMccResources, iEndpointId );
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl::CMccFileSourceImpl( TUint32 aEndpointId )
+ : iCurrentState( EConstructed ),
+ iIsAudio ( EFalse ),
+ iIsVideo ( EFalse ),
+ iEndpointId( aEndpointId ),
+ iDelayAfterStop( 0 ),
+ iEofTimer( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::~CMccFileSourceImpl.
+// -----------------------------------------------------------------------------
+//
+CMccFileSourceImpl::~CMccFileSourceImpl()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::~CMccFileSourceImpl" )
+
+ StopEofTimer();
+
+ if ( iMP4Handle )
+ {
+ MP4ParseClose( iMP4Handle );
+ iMP4Handle = NULL;
+ }
+
+ delete iFileAudio;
+ delete iFileVideo;
+
+ iAsyncEventHandler = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// 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, TBool aFileChangeMode )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileL" )
+
+ TCurrentState oldState = iCurrentState;
+
+ // Close old file (if exists)
+ CloseFileL( aFileChangeMode );
+
+ aFileName.ZeroTerminate();
+
+ TRAPD( err, OpenFileForStreamingL( aFileName ) );
+ if ( err )
+ {
+ if ( aFileChangeMode )
+ {
+ // Have to stop timers etc, since old file was closed
+ // and the new file is unusable
+ DoCleanupL( EFalse );
+ }
+ User::Leave( err );
+ }
+
+ this->SetFileName( aFileName );
+
+ if ( oldState == EPlaying )
+ {
+ // Continue playing with new file
+ iCurrentState = EPrimed;
+ SourcePlayL( ETrue, aFileChangeMode );
+ }
+ else
+ {
+ // Keep old state
+ iCurrentState = oldState;
+ }
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFile, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::CloseFileL()
+//
+// Closes the 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::CloseFileL( TBool aFileChangeMode )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::CloseFileL" )
+
+ if ( iCurrentState == EPlaying )
+ {
+ SourceStopL( ETrue, aFileChangeMode );
+ }
+
+ if ( iMP4Handle )
+ {
+ if ( MP4ParseClose( iMP4Handle ) != MP4_OK )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iMP4Handle = NULL;
+ iFileAudio->SetFileHandle( iMP4Handle );
+ iFileVideo->SetFileHandle( iMP4Handle );
+ }
+
+ iCurrentState = EConstructed;
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::CloseFileL, file closed" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::FileNameL()
+// -----------------------------------------------------------------------------
+//
+TFileName& CMccFileSourceImpl::FileNameL()
+ {
+ return iFileName;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetPositionL(TTimeIntervalMicroSeconds aPosition)
+//
+// Sets a new streaming position
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SetPositionL( TTimeIntervalMicroSeconds aPosition )
+ {
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::SetPositionL (us):",
+ aPosition.Int64() )
+
+ if ( iCurrentState == EStopped )
+ {
+ return;
+ }
+
+ TUint32 position = MicroToMilliSeconds( aPosition );
+
+ if ( VideoInUse() )
+ {
+ iFileVideo->SetPositionL( position );
+
+ // Position might not end up to what was requested as it is set to
+ // nearest IFrame. With audio there's no such limitation and
+ // therefore it is good to use actual video position for audio.
+ position = iFileVideo->Position();
+
+ __FILESOURCE_CONTROLL_INT1( "Pos modified to nearest IFrame (ms):",
+ position )
+ }
+
+ if ( AudioInUse() )
+ {
+ iFileAudio->SetPositionL( position );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoTypeL()
+//
+// Returns current video type
+// -----------------------------------------------------------------------------
+//
+CCMRMediaBuffer::TBufferType CMccFileSourceImpl::VideoTypeL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoTypeL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ return iFileVideo->Type();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioTypeL()
+//
+// Returns current audio type
+// -----------------------------------------------------------------------------
+//
+CCMRMediaBuffer::TBufferType CMccFileSourceImpl::AudioTypeL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioTypeL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ return iFileAudio->Type();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoFrameRateL()
+//
+// Returns current video frame rate
+// -----------------------------------------------------------------------------
+//
+TReal CMccFileSourceImpl::VideoFrameRateL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFrameRateL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ return iFileVideo->VideoFrameRateL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioBitRateL()
+//
+// Returns current audio bit rate
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileSourceImpl::AudioBitRateL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioBitRateL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ TUint32 audioBitRate = iFileAudio->AudioBitRate();
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::AudioBitRateL", audioBitRate )
+
+ return audioBitRate;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::DurationL()
+//
+// Returns duration of current media clip
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileSourceImpl::DurationL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::DurationL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ // Audio and video might have different duration, take longer one
+ //
+
+ TTimeIntervalMicroSeconds duration = 0;
+
+ if ( AudioInUse() )
+ {
+ duration = MilliToMicroSeconds( iFileAudio->Duration() );
+ }
+ if ( VideoInUse() )
+ {
+ TTimeIntervalMicroSeconds videoDuration =
+ MilliToMicroSeconds( iFileVideo->Duration() );
+ duration = videoDuration > duration ? videoDuration : duration;
+ }
+
+ __FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::DurationL in micro=",
+ duration.Int64())
+ return duration;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoFrameSizeL()
+//
+// Returns current video frame size
+// -----------------------------------------------------------------------------
+//
+TSize CMccFileSourceImpl::VideoFrameSizeL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFrameSizeL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ TSize size = iFileVideo->VideoFrameSize();
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoFrameSizeL iWidth",
+ size.iWidth )
+ __FILESOURCE_CONTROLL_INT1("CMccFileSourceImpl::VideoFrameSizeL iHeight",
+ size.iHeight )
+
+ return size;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoBitRateL()
+//
+// Returns current video bitrate
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileSourceImpl::VideoBitRateL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoBitRateL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ TUint32 audioBitRate = iFileAudio->AudioBitRate();
+
+ // Average bitrate is for the whole stream,
+ // subtract audio average to get video average
+ TUint32 averageBitRate = iFileVideo->StreamAverageBitRate() - audioBitRate;
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::VideoBitRateL, videoBitRate",
+ averageBitRate )
+
+ return averageBitRate;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PositionL()
+//
+// Returns current streaming position. If other stream is already at end
+// (zero pos) other ones position is used. Otherwise always less progressed
+// streams position is returned.
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileSourceImpl::PositionL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PositionL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ TTimeIntervalMicroSeconds audioPosition = 0;
+ TTimeIntervalMicroSeconds videoPosition = 0;
+
+ if ( AudioInUse() )
+ {
+ audioPosition = MilliToMicroSeconds( iFileAudio->Position() );
+ }
+ if ( VideoInUse() )
+ {
+ videoPosition = MilliToMicroSeconds( iFileVideo->Position() );
+ }
+
+ __FILESOURCE_CONTROLL_INT2( "CMccFileSourceImpl::PositionL in micro, audio:",
+ audioPosition.Int64(),
+ " video:", videoPosition.Int64() )
+
+ if ( videoPosition.Int64() == 0 || audioPosition.Int64() == 0 )
+ {
+ return Max( videoPosition, audioPosition );
+ }
+ return Min( videoPosition, audioPosition );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioFourCCL()
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccFileSourceImpl::AudioFourCCL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::AudioFourCCL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ return iFileAudio->GetFourCC();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoFourCCL()
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccFileSourceImpl::VideoFourCCL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::VideoFourCCL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ return iFileVideo->GetFourCC();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::GetConfigKeyL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::GetConfigKeyL( TDes8& aConfigKey )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::GetConfigKeyL" )
+
+ __ASSERT_ALWAYS( iMP4Handle && VideoInUse(), User::Leave( KErrNotReady ) );
+
+ HBufC8* configKey = iFileVideo->GetConfigKeyL();
+ CleanupStack::PushL( configKey );
+ __ASSERT_ALWAYS( configKey, User::Leave( KErrNotFound ) );
+ __ASSERT_ALWAYS( configKey->Length() <= aConfigKey.MaxLength(),
+ User::Leave( KErrOverflow ) );
+ aConfigKey.Copy( *configKey );
+ CleanupStack::PopAndDestroy( configKey );
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::GetConfigKeyL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PlayL()
+//
+// Starts streaming from 3gp file
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePlayL( TBool aIgnoreEvents, TBool aFileChangeMode )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePlayL" )
+
+ __ASSERT_ALWAYS( iCurrentState != EConstructed, User::Leave( KErrNotReady ) );
+
+ if ( iCurrentState == EPlaying )
+ {
+ return;
+ }
+
+ // Start decision for both needs to be done before starting either one
+ TBool videoStartNeeded = StartNeededL( *iFileVideo );
+ TBool audioStartNeeded = StartNeededL( *iFileAudio );
+
+ if ( videoStartNeeded && !aFileChangeMode )
+ {
+ iFileVideo->StartTimerL();
+ }
+
+ if ( audioStartNeeded && !aFileChangeMode )
+ {
+ iFileAudio->StartTimerL();
+ }
+
+ if ( !aIgnoreEvents )
+ {
+ if ( iCurrentState == EPaused )
+ {
+ SendStreamEventToClient( KMccEventCategoryStream, KMccStreamResumed );
+ }
+ else
+ {
+ SendStreamEventToClient( KMccEventCategoryStream, KMccStreamStarted );
+ }
+ }
+
+ iCurrentState = EPlaying;
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePlayL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourcePauseL()
+//
+// Pauses streaming by cancelling timers
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePauseL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePauseL" )
+
+ if ( iCurrentState != EPlaying && iCurrentState != EWaitingPause )
+ {
+ return;
+ }
+
+ if ( VideoInUse() )
+ {
+ iFileVideo->StopTimer();
+ iFileVideo->Cleanup();
+ }
+ if ( AudioInUse() )
+ {
+ iFileAudio->StopTimer();
+ iFileAudio->Cleanup();
+ }
+
+ StopEofTimer();
+
+ // If pause was caused by eof, paused event is passed to all filesource users
+ TUint32 eventNumData =
+ ( iCurrentState == EWaitingPause ) ? KMccAutomaticEvent : 0;
+
+ SendStreamEventToClient( KMccEventCategoryStream,
+ KMccStreamPaused,
+ KErrNone,
+ eventNumData );
+
+ iCurrentState = EPaused;
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePauseL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PauseAudioL()
+//
+// pause audio only
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::PauseAudioL( TInt aError )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseAudio" )
+
+ if ( iCurrentState != EPlaying )
+ {
+ return;
+ }
+
+ if ( AudioInUse() )
+ {
+ iFileAudio->StopTimer();
+ iFileAudio->Cleanup();
+ }
+
+ if ( aError )
+ {
+ SendStreamEventToClient( KMccEventCategoryStream,
+ KMccStreamPaused,
+ aError,
+ KMccAutomaticEvent );
+ }
+ else if ( !VideoInUse() || iFileVideo->IsPaused() )
+ {
+ // Initiate pause sequence only if all used media types are paused
+
+ StartEofTimerL();
+ }
+ else
+ {
+ // NOP
+ }
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseAudio, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::PauseVideoL()
+//
+// pause video only
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::PauseVideoL( TInt aError )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseVideo" )
+
+ if ( iCurrentState != EPlaying )
+ {
+ return;
+ }
+
+ if ( VideoInUse() )
+ {
+ iFileVideo->StopTimer();
+ iFileVideo->Cleanup();
+ }
+
+ if ( aError )
+ {
+ SendStreamEventToClient( KMccEventCategoryStream,
+ KMccStreamPaused,
+ aError,
+ KMccAutomaticEvent );
+ }
+ else if ( !AudioInUse() || iFileAudio->IsPaused() )
+ {
+ // Initiate pause sequence only if all used media types are paused
+
+ StartEofTimerL();
+ }
+ else
+ {
+ // NOP
+ }
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::PauseVideo, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::StopL()
+//
+// Stops streaming
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourceStopL( TBool aIgnoreEvents, TBool aFileChangeMode )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceStopL" )
+
+ if ( iCurrentState == EConstructed )
+ {
+ return;
+ }
+
+ DoCleanupL( aFileChangeMode );
+
+ if ( !aIgnoreEvents )
+ {
+ SendStreamEventToClient( KMccEventCategoryStream, KMccStreamStopped );
+ }
+
+ iCurrentState = EStopped;
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceStopL, exit" )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourceDataTypeCode()
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccFileSourceImpl::SourceDataTypeCode( TMediaId aMediaId )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceDataTypeCode" )
+
+ if ( KUidMediaTypeVideo == aMediaId.iMediaType &&
+ iFileVideo )
+ {
+ iIsVideo = ETrue;
+ return iFileVideo->GetFourCC();
+ }
+ else if ( KUidMediaTypeAudio == aMediaId.iMediaType &&
+ iFileAudio )
+ {
+ iIsAudio = ETrue;
+ return iFileAudio->GetFourCC();
+ }
+ else
+ {
+ return TFourCC( NULL );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetSourceDataTypeCode()
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::SetSourceDataTypeCode(
+ TFourCC aCodec,
+ TMediaId aMediaId )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SetSourceDataTypeCode" )
+
+ if ( KUidMediaTypeVideo == aMediaId.iMediaType
+ && VideoInUse()
+ && aCodec == iFileVideo->GetFourCC() )
+ {
+ return KErrNone;
+ }
+ else if ( KUidMediaTypeAudio == aMediaId.iMediaType
+ && AudioInUse()
+ && aCodec == iFileAudio->GetFourCC() )
+ {
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotSupported;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourcePrimeL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourcePrimeL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePrimeL" )
+
+ iCurrentState = EPrimed;
+ SendStreamEventToClient( KMccEventCategoryStream, KMccStreamPrepared );
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourcePrimeL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::FillBufferL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::FillBufferL( CMMFBuffer* aBuffer,
+ MDataSink* aConsumer,
+ TMediaId aMediaId )
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL" )
+
+ if ( aMediaId.iMediaType == KUidMediaTypeAudio &&
+ AudioInUse() )
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, audio" )
+
+ iFileAudio->FillBufferL( aBuffer, aConsumer );
+ }
+ else if (aMediaId.iMediaType == KUidMediaTypeVideo &&
+ VideoInUse() )
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, video" )
+
+ iFileVideo->FillBufferL( aBuffer, aConsumer );
+ }
+ else
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::FillBufferL, unknown media " )
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourceThreadLogon
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::SourceThreadLogon( MAsyncEventHandler& aEventHandler )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceThreadLogon" )
+
+ iAsyncEventHandler = static_cast<MAsyncEventHandler*>( &aEventHandler );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SourceThreadLogoff
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SourceThreadLogoff()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SourceThreadLogoff" )
+
+ iAsyncEventHandler = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::FileOpenErrorL
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::FileOpenErrorL( MP4Err error )
+ {
+ iMP4Handle = NULL;
+ if ( error == MP4_OUT_OF_MEMORY )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::MilliToMicroSeconds
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileSourceImpl::MilliToMicroSeconds(
+ TUint32 aMilliSeconds )
+ {
+ return TTimeIntervalMicroSeconds( (TInt64) aMilliSeconds * KMccMicroToMilliConst );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::MicroToMilliSeconds
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileSourceImpl::MicroToMilliSeconds(
+ TTimeIntervalMicroSeconds aMicroSeconds )
+ {
+ return ( aMicroSeconds.Int64() / KMccMicroToMilliConst );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetFileName()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SetFileName( const TFileName& aFileName )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::SetFileName" )
+
+ iFileName.Copy( aFileName );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::OpenFileForStreamingL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::OpenFileForStreamingL( TFileName aFileName )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileForStreamingL" )
+
+ TFileName fullFileName;
+ MP4Err error = MP4_OK;
+
+ RFs fS;
+ User::LeaveIfError( fS.Connect() );
+ CleanupClosePushL( fS );
+ TParse fp;
+ TInt err = fS.Parse( aFileName, fp );
+
+ if ( err )
+ {
+ __FILESOURCE_CONTROLL_INT1(
+ "CMccFileSourceImpl::OpenFileForStreamingL file name parse error:",
+ err )
+ User::Leave( err );
+ }
+
+ fullFileName = fp.FullName();
+ CleanupStack::PopAndDestroy( &fS );
+
+ this->SetFileName( aFileName );
+
+ const TInt KMccZeroTerminatorLen = 1;
+ __ASSERT_ALWAYS(
+ fullFileName.Length() + KMccZeroTerminatorLen <= fullFileName.MaxLength(),
+ User::Leave( KErrOverflow ) );
+
+ error = MP4ParseOpen( &iMP4Handle, (wchar_t *) fullFileName.PtrZ() );
+
+ if ( error != MP4_OK )
+ {
+ __FILESOURCE_CONTROLL_INT1(
+ "CMccFileSourceImpl::OpenFileForStreamingL parse open error:",
+ error )
+
+ iMP4Handle = NULL;
+ User::Leave( KErrGeneral );
+ }
+
+ TBool containAudio = iFileAudio->ParseUpdateAudioDescriptions( iMP4Handle );
+ TBool containVideo = iFileVideo->ParseUpdateVideoDescriptions( iMP4Handle );
+
+ if ( !containAudio && !containVideo )
+ {
+ __FILESOURCE_CONTROLL(
+ "CMccFileSourceImpl::OpenFileForStreamingL no audio/video" )
+
+ MP4ParseClose( iMP4Handle );
+ iMP4Handle = NULL;
+ User::Leave( KErrNotSupported );
+ }
+
+ iFileAudio->SetFileHandle( iMP4Handle );
+ iFileVideo->SetFileHandle( iMP4Handle );
+
+ iFileAudio->ParseUpdateStreamDescription( iMP4Handle );
+ iFileVideo->ParseUpdateStreamDescription( iMP4Handle );
+
+ // If filecontainers are reused (i.e. filename is changed),
+ // position has to be zeroed
+ SetPositionL( 0 );
+
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::OpenFileForStreamingL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SendStreamEventToClient()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SendStreamEventToClient(
+ TMccEventCategory aEventCategory,
+ TMccEventType aEventType,
+ TInt aError,
+ TUint32 aEventNumData )
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::SendStreamEventToClient" )
+
+ if ( iAsyncEventHandler )
+ {
+ ClearEvent();
+
+ iMccEvent.iEndpointId = iEndpointId;
+ iMccEvent.iEventCategory = aEventCategory;
+ iMccEvent.iEventType = aEventType;
+ iMccEvent.iErrorCode = aError;
+ iMccEvent.iEventNumData = aEventNumData;
+
+ TMccInternalEvent internalEvent( KMccFileSourceUid,
+ EMccInternalEventNone,
+ iMccEvent );
+
+ iAsyncEventHandler->SendEventToClient( internalEvent );
+ }
+ else
+ {
+ __FILESOURCE_MEDIA( "CMccFileSourceImpl::SendStreamEventToClient, \
+ iAsyncEventHandler=NULL" )
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::AudioInUse()
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileSourceImpl::AudioInUse() const
+ {
+ return ( iFileAudio && iIsAudio );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::VideoInUse()
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileSourceImpl::VideoInUse() const
+ {
+ return ( iFileVideo && iIsVideo );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::DoCleanupL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::DoCleanupL( TBool aFileChangeMode )
+ {
+ if ( VideoInUse() && !aFileChangeMode )
+ {
+ iFileVideo->StopTimer();
+ iFileVideo->ResetTimeL();
+ // clean the iConsumerBuffer and iConsumer,
+ // to prevent still send data after Stoped
+ iFileVideo->Cleanup();
+ }
+ if ( AudioInUse() && !aFileChangeMode )
+ {
+ iFileAudio->StopTimer();
+ iFileAudio->ResetTimeL();
+ iFileAudio->Cleanup();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::StartEofTimerL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::StartEofTimerL()
+ {
+ StopEofTimer();
+
+ TInt delayAfterStop( KMccMicroToMilliConst * DelayAfterStop() );
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::StartEofTimerL, microsecs:",
+ delayAfterStop )
+
+ iEofTimer = CMccEofTimer::NewL( this );
+
+ iEofTimer->After( delayAfterStop );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::EofTimerExpiredL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::EofTimerExpiredL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileSourceImpl::EofTimerExpiredL" );
+
+ iCurrentState = EWaitingPause;
+
+ SendStreamEventToClient( KMccEventCategoryStreamControl, KMccStreamPaused );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::StopEofTimer()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::StopEofTimer()
+ {
+ if ( iEofTimer )
+ {
+ __FILESOURCE_CONTROLL(
+ "CMccFileSourceImpl::StopEofTimer, cancel iEofTimer" )
+ iEofTimer->Cancel();
+ delete iEofTimer;
+ iEofTimer = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::SetDelayAfterStop()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::SetDelayAfterStop( TInt aDelay )
+ {
+ __FILESOURCE_CONTROLL_INT1( "CMccFileSourceImpl::SetDelayAfterStop aDelay:",
+ aDelay )
+ iDelayAfterStop = aDelay;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::DelayAfterStop()
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileSourceImpl::DelayAfterStop( ) const
+ {
+ return iDelayAfterStop;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::ClearEvent()
+// -----------------------------------------------------------------------------
+//
+void CMccFileSourceImpl::ClearEvent()
+ {
+ iMccEvent = TMccEvent();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileSourceImpl::StartNeededL()
+// Checks current file position and determines based on that whether starting
+// of this media type is needed. If this media type is already at end (at zero
+// pos) but other is not yet, this media type does not need starting.
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileSourceImpl::StartNeededL( CMccFileSourceTypeBase& aFileSource )
+ {
+ TBool startNeeded( ETrue );
+ TTimeIntervalMicroSeconds currentPosition = PositionL();
+
+ if ( aFileSource.MediaType().iMediaType == KUidMediaTypeAudio )
+ {
+ startNeeded = AudioInUse();
+ }
+ if ( aFileSource.MediaType().iMediaType == KUidMediaTypeVideo )
+ {
+ startNeeded = VideoInUse();
+ }
+
+ if ( startNeeded &&
+ currentPosition.Int64() > 0 &&
+ aFileSource.Position() == 0 )
+ {
+ startNeeded = EFalse;
+ }
+
+ return startNeeded;
+ }
+
+#ifndef EKA2
+// DLL interface code
+EXPORT_C TInt E32Dll( TDllReason )
+ {
+ return KErrNone;
+ }
+#endif