diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccsubcontroller/src/mccdatapathbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccsubcontroller/src/mccdatapathbase.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,667 @@ +/* +* Copyright (c) 2004-2007 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: Datapath baseclass +* +*/ + + + + +// INCLUDE FILES +#include +#include "mccdatapathbase.h" +#include "mcccompletecallback.h" +#include "mccsubcontrollerlogs.h" +#include "mccinternaldef.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::AddDataSourceL +// Adds a datasource to the datapath +// ----------------------------------------------------------------------------- +void CMccDataPathBase::AddDataSourceL( MDataSource* aSource ) + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSourceL" ) + __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( EStopped == iState, User::Leave( KErrNotReady ) ); + + if ( !iDataSink ) + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSourceL, added" ) + iDataSource = aSource; + } + else + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSourceL, creating path" ) + this->CreateDataPathL( aSource, iDataSink ); + iDataSource = aSource; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::AddDataSinkL +// Adds a datasink to the datapath +// ----------------------------------------------------------------------------- +void CMccDataPathBase::AddDataSinkL( MDataSink* aSink ) + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSinkL" ) + __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( EStopped == iState, User::Leave( KErrNotReady ) ); + + if ( !iDataSource ) + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSinkL, added" ) + iDataSink = aSink; + } + else + { + __SUBCONTROLLER( "CMccDataPathBase::AddDataSinkL, creating path" ) + this->CreateDataPathL( iDataSource, aSink ); + iDataSink = aSink; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SetAssociatedSink +// ----------------------------------------------------------------------------- +void CMccDataPathBase::SetAssociatedSink( MDataSink* aAssociatedSink ) + { + __SUBCONTROLLER_INT1( "CMccDataPathBase::SetAssociatedSinkId, id:", + MCC_ENDPOINT_ID( aAssociatedSink ) ) + + iAssociatedSink = aAssociatedSink; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SetAssociatedSource +// ----------------------------------------------------------------------------- +void CMccDataPathBase::SetAssociatedSource( MDataSource* aAssociatedSource ) + { + __SUBCONTROLLER_INT1( "CMccDataPathBase::SetAssociatedSourceId,id:", + MCC_ENDPOINT_ID( aAssociatedSource ) ) + + iAssociatedSource = aAssociatedSource; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::ChangeDataPathTransferState +// Changes the transfer state of the datapath +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::ChangeDataPathTransferState( + TTransferState aTransferState, + TBool aFailureFallback ) + { + // On failure fallback situation, keep on asking data + if ( !aFailureFallback && + ( iTransferState == EWaitSource && aTransferState == ENeedSourceData ) ) + { + // Do not allow fillbuffer request if such request is already active + return EFalse; + } + + iTransferState = aTransferState; + + switch( iState ) + { + case EStreaming: + if ( ( EWaitSink != iTransferState ) && + ( EWaitSource != iTransferState ) && + ( ECanceled != iTransferState ) ) + { + // If not waiting for something to happen, activate + TRequestStatus* stat = &iStatus; + this->Cancel(); + User::RequestComplete( stat, KErrNone ); + this->SetActive(); + } + break; + default: + // Not a supported state for transfer state + break; + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CreateDataPathL +// Datapath creating +// ----------------------------------------------------------------------------- +void CMccDataPathBase::CreateDataPathL( MDataSource* aSource, MDataSink* aSink ) + { + __SUBCONTROLLER( "CMccDataPathBase::CreateDataPathL" ) + iDataPathCreated = EFalse; + + if ( aSource && aSink ) + { + TFourCC sourceFourCC = aSource->SourceDataTypeCode( iMediaId ); + TFourCC sinkFourCC = aSink->SinkDataTypeCode( iMediaId ); + __SUBCONTROLLER_INT1( "CMccDataPathBase source", aSource->DataSourceType().iUid ) + __SUBCONTROLLER_INT1( "CMccDataPathBase sourceFourCC", sourceFourCC.FourCC() ) + __SUBCONTROLLER_INT1( "CMccDataPathBase sink", aSink->DataSinkType().iUid ) + __SUBCONTROLLER_INT1( "CMccDataPathBase sinkFourCC", sinkFourCC.FourCC() ) + + if ( ( sourceFourCC != sinkFourCC ) && + ( KMMFFourCCCodeNULL != sourceFourCC.FourCC() ) && + ( KMMFFourCCCodeNULL != sinkFourCC.FourCC() ) ) + { + __SUBCONTROLLER( "CMccDataPathBase::CreateDataPathL, not compatible, ignored" ) + iDataPathCreated = ETrue; + } + else + { + __SUBCONTROLLER( "CMccDataPathBase::CreateDataPathL, created" ) + iDataPathCreated = ETrue; + } + + User::LeaveIfError( this->SetSinkDataTypeCode( sourceFourCC, iMediaId ) ); + User::LeaveIfError( this->SetSourceDataTypeCode( sourceFourCC, iMediaId ) ); + } + else + { + __SUBCONTROLLER( "CMccDataPathBase::CreateDataPathL, KErrNotReady" ) + User::Leave( KErrNotReady ); + } + __SUBCONTROLLER( "CMccDataPathBase::CreateDataPathL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::~CMccDataPathBase +// Destructor +// ----------------------------------------------------------------------------- +CMccDataPathBase::~CMccDataPathBase() + { + delete iCompleteCallback; + Cancel(); + + + iDataSink = NULL; + iDataSource = NULL; + iSourceBuffer = NULL; + iSinkBuffer = NULL; + iEventHandler = NULL; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::ConstructSinkL +// From MDataSink +// ----------------------------------------------------------------------------- +void CMccDataPathBase::ConstructSinkL( const TDesC8& /*aInitData*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::ConstructSourceL +// From MDataSource +// ----------------------------------------------------------------------------- +void CMccDataPathBase::ConstructSourceL( const TDesC8& /*aInitData*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CanCreateSinkBuffer +// From MDataSink +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::CanCreateSinkBuffer() + { + // CMccDataPathBase can't create buffers + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CanCreateSourceBuffer +// From MDataSource +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::CanCreateSourceBuffer() + { + // CMccDataPathBase can't create buffers + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMccUlDataPath::CreateSinkBufferL +// From MDataSink +// ----------------------------------------------------------------------------- +CMMFBuffer* CMccDataPathBase::CreateSinkBufferL( TMediaId /*aMediaId*/, + TBool& /*aReference*/ ) + { + // CMccDataPathBase can't create buffers + User::Leave( KErrNotSupported ); + return NULL; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CreateSourceBufferL +// From MDataSource +// ----------------------------------------------------------------------------- +CMMFBuffer* CMccDataPathBase::CreateSourceBufferL( TMediaId /*aMediaId*/, + TBool& /*aReference*/ ) + { + // CMccDataPathBase can't create buffers + User::Leave( KErrNotSupported ); + return NULL; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// CMccDataPathBase::FillBufferL +// From MDataSource +// ----------------------------------------------------------------------------- +void CMccDataPathBase::FillBufferL( CMMFBuffer* /*aBuffer*/, + MDataSink* /*aConsumer*/, TMediaId /*aMediaId*/ ) + { + // Not implemented + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::IsBufferSupportedL +// Checks if the given buffer is supported +// ----------------------------------------------------------------------------- +void CMccDataPathBase::IsBufferSupportedL( CMMFBuffer* aBuffer ) + { + __ASSERT_ALWAYS ( aBuffer, User::Leave(KErrArgument) ); + + TUid type = aBuffer->Type(); + + if( KUidMmfDataBuffer == type ) + { + return; + } + else if( KUidMmfTransferBuffer == type ) + { + return; + } + else if( KUidMmfAudioBuffer == type ) + { + return; + } + else if( KUidMmfPtrBuffer == type ) + { + return; + } + else + { + User::Leave( KErrNotSupported ); + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CopyBuffer +// copy data and settings from one buffer to another +// ----------------------------------------------------------------------------- +void CMccDataPathBase::CopyBuffer( CMMFBuffer* aDesBuffer, + CMMFBuffer* aOrigBuffer) + { + // No need to copy if parameters point to the same buffer. + if ( ( aDesBuffer && aOrigBuffer ) && ( aDesBuffer != aOrigBuffer ) ) + { + // copy buffer data + CMMFDataBuffer* desBuffer( + static_cast( aDesBuffer ) ); + + desBuffer->Data().Copy( + static_cast( aOrigBuffer )->Data() ); + + // copy buffer setting + aDesBuffer->SetFrameNumber( aOrigBuffer->FrameNumber() ); + aDesBuffer->SetLastBuffer( aOrigBuffer->LastBuffer() ); + aDesBuffer->SetPosition( aOrigBuffer->Position() ); + aDesBuffer->SetStatus( aOrigBuffer->Status() ); + aDesBuffer->SetTimeToPlay( aOrigBuffer->TimeToPlay() ); + } + else + { + __SUBCONTROLLER("CMccDataPathBase::CopyBuffer, null buffer") + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::CreateCompleteCallBackL +// a CCompleteCallback object is created +// ----------------------------------------------------------------------------- +void CMccDataPathBase::CreateCompleteCallBackL() + { + __ASSERT_ALWAYS( iDataSink, User::Leave(KErrArgument) ); + + if ( iCompleteCallback ) + { + delete iCompleteCallback; + iCompleteCallback = NULL; + } + + TBool waitForSink = IsMmfEndpoint( iDataSink ); + iCompleteCallback = new ( ELeave ) CCompleteCallback( *iEventHandler, waitForSink ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SignalDataPathCompleteL +// a signal the datapath complete with a error code +// ----------------------------------------------------------------------------- +void CMccDataPathBase::SignalDataPathCompleteL( TInt aErrorCode ) + { + __ASSERT_ALWAYS( iCompleteCallback, User::Leave( KErrArgument ) ); + iCompleteCallback->SignalDataPathComplete( aErrorCode ); + } + + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SetSinkDataTypeCode +// From MDataSink +// ----------------------------------------------------------------------------- +TInt CMccDataPathBase::SetSinkDataTypeCode( TFourCC aSinkFourCC, TMediaId aMediaId ) + { + if( iMediaId.iMediaType == aMediaId.iMediaType ) + { + iSinkFourCC = aSinkFourCC; + if ( iAssociatedSink ) + { + iAssociatedSink->SetSinkDataTypeCode( aSinkFourCC, aMediaId ); + } + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SetSourceDataTypeCode +// From MDataSource +// ----------------------------------------------------------------------------- +TInt CMccDataPathBase::SetSourceDataTypeCode( TFourCC aSourceFourCC, TMediaId aMediaId ) + { + if( iMediaId.iMediaType == aMediaId.iMediaType ) + { + iSourceFourCC = aSourceFourCC; + if ( iAssociatedSource ) + { + iAssociatedSource->SetSourceDataTypeCode( aSourceFourCC, aMediaId ); + } + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SetState +// Sets the current datapath state +// ----------------------------------------------------------------------------- +void CMccDataPathBase::SetStateL( const TDataPathState& aState ) + { + /* + * States are EStopped, EPrimed, EStreaming + * Following transitions are valid: + * STOP -> EPrimed, EStopped + * PRIMED -> EStreaming, EStopped + * STREAMING -> EStopped, EPaused + * PAUSED -> EStreaming, EStopped + * ANY -> EStopped + */ + + switch( iState ) + { + case EStopped: + if( EPrimed == aState || EStopped == aState ) + { + iState = aState; + } + else + { + User::Leave( KErrArgument ); + } + break; + case EPrimed: + if( EStopped == aState || EStreaming == aState ) + { + iState = aState; + } + else + { + User::Leave( KErrArgument ); + } + break; + case EStreaming: + if( EStopped == aState || EPaused == aState ) + { + iState = aState; + } + else + { + User::Leave( KErrArgument ); + } + break; + case EPaused: + if( EStreaming == aState || EStopped == aState ) + { + iState = aState; + } + else + { + User::Leave( KErrArgument ); + } + break; + default: + User::Leave( KErrUnknown ); + break; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::EmptyBufferL +// From MDataSink +// ----------------------------------------------------------------------------- +void CMccDataPathBase::EmptyBufferL( CMMFBuffer* /* aBuffer */, MDataSource* + /*aSupplier*/, TMediaId /*aMediaId*/ ) + { + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SinkDataTypeCode +// From MDataSink +// ----------------------------------------------------------------------------- +TFourCC CMccDataPathBase::SinkDataTypeCode( TMediaId aMediaId ) + { + if( KUidMediaTypeAudio == aMediaId.iMediaType || + KUidMediaTypeVideo == aMediaId.iMediaType ) + { + return iSinkFourCC; + } + else + { + TFourCC dummy( KFourCCNULL ); + return dummy; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::SourceDataTypeCode +// From MDataSource +// ----------------------------------------------------------------------------- +TFourCC CMccDataPathBase::SourceDataTypeCode( TMediaId aMediaId ) + { + if( KUidMediaTypeAudio == aMediaId.iMediaType || + KUidMediaTypeVideo == aMediaId.iMediaType ) + { + return iSourceFourCC; + } + else + { + TFourCC dummy( KFourCCNULL ); + return dummy; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::State +// Returns the current datapath state +// ----------------------------------------------------------------------------- +TDataPathState CMccDataPathBase::State() const + { + return iState; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::TransferState +// Returns the current transferstate +// ----------------------------------------------------------------------------- +TTransferState CMccDataPathBase::TransferState() const + { + return iTransferState; + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::ControlSource +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::ControlSource( TUint32 aEndpointId ) const + { + return ( MCC_CONTROL_ALL_ENDPOINTS( aEndpointId ) || + aEndpointId == MCC_ENDPOINT_ID( iAssociatedSource ) ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::ControlSink +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::ControlSink( TUint32 aEndpointId ) const + { + return ( MCC_CONTROL_ALL_ENDPOINTS( aEndpointId ) || + aEndpointId == MCC_ENDPOINT_ID( iAssociatedSink ) ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::IsMmfEndpoint +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::IsMmfEndpoint( MDataSink* aSink ) const + { + return ( aSink && aSink->DataSinkType() == KUidMmfAudioOutput ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::IsMmfEndpoint +// ----------------------------------------------------------------------------- +TBool CMccDataPathBase::IsMmfEndpoint( MDataSource* aSource ) const + { + return ( aSource && aSource->DataSourceType() == KUidMmfAudioInput ); + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::DoCancel +// From CActive +// ----------------------------------------------------------------------------- +void CMccDataPathBase::DoCancel() + { + // Nothing to do + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::EndOfData +// End of data +// ----------------------------------------------------------------------------- +void CMccDataPathBase::EndOfData() + { + TRAPD( err, DoEndOfDataL() ); + + if ( err ) + { + __SUBCONTROLLER_INT1("CMccDataPathBase::EndOfData(), err=", err) + if ( iEventHandler ) + { + iEventHandler->SendEventToClient( + TMMFEvent( KMMFEventCategoryPlaybackComplete, err ) ); + } + else + { + __SUBCONTROLLER("CMccDataPathBase::EndOfData(),iEventHandler=NULL") + } + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::RunL +// From CActive +// ----------------------------------------------------------------------------- +void CMccDataPathBase::RunL() + { + switch ( State() ) + { + case EStopped: + break; + case EPrimed: + break; + case EPaused: + break; + case EStreaming: + switch ( TransferState() ) + { + case EWaitSink: + case EWaitSource: + break; + case ENeedSourceData: + FillSourceBufferL(); + break; + case ESendDataToSink: + EmptySinkBufferL(); + break; + case EEndOfData: + EndOfData(); + break; + default: + User::Leave( KErrArgument ); + break; + } + break; + default: + User::Leave( KErrArgument ); + break; + } + } + +// ----------------------------------------------------------------------------- +// CMccDataPathBase::RunError +// From CActive +// ----------------------------------------------------------------------------- +TInt CMccDataPathBase::RunError( TInt /*aError*/ ) + { + return KErrNone; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File