--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcecli/src/mcefilesource.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,782 @@
+/*
+* 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 "mcefilesource.h"
+#include "mcecomfilesource.h"
+#include "mceitcsender.h"
+#include "mcestreamobserver.h"
+#include "mcevideostream.h"
+#include "mceaudiostream.h"
+#include "mcemanager.h"
+#include "mce.h"
+#include "mcesession.h"
+#include "mceserial.h"
+#include "utf.h"
+#include "mceevents.h"
+#include "mceclilogs.h"
+
+#define _FLAT_DATA static_cast<CMceComFileSource*>( iFlatData )
+#define FLAT_DATA( data ) _FLAT_DATA->data
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMceFileSource* CMceFileSource::NewL(
+ CMceManager& aManager,
+ const TFileName& aFileName )
+ {
+ CMceFileSource* self = CMceFileSource::NewLC( aManager, aFileName );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMceFileSource* CMceFileSource::NewLC(
+ CMceManager& aManager,
+ const TFileName& aFileName )
+ {
+ CMceFileSource* self = new (ELeave) CMceFileSource();
+ CleanupStack::PushL( self );
+ self->ConstructL( &aManager, aFileName );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CMceFileSource::~CMceFileSource()
+ {
+ if ( iManager && iFlatData )
+ {
+ TRAP_IGNORE( DoCancelTranscodeL() );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::EnableL()
+ {
+ MCECLI_DEBUG("CMceFileSource::EnableL, Entry");
+
+ CMceMediaSource::DoEnableL();
+
+ MCECLI_DEBUG("CMceFileSource::EnableL, Exit");
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::DisableL()
+ {
+ MCECLI_DEBUG("CMceFileSource::DisableL, Entry");
+
+ CMceMediaSource::DoDisableL();
+
+ MCECLI_DEBUG("CMceFileSource::DisableL, Exit");
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMceFileSource::MediaElementCountL( TMceMediaType aType ) const
+ {
+ if ( aType == KMceAudio )
+ {
+ return FLAT_DATA( iFileInfo.iAudioElementCount );
+ }
+ else if ( aType == KMceVideo )
+ {
+ return FLAT_DATA( iFileInfo.iVideoElementCount );
+ }
+
+ return 0;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::SetCurrentMediaElementL(
+ TMceMediaType aType,
+ TInt aIndex )
+ {
+ __ASSERT_ALWAYS( aIndex >= 0 &&
+ aIndex < MediaElementCountL( aType ),
+ User::Leave( KErrArgument ) );
+
+ if ( aType == KMceAudio )
+ {
+ FLAT_DATA( iCurrentAudioElement ) = aIndex;
+ }
+ else if ( aType == KMceVideo )
+ {
+ FLAT_DATA( iCurrentVideoElement ) = aIndex;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMceFileSource::CurrentMediaElement( TMceMediaType aType )
+ {
+ if ( aType == KMceAudio )
+ {
+ return FLAT_DATA( iCurrentAudioElement );
+ }
+ else if ( aType == KMceVideo )
+ {
+ return FLAT_DATA( iCurrentVideoElement );
+ }
+
+ return 0;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::SetPositionL(
+ const TTimeIntervalMicroSeconds& aPosition )
+ {
+ MCECLI_DEBUG("CMceFileSource::SetPositionL, Entry");
+
+ __ASSERT_ALWAYS( aPosition <= DurationL() &&
+ aPosition >= TTimeIntervalMicroSeconds( 0 ),
+ User::Leave( KErrArgument ) );
+
+ if ( MCE_ENDPOINT_ITC_ALLOWED( *this ) )
+ {
+
+ TMceIds ids;
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+
+ TMceItcArgTime position( aPosition );
+
+ iStream->Session()->ITCSender().WriteL( ids, EMceItcSetFilePosition, position );
+
+ FLAT_DATA( iPosition ) = position();
+ }
+ else
+ {
+ FLAT_DATA( iPosition ) = aPosition;
+ MCECLI_DEBUG("CMceDisplaySink::SetPositionL, done locally");
+ }
+ MCECLI_DEBUG("CMceFileSource::SetPositionL, Exit");
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TTimeIntervalMicroSeconds CMceFileSource::PositionL() const
+ {
+ MCECLI_DEBUG("CMceFileSource::PositionL, Entry");
+
+ if ( MCE_ENDPOINT_ITC_ALLOWED( *this ) )
+ {
+
+ TPckgBuf<TTimeIntervalMicroSeconds> pckg( FLAT_DATA( iPosition ) );
+
+ TMceIds ids;
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+
+ TMceItcArgTime position;
+
+ iStream->Session()->ITCSender().ReadL( ids, EMceItcFilePosition, position );
+
+ FLAT_DATA( iPosition ) = position();
+ }
+ else
+ {
+ MCECLI_DEBUG("CMceDisplaySink::PositionL, done locally");
+ }
+
+ MCECLI_DEBUG("CMceFileSource::PositionL, Exit");
+ return FLAT_DATA( iPosition );
+
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TTimeIntervalMicroSeconds CMceFileSource::DurationL() const
+ {
+ return FLAT_DATA( iFileInfo.iDuration );
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::SetFastForwardL( TBool aUseFFWD )
+ {
+ MCECLI_DEBUG("CMceFileSource::SetFastForwardL, Entry");
+
+ __ASSERT_ALWAYS( this->MediaElementCountL( KMceVideo ) > 0,
+ User::Leave( KErrNotSupported ) );
+
+ if ( MCE_ENDPOINT_ITC_ALLOWED( *this ) )
+ {
+
+ TMceIds ids;
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+ ids.iState = aUseFFWD;
+
+ iStream->Session()->ITCSender().SendL( ids, EMceItcSetFastForward );
+
+ FLAT_DATA( iFastForward ) = static_cast<TBool>( ids.iState );
+ }
+ else
+ {
+ MCECLI_DEBUG("CMceDisplaySink::SetFastForwardL, done locally");
+ FLAT_DATA( iFastForward ) = aUseFFWD;
+ }
+
+ if ( FLAT_DATA( iFastForward ) )
+ {
+ FLAT_DATA( iFastRewind ) = EFalse ;
+ }
+
+ MCECLI_DEBUG("CMceFileSource::SetFastForwardL, Exit");
+
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::SetFastRewindL( TBool aUseFRWD )
+ {
+ MCECLI_DEBUG("CMceFileSource::SetFastRewindL, Entry");
+
+ __ASSERT_ALWAYS( this->MediaElementCountL( KMceVideo ) > 0,
+ User::Leave( KErrNotSupported ) );
+
+ if ( MCE_ENDPOINT_ITC_ALLOWED( *this ) )
+ {
+
+ TMceIds ids;
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+ ids.iState = aUseFRWD;
+
+ iStream->Session()->ITCSender().SendL( ids, EMceItcSetFastRewind );
+
+ FLAT_DATA( iFastRewind ) = static_cast<TBool>( ids.iState );
+ }
+ else
+ {
+ MCECLI_DEBUG("CMceDisplaySink::SetFastRewindL, done locally");
+ FLAT_DATA( iFastRewind ) = aUseFRWD;
+ }
+
+ if ( FLAT_DATA( iFastRewind ) )
+ {
+ FLAT_DATA( iFastForward ) = EFalse ;
+ }
+ MCECLI_DEBUG("CMceFileSource::SetFastRewindL, Exit");
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::UpdateL ( const TFileName& aFileName )
+ {
+ MCECLI_DEBUG("CMceFileSource::UpdateL, Entry");
+ MCECLI_DEBUG_SVALUE("file", aFileName );
+
+ FLAT_DATA( iFileInfo.iFileName ) = aFileName;
+
+ __ASSERT_ALWAYS( iManager, User::Leave( KErrNotReady ) );
+
+ MCECLI_DEBUG("CMceFileSource::UpdateL, querying file info");
+ GetFileInfoL( EFalse );
+
+ SynchronizeWithStreamL();
+
+ // If any of the streams need transcoding, filesource needs to be paused
+ TBool transcodingRequired = EFalse;
+ TInt index = 0;
+ while( index < iParents.Count() && !transcodingRequired )
+ {
+ transcodingRequired =
+ ( iParents[ index++ ]->State() == CMceMediaStream::ETranscodingRequired );
+ }
+
+ if ( transcodingRequired )
+ {
+ MCECLI_DEBUG("CMceFileSource::UpdateL, transcoding required");
+ if ( IsEnabled() )
+ {
+ // If enabled, filesource has to be disabled
+ MCECLI_DEBUG("CMceFileSource::UpdateL, disabling file source");
+ DisableL();
+ }
+ else
+ {
+ // If already disabled, stream state change can be notified immediately
+ Updated();
+ }
+ }
+ else
+ {
+ SetFileInfoL();
+ }
+
+ MCECLI_DEBUG("CMceFileSource::UpdateL, Exit");
+
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::TranscodeL( const TFileName& aFileName )
+ {
+ MCECLI_DEBUG("CMceDisplaySink::TranscodeL, Entry");
+ MCECLI_DEBUG_SVALUE("file", aFileName );
+
+ __ASSERT_ALWAYS( iManager, User::Leave( KErrNotReady ) );
+
+ FLAT_DATA( iTranscodeInfo.iFileName ) = aFileName;
+ FLAT_DATA( iTranscodeInfo.iQuality ) = 1;
+ FLAT_DATA( iTranscodeInfo.iError ) = KErrNone;
+ FLAT_DATA( iTranscodeInfo.iProgress ) = 0;
+
+ if ( FLAT_DATA( iID ) == KMceMediaIdNotAssigned )
+ {
+ FLAT_DATA( iID ) = iManager->NextMediaId();
+ }
+
+ TUint sessionid = iManager->TranscodeL( *this );
+
+ FLAT_DATA( iTranscodeInfo.iTranscodeSessionId ) = sessionid;
+
+ UpdateState( CMceMediaStream::ETranscoding );
+
+ MCECLI_DEBUG("CMceDisplaySink::TranscodeL, Exit");
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CMceFileSource::CancelTranscodeL()
+ {
+ MCECLI_DEBUG("CMceDisplaySink::CancelTranscodeL, Entry");
+
+ DoCancelTranscodeL();
+
+ SynchronizeWithStreamL();
+
+ MCECLI_DEBUG("CMceDisplaySink::CancelTranscodeL, Exit");
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::UpdateState( CMceMediaStream::TState aState )
+ {
+ TInt index = 0;
+ while( index < iParents.Count() )
+ {
+ iParents[ index++ ]->SetState( aState );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::SynchronizeWithStreamL()
+ {
+ TInt index = 0;
+ while( index < iParents.Count() )
+ {
+ iParents[ index++ ]->SynchronizeWithFileL( *this );
+ }
+ }
+
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMceFileSource::TranscodingProgressL() const
+ {
+ __ASSERT_ALWAYS( iManager, User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( iParents.Count() > 0, User::Leave( KErrNotReady ) );
+
+ return FLAT_DATA( iTranscodeInfo.iProgress );
+
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::InitializeL( CMceManager* aManager )
+ {
+ __ASSERT_ALWAYS( aManager, User::Leave( KErrArgument ) );
+ iManager = aManager;
+
+ if ( !FLAT_DATA( iInitialInfoRetrieved ) )
+ {
+ MCECLI_DEBUG("CMceFileSource::InitializeL, querying file info");
+ GetFileInfoL();
+
+ FLAT_DATA( iInitialInfoRetrieved ) = ETrue;
+
+ }
+
+
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CMceFileSource::SupportedVideo()
+ {
+ return FLAT_DATA( iFileInfo.iVideoCodec );
+
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CMceFileSource::SupportedAudio()
+ {
+ return FLAT_DATA( iFileInfo.iAudioCodec );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+const TMceFileInfo& CMceFileSource::FileInfo()
+ {
+ return FLAT_DATA( iFileInfo );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::StreamAddedL( CMceMediaStream& aParent )
+ {
+ CMceMediaSource::StreamAddedL( aParent );
+
+ if ( iManager ) //not intialized
+ {
+ SynchronizeWithStreamL();
+ }
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// Factory method for inner usage
+// -----------------------------------------------------------------------------
+//
+CMceFileSource* CMceFileSource::NewL()
+ {
+ CMceFileSource* self = CMceFileSource::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Factory method for inner usage
+// -----------------------------------------------------------------------------
+//
+CMceFileSource* CMceFileSource::NewLC()
+ {
+ CMceFileSource* self = new (ELeave) CMceFileSource();
+ CleanupStack::PushL( self );
+ self->ConstructL( NULL, KNullDesC() );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMceFileSource::CMceFileSource()
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::Updated
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::Updated()
+ {
+ MMceStreamObserver* observer = iManager->MediaObserver();
+
+ if ( observer && iParents.Count() > 0 )
+ {
+ observer->StreamStateChanged( *iParents[ 0 ], *this );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::EventReceivedL
+// -----------------------------------------------------------------------------
+//
+TInt CMceFileSource::EventReceivedL( TMceEvent& aEvent )
+ {
+ TInt status = CMceMediaSource::EventReceivedL( aEvent );
+ if ( status != KMceEventNotConsumed )
+ {
+ return status;
+ }
+
+ if ( aEvent.Id().IsSourceId() )
+ {
+ if ( aEvent.Action() == EMceItcTranscodingCompleted )
+ {
+ // If we leave here, client cannot interpret the failure
+ TRAPD( err, TranscodingCompletedL( aEvent ) )
+ if ( err )
+ {
+ // Client will see that transcoding failed as file info is not
+ // updated and stream will stay in transcoding needed state.
+ MCECLI_DEBUG("CMceFileSource::EventReceivedL, transcoding failed");
+ const TInt KMceTranscodingCompletedPercentage = 100;
+ FLAT_DATA( iTranscodeInfo.iProgress ) = KMceTranscodingCompletedPercentage;
+ }
+
+ SynchronizeWithStreamL();
+
+ }
+ status = HandleEvent( aEvent );
+
+ }
+ else
+ {
+ status = KMceEventNotConsumed;
+ }
+
+ return status;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::GetFileInfoL
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::GetFileInfoL( TBool aUseSession )
+ {
+ TMceIds ids;
+ TMceItcArgTFileInfo fileInfoBuf( FLAT_DATA( iFileInfo ) );
+
+ if ( iStream && iStream->Id().IsAssigned() &&
+ Id().IsAssigned() && aUseSession )
+ {
+
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+ iStream->Session()->ITCSender().ReadL( ids, EMceItcFileInfo, fileInfoBuf );
+ }
+ else
+ {
+ ids.iAppUID = iManager->AppUid().iUid;
+ _FLAT_DATA->SenderL(
+ iManager->ServerSession() ).ReadL( ids, EMceItcFileInfo, fileInfoBuf );
+ }
+
+ FLAT_DATA( iFileInfo ) = fileInfoBuf();
+
+ User::LeaveIfError( FLAT_DATA( iFileInfo.iAccessRights ) == TMceFileInfo::EZero ?
+ KErrAccessDenied : KErrNone );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::SetFileInfoL
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::SetFileInfoL()
+ {
+
+ if ( iStream && iStream->Id().IsAssigned() &&
+ Id().IsAssigned() )
+ {
+ TMceIds ids;
+ iStream->Session()->PrepareForITC( ids );
+ ids.iMediaID = iStream->Id();
+ ids.iSourceID = Id();
+
+ TMceItcArgTFileInfo fileInfo( FLAT_DATA( iFileInfo ) );
+
+ iStream->Session()->ITCSender().WriteL( ids, EMceItcSetFileInfo, fileInfo );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::HandleEvent
+// -----------------------------------------------------------------------------
+//
+TInt CMceFileSource::HandleEvent( TMceEvent& aEvent )
+ {
+ MCECLI_DEBUG("CMceFileSource::HandleEvent, Entry");
+ TInt status = KMceEventNotConsumed;
+
+ if ( aEvent.Action() == EMceItcTranscodingCompleted )
+ {
+ MCECLI_DEBUG("CMceFileSource::HandleEvent, transcoding completed");
+ iManager->TranscodeCompleted( *this );
+ status = KMceEventConsumed;
+ Updated();
+ }
+ else if ( aEvent.Action() == EMceItcTranscodingInProgress )
+ {
+ MCECLI_DEBUG("CMceFileSource::HandleEvent, transcoding in progress");
+ FLAT_DATA( iTranscodeInfo.iProgress ) = aEvent.ActionData();
+ status = KMceEventConsumed;
+ Updated();
+ }
+ else
+ {
+ //NOP
+ MCECLI_DEBUG("CMceFileSource::HandleEvent, not consumed");
+ }
+
+ MCECLI_DEBUG_DVALUE("CMceFileSource::HandleEvent, Exit. status", status );
+ return status;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::ConstructL( CMceManager* aManager,
+ const TFileName& aFileName )
+ {
+ CMceComFileSource* source = CMceComFileSource::NewLC();
+ CMceMediaSource::ConstructL( source );
+ CleanupStack::Pop( source );
+
+ FLAT_DATA( iFileInfo.iFileName ) = aFileName;
+ FLAT_DATA( iFileInfo.iDirection ) = TMceFileInfo::ERead;
+
+ if ( aManager )
+ {
+ InitializeL( aManager );
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::Manager
+// -----------------------------------------------------------------------------
+//
+CMceManager* CMceFileSource::Manager()
+ {
+ return iManager;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::TranscodingCompletedL
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::TranscodingCompletedL( TMceEvent& aEvent )
+ {
+ // Update file to be the transcoded file only if transcoding
+ // completed succesfully
+ User::LeaveIfError( aEvent.Id().iStatus );
+
+ FLAT_DATA( iFileInfo.iFileName ) = FLAT_DATA( iTranscodeInfo.iFileName );
+
+ MCECLI_DEBUG("CMceFileSource::TranscodingCompletedL, querying file info");
+ // Get new info outside session
+ GetFileInfoL( EFalse );
+
+ MCECLI_DEBUG("CMceFileSource::TranscodingCompletedL, setting file info");
+ // Set it to the session
+ SetFileInfoL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMceFileSource::DoCancelTranscodeL
+// -----------------------------------------------------------------------------
+//
+void CMceFileSource::DoCancelTranscodeL()
+ {
+ MCECLI_DEBUG("CMceDisplaySink::DoCancelTranscodeL, Entry");
+
+ __ASSERT_ALWAYS( iManager, User::Leave( KErrNotReady ) );
+
+ iManager->CancelTranscodeL( *this,
+ FLAT_DATA( iTranscodeInfo.iTranscodeSessionId ) );
+
+ MCECLI_DEBUG("CMceDisplaySink::DoCancelTranscodeL, Exit");
+ }
+
+// End of File
+