multimediacommscontroller/mmcch263payloadformat/src/mcch263payloadformatwrite.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "mcch263payloadformatwrite.h"
       
    24 #include "mccrtpdatasink.h"
       
    25 #include "mccinternaldef.h"
       
    26 #include "mcch263oldpayloadencoder.h"
       
    27 #include "mcch263newpayloadencoder.h"
       
    28 #include "mmcccodech263.h"
       
    29 #include "formatstatemachine.h"
       
    30 #include "mcch263formatlogs.h"
       
    31 
       
    32 #include "mmccnetworksettings.h"
       
    33 
       
    34 #ifdef VOIP_TRACE_ENABLED
       
    35 #include <voip_trace.h>
       
    36 #endif
       
    37 
       
    38 // EXTERNAL DATA STRUCTURES
       
    39 
       
    40 // EXTERNAL FUNCTION PROTOTYPES  
       
    41 
       
    42 // CONSTANTS
       
    43 
       
    44 // Camera may give very big H.263 frame if there's big change in scene
       
    45 const TInt KH263DefaultPayloadSize = 12000; 
       
    46 
       
    47 // MACROS
       
    48 
       
    49 // LOCAL CONSTANTS AND MACROS
       
    50 
       
    51 // MODULE DATA STRUCTURES
       
    52 
       
    53 // LOCAL FUNCTION PROTOTYPES
       
    54 
       
    55 // FORWARD DECLARATIONS
       
    56 
       
    57 // ============================= LOCAL FUNCTIONS ===============================
       
    58 
       
    59 
       
    60 // ============================ MEMBER FUNCTIONS ===============================
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CMccH263PayloadFormatWrite::CMccH263PayloadFormatWrite
       
    64 // C++ default constructor can NOT contain any code, that
       
    65 // might leave.
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 CMccH263PayloadFormatWrite::CMccH263PayloadFormatWrite()
       
    69     {
       
    70     }
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // CMccH263PayloadFormatWrite::ConstructL
       
    74 // Symbian 2nd phase constructor can leave.
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 void CMccH263PayloadFormatWrite::ConstructL( MDataSink* aSink )
       
    78     {        
       
    79     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::ConstructL" )
       
    80 
       
    81     iFourCC = TFourCC( KMccFourCCIdH263 );
       
    82     
       
    83     iIsRtpSink = ( KMccRtpSinkUid  == aSink->DataSinkType() );
       
    84     iClip = aSink;
       
    85         
       
    86     iStateMachine = CFormatEncodeStateMachine::NewL( this );
       
    87     iStateMachine->ChangeState( EEncodeIdle );
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CMccH263PayloadFormatWrite::NewL
       
    92 // Two-phased constructor.
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 CMccH263PayloadFormatWrite* CMccH263PayloadFormatWrite::NewL( MDataSink* aSink )
       
    96     {
       
    97     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
    98 
       
    99     CMccH263PayloadFormatWrite* self = new( ELeave ) CMccH263PayloadFormatWrite;
       
   100     
       
   101     CleanupStack::PushL( self );
       
   102     self->ConstructL( aSink );
       
   103     CleanupStack::Pop( self );
       
   104 
       
   105     return self;
       
   106     }
       
   107 
       
   108 CMccH263PayloadFormatWrite::~CMccH263PayloadFormatWrite()
       
   109     {
       
   110     iBuffers.ResetAndDestroy();
       
   111     delete iSourceBuffer;    
       
   112     delete iStateMachine;
       
   113 	delete iPayloadEncoder; 
       
   114 	
       
   115     iClip = NULL;
       
   116     }
       
   117 
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CMccH263PayloadFormatWrite::SinkThreadLogon
       
   121 // Passes the logon command to the sink clip.
       
   122 // -----------------------------------------------------------------------------
       
   123 //
       
   124 TInt CMccH263PayloadFormatWrite::SinkThreadLogon( 
       
   125     MAsyncEventHandler& aEventHandler )
       
   126     {
       
   127     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogon" )
       
   128     
       
   129     iStateMachine->ChangeState( EEncodeIdle );
       
   130     return iClip->SinkThreadLogon( aEventHandler );
       
   131     }
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CMccH263PayloadFormatWrite::SinkThreadLogoff
       
   135 // Passes the logoff command to the sink clip.
       
   136 // -----------------------------------------------------------------------------
       
   137 //
       
   138 void CMccH263PayloadFormatWrite::SinkThreadLogoff()
       
   139     {
       
   140     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogoff" )
       
   141 
       
   142     if( iClip )
       
   143 	    {
       
   144 	   	iClip->SinkThreadLogoff();
       
   145 	    }
       
   146     else
       
   147 	    {
       
   148 	    __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkThreadLogoff\
       
   149 	                            iClip is NULL, Error!..." )
       
   150 	    }
       
   151     }
       
   152 
       
   153 // -----------------------------------------------------------------------------
       
   154 // CMccH263PayloadFormatWrite::CanCreateSinkBuffer
       
   155 // EmptyBufferL() is not used.
       
   156 // -----------------------------------------------------------------------------
       
   157 //
       
   158 TBool CMccH263PayloadFormatWrite::CanCreateSinkBuffer()
       
   159     {
       
   160     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::CanCreateSinkBuffer" )
       
   161     return ETrue;
       
   162     }
       
   163 	    
       
   164 // -----------------------------------------------------------------------------
       
   165 // CMccH263PayloadFormatWrite::CreateSinkBufferL
       
   166 // Create a sink buffer.
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 CMMFBuffer* CMccH263PayloadFormatWrite::CreateSinkBufferL( 
       
   170 	TMediaId /*aMediaId*/,
       
   171     TBool&     aReference )
       
   172     {
       
   173     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::CreateSinkBufferL" )
       
   174 
       
   175     if ( !iSourceBuffer )
       
   176 	    {  
       
   177 	    iSourceBuffer = CMMFDataBuffer::NewL( KH263DefaultPayloadSize );
       
   178     	iSourceBuffer->Data().FillZ( KH263DefaultPayloadSize );
       
   179     	iSourceBuffer->SetRequestSizeL( KH263DefaultPayloadSize );
       
   180 	    }
       
   181 	// the ownership of iSourceBuffer is in CMccH263PayloadFormatWrite
       
   182 	aReference = ETrue;  
       
   183     return iSourceBuffer;
       
   184     }
       
   185     
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CMccH263PayloadFormatWrite::SetSinkDataTypeCode
       
   189 // Set the sink data type to the given FourCC code for the given media.
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 TInt CMccH263PayloadFormatWrite::SetSinkDataTypeCode( 
       
   193 	TFourCC  aSinkFourCC, 
       
   194     TMediaId aMediaId )
       
   195     {
       
   196     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SetSinkDataTypeCode" )
       
   197 
       
   198     if ( KUidMediaTypeVideo != aMediaId.iMediaType || 
       
   199          iFourCC != aSinkFourCC )
       
   200         {
       
   201         return KErrNotSupported;
       
   202         }
       
   203     else
       
   204 	    {
       
   205 	    iMediaId = aMediaId;    
       
   206         return KErrNone;	
       
   207 	    }
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CMccH263PayloadFormatWrite::SinkDataTypeCode
       
   212 // Return the sink data type (four CC code) for the given media.
       
   213 // -----------------------------------------------------------------------------
       
   214 //
       
   215 TFourCC CMccH263PayloadFormatWrite::SinkDataTypeCode( TMediaId aMediaId )
       
   216     {
       
   217     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkDataTypeCode" )
       
   218    
       
   219     if ( KUidMediaTypeVideo == aMediaId.iMediaType )
       
   220         {
       
   221         return iFourCC;
       
   222         }
       
   223     else
       
   224         {
       
   225         return TFourCC(); //defaults to 'NULL' fourCC
       
   226         }
       
   227     }
       
   228 
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CMccH263PayloadFormatWrite::FrameTimeInterval
       
   232 // Gets audio frame size in milliseconds.
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 TTimeIntervalMicroSeconds 
       
   236     CMccH263PayloadFormatWrite::FrameTimeInterval( 
       
   237     TMediaId aMediaType ) const
       
   238     {
       
   239     if( KUidMediaTypeVideo != aMediaType.iMediaType )
       
   240 	    {
       
   241 	    __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::FrameTimeInterval \
       
   242 aMediaType is not KUidMediaTypeVideo, Error!!!" )	
       
   243 	    }
       
   244     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   245     }
       
   246 
       
   247 // -----------------------------------------------------------------------------
       
   248 // CMccH263PayloadFormatWrite::Duration
       
   249 // Gets the duration of the sink clip for the specified media ID.
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 TTimeIntervalMicroSeconds 
       
   253     CMccH263PayloadFormatWrite::Duration( TMediaId aMediaType ) const
       
   254     {
       
   255     if( KUidMediaTypeVideo != aMediaType.iMediaType )
       
   256 	    {
       
   257 	    __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::Duration \
       
   258 aMediaType is not KUidMediaTypeVideo, Error!!!" )
       
   259 	    }
       
   260     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // CMccH263PayloadFormatWrite::BufferEmptiedL
       
   265 // Called by RTP data sink. Indicates that DTMF data is sent to the network.
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 void CMccH263PayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
       
   269     {
       
   270     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::BufferEmptiedL" )
       
   271     }
       
   272     
       
   273 // -----------------------------------------------------------------------------
       
   274 // CMccH263PayloadFormatWrite::SinkPrimeL
       
   275 // Passes prime transition to the RTP data sink.
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 void CMccH263PayloadFormatWrite::SinkPrimeL()
       
   279     {
       
   280     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPrimeL" )
       
   281     __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
       
   282 
       
   283     iClip->SinkPrimeL();
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CMccH263PayloadFormatWrite::SinkPlayL
       
   288 // Passes play transition to the RTP data sink and resets state variables.
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CMccH263PayloadFormatWrite::SinkPlayL()
       
   292     {
       
   293     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPlayL" )    
       
   294     __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
       
   295     
       
   296     iClip->SinkPlayL();
       
   297     }
       
   298     
       
   299 // -----------------------------------------------------------------------------
       
   300 // CMccH263PayloadFormatWrite::SinkPauseL
       
   301 // Passes pause transition to the RTP data sink.
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 void CMccH263PayloadFormatWrite::SinkPauseL()
       
   305     {
       
   306     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkPauseL" )
       
   307     __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
       
   308     
       
   309     iClip->SinkPauseL();
       
   310     }
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CMccH263PayloadFormatWrite::SinkStopL
       
   314 // Passes stop transition to the RTP data sink.
       
   315 // -----------------------------------------------------------------------------
       
   316 //  
       
   317 void CMccH263PayloadFormatWrite::SinkStopL()
       
   318     {
       
   319     __H263FORMAT_CONTROLL( "CMccH263PayloadFormatWrite::SinkStopL" )
       
   320     __ASSERT_ALWAYS( iClip, User::Leave( KErrArgument ) );
       
   321 
       
   322     iClip->SinkStopL();
       
   323     }
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CMccH263PayloadFormatWrite::EmptyBufferL
       
   327 // Not used because DTMF payload formatter generates DTMF independently.
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 void CMccH263PayloadFormatWrite::EmptyBufferL( 
       
   331 	CMMFBuffer*  aBuffer, 
       
   332     MDataSource* aSupplier, 
       
   333     TMediaId   /*aMediaId*/
       
   334                                           )
       
   335     {
       
   336     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptyBufferL" )
       
   337     __ASSERT_ALWAYS ( aBuffer, User::Leave(KErrArgument) );
       
   338     // reference of iSourceBuffer is passed to ULdatapath 
       
   339     // by calling CreateSinkBuffer
       
   340     __ASSERT_ALWAYS ( aBuffer == iSourceBuffer, User::Leave(KErrArgument) );
       
   341     __ASSERT_ALWAYS ( aSupplier, User::Leave(KErrArgument) );
       
   342     __ASSERT_ALWAYS ( iPayloadEncoder, User::Leave(KErrArgument) );
       
   343     __ASSERT_ALWAYS ( iStateMachine, User::Leave(KErrArgument) );
       
   344 
       
   345     // Save source buffer parameters and change the state.
       
   346     iDataSource = aSupplier;
       
   347     
       
   348 	iBuffers.ResetAndDestroy();
       
   349 	
       
   350 	CleanupStack::PushL( TCleanupItem( PayloadEncodeCleanup, this ) );
       
   351     iPayloadEncoder->EncodeL(aBuffer, iBuffers);
       
   352     CleanupStack::Pop( ); // TCleanupItem
       
   353     
       
   354     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptyBufferL, \
       
   355 array count ..." )
       
   356     __H263FORMAT_MEDIA_INT1( "CMccH263PayloadFormatWrite::EmptyBufferL, \
       
   357 array count:", iBuffers.Count())
       
   358             
       
   359     // empty the encoded data to RtpSink
       
   360     iStateMachine->ChangeState( EEmptySourceBuffer );     
       
   361     }
       
   362 
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CMccH263PayloadFormatWrite::ConfigurePayloadFormatL
       
   366 // Configure payload encoding parameters.
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 void CMccH263PayloadFormatWrite::ConfigurePayloadFormatL(
       
   370     const TDesC8& aConfigParams, 
       
   371     CMccRtpMediaClock& /*aClock*/  )
       
   372 
       
   373     {   
       
   374     __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
       
   375     				 User::Leave( KErrArgument ) );
       
   376 
       
   377     TMccCodecInfoBuffer infoBuffer;
       
   378     infoBuffer.Copy( aConfigParams );
       
   379     iCInfo = infoBuffer();
       
   380     
       
   381     if ( !iPayloadEncoder )
       
   382 	    {
       
   383 	    // Don't use old mode encoder for 1998 or 2000 modes, codec mode
       
   384 	    // old means 1998 mode in configuration parameters
       
   385 	    if( iCInfo.iCodecMode == KH263FormatModeOld ||
       
   386 	        iCInfo.iCodecMode == KH263FormatModeNew )
       
   387 	    	{
       
   388 			iPayloadEncoder = CMccH263NewPayloadEncoder::NewL();
       
   389 	    	}
       
   390 	    else
       
   391 	    	{
       
   392 	    	User::Leave( KErrNotSupported );
       
   393 	    	}
       
   394 	    }	    
       
   395     iPayloadEncoder->SetPayloadType( iCInfo.iPayloadType );        
       
   396     }
       
   397     
       
   398     
       
   399 // -----------------------------------------------------------------------------
       
   400 // CMccH263PayloadFormatWrite::EmptySourceBufferL
       
   401 // -----------------------------------------------------------------------------
       
   402 //
       
   403 void CMccH263PayloadFormatWrite::EmptySourceBufferL()
       
   404 	{
       
   405     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \
       
   406 from state machine" )	
       
   407     __ASSERT_ALWAYS ( iStateMachine, User::Leave(KErrArgument) );
       
   408     __ASSERT_ALWAYS ( iClip, User::Leave(KErrArgument) );
       
   409     
       
   410     // tell the source to give more data
       
   411     iStateMachine->ChangeState( ESourceBufferEmptied );  
       
   412     
       
   413 	while ( iBuffers.Count() )
       
   414     	{
       
   415 	    __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \
       
   416 sending" )
       
   417     	CBufferContainer* container = iBuffers[0];
       
   418     	if ( iIsRtpSink )
       
   419     	    {
       
   420         	CMccRtpDataSink* rtpSink = static_cast<CMccRtpDataSink*>( iClip );
       
   421     	    rtpSink->EmptyBufferL( container->iBuffer, this, iMediaId, container->iSendHeader );
       
   422     	    }
       
   423     	else
       
   424     	    {
       
   425     	    __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL copying values" )
       
   426     	    container->iBuffer->SetTimeToPlay( container->iSendHeader.iTimestamp );
       
   427 		    container->iBuffer->SetLastBuffer( container->iSendHeader.iMarker );
       
   428     	    iClip->EmptyBufferL( container->iBuffer, this, iMediaId );
       
   429     	    }
       
   430     	iBuffers.Remove(0);
       
   431     	delete container->iBuffer;
       
   432     	container->iBuffer = NULL;
       
   433     	delete container;
       
   434     	container = NULL;
       
   435     	}
       
   436     iBuffers.ResetAndDestroy();
       
   437     	
       
   438     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL \
       
   439 all data sent" )
       
   440    	}
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CMccH263PayloadFormatWrite::SourceBufferEmptiedL
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 void CMccH263PayloadFormatWrite::SourceBufferEmptiedL()
       
   447 	{
       
   448     __H263FORMAT_MEDIA( "CMccH263PayloadFormatWrite::EmptySourceBufferL from state machine" )
       
   449    
       
   450     __ASSERT_ALWAYS( iDataSource, User::Leave( KErrArgument ) );
       
   451 
       
   452 	iDataSource->BufferEmptiedL( iSourceBuffer );   
       
   453 	}
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CMccH263PayloadFormatWrite::PayloadEncodeCleanup
       
   457 // -----------------------------------------------------------------------------
       
   458 // 
       
   459 void CMccH263PayloadFormatWrite::PayloadEncodeCleanup( TAny* aAny )
       
   460 	{
       
   461 	// Error occured at payload encoding, cleanup and keep on asking more data
       
   462 	// to be encoded.
       
   463 	CMccH263PayloadFormatWrite* write = 
       
   464 		static_cast<CMccH263PayloadFormatWrite*>( aAny );
       
   465 	write->iBuffers.ResetAndDestroy();
       
   466 	
       
   467 	write->iStateMachine->ChangeState( ESourceBufferEmptied ); 
       
   468 	}
       
   469 
       
   470 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   471 
       
   472 //  End of File