multimediacommscontroller/mmccsubcontroller/src/mccdatapathbase.cpp
changeset 0 1bce908db942
--- /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 <mmf/common/mmfutilities.h>
+#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<CMMFDataBuffer*>( aDesBuffer ) );
+        
+        desBuffer->Data().Copy(
+            static_cast<CMMFDataBuffer*>( 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