--- /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