diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccredpayloadformat/src/mccredpayloadwrite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccredpayloadformat/src/mccredpayloadwrite.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,386 @@ +/* +* Copyright (c) 2005-2006 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: Implements format encode interface for redundancy plugin. +* +*/ + + + + + +// INCLUDE FILES +#include "rtpheader.h" +#include "mccredpayloadwrite.h" +#include "mccredencoder.h" +#include "mccrtpdatasink.h" +#include "mccredpayloadformatdefs.h" +#include "mccdef.h" +#include "mccinternaldef.h" +#include "mccrtpmediaclock.h" + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::CMccRedPayloadWrite +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMccRedPayloadWrite::CMccRedPayloadWrite() + { + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::ConstructL( MDataSink* aSink ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::ConstructL" ) + __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) ); + + iClip = aSink; + iRedEncoder = CMccRedEncoder::NewL(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMccRedPayloadWrite* CMccRedPayloadWrite::NewL( MDataSink* aSink ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::NewL" ) + __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( KMccRtpSinkUid == aSink->DataSinkType(), + User::Leave( KErrNotSupported ) ); + + CMccRedPayloadWrite* self = new( ELeave ) CMccRedPayloadWrite; + + CleanupStack::PushL( self ); + self->ConstructL( aSink ); + CleanupStack::Pop( self ); + + return self; + } + + +// Destructor +CMccRedPayloadWrite::~CMccRedPayloadWrite() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::~CMccRedPayloadWrite" ) + + delete iRedEncoder; + delete iSinkBuffer; + iDataSource = NULL; + iBufToEmptyPtr = NULL; + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadRead::ConfigurePayloadFormatL +// Configure payload encoding parameters. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::ConfigurePayloadFormatL( const TDesC8& aConfigParams, + CMccRtpMediaClock& /*aClock*/ ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::ConfigurePayloadFormatL" ) + __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccRedPayloadWriteConfig ), + User::Leave( KErrArgument ) ); + + TMccRedPayloadWritePckg cPckg; + cPckg.Copy( aConfigParams ); + iPLConfig = cPckg(); + + __ASSERT_ALWAYS( iPLConfig.iRedBlockCount <= KMaxRedCount, + User::Leave( KErrArgument ) ); + + if ( iSinkBuffer ) + { + delete iSinkBuffer; + iSinkBuffer = NULL; + } + + // Extra variables for clarity + TInt redPayloadSize + = iPLConfig.iMaxPayloadSize * ( 1 + iPLConfig.iRedBlockCount ); + TInt redHeadersSize + = iPLConfig.iRedBlockCount * KRedHeaderSize + KFinalHeaderSize; + iSinkBuffer = CMMFDataBuffer::NewL( redPayloadSize + redHeadersSize ); + + iRedEncoder->InitializeL( iPLConfig.iRedBlockCount, + iPLConfig.iMaxPayloadSize, + iPLConfig.iNumOfEncodings ); + + RArray encPTs; + CleanupClosePushL( encPTs ); + + TInt maxNumOfEncodings = iPLConfig.iEncPayloadTypes.Count(); + for ( TInt i = 0; i < maxNumOfEncodings; i++ ) + { + if ( KPayloadNotDefined != iPLConfig.iEncPayloadTypes[i] ) + { + encPTs.AppendL( iPLConfig.iEncPayloadTypes[i] ); + } + } + + User::LeaveIfError( iRedEncoder->SetPayloadTypes( encPTs ) ); + CleanupStack::PopAndDestroy( &encPTs ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::FrameTimeInterval +// NOT USED. Pure virtual method implementation from CMMFormatEncode needed. +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CMccRedPayloadWrite::FrameTimeInterval( + TMediaId /*aMediaType*/ ) const + { + DP_RED_ENCODE( "CMccRedPayloadWrite::FrameTimeInterval" ) + + return TTimeIntervalMicroSeconds( TInt64( 0 ) ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::Duration +// NOT USED. Pure virtual method implementation from CMMFormatEncode needed. +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds CMccRedPayloadWrite::Duration( + TMediaId /*aMediaType*/ ) const + { + DP_RED_ENCODE( "CMccRedPayloadWrite::Duration" ) + + return TTimeIntervalMicroSeconds( TInt64( 0 ) ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::CreateSinkBufferL +// ----------------------------------------------------------------------------- +// +CMMFBuffer* CMccRedPayloadWrite::CreateSinkBufferL( TMediaId /*aMediaId*/, + TBool& /*aReference*/ ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::CreateSinkBufferL" ) + User::Leave( KErrNotSupported ); + return NULL; + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::DataSinkType +// +// ----------------------------------------------------------------------------- +// +TUid CMccRedPayloadWrite::DataSinkType() const + { + return TUid::Uid( KImplUidRedPayloadFormatEncode ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkDataTypeCode +// NOT USED. +// ----------------------------------------------------------------------------- +// +TFourCC CMccRedPayloadWrite::SinkDataTypeCode( TMediaId /*aMediaId*/ ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkDataTypeCode" ) + + return TFourCC(); + } + + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SetSinkDataTypeCode +// NOT USED. +// ----------------------------------------------------------------------------- +// +TInt CMccRedPayloadWrite::SetSinkDataTypeCode( TFourCC /*aSinkFourCC*/, + TMediaId /*aMediaId*/ ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SetSinkDataTypeCode" ) + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkThreadLogon +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +TInt CMccRedPayloadWrite::SinkThreadLogon( MAsyncEventHandler& aEventHandler ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkThreadLogon" ) + + iClip->SinkThreadLogon( aEventHandler ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkThreadLogoff +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::SinkThreadLogoff() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkThreadLogoff" ) + + iClip->SinkThreadLogoff(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkPrimeL +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::SinkPrimeL() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPrimeL" ) + + iClip->SinkPrimeL(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkPlayL +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::SinkPlayL() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPlayL" ) + + iClip->SinkPlayL(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkPauseL +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::SinkPauseL() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkPauseL" ) + + iClip->SinkPauseL(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SinkStopL +// Passes state transition to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::SinkStopL() + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SinkStopL" ) + + iClip->SinkStopL(); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::EmptyBufferL +// NOT USED. +// Overloaded emptybuffer with additional RTP header parameter used instead. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::EmptyBufferL( CMMFBuffer* /*aBuffer*/, + MDataSource* /*aSupplier*/, + TMediaId /*aMediaId*/ ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL" ) + + User::Leave( KErrNotSupported ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::BufferEmptiedL +// Called by data sink of redundancy payload plugin, when payload is emptied. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::BufferEmptiedL( CMMFBuffer* aBuffer ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::BufferEmptiedL" ) + __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( iBufToEmptyPtr, User::Leave( KErrNotReady ) ); + + iDataSource->BufferEmptiedL( iBufToEmptyPtr ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::EmptyBufferL +// Encodes contents of source buffer with redundancy encoder and forwards +// result buffer to the data sink of redundancy payload plugin. +// ----------------------------------------------------------------------------- +// +void CMccRedPayloadWrite::EmptyBufferL( CMMFBuffer* aSourceBuffer, + MDataSource* aSupplier, + TMediaId aMediaId, + TRtpSendHeader& aSendHeader ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL" ) + __ASSERT_ALWAYS( aSourceBuffer, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( KUidMmfDataBuffer == aSourceBuffer->Type(), + User::Leave( KErrNotSupported ) ); + __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) ); + __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType, + User::Leave( KErrNotSupported ) ); + + DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL() - MEDIA TYPE OK" ) + + iDataSource = aSupplier; + iBufToEmptyPtr = static_cast( aSourceBuffer ); + + if ( KComfortNoisePT != aSendHeader.iPayloadType ) + { + // Comfort noise packets are forwarded without encoding + iRedEncoder->SetEncodingBlockL( + EMccPrimaryEncoding, iBufToEmptyPtr->Data() ); + iRedEncoder->EncodePayloadL( aSendHeader.iTimestamp ); + iRedEncoder->GetEncodingBlockL( EMccRTPPayload, iSinkBuffer->Data() ); + + DP_RED_ENCODE( "CMccRedPayloadWrite::EmptyBufferL() - Buffer encoded" ) + aSendHeader.iPayloadType = iPLConfig.iRedPayloadType; + } + + // Deliver the packet + static_cast( iClip ) + ->EmptyBufferL( iSinkBuffer, this, aMediaId, aSendHeader ); + } + +// ----------------------------------------------------------------------------- +// CMccRedPayloadWrite::SetPayloadTypes +// Set payload types to accept as encodings. +// ----------------------------------------------------------------------------- +// +TInt CMccRedPayloadWrite::SetPayloadTypes( RArray& aPayloadTypes ) + { + DP_RED_ENCODE( "CMccRedPayloadWrite::SetPayloadTypes" ) + + if ( aPayloadTypes.Count() ) + { + iPLConfig.iRedPayloadType = aPayloadTypes[0]; + aPayloadTypes.Remove( 0 ); + + return iRedEncoder->SetPayloadTypes( aPayloadTypes ); + } + else + { + return KErrArgument; + } + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File