multimediacommscontroller/mmccg711payloadformat/src/g711payloadformatread.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccg711payloadformat/src/g711payloadformatread.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,900 @@
+/*
+* Copyright (c) 2004-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:    PayloadFormat component capable to read RTP payload containing
+*                G711 audio.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include    "g711payloadformatread.h"
+#include    "g711payloadformatdefs.h"
+#include    "mccrtpdatasource.h"
+#include    "mccinternaldef.h"
+#include    "mccdef.h"
+#include    "mccredpayloadread.h"
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::CG711PayloadFormatRead
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CG711PayloadFormatRead::CG711PayloadFormatRead()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::ConstructL( MDataSource* aSource )
+    {
+    __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
+    
+    iClip = aSource;
+    iBufferToReadExists = EFalse;
+
+    iFourCC.Set( KMccFourCCIdG711 );
+
+    iFramesPerPacket = 1;
+
+    // Initialize decoding state machine
+    iStateMachine = CFormatDecodeStateMachine::NewL( this );
+
+    iStateMachine->ChangeState( EDecodeIdle );
+
+    iCurrentBuffer = EBufferOne;
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CG711PayloadFormatRead* CG711PayloadFormatRead::NewL( MDataSource* aSource )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::NewL()" );
+
+    __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
+
+    CG711PayloadFormatRead* self = new (ELeave) CG711PayloadFormatRead;
+    CleanupStack::PushL( self );
+    self->ConstructL( aSource );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// Destructor
+CG711PayloadFormatRead::~CG711PayloadFormatRead()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::~CG711PayloadFormatRead()" );
+    
+    delete iFrameBufferOne;
+    delete iFrameBufferTwo;
+    if ( iSourceBufOwnership )
+        {
+        delete iSourceBuffer;
+        }
+    
+    delete iStateMachine;
+    
+    iClip = NULL;
+    iFrameArray.Close();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SendDataToSinkL
+// Send full frame buffer to the DataPath.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::SendDataToSinkL()
+    {
+    if ( iCurrentBuffer == EBufferOne )
+        {
+        DP_G711_READ( "CG711PayloadFormatRead::SendDataToSinkL() - BufferOne" );
+
+        iDataPath->BufferFilledL( iFrameBufferOne );
+        iCurrentBuffer = EBufferTwo;
+        if ( iBufferToReadExists && !iFrameBufferOne->LastBuffer() )
+            {
+            // More payload buffer is ready
+            iStateMachine->ChangeState( ESourceDataReady );
+            }
+        }
+    else
+        {
+        DP_G711_READ( "CG711PayloadFormatRead::SendDataToSinkL() - BufferTwo" );            
+
+        iDataPath->BufferFilledL( iFrameBufferTwo );
+        iCurrentBuffer = EBufferOne;
+        if ( iBufferToReadExists && !iFrameBufferTwo->LastBuffer() )
+            {
+            // More payload buffer is ready
+            iStateMachine->ChangeState( ESourceDataReady );
+            }
+       }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::FillSinkBuffer
+// Fill SinkBuffer.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::FillSinkBufferL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBuffer()" );
+    
+    CMMFDataBuffer* curFrameBuffer = NULL;
+    if ( EBufferOne == iCurrentBuffer )
+        {
+        curFrameBuffer = iFrameBufferOne;
+        }
+    else
+        {
+        curFrameBuffer = iFrameBufferTwo;
+        }
+        
+    TDes8& curFrameData( curFrameBuffer->Data() );
+    curFrameData.SetLength( KVoIPHeaderLength );
+
+    // Put next frame decoded from RTP payload to the framebuffer
+    iBufferToReadExists = GetNextFrame( curFrameData );
+
+    // G.711 Gwc expects 2 bytes for dtx-decision
+    if ( iCnFrame )
+        {
+	    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBufferL add dtx-header" );
+
+        curFrameData[0] = KVoIPCNFrame;
+        curFrameData[1] = 0;
+	    }
+    else
+        {
+	    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBufferL add voice-header" );
+
+        curFrameData[0] = KVoIPAudioFrame;
+        curFrameData[1] = 0;
+        }
+
+	curFrameBuffer->SetFrameNumber( iRecvHeader.iTimestamp + ( ( iFrameIndex - 1 )
+	                           * TUint( iCInfo.iHwFrameTime * KDefaultSampleRateInkHz ) ) );
+
+    DP_G711_READ2( "CG711PayloadFormatRead::FillSinkBuffer - FRAMENUM: %u",
+        curFrameBuffer->FrameNumber() );
+    
+    const TInt dataLen( ( iCInfo.iHwFrameTime * KBitsPerByte )
+                            + KVoIPHeaderLength );
+    curFrameData.SetLength( dataLen );          
+    curFrameBuffer->SetStatus( EFull );
+
+    DP_G711_READ2( "CG711PayloadFormatRead: Filled framebuffer with buf. size: %d",
+        curFrameBuffer->BufferSize() );
+
+    iStateMachine->ChangeState( EEmptyDataToSink );
+
+    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBuffer - DONE" );
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::FillSourceBufferL
+// Send fill buffer request to the RTP Data Source.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::FillSourceBufferL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::FillSourceBufferL()");
+    
+    const TMediaId mediaId( KUidMediaTypeAudio );
+    iClip->FillBufferL( iSourceBuffer, this, mediaId );     
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourcePrimeL
+// Prime source.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::SourcePrimeL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::SourcePrimeL()" );
+    
+    iClip->SourcePrimeL();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourcePlayL
+// Start playing.
+// -----------------------------------------------------------------------------
+void CG711PayloadFormatRead::SourcePlayL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::SourcePlayL()" );
+    
+    iClip->SourcePlayL();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourcePauseL
+// Pause source.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::SourcePauseL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::SourcePauseL" );
+    
+    iStateMachine->Cancel();
+    iStateMachine->ChangeState( EDecodeIdle );
+    
+    iFrameBufferOne->SetLastBuffer( EFalse );
+    iFrameBufferTwo->SetLastBuffer( EFalse );
+
+    iFrameBufferOne->SetStatus( EAvailable );
+    iFrameBufferTwo->SetStatus( EAvailable );
+
+    iBufferToReadExists = EFalse;
+    iCurrentBuffer = EBufferOne;
+    
+    iClip->SourcePauseL();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourceStopL
+// Stop source
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::SourceStopL()
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::SourceStopL" );
+    
+    // DO NOT RESET PACKET COUNT BACK TO ZERO HERE
+    // UPPER LAYER MAY CALL LastDlPacketCount LATER
+
+    iStateMachine->Cancel();
+
+    iStateMachine->ChangeState( EDecodeIdle );
+    iFrameBufferOne->SetLastBuffer( EFalse );
+    iFrameBufferTwo->SetLastBuffer( EFalse );
+
+    iFrameBufferOne->SetStatus( EAvailable );
+    iFrameBufferTwo->SetStatus( EAvailable );
+
+    iBufferToReadExists = EFalse;
+    iCurrentBuffer = EBufferOne;
+
+    iClip->SourceStopL();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::BufferFilledL
+// 
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::DataBufferFilledL( CMMFBuffer* aBuffer,
+    const TRtpRecvHeader& aRecvHeader )
+    {
+    DP_G711_READ2( "CG711PayloadFormatRead::DataBufferFilledL iTimestamp: %u",
+        aRecvHeader.iTimestamp )
+    DP_G711_READ2( "CG711PayloadFormatRead::DataBufferFilledL this: 0x%x", this )
+    
+    __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( KUidMmfDataBuffer == aBuffer->Type(), 
+        User::Leave( KErrNotSupported ) );
+    __ASSERT_ALWAYS( iSourceBuffer == aBuffer, User::Leave( KErrArgument ) );
+    
+	iRecvHeader = aRecvHeader;
+    if ( KComfortNoisePT == iRecvHeader.iPayloadType
+        || KOldComfortNoisePT == iRecvHeader.iPayloadType )
+        {
+        iCnFrame = ETrue;
+        }
+    else 
+        {
+        iCnFrame = EFalse;
+        }
+    
+    TInt numOfFrames = DecodePayload( iSourceBuffer->Data() );
+    
+    // Whenever BufferFilledL is called from RtpSourceSink
+    // Set the state machine to fillsinkbuffer
+    if ( numOfFrames )
+        {
+        iBufferToReadExists = ETrue;
+        iSourceBuffer->SetFrameNumber( iRecvHeader.iTimestamp );
+        iStateMachine->ChangeState( ESourceDataReady );
+        }
+    else
+        {
+        DP_G711_READ( "CG711PayloadFormatRead::BufferFilledL, decode failed" )
+        
+        FillSourceBufferL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SampleRate
+// Returns samplerate.
+// -----------------------------------------------------------------------------
+//
+TUint CG711PayloadFormatRead::SampleRate()
+    {
+    return KDefaultSampleRate;
+    }  
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SetSampleRate
+// Set samplerate.
+// -----------------------------------------------------------------------------
+//
+TInt CG711PayloadFormatRead::SetSampleRate( TUint aSampleRate )
+    {
+    if ( KDefaultSampleRate != aSampleRate )
+        {
+        return KErrNotSupported;
+        }
+    else
+        {
+        return KErrNone;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::NumChannels
+// Returns number of channels.
+// -----------------------------------------------------------------------------
+//
+TUint CG711PayloadFormatRead::NumChannels()
+    {
+    return KMono;
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourceThreadLogoff
+// Logout the source thread.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::SourceThreadLogoff()
+    {
+    iClip->SourceThreadLogoff();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::NegotiateSourceL
+// Negotiate Source.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::NegotiateSourceL( MDataSink& aDataSink )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::NegotiateSourceL()" ) ;
+    
+    iDataPath = &aDataSink;
+    iClip->NegotiateSourceL( *this );
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourceThreadLogon
+// Logon to the source thread.
+// -----------------------------------------------------------------------------
+//
+TInt CG711PayloadFormatRead::SourceThreadLogon( MAsyncEventHandler& aEventHandler )
+    {
+    if ( iClip )
+        {
+        iClip->SourceThreadLogon( aEventHandler );
+        return KErrNone;
+        }
+    else
+        {
+        return KErrNotReady;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SetSourceDataTypeCode
+// Sets source datatype fourCC code
+// -----------------------------------------------------------------------------
+//
+TInt CG711PayloadFormatRead::SetSourceDataTypeCode( TFourCC aSourceFourCC,
+                                                    TMediaId aMediaId )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::SetSourceDataTypeCode()" );
+    
+    if ( KUidMediaTypeAudio != aMediaId.iMediaType ) 
+        {
+        return KErrNotSupported;
+        }
+
+    iFourCC = aSourceFourCC;
+
+    iClip->SetSourceDataTypeCode( iFourCC, aMediaId );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SourceDataTypeCode
+// Returns the current datatype FourCC code.
+// -----------------------------------------------------------------------------
+//
+TFourCC CG711PayloadFormatRead::SourceDataTypeCode( TMediaId aMediaId )
+    {
+    if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+        {
+        return iFourCC;
+        }
+    else
+        {
+        return TFourCC(); //defaults to 'NULL' fourCC
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::SinkDataTypeCode
+// Returns the current datatype FourCC code.
+// -----------------------------------------------------------------------------
+//
+TFourCC CG711PayloadFormatRead::SinkDataTypeCode( TMediaId aMediaId )
+    {
+    if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+        {
+        return iFourCC;
+        }
+    else
+        {
+        return TFourCC(); //defaults to 'NULL' fourCC
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::CreateSourceBufferL
+// Create a source buffer for the given media and indicate in aReference if 
+// buffer is created.
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CG711PayloadFormatRead::CreateSourceBufferL( TMediaId aMediaId,
+                                                         TBool &aReference )
+    {
+    if ( KUidMediaTypeAudio != aMediaId.iMediaType )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    // The source buffers belong to G711PayloadFormatRead not to datapath
+    // aference should be set to ETrue and destroyed by G711PayloadFormatRead itself.
+    aReference = ETrue;
+    
+    return iFrameBufferOne; 
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::CreateSourceBufferL
+// Create a source buffer for the given media, setting frame size to match
+// the given sink buffer.
+// -----------------------------------------------------------------------------
+CMMFBuffer* CG711PayloadFormatRead::CreateSourceBufferL( TMediaId aMediaId,
+                                                        CMMFBuffer& /*aSinkBuffer*/,
+                                                        TBool& aReference )
+    {
+    if ( KUidMediaTypeAudio != aMediaId.iMediaType )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    return CreateSourceBufferL( aMediaId, aReference );
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::FillBufferL
+// Fill Buffer.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::FillBufferL( CMMFBuffer* aBuffer, 
+                                          MDataSink* aConsumer, 
+                                          TMediaId aMediaId )
+    {
+    if ( NULL == aBuffer ) 
+        {
+        User::Leave( KErrGeneral );
+        }
+        
+    DP_G711_READ3( 
+    "CG711PayloadFormatRead::FillBufferL() buffer 0x%x passed in with length %d bytes",
+    aBuffer, aBuffer->BufferSize() );
+         
+    if ( KUidMediaTypeAudio != aMediaId.iMediaType )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    if ( KUidMmfDataBuffer != aBuffer->Type() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    iDataPath = aConsumer;
+
+    // aBuffer is a reference to those frame buffers that G711PayloadFormatRead owns
+    aBuffer->SetLastBuffer( EFalse );
+
+    if ( EBufferOne == iCurrentBuffer )
+        {
+        iFrameBufferTwo->SetStatus( EAvailable );
+        }
+    else
+        {
+        iFrameBufferOne->SetStatus( EAvailable );
+        }
+
+    if ( iBufferToReadExists )
+        {
+        // All decoded frame are not passed to the datapath
+        iStateMachine->ChangeState( ESourceDataReady );
+        }
+    else
+        {
+        FillSourceBufferL(); // No payload ask for it
+        } 
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::Streams
+// Return number of audio streams for the given media.
+// -----------------------------------------------------------------------------
+//
+TUint CG711PayloadFormatRead::Streams( TUid aMediaType ) const
+    {
+    // Need to check aMediaType for audio
+    if ( KUidMediaTypeAudio == aMediaType )
+        {
+        return 1;
+        }
+    else
+        {
+        return 0;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::FrameTimeInterval
+// Return the frame time interval for the given media
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds 
+    CG711PayloadFormatRead::FrameTimeInterval( TMediaId aMediaId ) const
+    {
+    if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+        {
+        return iFrameTimeInterval;
+        }
+    else
+        {
+        return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::Duration
+// Return the frame time interval for the given media.
+// NOT SUPPORTED
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds 
+    CG711PayloadFormatRead::Duration( TMediaId /*aMediaType*/ ) const
+    {
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::DecodePayload
+// Decodes all audio frames from the received RTP payload buffer. Decoded
+// audio frames are saved to the internal array so that audio frames can be
+// requested one at a time with GetNextFrame() -method.
+// No assumption about frame count in RTP packet is done.
+// -----------------------------------------------------------------------------
+//
+TInt CG711PayloadFormatRead::DecodePayload( TDes8& aSourceBuffer )
+    {
+    DP_G711_READ2( "CG711PayloadFormatRead::DecodePayload SourceBufSize: %d",
+        aSourceBuffer.Size() );
+    DP_G711_READ2( "CG711PayloadFormatRead::DecodePayload SourceBufLength: %d",
+        aSourceBuffer.Length() );
+    
+    iFrameIndex = 0;
+    
+    const TUint8* framePtr = aSourceBuffer.Ptr();
+    const TUint8* endPtr = aSourceBuffer.Ptr() + aSourceBuffer.Size();
+    
+    TInt frames = aSourceBuffer.Size() / TInt( iCInfo.iFrameSize );
+    
+    DP_G711_READ2( "CG711PayloadFormatRead::DecodePayload FrameSize: %d",
+        iCInfo.iFrameSize );
+    DP_G711_READ2( "CG711PayloadFormatRead::DecodePayload Frames: %d",
+        frames );
+    
+    // Construct pointers to frames in payload if not in CN mode
+    if ( !iCnFrame )
+        {
+        while ( frames-- )
+            {
+            const TPtr8 bufPtr( const_cast<TUint8*>( framePtr ),
+                iCInfo.iFrameSize, iCInfo.iFrameSize );
+            iFrameArray.Append( bufPtr );
+            
+            framePtr += iCInfo.iFrameSize;
+            if ( framePtr >= endPtr )
+                {
+                frames = 0;
+                }
+            }
+        }
+    else if ( aSourceBuffer.Size() && iCnFrame )
+        {
+        // If it is a CN frame, then we must do special handling. This is
+        // because e.g Cisco kit sends 1 byte CN frames, thus we need to
+        // expand the source buffer with zeroes.
+        TInt targetLen = iCInfo.iFrameSize;
+        targetLen = targetLen - aSourceBuffer.Size();
+        
+        DP_G711_READ2( "CG711PayloadFormatRead::DecodePayload CN frame size adjust: %d",
+            targetLen );
+        
+        const TChar zero( '0' );
+        aSourceBuffer.AppendFill( zero, targetLen );
+        
+        const TPtr8 bufPtr( const_cast<TUint8*>( framePtr ),
+            iCInfo.iFrameSize, iCInfo.iFrameSize );
+        
+        iFrameArray.Append( bufPtr );
+        }
+    
+    
+    return iFrameArray.Count();
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::GetNextFrameL
+// Passes next audio frame decoded with DecodePayload(). Return ETrue if decoded
+// frames are remaining.
+// -----------------------------------------------------------------------------
+//
+TBool CG711PayloadFormatRead::GetNextFrame( TDes8& aToBuffer )
+    {
+    iFrameIndex++;
+    
+    DP_G711_READ3( "CG711PayloadFormatRead::GetNextFrame - FrameCount: %d, FrameIndex: %d",
+        iFrameArray.Count(), iFrameIndex );
+    
+    const TInt frameCount( iFrameArray.Count() );
+    
+    if ( iFrameIndex == frameCount )
+        {
+        aToBuffer.Append( iFrameArray[iFrameIndex - 1] );
+        iFrameArray.Reset();
+        return EFalse;
+        }
+    else if ( iFrameIndex < frameCount )
+        {
+        aToBuffer.Append( iFrameArray[iFrameIndex - 1] );
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }        
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::ConfigurePayloadFormatL
+// Configure payload decoding parameters.
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::ConfigurePayloadFormatL( const TDesC8& aConfigParams )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::ConfigurePayloadFormatL" );
+    
+    __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
+        User::Leave( KErrArgument ) );
+    
+    TMccCodecInfoBuffer infoBuffer;
+    infoBuffer.Copy( aConfigParams );
+    
+    if ( !infoBuffer() .iIsUpdate )
+        {
+        iCInfo = infoBuffer();
+        // Calculates frames/packet, frame size and frame time interval
+        iFramesPerPacket = TInt8( iCInfo.iMaxPtime / iCInfo.iHwFrameTime );
+        iCInfo.iFrameSize =
+            static_cast<TUint>( KDefaultSampleRateInkHz * iCInfo.iHwFrameTime );
+        iFrameTimeInterval = TInt64( iCInfo.iHwFrameTime );
+    	
+        // Create two frame buffers used in data transfer with datapath.
+        // Space for two byte additional header needed by HW codec is reserved.
+        iFrameBufferOne =
+            CMMFDataBuffer::NewL( iCInfo.iFrameSize + KVoIPHeaderLength );
+        iFrameBufferTwo =
+            CMMFDataBuffer::NewL( iCInfo.iFrameSize + KVoIPHeaderLength );
+        
+        // PayloadBuffer contains data received from network
+        TInt plSize = iCInfo.iFrameSize * iFramesPerPacket;
+        DP_G711_READ3( "CG711PayloadFormatRead::ConfigurePayloadFormatL \
+FramesPerPacket: %d, FrameSize: %d" , iFramesPerPacket, iCInfo.iFrameSize );
+        
+        if ( EGenRedUsed == iCInfo.iAlgoUsed )
+            {
+            DP_G711_READ2( "CG711PayloadFormatRead::ConfigurePayloadFormatL, RED LEVEL: %d",
+                iCInfo.iRedundancyCount );
+            
+            if ( iCInfo.iRedundancyCount )
+                {
+                plSize *= iCInfo.iRedundancyCount;
+                }
+            
+            CPayloadFormatRead* redDecoder 
+                = static_cast<CPayloadFormatRead*>( iClip );
+            
+            TMccRedPayloadReadConfig config;
+            config.iRedBlockCount = iCInfo.iRedundancyCount;
+            config.iMaxPayloadSize = iCInfo.iFrameSize * iFramesPerPacket;
+            config.iNumOfEncodings = 1;
+            config.iRedPayloadType = iCInfo.iRedundantPayload;
+            config.InitPayloadTypes();
+            config.iEncPayloadTypes[0] = iCInfo.iPayloadType;
+            TMccRedPayloadReadPckg pckg( config );
+            redDecoder->ConfigurePayloadFormatL( pckg );
+            }
+        
+        iSourceBuffer = CreateClipBufferL( plSize, iSourceBufOwnership );
+        }
+    else
+        {
+        DP_G711_READ( "CG711PayloadFormatRead::ConfigurePayloadFormatL - Update Configuration" );
+        
+        UpdateConfigurationL( infoBuffer() ); 
+        }
+    
+    DP_G711_READ( "CG711PayloadFormatRead::ConfigurePayloadFormatL OUT" );
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::UpdateConfigurationL
+// Update payload decoder parameters
+// -----------------------------------------------------------------------------
+//
+void CG711PayloadFormatRead::UpdateConfigurationL( TMccCodecInfo& aCodecInfo )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::UpdateConfigurationL" );
+    
+    DP_G711_READ2( "CG711PayloadFormatRead::UpdateConfigurationL maxptime: %d", 
+                   aCodecInfo.iMaxPtime )
+    DP_G711_READ2( "CG711PayloadFormatRead::UpdateConfigurationL hwframe: %d", 
+                   aCodecInfo.iHwFrameTime )
+    
+    if ( iCInfo.iMaxPtime != aCodecInfo.iMaxPtime ||
+        iCInfo.iHwFrameTime != aCodecInfo.iHwFrameTime )
+        {
+        DP_G711_READ( "CG711PayloadFormatRead::UpdateConfigurationL IS UPDATE" )
+        
+        iCInfo.iHwFrameTime = aCodecInfo.iHwFrameTime;
+        iCInfo.iMaxPtime = aCodecInfo.iMaxPtime;
+        
+        iFrameTimeInterval = TInt64( iCInfo.iHwFrameTime );
+        
+        if ( iSourceBufOwnership )
+            {
+            delete iSourceBuffer;
+            }
+
+        iSourceBuffer = NULL;
+        
+        // Update sink buffers only if they are not big enough, extra space
+        // does not matter really
+        TUint updatedFrameSize = 
+            static_cast<TUint>( KDefaultSampleRateInkHz * iCInfo.iHwFrameTime );
+        if ( updatedFrameSize > iCInfo.iFrameSize )
+            {
+            DP_G711_READ( "CG711PayloadFormatRead::UpdateConfigurationL, \
+creating new sink buffers" );
+            
+            CMMFDataBuffer* bufferOne = 
+                CMMFDataBuffer::NewL( updatedFrameSize + KVoIPHeaderLength ); 
+            CleanupStack::PushL( bufferOne ); 
+            CMMFDataBuffer* bufferTwo =
+                CMMFDataBuffer::NewL( updatedFrameSize + KVoIPHeaderLength );
+            CleanupStack::PushL( bufferTwo ); 
+            delete iFrameBufferOne;
+            iFrameBufferOne = bufferOne;
+            delete iFrameBufferTwo;
+            iFrameBufferTwo = bufferTwo;
+            CleanupStack::Pop( bufferTwo );
+            CleanupStack::Pop( bufferOne );
+            }
+            
+        iCInfo.iFrameSize = updatedFrameSize;
+        
+        // PayloadBuffer contains data received from network
+        const TUint pktCount = aCodecInfo.iMaxPtime / iCInfo.iHwFrameTime;
+        TInt plSize = iCInfo.iFrameSize * pktCount;
+        if ( iCInfo.iRedundancyCount )
+            {
+            plSize *= iCInfo.iRedundancyCount;
+            }
+        
+        DP_G711_READ3( "CG711PayloadFormatRead::UpdateConfigurationL \
+pktCount: %d, iFrameSize: %d", pktCount, iCInfo.iFrameSize )
+        
+        iSourceBuffer = CreateClipBufferL( plSize, iSourceBufOwnership );
+        iFrameArray.Reset();
+        iFrameIndex = 0;
+        iBufferToReadExists = EFalse;
+        FillSourceBufferL();
+        }
+    
+    DP_G711_READ( "CG711PayloadFormatRead::UpdateConfigurationL, exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CG711PayloadFormatRead::CreateClipBufferL
+// Creates buffer needed in data transfer with format readers clip.
+// -----------------------------------------------------------------------------
+//
+CMMFDataBuffer* CG711PayloadFormatRead::CreateClipBufferL( 
+        TUint aSize, TBool& aIsOwnBuffer )
+    {
+    DP_G711_READ( "CG711PayloadFormatRead::CreateClipBufferL" );
+    CMMFDataBuffer* buffer( NULL );
+    
+    if ( iClip->CanCreateSourceBuffer() )
+        {
+        static_cast<CMMFFormatDecode*>( iClip )->SuggestSourceBufferSize( aSize );
+        
+        TBool reference( EFalse );
+        CMMFBuffer* sourceBuf 
+            = iClip->CreateSourceBufferL( KUidMediaTypeAudio, reference );
+        TBool isSupportedBuf 
+            = CMMFBuffer::IsSupportedDataBuffer( sourceBuf->Type() );
+        TBool isOwnBuffer = reference ? EFalse : ETrue;
+        
+        if ( !isSupportedBuf )
+            {
+            if ( isOwnBuffer )
+                {
+                delete sourceBuf;
+                }
+            
+            User::Leave( KErrNotSupported );
+            }
+        
+        aIsOwnBuffer = isOwnBuffer;
+        buffer = static_cast<CMMFDataBuffer*>( sourceBuf );
+        }
+    else
+        {
+        aIsOwnBuffer = ETrue;
+        buffer = CMMFDataBuffer::NewL( aSize );
+        }
+    
+    return buffer;
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File