multimediacommscontroller/mmcch263payloadformat/src/mcch263payloadformatwrite.cpp
changeset 0 1bce908db942
--- /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 <voip_trace.h>
+#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<CMccRtpDataSink*>( 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<CMccH263PayloadFormatWrite*>( aAny );
+	write->iBuffers.ResetAndDestroy();
+	
+	write->iStateMachine->ChangeState( ESourceBufferEmptied ); 
+	}
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File