diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccdtmfpayloadformat/src/dtmfpayloadformatread.cpp --- /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 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( 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( 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( 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( 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