multimediacommscontroller/mmccsubcontroller/src/mccsymdlstream.cpp
changeset 0 1bce908db942
child 32 f2ed1fc4c163
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccsubcontroller/src/mccsymdlstream.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,776 @@
+/*
+* Copyright (c) 2005-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:    Mcc Symmetric subthread downlink stream
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <mmf/server/mmfformat.h>
+#include <mmf/server/mmfaudiooutput.h>
+#include "mccsymdlstream.h"
+#include "mccdldatapath.h"
+#include "mccjitterbuffer.h"
+#include "mccrtpmanager.h"
+#include "mcccodecconfigurator.h"
+#include "mccinternaldef.h"
+#include "mccaudiorouter.h"
+#include "mccsubcontrollerlogs.h"
+#include "mccmultiplexer.h"
+#include "mccresources.h"
+#include "mccredpayloadread.h"
+
+// CONSTANTS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::CMccSymDlStream
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMccSymDlStream::CMccSymDlStream( 
+    TUint32 aMccStreamId, 
+    MAsyncEventHandler* aEventhandler, 
+    MMccResources* aMccResources, 
+    CMccRtpManager* aManager, 
+    TInt aStreamType ) : 
+    CMccSymStreamBase( aMccStreamId, 
+                       aEventhandler, 
+                       aMccResources, 
+                       aManager, 
+                       aStreamType ), 
+    iJitterBuffer( NULL ), 
+    iFormatDecode( NULL )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMccSymDlStream* CMccSymDlStream::NewLC( 
+    TUint32 aMccStreamId, 
+    MAsyncEventHandler* aEventhandler, 
+    MMccResources* aMccResources,
+    CMccRtpManager* aManager, 
+    TInt aStreamType ) 
+    {
+    CMccSymDlStream* s = 
+            new ( ELeave ) CMccSymDlStream( aMccStreamId, 
+                                            aEventhandler, 
+                                            aMccResources,
+                                            aManager, 
+                                            aStreamType );
+    CleanupStack::PushL( s );
+    s->ConstructL();
+    return s;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::ConstructL()
+    {
+    iDatapath = 
+        CMccDlDataPath::NewL( this, iMccResources, KUidMediaTypeAudio );
+    iJitterBuffer = CMccJitterBuffer::NewL( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::~CMccSymDlStream
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMccSymDlStream::~CMccSymDlStream()
+    {
+    delete iAudioRouter;
+    
+    if ( iSoundDevice )
+        {
+        iSoundDevice = NULL;
+        }
+        
+    if ( iJitterBuffer )
+        {
+        iJitterBuffer->SinkThreadLogoff();
+        delete iJitterBuffer;
+        iJitterBuffer = NULL;
+        }
+    
+    // Must do mux cleanup before decoder (mux sink) deletion
+    MultiplexerCleanup();
+         
+    if ( iFormatDecode )
+        {
+        iFormatDecode->SourceThreadLogoff();
+        delete iFormatDecode;
+        iFormatDecode = NULL;
+        }
+    
+    delete iRedFormatDecode;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::SetPrioritySettingsL
+// Sets the MMF priority settings for this stream
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::SetPrioritySettingsL( 
+        const TMMFPrioritySettings& aPriority )
+    {
+    __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) );    
+    
+    iDatasink->SetSinkPrioritySettings( aPriority );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::AddSinkAndSourceL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::AddSinkAndSourceL( MDataSink* aDatasink, 
+        MDataSource* aDatasource )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::AddSinkAndSourceL" )
+    
+    __ASSERT_ALWAYS( aDatasink && aDatasource, User::Leave( KErrArgument ) );
+
+    iDatasink = aDatasink;
+    iDatasource = aDatasource;
+
+    iMultiplexer = iMccResources->MultiplexerL( iDatasource );
+    
+ 	if ( iDatasink->DataSinkType() == KUidMmfAudioOutput )
+    	{
+	    iJitterBuffer->AddDataSinkL( iDatasink );
+	    
+	    // Cause the devsound to be loaded, as this call will pass through
+	    // jitterbuffer
+	    User::LeaveIfError( iJitterBuffer->SinkThreadLogon( *this ) );
+	    
+	    __SUBCONTROLLER( "CMccSymDlStream::AddSinkAndSourceL, devsound loaded" )
+	    
+	    iSoundDevice = &( static_cast<MMMFAudioOutput*>( iDatasink )->SoundDevice() );
+	    
+	    // Create new audio router
+	    delete iAudioRouter;
+        iAudioRouter = 0;
+        iAudioRouter = CMccAudioRouter::NewL( *iSoundDevice );
+    
+        iDatapath->AddDataSinkL( iJitterBuffer );
+    	}
+    else if ( iDatasink->DataSinkType() == KMccVideoSinkUid )
+    	{
+        iDatapath->AddDataSinkL( iDatasink );
+                                 
+        User::LeaveIfError( iDatasink->SinkThreadLogon(*this ) );
+    	}
+    else
+        {
+        }
+        
+    // Inform datapath about ids of associated sink and source
+    iDatapath->SetAssociatedSink( iDatasink );
+    iDatapath->SetAssociatedSource( iDatasource );
+    
+    __SUBCONTROLLER( "CMccSymDlStream::AddSinkAndSourceL, exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::LoadCodecL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::LoadCodecL( const TMccCodecInfo& aCodecInfo,
+                                  const TDesC8& aFmtp )
+    {
+    __SUBCONTROLLER_INT1( "CMccSymDlStream::LoadCodecL codec state:", 
+        CurrentCodecState() )
+    
+    __ASSERT_ALWAYS( CurrentCodecState() == EStateCodecNone || 
+                     iCodecInfo.iFourCC == aCodecInfo.iFourCC,
+                     User::Leave( KErrArgument ) );
+    
+    TMccCodecInfo orig = iCodecInfo;
+    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() );
+                                                
+        SetCodecState( EStateCodecPrepared );
+        }
+    else if ( CurrentCodecState() == EStateCodecPrepared )
+        {
+        if ( CodecLoadingAllowed() )
+            {
+            // Load the codec
+            static_cast<CMccDlDataPath*>( iDatapath )->LoadL( *iFormatDecode );
+            
+            TInt jbufLen = iCodecInfo.iMaxPtime;
+            iJitterBuffer->SetupL( jbufLen, 
+                                   iCodecInfo.iJitterBufThreshold, 
+                                   iCodecInfo );
+            
+            // Set state before updating as the state affects to update functionality
+            SetCodecState( EStateCodecLoaded );
+                                               
+            UpdateCodecInformationL( orig, 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( orig, iCodecInfo );
+        }
+    else
+        {
+        User::Leave( KErrNotReady );
+        }
+        
+    __SUBCONTROLLER_INT1( "CMccSymDlStream::LoadCodecL exit, new state:", 
+        CurrentCodecState() )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::UpdateCodecInformationL
+// From CMccSymStreamBase
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::UpdateCodecInformationL( const TMccCodecInfo& aOriginal,
+    const TMccCodecInfo& aNew )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::UpdateCodecInformationL Entry" )
+    
+    // UpdateCodecInformationL is called from LoadCodecL which checks that
+    // codec itself is not changed. Here we re-configure the codec
+    // parameters.
+    __ASSERT_ALWAYS( iFormatDecode, User::Leave( KErrNotReady ) );
+    __ASSERT_ALWAYS( iDatasink, User::Leave( KErrNotReady ) );
+    
+    HandleSpecialSinksAndSources();
+    
+    // NB; updated in LoadCodecL, update information added here
+    iCodecInfo.iIsUpdate = ETrue;
+    
+    TBool specNeed = MccCodecConfigurator::IlbcNeedsStopResume(
+            aOriginal.iBitrate,
+            iCodecInfo.iBitrate,
+            iCodecInfo.iFourCC );
+    
+    // Need to check also the codec state because CurrentCodecState may
+    // return such codec state that does not allow iLBC reconfiguration.
+    TCodecState codecState = CurrentCodecState();
+    if ( specNeed && EStateStreaming == CurrentState() )
+        {
+        iJitterBuffer->SinkStopL();
+        codecState = CMccSymStreamBase::EStateCodecLoaded;
+        }
+    
+    MccCodecConfigurator::ConfigureCodecL( *iFormatDecode,
+                                           *iDatasink,
+                                           aNew,
+                                           *iRtpMediaClock,
+                                           codecState );
+    
+    if ( specNeed && EStateStreaming == CurrentState() )
+        {
+        iJitterBuffer->SinkPlayL();
+        }
+    
+    __SUBCONTROLLER( "CMccSymDlStream::UpdateCodecInformationL Exit" )
+    }
+    
+
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::CreatePayloadFormatDecoderL
+// Creates the payload format decoder
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::CreatePayloadFormatDecoderL()
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::CreatePayloadFormatEncoderL" )
+    __ASSERT_ALWAYS( NULL == iFormatDecode, User::Leave( KErrAlreadyExists ) );
+    __ASSERT_ALWAYS( iMultiplexer, User::Leave( KErrNotReady ) );
+    
+    TUid formatuid;
+    formatuid.iUid = iCodecInfo.iPayloadFormatDecoder;
+    
+    RArray<TUint> payloads;
+    CleanupClosePushL( payloads );
+    ParsePayloadTypesL( payloads, iCodecInfo );
+    
+    if ( EGenRedUsed == iCodecInfo.iAlgoUsed )
+        {
+        __ASSERT_ALWAYS( KMccPayloadTypeMax != iCodecInfo.iRedundantPayload,
+            User::Leave( KErrArgument ) );
+        
+        iRedFormatDecode = CMMFFormatDecode::NewL(
+            TUid::Uid( KImplUidRedPayloadFormatDecode ), iMultiplexer );
+        
+        iFormatDecode = CMMFFormatDecode::NewL( formatuid, iRedFormatDecode );
+        User::LeaveIfError( iMultiplexer->MultiplexerSourceThreadLogon( *this, 
+            *iRedFormatDecode, ETrue, Type(), EFalse ) );
+        
+        iMultiplexer->RegClientForPayloadsL( *iRedFormatDecode, payloads );
+        }
+    else
+        {
+        iFormatDecode = CMMFFormatDecode::NewL( formatuid, iMultiplexer );
+        User::LeaveIfError( iMultiplexer->MultiplexerSourceThreadLogon( *this, 
+            *iFormatDecode, ETrue, Type(), EFalse ) );
+        
+        iMultiplexer->RegClientForPayloadsL( *iFormatDecode, payloads );
+        }
+    
+    iFormatDecode->SetSourceDataTypeCode( iCodecInfo.iFourCC, Type() );
+    User::LeaveIfError( iFormatDecode->SourceThreadLogon( *this ) );
+
+    CleanupStack::PopAndDestroy( &payloads );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::PrimeL
+// Primes the audio stream ready
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::PrimeL( const TUint32 aEndpointId )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::PrimeL" )
+    
+    TBool controlNetworkResources = SetStateL( EStatePrepared, aEndpointId );    
+
+    if ( controlNetworkResources )
+        {
+        iRtpmanager->CreateReceiveStreamL( *iDatasource, iCodecInfo );
+        }
+            
+    LoadCodecL( iCodecInfo, KNullDesC8 ); 
+                                                    
+    DoPrimeL();
+    
+    InformStreamStateChange( KMccStreamPrepared, aEndpointId );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::PlayL
+// Starts audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::PlayL( const TUint32 aEndpointId,
+							 TBool /*aStreamPaused*/, 
+                             TBool aEnableRtcp )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::PlayL" )
+        
+    TBool controlNetworkResources = SetStateL( EStateStreaming, aEndpointId );
+    
+    if ( controlNetworkResources )
+        {
+        iRtpmanager->StartSessionL();
+        }
+    
+    User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) ); 
+    
+    UpdateCodecLoadingPermission( IsCodecOperationAllowed() );
+    
+    LoadCodecL( iCodecInfo, KNullDesC8 );
+    
+    DoPlayL();
+    
+    HandleStandby( aEndpointId, EFalse );
+
+    InformStreamStateChange( KMccStreamStarted, aEndpointId );
+    
+    __SUBCONTROLLER( "CMccSymDlStream::PlayL, exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::PauseL
+// Pauses audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::PauseL( const TUint32 aEndpointId, TBool aEnableRtcp )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::PauseL" )
+    
+    /*TBool standbyEndpointControl( StandbyStream() && 
+                                  aEndpointId == MCC_ENDPOINT_ID( iDatasink ) );*/
+    
+    SetStateL( EStatePaused, aEndpointId );
+    User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) );
+    
+    DoPauseL();
+    
+    HandleStandby( aEndpointId, ETrue );
+    
+    InformStreamStateChange( KMccStreamPaused, aEndpointId ); 
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::ResumeL
+// Resumes paused audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::ResumeL( const TUint32 aEndpointId, TBool aEnableRtcp )
+    { 
+    __SUBCONTROLLER( "CMccSymDlStream::ResumeL" )
+    
+    // In first resume of the standby stream sink is treated as in normal
+    // startup phase
+    TBool standbyEndpointControl( StandbyStream() && 
+                                  aEndpointId == MCC_ENDPOINT_ID( iDatasink ) );
+    
+    if ( standbyEndpointControl && !iFirstResumeDone )
+        {
+        __SUBCONTROLLER( "CMccSymDlStream::ResumeL, standby, first resume" )
+        
+        SetStateL( EStateStreaming, aEndpointId );
+        
+        UpdateCodecLoadingPermission( IsCodecOperationAllowed() );
+    
+        LoadCodecL( iCodecInfo, KNullDesC8 );
+        
+        DoPlayL();
+        
+        iFirstResumeDone = IsControllingMmfEndpoint();
+        }
+    else
+        {
+        /*TBool controlNetworkResources = */
+        SetStateL( EStateStreaming, aEndpointId );
+
+        User::LeaveIfError( iRtpmanager->SetRTCPSendReceive( aEnableRtcp ) );
+
+        DoResumeL();
+        }
+        
+    HandleStandby( aEndpointId, EFalse );
+       
+    InformStreamStateChange( KMccStreamResumed, aEndpointId );
+    
+    __SUBCONTROLLER( "CMccSymDlStream::ResumeL, exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::StopL
+// Stops the audio streaming
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::StopL( const TUint32 aEndpointId )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::StopL" )
+    
+    SetStateL( EStateStopped, aEndpointId );    
+    
+    DoStopL();
+    
+    InformStreamStateChange( KMccStreamStopped, aEndpointId );
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::SetBalanceL
+// Sets the current play balance
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::SetBalanceL( TInt aLeftBal, TInt aRightBal )
+    {
+    if( !iSoundDevice )
+        {
+        User::Leave( KErrNotReady );
+        }
+    else
+        {
+        iSoundDevice->SetPlayBalanceL( aLeftBal, aRightBal );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::GetBalanceL
+// Returns the current play balance
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::GetBalanceL( TInt& aLeftbal, TInt& aRightbal )
+    {
+    if( !iSoundDevice )
+        {
+        User::Leave( KErrNotReady );
+        }
+    else
+        {
+        iSoundDevice->GetPlayBalanceL( aLeftbal, aRightbal );
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::GetSSRCL
+// Returns SSRC value
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::GetSSRCL( TUint32& /*aSSRCValue*/ )
+    {
+    User::Leave ( KErrNotSupported );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::ResetCountersL
+// Resets Jitterbuffer
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::ResetCountersL( )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::SendMediaSignalL
+// Downlink can send RTCP media signals (only receiver reports)
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::SendMediaSignalL( const TMccEvent& aEvent )
+    {
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrNotReady ) );
+    
+    CMccRtpDataSource* p = static_cast<CMccRtpDataSource*>( iDatasource );
+    p->SendMediaSignallingL( aEvent );
+    }
+        
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::SendRTCPReceiverReportL
+// Sends a RTCP receiver report
+// -----------------------------------------------------------------------------
+//  
+void CMccSymDlStream::SendRTCPReceiverReportL()
+    {
+    User::LeaveIfNull( iDatasource );
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    User::LeaveIfError( dSource->SendRTCPReceiverReport() );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::StartInactivityTimerL
+// Starts inactivity timer for a stream
+// -----------------------------------------------------------------------------
+// 
+void CMccSymDlStream::StartInactivityTimerL( TUint32 aTimeoutTime )
+    {
+    User::LeaveIfNull( iDatasource );
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StartInactivityTimerL( aTimeoutTime );
+    }
+
+      
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::StopInactivityTimerL
+// Stops inactivity timer for a stream 
+// -----------------------------------------------------------------------------
+// 
+void CMccSymDlStream::StopInactivityTimerL()
+    {
+    User::LeaveIfNull( iDatasource );
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StopInactivityTimerL( );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::IsUplink
+// -----------------------------------------------------------------------------
+// 
+TBool CMccSymDlStream::IsUplink()
+    {
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::StandByL
+// -----------------------------------------------------------------------------
+// 
+void CMccSymDlStream::StandByL()
+    {
+    User::LeaveIfNull( iDatasource );
+    CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+    dSource->StandBy( EForceStandby, iCodecInfo.iPayloadType );
+    iJitterBuffer->ResetBuffer( EFalse );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::SetAudioRouteL
+// -----------------------------------------------------------------------------
+//    
+void CMccSymDlStream::SetAudioRouteL( TUint32 aRoutingDestination )
+    {
+    __ASSERT_ALWAYS( iAudioRouter, User::Leave( KErrNotReady ) );
+    iAudioRouter->SetAudioRouteL( aRoutingDestination );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::GetAudioRouteL
+// -----------------------------------------------------------------------------
+//     
+void CMccSymDlStream::GetAudioRouteL( TUint32& aRoutingDestination )
+    {
+    __ASSERT_ALWAYS( iAudioRouter, User::Leave( KErrNotReady ) );
+    iAudioRouter->GetAudioRouteL( aRoutingDestination );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::JitterBufferError
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::JitterBufferError( TInt aError )
+    {
+    __SUBCONTROLLER_INT1("CMccSymDlStream::JitterBufferError, err=", aError)
+    if ( aError == MJitterBufferObserver::EBufferOverflow && iDatasource )
+        {
+        CMccRtpDataSource* dSource = static_cast<CMccRtpDataSource*>( iDatasource );
+        dSource->StandBy( EForceStandby, iCodecInfo.iPayloadType ); 
+        }
+       
+    __SUBCONTROLLER( "CMccSymDlStream::JitterBufferError, exit" )
+
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::MultiplexerSink
+// -----------------------------------------------------------------------------
+//
+MDataSink* CMccSymDlStream::MultiplexerSink()
+    {
+    if ( EGenRedUsed == iCodecInfo.iAlgoUsed )
+        {
+        return iRedFormatDecode;
+        }
+    else
+        {
+        return iFormatDecode;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::DynamicBufferChangeRequest
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::DynamicBufferChangeRequest( TInt aBufferSize )
+    {
+    const TInt KMccBitsPerByte = 8;
+    const TInt hwFrameTime( aBufferSize / KMccBitsPerByte );
+    
+    __SUBCONTROLLER_INT1("CMccSymDlStream::DynamicBufferChangeRequest, aBufferSize = ", aBufferSize ) 
+    __SUBCONTROLLER_INT1("CMccSymDlStream::DynamicBufferChangeRequest, hwFrameTime = ", hwFrameTime )
+    __SUBCONTROLLER_INT1("CMccSymDlStream::DynamicBufferChangeRequest, iHwFrameTime = ", iCodecInfo.iHwFrameTime )
+    
+    if ( hwFrameTime != iCodecInfo.iHwFrameTime
+        && iCodecInfo.iFourCC == KMccFourCCIdG711 )
+        {
+        TRAPD( err, DoDynamicFrameSizeChangeL( hwFrameTime ) );
+        if ( KErrNone == err )
+            {
+            iCodecInfo.iHwFrameTime = hwFrameTime;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::DynamicBufferChangeRequest
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::DoDynamicFrameSizeChangeL( TInt aFrameTime )
+    {
+    __SUBCONTROLLER( "CMccSymDlStream::DoDynamicFrameSizeChangeL" )
+    
+    __ASSERT_ALWAYS( iFormatDecode && iJitterBuffer,
+                    User::Leave( KErrNotReady ) );
+    
+    TMccCodecInfo codecInfo( iCodecInfo );
+    codecInfo.iHwFrameTime = aFrameTime;
+    codecInfo.iIsUpdate = ETrue;
+    const TMccCodecInfoBuffer buffer( codecInfo );
+    
+    CPayloadFormatRead* g711Format(
+        static_cast<CPayloadFormatRead*>( iFormatDecode ) );
+        
+    g711Format->ConfigurePayloadFormatL( buffer );
+        
+    const TInt jbufLen( codecInfo.iMaxPtime );
+    iJitterBuffer->SetupL( jbufLen, 
+                           codecInfo.iJitterBufThreshold,
+                           codecInfo );
+    }
+
+// -----------------------------------------------------------------------------
+// CMccSymDlStream::BindContextIntoStreamL
+// -----------------------------------------------------------------------------
+//
+void CMccSymDlStream::BindContextIntoStreamL( TUint32 aEndpointId,
+                                      const TMccCryptoContext& aContextParams )
+    {
+    __ASSERT_ALWAYS( iDatasource, User::Leave( KErrNotReady ) );   
+    
+    if ( iDatasource->DataSourceType() == KMccRtpSourceUid &&
+         aEndpointId == MCC_ENDPOINT_ID( iDatasource )  )
+	    {
+        CMccRtpDataSource* dataSource =
+            static_cast<CMccRtpDataSource*>( iDatasource );
+            
+        dataSource->ApplyCryptoContextL( aContextParams );
+	    }
+	else
+	    {
+	    User::Leave( KErrNotFound );
+	    }        
+    }
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File