diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmcch263payloadformat/src/mcch263payloadformatwrite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmcch263payloadformat/src/mcch263payloadformatwrite.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,472 @@ +/* +* Copyright (c) 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: +* +*/ + + + + + +// INCLUDE FILES +#include "mcch263payloadformatwrite.h" +#include "mccrtpdatasink.h" +#include "mccinternaldef.h" +#include "mcch263oldpayloadencoder.h" +#include "mcch263newpayloadencoder.h" +#include "mmcccodech263.h" +#include "formatstatemachine.h" +#include "mcch263formatlogs.h" + +#include "mmccnetworksettings.h" + +#ifdef VOIP_TRACE_ENABLED +#include +#endif + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// Camera may give very big H.263 frame if there's big change in scene +const TInt KH263DefaultPayloadSize = 12000; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::CMccH263PayloadFormatWrite +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMccH263PayloadFormatWrite::CMccH263PayloadFormatWrite() + { + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::ConstructL( MDataSink* aSink ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::ConstructL" ) + + iFourCC = TFourCC( KMccFourCCIdH263 ); + + iIsRtpSink = ( KMccRtpSinkUid == aSink->DataSinkType() ); + iClip = aSink; + + iStateMachine = CFormatEncodeStateMachine::NewL( this ); + iStateMachine->ChangeState( EEncodeIdle ); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMccH263PayloadFormatWrite* CMccH263PayloadFormatWrite::NewL( MDataSink* aSink ) + { + __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) ); + + CMccH263PayloadFormatWrite* self = new( ELeave ) CMccH263PayloadFormatWrite; + + CleanupStack::PushL( self ); + self->ConstructL( aSink ); + CleanupStack::Pop( self ); + + return self; + } + +CMccH263PayloadFormatWrite::~CMccH263PayloadFormatWrite() + { + iBuffers.ResetAndDestroy(); + delete iSourceBuffer; + delete iStateMachine; + delete iPayloadEncoder; + + iClip = NULL; + } + + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkThreadLogon +// Passes the logon command to the sink clip. +// ----------------------------------------------------------------------------- +// +TInt CMccH263PayloadFormatWrite::SinkThreadLogon( + MAsyncEventHandler& aEventHandler ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogon" ) + + iStateMachine->ChangeState( EEncodeIdle ); + return iClip->SinkThreadLogon( aEventHandler ); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkThreadLogoff +// Passes the logoff command to the sink clip. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SinkThreadLogoff() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogoff" ) + + if( iClip ) + { + iClip->SinkThreadLogoff(); + } + else + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogoff\ + iClip is NULL, Error!..." ) + } + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::CanCreateSinkBuffer +// EmptyBufferL() is not used. +// ----------------------------------------------------------------------------- +// +TBool CMccH263PayloadFormatWrite::CanCreateSinkBuffer() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::CanCreateSinkBuffer" ) + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::CreateSinkBufferL +// Create a sink buffer. +// ----------------------------------------------------------------------------- +// +CMMFBuffer* CMccH263PayloadFormatWrite::CreateSinkBufferL( + TMediaId /*aMediaId*/, + TBool& aReference ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::CreateSinkBufferL" ) + + if ( !iSourceBuffer ) + { + iSourceBuffer = CMMFDataBuffer::NewL( KH263DefaultPayloadSize ); + iSourceBuffer->Data().FillZ( KH263DefaultPayloadSize ); + iSourceBuffer->SetRequestSizeL( KH263DefaultPayloadSize ); + } + // the ownership of iSourceBuffer is in CMccH263PayloadFormatWrite + aReference = ETrue; + return iSourceBuffer; + } + + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SetSinkDataTypeCode +// Set the sink data type to the given FourCC code for the given media. +// ----------------------------------------------------------------------------- +// +TInt CMccH263PayloadFormatWrite::SetSinkDataTypeCode( + TFourCC aSinkFourCC, + TMediaId aMediaId ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SetSinkDataTypeCode" ) + + if ( KUidMediaTypeVideo != aMediaId.iMediaType || + iFourCC != aSinkFourCC ) + { + return KErrNotSupported; + } + else + { + iMediaId = aMediaId; + return KErrNone; + } + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkDataTypeCode +// Return the sink data type (four CC code) for the given media. +// ----------------------------------------------------------------------------- +// +TFourCC CMccH263PayloadFormatWrite::SinkDataTypeCode( TMediaId aMediaId ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkDataTypeCode" ) + + if ( KUidMediaTypeVideo == aMediaId.iMediaType ) + { + return iFourCC; + } + else + { + return TFourCC(); //defaults to 'NULL' fourCC + } + } + + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::FrameTimeInterval +// Gets audio frame size in milliseconds. +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds + CMccH263PayloadFormatWrite::FrameTimeInterval( + TMediaId aMediaType ) const + { + if( KUidMediaTypeVideo != aMediaType.iMediaType ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::FrameTimeInterval \ +aMediaType is not KUidMediaTypeVideo, Error!!!" ) + } + return TTimeIntervalMicroSeconds( TInt64( 0 ) ); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::Duration +// Gets the duration of the sink clip for the specified media ID. +// ----------------------------------------------------------------------------- +// +TTimeIntervalMicroSeconds + CMccH263PayloadFormatWrite::Duration( TMediaId aMediaType ) const + { + if( KUidMediaTypeVideo != aMediaType.iMediaType ) + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::Duration \ +aMediaType is not KUidMediaTypeVideo, Error!!!" ) + } + return TTimeIntervalMicroSeconds( TInt64( 0 ) ); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::BufferEmptiedL +// Called by RTP data sink. Indicates that DTMF data is sent to the network. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ ) + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::BufferEmptiedL" ) + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkPrimeL +// Passes prime transition to the RTP data sink. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SinkPrimeL() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPrimeL" ) + __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) ); + + iClip->SinkPrimeL(); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkPlayL +// Passes play transition to the RTP data sink and resets state variables. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SinkPlayL() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPlayL" ) + __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) ); + + iClip->SinkPlayL(); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkPauseL +// Passes pause transition to the RTP data sink. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SinkPauseL() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPauseL" ) + __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) ); + + iClip->SinkPauseL(); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SinkStopL +// Passes stop transition to the RTP data sink. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SinkStopL() + { + __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkStopL" ) + __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) ); + + iClip->SinkStopL(); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::EmptyBufferL +// Not used because DTMF payload formatter generates DTMF independently. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::EmptyBufferL( + CMMFBuffer* aBuffer, + MDataSource* aSupplier, + TMediaId /*aMediaId*/ + ) + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptyBufferL" ) + __ASSERT_ALWAYS ( aBuffer, User::Leave(KErrArgument) ); + // reference of iSourceBuffer is passed to ULdatapath + // by calling CreateSinkBuffer + __ASSERT_ALWAYS ( aBuffer == iSourceBuffer, User::Leave(KErrArgument) ); + __ASSERT_ALWAYS ( aSupplier, User::Leave(KErrArgument) ); + __ASSERT_ALWAYS ( iPayloadEncoder, User::Leave(KErrArgument) ); + __ASSERT_ALWAYS ( iStateMachine, User::Leave(KErrArgument) ); + + // Save source buffer parameters and change the state. + iDataSource = aSupplier; + + iBuffers.ResetAndDestroy(); + + CleanupStack::PushL( TCleanupItem( PayloadEncodeCleanup, this ) ); + iPayloadEncoder->EncodeL(aBuffer, iBuffers); + CleanupStack::Pop( ); // TCleanupItem + + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptyBufferL, \ +array count ..." ) + __H263FORMAT_MEDIA_INT1( "CMccH263PayloadFormatWrite::EmptyBufferL, \ +array count:", iBuffers.Count()) + + // empty the encoded data to RtpSink + iStateMachine->ChangeState( EEmptySourceBuffer ); + } + + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::ConfigurePayloadFormatL +// Configure payload encoding parameters. +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::ConfigurePayloadFormatL( + const TDesC8& aConfigParams, + CMccRtpMediaClock& /*aClock*/ ) + + { + __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ), + User::Leave( KErrArgument ) ); + + TMccCodecInfoBuffer infoBuffer; + infoBuffer.Copy( aConfigParams ); + iCInfo = infoBuffer(); + + if ( !iPayloadEncoder ) + { + // Don't use old mode encoder for 1998 or 2000 modes, codec mode + // old means 1998 mode in configuration parameters + if( iCInfo.iCodecMode == KH263FormatModeOld || + iCInfo.iCodecMode == KH263FormatModeNew ) + { + iPayloadEncoder = CMccH263NewPayloadEncoder::NewL(); + } + else + { + User::Leave( KErrNotSupported ); + } + } + iPayloadEncoder->SetPayloadType( iCInfo.iPayloadType ); + } + + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::EmptySourceBufferL +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::EmptySourceBufferL() + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \ +from state machine" ) + __ASSERT_ALWAYS ( iStateMachine, User::Leave(KErrArgument) ); + __ASSERT_ALWAYS ( iClip, User::Leave(KErrArgument) ); + + // tell the source to give more data + iStateMachine->ChangeState( ESourceBufferEmptied ); + + while ( iBuffers.Count() ) + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \ +sending" ) + CBufferContainer* container = iBuffers[0]; + if ( iIsRtpSink ) + { + CMccRtpDataSink* rtpSink = static_cast( iClip ); + rtpSink->EmptyBufferL( container->iBuffer, this, iMediaId, container->iSendHeader ); + } + else + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL copying values" ) + container->iBuffer->SetTimeToPlay( container->iSendHeader.iTimestamp ); + container->iBuffer->SetLastBuffer( container->iSendHeader.iMarker ); + iClip->EmptyBufferL( container->iBuffer, this, iMediaId ); + } + iBuffers.Remove(0); + delete container->iBuffer; + container->iBuffer = NULL; + delete container; + container = NULL; + } + iBuffers.ResetAndDestroy(); + + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \ +all data sent" ) + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::SourceBufferEmptiedL +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::SourceBufferEmptiedL() + { + __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL from state machine" ) + + __ASSERT_ALWAYS( iDataSource, User::Leave( KErrArgument ) ); + + iDataSource->BufferEmptiedL( iSourceBuffer ); + } + +// ----------------------------------------------------------------------------- +// CMccH263PayloadFormatWrite::PayloadEncodeCleanup +// ----------------------------------------------------------------------------- +// +void CMccH263PayloadFormatWrite::PayloadEncodeCleanup( TAny* aAny ) + { + // Error occured at payload encoding, cleanup and keep on asking more data + // to be encoded. + CMccH263PayloadFormatWrite* write = + static_cast( aAny ); + write->iBuffers.ResetAndDestroy(); + + write->iStateMachine->ChangeState( ESourceBufferEmptied ); + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File