multimediacommscontroller/mmccsubcontroller/src/mccsymsimpledlstream.cpp
changeset 0 1bce908db942
child 32 f2ed1fc4c163
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccsubcontroller/src/mccsymsimpledlstream.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,606 @@
+/*
+* Copyright (c) 2006-2008 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:    MCP Symmetric subthread downlink stream
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <mmf/server/mmfformat.h>
+#include <mmf/server/mmfaudiooutput.h>
+#include "mccsymsimpledlstream.h"
+#include "mccdldatapath.h"
+#include "mccjitterbuffer.h"
+#include "mccuids.hrh"
+#include "mccrtpmanager.h"
+#include "mcccodecconfigurator.h"
+#include "mccinternaldef.h"
+#include "mccvideosink.h"
+#include "mccsubcontrollerlogs.h"
+#include "mccmultiplexer.h"
+#include "mccresources.h"
+
+// CONSTANTS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::CMccSymSimpleDlStream
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMccSymSimpleDlStream::CMccSymSimpleDlStream( 
+    TUint32 aMccStreamId, 
+    MAsyncEventHandler* aEventhandler, 
+    MMccResources* aMccResources,
+    CMccRtpManager* aManager, 
+    TFourCC aFourCC,
+    TInt aStreamType ) : 
+    CMccSymStreamBase( aMccStreamId, 
+                       aEventhandler, 
+                       aMccResources, 
+                       aManager, 
+                       aStreamType )
+    {
+    iFourCC = aFourCC;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMccSymSimpleDlStream* CMccSymSimpleDlStream::NewLC( 
+    TUint32 aMccStreamId, 
+    MAsyncEventHandler* aEventhandler, 
+    MMccResources* aMccResources,
+    CMccRtpManager* aManager, 
+    TFourCC aFourCC,
+    TInt aStreamType ) 
+    {
+    CMccSymSimpleDlStream* s = 
+            new ( ELeave ) CMccSymSimpleDlStream( aMccStreamId, 
+                                                  aEventhandler,
+                                                  aMccResources, 
+                                                  aManager, 
+                                                  aFourCC, 
+                                                  aStreamType );
+    CleanupStack::PushL( s );
+    s->ConstructL();
+
+    return s;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::ConstructL()
+    {
+    iDatapath = CMccDlDataPath::NewL( this, iMccResources, Type() );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::~CMccSymSimpleDlStream
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMccSymSimpleDlStream::~CMccSymSimpleDlStream()
+    {
+    if( iSoundDevice )
+        {
+        iSoundDevice = NULL;
+        }
+    
+    // Must do mux cleanup before decoder (mux sink) deletion
+    MultiplexerCleanup();
+        
+    if( iFormatDecode )
+        {
+        iFormatDecode->SourceThreadLogoff();
+        delete iFormatDecode;
+        iFormatDecode = NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::SetPrioritySettingsL
+// Sets the MMF priority settings for this stream
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::SetPrioritySettingsL( 
+    const TMMFPrioritySettings& aPriority )
+    {
+    __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) ); 
+   
+    iDatasink->SetSinkPrioritySettings( aPriority );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::AddSinkAndSourceL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::AddSinkAndSourceL( 
+    MDataSink* aDatasink, 
+    MDataSource* aDatasource )
+    {
+    __ASSERT_ALWAYS( aDatasink && aDatasource, User::Leave( KErrArgument ) );
+
+    iDatasink = aDatasink;
+    iDatasource = aDatasource;    
+    
+    iMultiplexer = iMccResources->MultiplexerL( iDatasource );
+    
+    // Inform datapath about ids of associated sink and source
+    iDatapath->SetAssociatedSink( iDatasink );
+    iDatapath->SetAssociatedSource( iDatasource );
+	        
+	iDatapath->AddDataSinkL( aDatasink );
+
+    User::LeaveIfError( iDatasink->SinkThreadLogon( *this ) );
+	      
+    iDatapath->AddDataSourceL( aDatasource );		    
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::LoadCodecL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::LoadCodecL( 
+    const TMccCodecInfo& aCodecInfo,
+    const TDesC8& aFmtp )
+    {
+    __SUBCONTROLLER_INT1( "CMccSymSimpleDlStream::LoadCodecL, codec state:", 
+                          CurrentCodecState() )
+    
+    __ASSERT_ALWAYS( CurrentCodecState() == EStateCodecNone || 
+                     iCodecInfo.iFourCC == aCodecInfo.iFourCC,
+                     User::Leave( KErrArgument ) );
+        
+    iCodecInfo = aCodecInfo;
+    
+    if ( CurrentCodecState() == EStateCodecNone )
+        {
+        delete iFmtpAttr;
+        iFmtpAttr = NULL;
+
+    	iFmtpAttr = HBufC8::NewL( aFmtp.Length() );
+        iFmtpAttr->Des().Copy( aFmtp );
+        
+        iCodecInfo.iFmtpLength = iFmtpAttr->Length();
+        CreatePayloadFormatDecoderL();
+        
+        // Just negotiate the codec, load it later
+        static_cast<CMccDlDataPath*>( iDatapath )->NegotiateL( *iFormatDecode );
+        
+        SetCodecState( EStateCodecNegotiated );        	
+        }
+    else if ( CurrentCodecState() == EStateCodecNegotiated )
+        {
+        // Codec is not fully usable yet, do just formatter initialization
+        MccCodecConfigurator::ConfigureCodecL( *iFormatDecode,
+                                                *iDatasink,
+                                                aCodecInfo,
+                                                *iRtpMediaClock,
+                                                CurrentCodecState() );
+                                                
+        MccCodecConfigurator::ConfigureCodecL( *iDatasource,
+                                                *iDatasink, 
+                                                iCodecInfo,
+                                                *iRtpMediaClock,
+                                                CurrentCodecState() );
+                                                
+        SetCodecState( EStateCodecPrepared );
+        }
+    else if ( CurrentCodecState() == EStateCodecPrepared )
+        {
+        if ( CodecLoadingAllowed() )
+            {
+            // Load the codec
+            static_cast<CMccDlDataPath*>( iDatapath )->LoadL( *iFormatDecode );
+            
+            // Set state before updating as the state affects to update functionality
+            SetCodecState( EStateCodecLoaded );
+                                               
+            UpdateCodecInformationL( iCodecInfo );
+            }
+        }
+    else if ( CurrentCodecState() == EStateCodecLoaded ||
+              CurrentCodecState() == EStateCodecLoadedAndUpdating )
+        {
+        // Update codec info
+        if ( iDatasource->DataSourceType() == KMccRtpSourceUid )
+       	    {
+            CMccRtpDataSource* dataSource = 
+                static_cast<CMccRtpDataSource*>( iDatasource );
+            
+            // For updating keep alive parameters
+            TMccCodecInfoBuffer infoBuffer( iCodecInfo );     
+            dataSource->ConfigureL( infoBuffer );
+       	    }
+        SetCodecState( EStateCodecLoadedAndUpdating );
+    	UpdateCodecInformationL( iCodecInfo );
+        }
+    else
+        {
+        User::Leave( KErrNotReady );
+        }
+        
+    __SUBCONTROLLER_INT1( "CMccSymSimpleDlStream::LoadCodecL, exit, new state:", 
+                          CurrentCodecState() )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::UpdateCodecInformationL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::UpdateCodecInformationL( TMccCodecInfo& aCodecInfo )
+    {
+    __ASSERT_ALWAYS( iFormatDecode, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasink, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) );
+
+    HandleSpecialSinksAndSources();
+    
+    iCodecInfo.iIsUpdate = ETrue;
+    
+    // Configure the decoder
+    MccCodecConfigurator::ConfigureCodecL( *iFormatDecode,
+                                            *iDatasink, 
+                                            aCodecInfo,
+                                            *iRtpMediaClock,
+                                            CurrentCodecState() );
+    
+    // Configure also the real source
+    MccCodecConfigurator::ConfigureCodecL( *iDatasource,
+                                            *iDatasink, 
+                                            iCodecInfo,
+                                            *iRtpMediaClock,
+                                            CurrentCodecState() );
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::CreatePayloadFormatDecoderL
+// Creates the payload format decoder
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::CreatePayloadFormatDecoderL()
+    {
+    __ASSERT_ALWAYS( iMultiplexer, User::Leave( KErrArgument ) );
+
+    TUid formatuid;
+    CMMFFormatDecode* tmp = NULL;
+    
+    formatuid.iUid = KImplUidAnyPayloadFormatDecode;
+    
+    // Multiplexer is the source of the decoder
+    tmp = CMMFFormatDecode::NewL( formatuid, iMultiplexer );
+    
+	tmp->SetSourceDataTypeCode( iCodecInfo.iFourCC, Type() );
+
+    if( iFormatDecode )
+        {
+        // Remove old one from multiplexer
+        iMultiplexer->MultiplexerSourceThreadLogoff( iFormatDecode );
+        
+        iFormatDecode->SourceThreadLogoff();
+        delete iFormatDecode;
+        }
+    
+    iFormatDecode = tmp;
+    User::LeaveIfError( iFormatDecode->SourceThreadLogon( *this ) );
+    
+    // Add decoder as sink of the multiplexer
+    User::LeaveIfError( 
+        iMultiplexer->MultiplexerSourceThreadLogon( *this, *iFormatDecode, ETrue, Type() ) );
+
+    if ( KMccRtpSourceUid == iDatasource->DataSourceType() )
+        {
+        RArray<TUint> payloads;
+        CleanupClosePushL( payloads );
+        ParsePayloadTypesL( payloads, iCodecInfo );
+        iMultiplexer->RegClientForPayloadsL( *iFormatDecode, payloads );
+        CleanupStack::PopAndDestroy( &payloads );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::PrimeL
+// Primes the audio stream ready
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::PrimeL( const TUint32 aEndpointId )
+    {
+    __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) );
+
+    TBool controlNetworkResources = SetStateL( EStatePrepared, aEndpointId );
+    
+     if ( controlNetworkResources && !LocalStream() )
+        {
+        iRtpmanager->CreateReceiveStreamL( *iDatasource, iCodecInfo );
+        }
+    
+    LoadCodecL( iCodecInfo, KNullDesC8 );
+    
+    DoPrimeL();
+    
+    InformStreamStateChange( KMccStreamPrepared, aEndpointId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::PlayL
+// Starts audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::PlayL( 
+    const TUint32 aEndpointId, 
+    TBool /*aStreamPaused*/, 
+    TBool aEnableRtcp )
+    {
+    __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) );
+    
+    TBool controlNetworkResources = SetStateL( EStateStreaming, aEndpointId );
+    
+    if ( !LocalStream() )
+        {  
+        if ( controlNetworkResources )
+            {
+            iRtpmanager->StartSessionL();
+            }
+            
+        User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) );
+        }
+    
+    UpdateCodecLoadingPermission( ETrue );
+    
+    LoadCodecL( iCodecInfo, KNullDesC8 );
+    
+    DoPlayL();
+    
+    InformStreamStateChange( KMccStreamStarted, aEndpointId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::PauseL
+// Pauses audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::PauseL( const TUint32 aEndpointId, TBool aEnableRtcp )
+    {
+    __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) );
+    
+    SetStateL( EStatePaused, aEndpointId );
+    
+     if ( !LocalStream() )
+        { 
+        User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) );
+        }
+
+    DoPauseL();
+    
+    InformStreamStateChange( KMccStreamPaused, aEndpointId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::ResumeL
+// Resumes paused audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::ResumeL( const TUint32 aEndpointId, TBool aEnableRtcp )
+    {
+    __ASSERT_ALWAYS( iRtpmanager, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) );
+    
+    SetStateL( EStateStreaming, aEndpointId );
+    
+    if ( !LocalStream() )
+        { 
+        User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) );
+        }
+
+    DoResumeL();
+    
+    InformStreamStateChange( KMccStreamResumed, aEndpointId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::StopL
+// Stops the audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::StopL( const TUint32 aEndpointId )
+    {
+    __ASSERT_ALWAYS( iDatapath, User::Leave( KErrArgument ) );    
+    
+    SetStateL( EStateStopped, aEndpointId );
+    
+    DoStopL();
+    
+    InformStreamStateChange( KMccStreamStopped, aEndpointId );   
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::SetBalanceL
+// Sets the current play balance
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::SetBalanceL( TInt aLeftBal, TInt aRightBal )
+    {
+    if( !iSoundDevice )
+        {
+        User::Leave( KErrNotReady );
+        }
+    else
+        {
+        iSoundDevice->SetPlayBalanceL( aLeftBal, aRightBal );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::GetBalanceL
+// Returns the current play balance
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::GetBalanceL( TInt& aLeftbal, TInt& aRightbal )
+    {
+    if( !iSoundDevice )
+        {
+        User::Leave( KErrNotReady );
+        }
+    else
+        {
+        iSoundDevice->GetPlayBalanceL( aLeftbal, aRightbal );
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::GetSSRCL
+// Returns SSRC value
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::GetSSRCL( TUint32& /*aSSRCValue*/ )
+    {
+    User::Leave ( KErrNotSupported );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::ResetCountersL
+// Resets Jitterbuffer
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::ResetCountersL( )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::SendMediaSignalL
+// Downlink can send RTCP media signals (only receiver reports)
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::SendMediaSignalL( const TMccEvent& aEvent )
+    {
+    __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrNotReady ) );
+    
+    CMccRtpDataSource* p = static_cast<CMccRtpDataSource*>( iDatasource );
+    p->SendMediaSignallingL( aEvent );
+    }
+        
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::SendRTCPReceiverReportL
+// Sends a RTCP receiver report
+// -----------------------------------------------------------------------------
+//  
+void CMccSymSimpleDlStream::SendRTCPReceiverReportL()
+    {
+    __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) );
+
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    User::LeaveIfError( dSource->SendRTCPReceiverReport() );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::StartInactivityTimerL
+// Starts inactivity timer for a stream
+// -----------------------------------------------------------------------------
+// 
+void CMccSymSimpleDlStream::StartInactivityTimerL( TUint32 aTimeoutTime )
+    {
+    __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) );
+    
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StartInactivityTimerL( aTimeoutTime );
+    }
+
+      
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::StopInactivityTimerL
+// Stops inactivity timer for a stream 
+// -----------------------------------------------------------------------------
+// 
+void CMccSymSimpleDlStream::StopInactivityTimerL()
+    {
+    __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) );
+    
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StopInactivityTimerL( );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::IsUplink
+// -----------------------------------------------------------------------------
+// 
+TBool CMccSymSimpleDlStream::IsUplink()
+    {
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::StandByL
+// -----------------------------------------------------------------------------
+// 
+void CMccSymSimpleDlStream::StandByL()
+    {
+    __ASSERT_ALWAYS( !LocalStream(), User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrArgument ) );
+    
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StandBy( EForceStandby, iCodecInfo.iPayloadType );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::JitterBufferError
+// -----------------------------------------------------------------------------
+// 
+void CMccSymSimpleDlStream::JitterBufferError( TInt /*aError*/ )
+	{
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::DynamicBufferChangeRequest
+// -----------------------------------------------------------------------------
+//
+void CMccSymSimpleDlStream::DynamicBufferChangeRequest( TInt /* aBufferSize*/ )
+    {
+    
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymSimpleDlStream::MultiplexerSink
+// -----------------------------------------------------------------------------
+//
+MDataSink* CMccSymSimpleDlStream::MultiplexerSink()
+    {
+    return iFormatDecode;
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File