multimediacommscontroller/mmccdtmfpayloadformat/src/dtmfpayloadformatread.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccdtmfpayloadformat/src/dtmfpayloadformatread.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,846 @@
+/*
+* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    Contains functionality for DTMF and line event 
+*                decoding and playing.
+*
+*/
+
+
+
+
+// INCLUDES
+#include "dtmfpayloadformatread.h"
+#include "dtmfpayloaddecoder.h"
+#include "dtmfeventpayloadinfo.h"
+#include "dtmftonepayloadinfo.h"
+#include "mccuids.hrh"
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::CDTMFPayloadFormatRead
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ---------------------------------------------------------------------------
+//
+CDTMFPayloadFormatRead::CDTMFPayloadFormatRead()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CDTMFPayloadFormatRead") );
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::ConstructL
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::ConstructL( MDataSource* aSource )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::ConstructL") );
+    
+    iClip = aSource;
+    iBufferToReadExists = EFalse;
+
+    // Initialize decoding state machine
+    iStateMachine = CFormatDecodeStateMachine::NewL( this );
+    iStateMachine->ChangeState( EDecodeIdle );
+
+    iPayloadDecoder = CDTMFPayloadDecoder::NewL();
+
+    iTonePlayer = CMdaAudioToneUtility::NewL( *this );
+    TInt maxVol = iTonePlayer->MaxVolume();
+    // Use intermediate volume value
+    iTonePlayer->SetVolume( ( maxVol / 2 ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CDTMFPayloadFormatRead* CDTMFPayloadFormatRead::NewL( MDataSource* aSource )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::NewL") );
+    
+    __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
+
+    CDTMFPayloadFormatRead* self = new( ELeave ) CDTMFPayloadFormatRead;
+
+    CleanupStack::PushL( self );
+    self->ConstructL( aSource );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::~CDTMFPayloadFormatRead
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDTMFPayloadFormatRead::~CDTMFPayloadFormatRead()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::~CDTMFPayloadFormatRead") );
+
+    if ( iSourceBufOwnership )
+        {
+        delete iSourceBuffer;
+        }
+    
+    iSourceBuffer = NULL;
+        
+    delete iPayloadDecoder;
+
+    if ( iStateMachine )
+        {
+        iStateMachine->Cancel();
+        delete iStateMachine;
+        }
+
+    delete iTonePlayer;
+
+    // for PC_LINT #1740
+    iClip = NULL;
+
+    iEventPayloadInfo.Close();
+    iTonePayloadInfo.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::Streams
+// Not applicable for DTMF payload formatter. Pure virtual method
+// implementation needed anyway.
+// ---------------------------------------------------------------------------
+//
+TUint CDTMFPayloadFormatRead::Streams( TUid aMediaType ) const
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::Streams") );
+
+    if ( KUidMediaTypeAudio == aMediaType )
+        {
+        return 1;
+        }
+    else
+        {
+        return 0;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::FrameTimeInterval
+// Not applicable for DTMF payload formatter. Pure virtual method
+// implementation needed anyway.
+// ---------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CDTMFPayloadFormatRead::FrameTimeInterval( 
+    TMediaId /*aMediaType*/ ) const
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::FrameTimeInterval") );
+
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::Duration
+// Not applicable for DTMF payload formatter. Pure virtual method
+// implementation needed anyway.
+// ---------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CDTMFPayloadFormatRead::Duration( 
+    TMediaId /*aMediaType*/ ) const
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::Duration") );
+    
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::CanCreateSourceBuffer
+// SourceBuffer creation is not supported, because there is no need to
+// exchange DTMF data with datapath. DTMF payload formatter handles DTMF
+// playing independently through tone player.
+// ---------------------------------------------------------------------------
+//
+TBool CDTMFPayloadFormatRead::CanCreateSourceBuffer()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CanCreateSourceBuffer") );
+    
+    return EFalse;
+    }
+        
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::CreateSourceBufferL
+// Should not be used.
+// ---------------------------------------------------------------------------
+//
+CMMFBuffer* CDTMFPayloadFormatRead::CreateSourceBufferL( TMediaId /*aMediaId*/,
+    TBool& /*aReference*/ )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CreateSourceBufferL") );
+    
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourceDataTypeCode
+// Returns source data type code.
+// ---------------------------------------------------------------------------
+//
+TFourCC CDTMFPayloadFormatRead::SourceDataTypeCode( TMediaId aMediaId )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourceDataTypeCode() ") );
+    
+    if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+        {
+        return TFourCC( KMccFourCCIdDTMF );
+        }
+    else
+        {
+         // Defaults to 'NULL' fourCC
+        return TFourCC();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SinkDataTypeCode
+// Returns the current datatype FourCC code.
+// ---------------------------------------------------------------------------
+//
+TFourCC CDTMFPayloadFormatRead::SinkDataTypeCode( TMediaId aMediaId )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SinkDataTypeCode") );
+    
+    if ( KUidMediaTypeAudio == aMediaId.iMediaType )
+        {
+        return TFourCC( KMccFourCCIdDTMF );
+        }
+    else
+        {
+         // Defaults to 'NULL' fourCC
+        return TFourCC();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SetPayloadFormat
+// Sets payload format used in DTMF decoding.
+// ---------------------------------------------------------------------------
+//
+TInt CDTMFPayloadFormatRead::SetPayloadFormat( 
+    TDTMFPayloadFormat aPayloadFormat )
+    {
+    DP_DTMF_READ2( _L("CDTMFPayloadFormatWrite::SetPayloadFormat - Format: %d"),
+        aPayloadFormat );
+
+    TInt err = iPayloadDecoder->SetPayloadFormat( aPayloadFormat );
+    if ( KErrNone == err )
+        {
+        iPayloadFormat = aPayloadFormat;
+        }
+
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::FillBufferL
+// No need for data exchange with DataPath. DTMF receiving and processing
+// cycle is managed by SourcePrimeL(), SourcePlayL(), SourcePauseL(),
+// SourceStopL() methods.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::FillBufferL( CMMFBuffer* /*aBuffer*/, 
+                                          MDataSink* /*aConsumer*/, 
+                                          TMediaId /*aMediaId*/ )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::FillBufferL") );
+    
+    User::Leave( KErrNotSupported );
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::FillSourceBufferL
+// Called by state machine. Send fill buffer request to the RTP Data Source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::FillSourceBufferL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::FillSourceBufferL") );
+    
+    iClip->FillBufferL( iSourceBuffer, this, KUidMediaTypeAudio ); 
+    }
+    
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::FillSinkBuffer
+// Called by state machine. Decode payload to DTMF string and fill
+// sink buffer.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::FillSinkBufferL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::FillSinkBufferL") );
+
+    if ( iBufferToReadExists )
+        {
+        // Decode payload here and send data for continued handling in 
+        // SendDataToSinkL()
+        switch ( iPayloadFormat )
+            {
+            case EDTMFPayloadFormatEvent:
+            case EDTMFPayloadFormatRedEvents:
+                iPayloadDecoder
+                    ->DecodeEventPayload( iSourceBuffer, iEventPayloadInfo );
+                break;
+            case EDTMFPayloadFormatTone:
+                iPayloadDecoder
+                    ->DecodeTonePayload( iSourceBuffer, iTonePayloadInfo );
+                break;
+            default:
+                // Undefined Payload format
+                DP_DTMF_READ( _L("Unsupported payload format!") );
+                ASSERT( EFalse );
+                break;
+            }
+        
+        iStateMachine->ChangeState( EEmptyDataToSink );
+        }
+    else
+        {
+        DP_DTMF_READ( _L("No DTMF packets waiting at Data source.") );
+        
+        FillSourceBufferL();
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SendDataToSinkL
+// Called by state machine. Send decoded payload to sound device for playback.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SendDataToSinkL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SendDataToSinkL") );
+    
+    if ( iBufferToReadExists )
+        {
+        iBufferToReadExists = EFalse;
+        
+        if ( EDTMFPayloadFormatEvent == iPayloadFormat 
+             || EDTMFPayloadFormatRedEvents == iPayloadFormat )
+            {
+            HandleDTMFEventsL();
+            }
+        else if ( EDTMFPayloadFormatTone == iPayloadFormat )
+            {
+            HandleDTMFTones();
+            }
+        else
+            {
+            // undefined payload format
+            DP_DTMF_READ( _L("Unsupported payload format!") );
+            ASSERT( EFalse );
+            }
+        }
+    
+    FillSourceBufferL();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::HandleDTMFEvents
+// Handle and play DTMF events using tone player.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::HandleDTMFEventsL()
+    {
+    DP_DTMF_READ3( _L("CDTMFPayloadFormatRead::HandleDTMFEventsL, EVENTCOUNT: %d, tick = %u"),
+        iEventPayloadInfo.Count(), User::NTickCount() );
+    
+    const TUint eventCount( iEventPayloadInfo.Count() );
+    
+    if ( 1 == eventCount )
+        {
+        // Stop DTMF playing when end bit is set or new
+        // event has been received
+        if ( iEventPayloadInfo[0].EndBit() )
+            {
+            DP_DTMF_READ( _L("END BIT SET, CANCEL") );
+            iTonePlayer->CancelPlay();
+            }
+        else
+            {
+            TBool prepareToPlay( EFalse );
+
+            if ( iFirstPacket )
+                {
+                DP_DTMF_READ( _L("M BIT SET, CANCEL") );
+                iFirstPacket = EFalse;
+                prepareToPlay = ETrue;
+                }
+            else if ( iCurrentEvent != iEventPayloadInfo[0].Event()
+                || iTimeStampOfPrevEvent != iEventPayloadInfo[0].TimeStamp() )
+                {
+                DP_DTMF_READ( _L("NEW EVENT, CANCEL") );
+                prepareToPlay = ETrue;
+                }
+            else
+                {
+                // Make PC-LINT happy
+                }                
+            
+            iTimeStampOfPrevEvent = iEventPayloadInfo[0].TimeStamp();
+
+            if ( prepareToPlay )
+                {
+                DP_DTMF_READ( _L("PREPARING TO PLAY NEW DIGIT") );
+                iTonePlayer->CancelPlay();
+                iCurrentEvent = iEventPayloadInfo[0].Event();
+                
+                // Play DTMF until we have received final packet
+                TBuf<1> buf;
+                buf.Append( iEventPayloadInfo[0].Event() );
+                iTonePlayer->SetDTMFLengths( KDTMFMaxTonePlaybackTime,
+                                             KDTMFDefToneOffLengthInUs,
+                                             KDTMFDefPauseLengthInUs );
+                iTonePlayer->PrepareToPlayDTMFString( buf );
+                }
+            }            
+        }
+    else if ( 1 < eventCount )
+        {
+        // Play out contiguous (mutually exclusive) events
+        TBuf<KMaxDtmfRedCount> buf;
+        for ( TUint i = 0; i < KMaxDtmfRedCount; i++ )
+            {
+            buf.Append( iEventPayloadInfo[i].Event() );
+            }
+        
+        // Playing with default settings
+        iTonePlayer->PrepareToPlayDTMFString( buf );
+        }
+    else
+        {
+        // Some error, no events
+        }
+        
+    // Reset for a new RTP packet and to save memory
+    iEventPayloadInfo.Reset();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::HandleDTMFTones
+// NOT SUPPORTED. Handle and play DTMF tone payload.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::HandleDTMFTones()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::HandleDTMFTones") );
+    
+    const TUint toneCount( iTonePayloadInfo.Count() );
+
+    // Loop is needed for subscriber line event construction, which may have
+    // longer cycles than one tone play out. E.g. "special information tone".
+    // TBD: PlayDualToneL may stop previous tone playback
+    for ( TUint i = 0; i < toneCount; i++ )
+        {
+        iTonePlayer->SetVolume( iTonePayloadInfo[i].Volume() );
+        iTonePlayer->PrepareToPlayDualTone( 
+                                        iTonePayloadInfo[i].LowFrequency(),
+                                        iTonePayloadInfo[i].HighFrequency(),
+                                        iTonePayloadInfo[i].ToneOnPeriod() );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourceThreadLogon
+// Passes logon request to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+TInt CDTMFPayloadFormatRead::SourceThreadLogon(
+    MAsyncEventHandler& aEventHandler )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourceThreadLogon") );
+
+    if ( iClip )
+        {
+        iClip->SourceThreadLogon( aEventHandler );
+        return KErrNone;
+        }
+    else
+        {
+        return KErrNotReady;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourceThreadLogoff
+// Passes log out request to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SourceThreadLogoff( )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourceThreadLogoff") );
+    
+    iClip->SourceThreadLogoff( );
+    }
+        
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourcePrimeL
+// Passes prime transition to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SourcePrimeL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourcePrimeL") );
+    
+    iClip->SourcePrimeL();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourcePlayL
+// Passes play transition to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SourcePlayL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourcePlayL") );
+    
+    iClip->SourcePlayL();
+    FillSourceBufferL();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourcePauseL
+// Passes pause transition to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SourcePauseL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourcePauseL") );
+    
+    iClip->SourcePauseL();
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SourceStopL
+// Passes stop transition to the RTP data source.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SourceStopL()
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SourceStopL") );
+      
+    iClip->SourceStopL();
+    iStateMachine->Cancel( );
+    iStateMachine->ChangeState( EDecodeIdle );
+    iBufferToReadExists = EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::BufferFilledL
+// Called by DataSource after it has been filled the buffer.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::DataBufferFilledL( CMMFBuffer* aBuffer, 
+    const TRtpRecvHeader& aRtpHeader )
+    {
+    DP_DTMF_READ3( _L("CDTMFPayloadFormatRead::DataBufferFilledL, TSTAMP: %u, tick = %u"),
+        aRtpHeader.iTimestamp, User::NTickCount() );
+    
+    if ( iCInfo.iPayloadType != aRtpHeader.iPayloadType )
+        {
+        // We are not interested about this RTP packet. Ask another.
+        FillSourceBufferL();
+        return;
+        }
+    
+    // Do other checks, null ptr and buffer type.
+    __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+    if ( KUidMmfDataBuffer != aBuffer->Type() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    
+    if ( iStateMachine->IsActive() )
+        {
+        DP_DTMF_READ( _L("CDTMFPayloadFormatRead::BufferFilledL - REJECTED") );
+        // We are processing former events, do not mind incoming packets
+        // but ask for more.
+        FillSourceBufferL();
+        }
+    else
+        {
+        CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>( aBuffer );
+        if ( !dataBuffer->Data().Length() )
+            {
+            // Do not handle packet, ask for more
+            DP_DTMF_READ( _L("CDTMFPayloadFormatRead::BufferFilledL - NULL PAYLOAD") );
+            FillSourceBufferL();
+            }
+        else
+            {
+            // If we have already received the first packet from this event,
+            // then we should not decode and thus restart the playback because
+            // this will do unnecessary stop, prepare and play sequence to
+            // the tone player and causes distortions to DTMF playback.
+            // Normally events with marker bit set in RTP header are sent three
+            // times as specified in RFC2833 in order the implementation to be
+            // robust.
+            if ( !CompareFirstPacketRtpHeaders( aRtpHeader ) )
+                {
+                DP_DTMF_READ( _L("CDTMFPayloadFormatRead::BufferFilledL - NEW DATA") );
+                
+                iBufferToReadExists = ETrue;
+                iFirstPacket = aRtpHeader.iMarker;
+            
+                // Copy received buffer
+                iSourceBuffer->Data().Copy( dataBuffer->Data() );
+                iPayloadDecoder->SetCurTimeStamp( aRtpHeader.iTimestamp );
+
+                // Whenever BufferFilledL is called from RtpSourceSink
+                // set the state machine to fillsinkbuffer.
+                iStateMachine->ChangeState( ESourceDataReady );
+                }
+            else
+                {
+                DP_DTMF_READ( _L("CDTMFPayloadFormatRead::BufferFilledL - OLD DATA") );
+                
+                // Ask more data.
+                FillSourceBufferL();
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::SetSourcePrioritySettings
+//
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::SetSourcePrioritySettings( 
+                            const TMMFPrioritySettings& aPrioritySettings )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::SetSinkPrioritySettings") );
+
+    TMMFPrioritySettings settings = aPrioritySettings;
+    settings.iState = EMMFStateTonePlaying;
+    iTonePlayer->SetPriority( settings.iPriority, settings.iPref );
+    }
+    
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::MatoPrepareComplete
+// 
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::MatoPrepareComplete( TInt aError )
+    {
+    if ( aError )
+        {
+        // Some error, do not try to play DTMF
+        DP_DTMF_READ2( _L("CDTMFPayloadFormatRead::MatoPrepareComplete - ERR: %d "), aError );
+        }
+    else
+        {
+        DP_DTMF_READ2( _L("CDTMFPayloadFormatRead::MatoPrepareComplete, tick = %u"),
+            User::NTickCount() );
+        iTonePlayer->Play();
+        }    
+    }
+    
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::MatoPlayComplete
+// 
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::MatoPlayComplete( TInt aError )
+    {
+    if ( KErrNone != aError )
+        {
+        DP_DTMF_READ2( _L(
+            "CDTMFPayloadFormatRead::MatoPlayComplete - ERR: %d"), aError );
+        }
+    else
+        {
+        DP_DTMF_READ2( _L("CDTMFPayloadFormatRead::MatoPlayComplete KErrNone, tick = %u"),
+            User::NTickCount() );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::ConfigurePayloadFormatL
+// Configure payload decoding parameters.
+// ---------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::ConfigurePayloadFormatL( 
+    const TDesC8& aConfigParams )
+    {
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::ConfigurePayloadFormatL") );
+
+    if ( aConfigParams.Size() == sizeof( TMccCodecInfo ) )
+        {
+        TMccCodecInfoBuffer infoBuffer;
+        infoBuffer.Copy( aConfigParams );
+        iCInfo = infoBuffer();
+        
+        if ( !iPayloadDecoder )
+            {
+            iPayloadDecoder = CDTMFPayloadDecoder::NewL();
+            }
+
+        if ( 0 < iCInfo.iRedundancyCount
+            && KMaxDtmfRedCount >= TInt( iCInfo.iRedundancyCount ) )
+            {
+            if ( EGenRedUsed == iCInfo.iAlgoUsed )
+                {
+                iPayloadDecoder->SetPayloadFormat( 
+                                                EDTMFPayloadFormatRedEvents );
+                }
+            else
+                {
+                User::Leave( KErrArgument );
+                }
+            }
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+    
+    CreateClipBufferL();
+    
+    DP_DTMF_READ( _L( "CDTMFPayloadFormatRead::ConfigurePayloadFormatL OUT") );
+    }
+    
+// -----------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::CreateClipBufferL
+// Creates buffer needed in data transfer with format readers clip.
+// -----------------------------------------------------------------------------
+//
+void CDTMFPayloadFormatRead::CreateClipBufferL()
+    {
+    // If we have a source buffer already and it's size is correct, then this
+    // one is a NOP
+    if ( iSourceBuffer && KDTMFDefaultPayloadSize ==
+         iSourceBuffer->Data().MaxLength() )
+        {
+        DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CreateClipBufferL NOP") );
+        
+        return;
+        }
+    // We already have source buffer, own it and it can be reallocated.
+    else if ( iSourceBuffer && iSourceBufOwnership &&
+              KUidMmfDescriptorBuffer == iSourceBuffer->Type() )
+        {
+        DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CreateClipBufferL ReAlloc") );
+        
+        CMMFDescriptorBuffer* desBuf =
+            static_cast<CMMFDescriptorBuffer*>( iSourceBuffer );
+        desBuf->ReAllocBufferL( KDTMFDefaultPayloadSize );
+        desBuf = NULL;
+        return;
+        }
+    // everything else...
+    
+    DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CreateClipBufferL") );
+    
+    if ( iSourceBufOwnership )
+        {
+        delete iSourceBuffer;
+        iSourceBuffer = NULL;
+        }
+    
+    DP_DTMF_READ2( _L("CDTMFPayloadFormatRead::CreateClipBufferL 0x%x"), 
+        iClip->DataSourceType().iUid );
+    
+    // We are normally dealing with multiplexer, so check against it.
+    if ( iClip->CanCreateSourceBuffer() &&
+         TUid::Uid( KDllUidMccMultiplexer ) == iClip->DataSourceType() )
+        {
+        static_cast<CMMFFormatDecode*>( iClip )->SuggestSourceBufferSize(
+            KDTMFDefaultPayloadSize );
+        
+        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 );
+            }
+        
+        iSourceBufOwnership = isOwnBuffer;
+        iSourceBuffer = static_cast<CMMFDataBuffer*>( sourceBuf );
+        }
+    else
+        {
+        DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CreateClipBufferL own buffer") );
+        
+        iSourceBufOwnership = ETrue;
+        iSourceBuffer = CMMFDataBuffer::NewL( KDTMFDefaultPayloadSize );
+        }
+    
+    // If we are already waiting for source data we must renew that request
+    // as the pointer to our buffer goes dangling in other components, esp.
+    // multiplexer.
+    FillSourceBufferL();
+    
+    DP_DTMF_READ2( _L("CDTMFPayloadFormatRead::CreateClipBufferL ownership: %d"),
+        iSourceBufOwnership );
+    }
+
+// ---------------------------------------------------------------------------
+// From class MPayloadFormatRead.
+//
+// ---------------------------------------------------------------------------
+//
+TInt CDTMFPayloadFormatRead::HandleError( TInt aError, 
+    TFormatDecodeState /*aState*/ )
+    {
+    return aError;
+    }
+
+// ---------------------------------------------------------------------------
+// CDTMFPayloadFormatRead::CompareFirstPacketRtpHeaders
+// ---------------------------------------------------------------------------
+//
+TBool CDTMFPayloadFormatRead::CompareFirstPacketRtpHeaders(
+    const TRtpRecvHeader& aRtpheader )
+    {
+    const TRtpSequence next = iReceivedHeader.iSeqNum + 1;
+    TBool ret = EFalse;
+    const TUint8 KMarkerSet = 1;
+    
+    if ( next == aRtpheader.iSeqNum && 
+        iReceivedHeader.iPayloadType == aRtpheader.iPayloadType &&
+        iReceivedHeader.iTimestamp == aRtpheader.iTimestamp &&
+        KMarkerSet == iReceivedHeader.iMarker &&
+        KMarkerSet == aRtpheader.iMarker )
+        {
+        DP_DTMF_READ( _L("CDTMFPayloadFormatRead::CompareFirstPacketRtpHeaders MATCH") )
+        ret = ETrue;
+        }
+    // else we return EFalse as set when declaring ret.
+    
+    iReceivedHeader = aRtpheader;
+    return ret;
+    }
+
+//  End of File