multimediacommscontroller/mmccg711payloadformat/src/g711payloadformatwrite.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2004-2008 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:    Payload format component capable to write RTP payload
       
    15 *                containing G711 audio.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "rtpheader.h"
       
    24 #include    "g711payloadformatwrite.h"
       
    25 #include    "mccrtpdatasink.h"
       
    26 #include    "g711payloadformatdefs.h"
       
    27 #include    "mccuids.hrh"
       
    28 #include    "mccdef.h"
       
    29 #include    "mccrtpmediaclock.h"
       
    30 #include    "mccredpayloadwrite.h"
       
    31 #include    "mccinternaldef.h"
       
    32 
       
    33 // ============================= LOCAL FUNCTIONS ===============================
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CG711PayloadFormatRead::CG711PayloadFormatRead
       
    39 // C++ default constructor can NOT contain any code, that
       
    40 // might leave.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CG711PayloadFormatWrite::CG711PayloadFormatWrite()
       
    44     {
       
    45     }
       
    46     
       
    47 // -----------------------------------------------------------------------------
       
    48 // CG711PayloadFormatWrite::ConstructL
       
    49 // Symbian 2nd phase constructor can leave.
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 void CG711PayloadFormatWrite::ConstructL ( MDataSink* aSink )
       
    53     {
       
    54     DP_G711_WRITE( "CG711PayloadFormatWrite::ConstructL()" );
       
    55     
       
    56     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
    57     
       
    58     // Set default values
       
    59     iFourCC.Set( KMccFourCCIdG711 );
       
    60     
       
    61     iIsRtpSink = ( KMccRtpSinkUid  == aSink->DataSinkType() );
       
    62     TBool isRedEncoder 
       
    63         = ( TUid::Uid( KImplUidRedPayloadFormatEncode ) == aSink->DataSinkType() );
       
    64     
       
    65     if ( iIsRtpSink )
       
    66         {
       
    67         CMccRtpDataSink* tmp = static_cast<CMccRtpDataSink*>( aSink );
       
    68         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    69         }
       
    70     else if ( isRedEncoder )
       
    71         {
       
    72         CMccRedPayloadWrite* tmp = static_cast<CMccRedPayloadWrite*>( aSink );
       
    73         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    74         iIsRtpSink = ETrue;
       
    75         }
       
    76     else
       
    77         {
       
    78         DP_G711_WRITE( "CG711PayloadFormatWrite::ConstructL, sink not RTP one" );
       
    79         }
       
    80     
       
    81     iClip = aSink;
       
    82     
       
    83     // Initialize state machine
       
    84     iStateMachine = CFormatEncodeStateMachine::NewL( this );
       
    85     iStateMachine->ChangeState( EEncodeIdle );
       
    86     }
       
    87     
       
    88 // -----------------------------------------------------------------------------
       
    89 // CG711PayloadFormatWrite::NewL
       
    90 // Two-phased constructor.
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 CG711PayloadFormatWrite* CG711PayloadFormatWrite::NewL ( MDataSink* aSink )
       
    94     {
       
    95     DP_G711_WRITE( "CG711PayloadFormatWrite::NewL()" );
       
    96     
       
    97     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
    98     
       
    99     CG711PayloadFormatWrite* self = new (ELeave) CG711PayloadFormatWrite;
       
   100     CleanupStack::PushL( self );
       
   101     self->ConstructL( aSink );
       
   102     CleanupStack::Pop( self );
       
   103     return self;
       
   104     }
       
   105 
       
   106 // Destructor
       
   107 CG711PayloadFormatWrite::~CG711PayloadFormatWrite ()
       
   108     {
       
   109     DP_G711_WRITE( "CG711PayloadFormatWrite::~CG711PayloadFormatWrite()" );
       
   110     if ( iStateMachine )
       
   111         {
       
   112         iStateMachine->Cancel();
       
   113         }
       
   114     
       
   115     // Media clock is not owned
       
   116     if ( iRtpMediaClock )
       
   117         {
       
   118         iRtpMediaClock->UnregisterMediaFormat( iKey );
       
   119         }
       
   120     
       
   121     delete iSourceBuffer;
       
   122     delete iSinkBuffer;
       
   123     delete iStateMachine;
       
   124     }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CG711PayloadFormatWrite::SinkThreadLogon
       
   128 // Passes the logon command to the sink clip
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 TInt CG711PayloadFormatWrite::SinkThreadLogon(MAsyncEventHandler& aEventHandler)
       
   132     {
       
   133     iClip->SinkThreadLogon( aEventHandler );
       
   134     return KErrNone;
       
   135     }
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // CG711PayloadFormatWrite::SinkThreadLogoff
       
   139 // Passes the logoff command to the sink clip
       
   140 // -----------------------------------------------------------------------------
       
   141 void CG711PayloadFormatWrite::SinkThreadLogoff()
       
   142     {
       
   143     iClip->SinkThreadLogoff();
       
   144     }
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CG711PayloadFormatWrite::CreateSinkBufferL
       
   148 // Create a sink buffer
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 CMMFBuffer* CG711PayloadFormatWrite::CreateSinkBufferL( TMediaId aMediaId,
       
   152                                                         TBool &aReference )
       
   153     {
       
   154     DP_G711_WRITE( "CG711PayloadFormatWrite::CreateSinkBufferL()" );
       
   155     
       
   156     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   157         {
       
   158         User::Leave( KErrNotSupported );
       
   159         }
       
   160 
       
   161     aReference = ETrue;
       
   162 
       
   163     // Create buffer for data transfer between ULDataPath and FormatWrite
       
   164     return CreateSinkBufferOfSizeL( iCInfo.iFrameSize + KVoIPHeaderLength );
       
   165     }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // CG711PayloadFormatWrite::CreateSinkBufferOfSizeL
       
   169 // Create a sink buffer of the given size.
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 CMMFDataBuffer* CG711PayloadFormatWrite::CreateSinkBufferOfSizeL( TUint aSize )
       
   173     {
       
   174     DP_G711_WRITE( "CG711PayloadFormatWrite::CreateSinkBufferOfSizeL()" );
       
   175     
       
   176     // Needs to create source buffer
       
   177     if ( !iSourceBuffer )
       
   178 	    {  
       
   179 	    iSourceBuffer = CMMFDataBuffer::NewL( aSize );
       
   180     	iSourceBuffer->Data().FillZ( aSize );
       
   181     	iSourceBuffer->SetRequestSizeL( aSize );
       
   182 	    }
       
   183 	    
       
   184     return iSourceBuffer;
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CG711PayloadFormatWrite::EmptyBufferL
       
   189 // Empty the given source buffer
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 void CG711PayloadFormatWrite::EmptyBufferL( CMMFBuffer* aBuffer, 
       
   193                                             MDataSource* aSupplier, 
       
   194                                             TMediaId aMediaId )
       
   195     {
       
   196     DP_G711_WRITE( "CG711PayloadFormatWrite::EmptyBufferL()" );
       
   197     
       
   198     __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
       
   199     __ASSERT_ALWAYS( aBuffer == iSourceBuffer, User::Leave( KErrArgument ) );
       
   200     __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) );
       
   201     __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType,
       
   202         User::Leave( KErrNotSupported ) );
       
   203     
       
   204     // Save source buffer parameters and change the state.
       
   205     iDataPath = aSupplier;
       
   206     iSourceBuffer = static_cast<CMMFDataBuffer*>( aBuffer );
       
   207     
       
   208     if ( !iSinkBuffer )
       
   209         {
       
   210         DP_G711_WRITE( "CG711PayloadFormatWrite::EmptyBufferL, sink not ready!" );
       
   211         
       
   212         iStateMachine->ChangeState( ESourceBufferEmptied );
       
   213         return;
       
   214         }
       
   215     
       
   216     // Check if hw has sent different length buffer compared to last time.
       
   217     // This means that we need to update the media clock. This allows G.711
       
   218     // codec to change dynamically the buffer size.
       
   219     const TInt dataLen( iSourceBuffer->Data().Length() - KVoIPHeaderLength );
       
   220     const TInt audioLen( dataLen / KBitsPerByte );
       
   221     if ( audioLen != iCInfo.iHwFrameTime )
       
   222         {
       
   223         // Re-register to RTP clock.
       
   224         iCInfo.iHwFrameTime = audioLen;
       
   225         iRtpMediaClock->UnregisterMediaFormat( iKey );
       
   226         iKey = iRtpMediaClock->RegisterMediaFormat( KDefaultSampleRate, iCInfo.iHwFrameTime );
       
   227         }
       
   228         
       
   229     DP_G711_WRITE( "CG711PayloadFormatWrite::EmptyBufferL, SetTimeToPlay" );
       
   230     
       
   231     TUint32 ts = 0;
       
   232     User::LeaveIfError( iRtpMediaClock->GetTimeStamp( iKey, ts ) );
       
   233     
       
   234     if ( iRtpMediaClock->TimeBasedIncrement() )
       
   235     	{
       
   236     	DP_G711_WRITE( 
       
   237     		"CG711PayloadFormatWrite::EmptyBufferL(), New stream begins" );
       
   238     	iFirstPacketFinished = EFalse;
       
   239     	}
       
   240     
       
   241     if ( !iSinkBuffer->Data().Length() )
       
   242         {
       
   243         iSinkBuffer->SetTimeToPlay( TInt64( ts ) );
       
   244         iSinkBuffer->SetFrameNumber( aBuffer->FrameNumber() );
       
   245         }
       
   246     else
       
   247         {
       
   248         iSourceBuffer->SetTimeToPlay( TInt64( ts ) );
       
   249         }
       
   250     
       
   251     iStateMachine->ChangeState( EEmptySourceBuffer );
       
   252     }
       
   253 
       
   254 // -----------------------------------------------------------------------------
       
   255 // CG711PayloadFormatWrite::SetSinkDataTypeCode
       
   256 // Set the sink data type to the given four CC code for the given media
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 TInt CG711PayloadFormatWrite::SetSinkDataTypeCode( TFourCC aSinkFourCC,
       
   260                                                    TMediaId aMediaId )
       
   261     {
       
   262     DP_G711_WRITE( "CG711PayloadFormatWrite::SetSinkDataTypeCode()" );
       
   263     
       
   264     if ( KUidMediaTypeAudio != aMediaId.iMediaType ) 
       
   265         {
       
   266         return KErrNotSupported;
       
   267         }
       
   268     
       
   269     iFourCC = aSinkFourCC;
       
   270     
       
   271     return KErrNone;
       
   272     }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CG711PayloadFormatWrite::SinkDataTypeCode
       
   276 // Return the sink data type (four CC code) for the given media ID
       
   277 // -----------------------------------------------------------------------------
       
   278 //
       
   279 TFourCC CG711PayloadFormatWrite::SinkDataTypeCode( TMediaId aMediaId )
       
   280     {
       
   281     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   282         {
       
   283         return iFourCC;
       
   284         }
       
   285     else
       
   286         {
       
   287         return TFourCC(); //defaults to 'NULL' fourCC
       
   288         }
       
   289     }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CG711PayloadFormatWrite::BufferEmptiedL
       
   293 // Called after payload buffer is completely emptied by RtpDataSink.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 void CG711PayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
       
   297     {
       
   298         
       
   299     }
       
   300 
       
   301 // -----------------------------------------------------------------------------
       
   302 // CG711PayloadFormatWrite::NumChannels
       
   303 // Returns number of channels
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 TUint CG711PayloadFormatWrite::NumChannels()
       
   307     {
       
   308     return KMono;
       
   309     }
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CG711PayloadFormatWrite::SampleRate
       
   313 // Returns SampleRate
       
   314 // -----------------------------------------------------------------------------
       
   315 //
       
   316 TUint CG711PayloadFormatWrite::SampleRate()
       
   317     {
       
   318     return KDefaultSampleRate;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CG711PayloadFormatWrite::SetSampleRate
       
   323 // Set SampleRate
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 TInt CG711PayloadFormatWrite::SetSampleRate( TUint aSampleRate )
       
   327     {
       
   328     if ( KDefaultSampleRate != aSampleRate )
       
   329         {
       
   330         return KErrNotSupported;
       
   331         }
       
   332     else
       
   333         {
       
   334         return KErrNone;
       
   335         }
       
   336     }
       
   337 
       
   338 // -----------------------------------------------------------------------------
       
   339 // CG711PayloadFormatWrite::FrameTimeInterval
       
   340 // Return the frame time interval for the given media
       
   341 // -----------------------------------------------------------------------------
       
   342 //
       
   343 TTimeIntervalMicroSeconds 
       
   344     CG711PayloadFormatWrite::FrameTimeInterval( TMediaId aMediaId ) const
       
   345     {
       
   346     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   347         {
       
   348         return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   349         }
       
   350     else
       
   351         {
       
   352         return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   353         }
       
   354     }
       
   355 
       
   356 // -----------------------------------------------------------------------------
       
   357 // CG711PayloadFormatWrite::Duration
       
   358 // Return the frame time interval for the given media
       
   359 // NOT SUPPORTED
       
   360 // -----------------------------------------------------------------------------
       
   361 //
       
   362 TTimeIntervalMicroSeconds 
       
   363     CG711PayloadFormatWrite::Duration( TMediaId /*aMediaType*/ ) const
       
   364     {
       
   365     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   366     }
       
   367 
       
   368 // -----------------------------------------------------------------------------
       
   369 // CG711PayloadFormatWrite::EmptySourceBufferL
       
   370 // Empty the given sourcebuffer
       
   371 // Sourcebuffer is given in iSourceBuffer
       
   372 // Called by statemachine
       
   373 // -----------------------------------------------------------------------------
       
   374 //
       
   375 void CG711PayloadFormatWrite::EmptySourceBufferL()
       
   376 	{
       
   377     const TDesC8& srcDes( iSourceBuffer->Data() );
       
   378     
       
   379     DP_G711_WRITE2( "CG711PayloadFormatWrite::EmptySourceBufferL - SRC BUF SIZE: %d", srcDes.Size() );
       
   380     DP_G711_WRITE2( "CG711PayloadFormatWrite::EmptySourceBufferL - AUDIO SIZE: %d", srcDes.Size() - KVoIPHeaderLength );
       
   381     
       
   382     TPtrC8 audioFrame( srcDes.Mid( KVoIPHeaderLength ) );
       
   383     TPtrC8 frameHeader( srcDes.Left( KVoIPHeaderLength ) );
       
   384     TDes8& destDes( iSinkBuffer->Data() );
       
   385 
       
   386     if ( audioFrame.Size() > destDes.MaxSize() - destDes.Size() || !frameHeader.Length() )
       
   387         {
       
   388         DP_G711_WRITE( "CG711PayloadFormatWrite::EmptySourceBufferL WARNING SRCBUF LARGER THAN SINKBUF" );
       
   389         }
       
   390     else
       
   391         {
       
   392         const TUint8 frmHdrByte( frameHeader[0] );
       
   393         if ( KVoIPAudioFrame == frmHdrByte )
       
   394             {
       
   395             DP_G711_WRITE( "CG711PayloadFormatWrite::EmptySourceBufferL - AUDIO FRAME" );
       
   396             if ( iCNModeON )
       
   397                 {
       
   398                 iCNModeON = EFalse;
       
   399                 iFirstPacketFinished = EFalse;
       
   400                 }
       
   401 
       
   402             destDes.Append( audioFrame );
       
   403             }
       
   404         else if ( KVoIPCNFrame == frmHdrByte )
       
   405             {
       
   406             DP_G711_WRITE( "CG711PayloadFormatWrite::EmptySourceBufferL - CNOISE FRAME" );
       
   407             if ( destDes.Length() )
       
   408                 {
       
   409                 // Send audio frames first
       
   410                 DeliverPacketL( *iSinkBuffer );
       
   411                 iSinkBuffer->SetTimeToPlay( iSourceBuffer->TimeToPlay() );
       
   412                 }
       
   413 
       
   414             iCNModeON = ETrue;
       
   415             destDes.Append( audioFrame );
       
   416             }
       
   417         else
       
   418             {
       
   419             DP_G711_WRITE( "CG711PayloadFormatWrite::EmptySourceBufferL - UNVOICED NON-SID FRAME" );
       
   420             }
       
   421         }        
       
   422     
       
   423     // If we have filled the buffer enough or the frame is a CN packet
       
   424     // then send it.
       
   425     const TInt sendBytes( iCInfo.iPtime * KBitsPerByte );
       
   426     if ( sendBytes == destDes.Size() || iCNModeON )
       
   427         {
       
   428         this->DeliverPacketL( *iSinkBuffer );
       
   429         }
       
   430 
       
   431     iStateMachine->ChangeState( ESourceBufferEmptied );
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CG711PayloadFormatWrite::DeliverPacketL
       
   436 // Prepare the packet header and deliver the packet to the datasink.
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 void CG711PayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload )
       
   440     {
       
   441     DP_G711_WRITE2( "CG711PayloadFormatWrite::DeliverPacketL - TSTAMP: %u",
       
   442         static_cast<TUint32>( aPayload.TimeToPlay().Int64() ) );
       
   443     
       
   444     if ( !iClip )
       
   445         {
       
   446         DP_G711_WRITE( "CG711PayloadFormatWrite::DeliverPacketL NO DATASINK!" );
       
   447 
       
   448         User::Leave( KErrNotReady );
       
   449         }
       
   450 
       
   451     // Construct RTP header. Note that CN frames must not have the marker bit
       
   452     // set, only first audioframe after silence period.
       
   453     TRtpSendHeader sendHdr;
       
   454     if ( !iFirstPacketFinished && !iCNModeON )
       
   455         {
       
   456         sendHdr.iMarker = 1;
       
   457         iFirstPacketFinished = ETrue;
       
   458         }
       
   459     else
       
   460         {
       
   461         sendHdr.iMarker = 0;
       
   462         }
       
   463 
       
   464     sendHdr.iTimestamp 
       
   465         = static_cast<TUint32>( aPayload.TimeToPlay().Int64() );
       
   466     
       
   467     const TMediaId mediaId( KUidMediaTypeAudio );
       
   468     const TInt dataSize( aPayload.Data().Size() );
       
   469     if ( iCNModeON )
       
   470         {
       
   471         if ( iCInfo.iComfortNoiseGenerationPt != KPayloadTypeUndefined )
       
   472             {
       
   473             sendHdr.iPayloadType = iCInfo.iComfortNoiseGenerationPt;
       
   474             if ( dataSize )
       
   475                 {  
       
   476                 if ( iIsRtpSink )
       
   477                     {
       
   478                     iRtpDataSink->EmptyBufferL( &aPayload, this, mediaId, sendHdr );
       
   479                     }
       
   480                 else
       
   481                     {
       
   482         		    aPayload.SetLastBuffer( sendHdr.iMarker );
       
   483                     iClip->EmptyBufferL( &aPayload, this, mediaId );
       
   484                     }
       
   485                 }
       
   486             }
       
   487         }
       
   488     else
       
   489         {
       
   490         sendHdr.iPayloadType = iCInfo.iPayloadType;
       
   491         
       
   492         if ( dataSize )
       
   493             {  
       
   494             if ( iIsRtpSink )
       
   495                 {
       
   496                 iRtpDataSink->EmptyBufferL( &aPayload, this, mediaId, sendHdr );
       
   497                 }
       
   498             else
       
   499                 {
       
   500     		    aPayload.SetLastBuffer( sendHdr.iMarker );
       
   501                 iClip->EmptyBufferL( &aPayload, this, mediaId );
       
   502                 }
       
   503             }
       
   504         }        
       
   505     
       
   506     // Reset the payload buffer -- only if previous EmptyBufferL() is a 
       
   507     // synchronous call.
       
   508     aPayload.Data().Zero();
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CG711PayloadFormatWrite::SourceBufferEmptiedL
       
   513 // Handle the event that sourcebuffer has been emptied.
       
   514 // Sourcebuffer is given in "iSourceBuffer".
       
   515 // Called by the statemachine.
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 void CG711PayloadFormatWrite::SourceBufferEmptiedL()
       
   519     {
       
   520     DP_G711_WRITE( "CG711PayloadFormatWrite::SourceBufferEmptiedL()" );
       
   521     iDataPath->BufferEmptiedL( iSourceBuffer );
       
   522     }
       
   523 
       
   524 // -----------------------------------------------------------------------------
       
   525 // CG711PayloadFormatWrite::SinkPrimeL
       
   526 // Prime sink
       
   527 // -----------------------------------------------------------------------------
       
   528 //
       
   529 void CG711PayloadFormatWrite::SinkPrimeL()
       
   530     {
       
   531     DP_G711_WRITE( "CG711PayloadFormatWrite::SinkPrimeL()"  );
       
   532     iClip->SinkPrimeL();
       
   533     }
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CG711PayloadFormatWrite::SinkPlayL
       
   537 // Start playing.
       
   538 // -----------------------------------------------------------------------------
       
   539 //
       
   540 void CG711PayloadFormatWrite::SinkPlayL()
       
   541     {
       
   542     DP_G711_WRITE( "CG711PayloadFormatWrite::SinkPlayL()" );
       
   543     // Allocate buffer for data transfer between 
       
   544     // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
   545     delete iSinkBuffer;
       
   546     iSinkBuffer = NULL;
       
   547     iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iPtime * KBitsPerByte );
       
   548     
       
   549     // Start state machine
       
   550     iStateMachine->ChangeState( EEncodeIdle ); 
       
   551     iFirstPacketFinished = EFalse;
       
   552 
       
   553     // Start a new cycle of frame collecting
       
   554     if ( iSinkBuffer )
       
   555         {
       
   556         iSinkBuffer->SetLastBuffer( EFalse );
       
   557         }
       
   558 
       
   559     iClip->SinkPlayL();
       
   560     }
       
   561 
       
   562 // -----------------------------------------------------------------------------
       
   563 // CG711PayloadFormatWrite::SinkPauseL
       
   564 // Pause sink
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 void CG711PayloadFormatWrite::SinkPauseL()
       
   568     {
       
   569     DP_G711_WRITE( "CG711PayloadFormatWrite::SinkPauseL()" );
       
   570     iStateMachine->Cancel();
       
   571     iStateMachine->ChangeState( EEncodeIdle );
       
   572     
       
   573     iClip->SinkPauseL();
       
   574     }
       
   575 
       
   576 // -----------------------------------------------------------------------------
       
   577 // CG711PayloadFormatWrite::SinkStopL
       
   578 // Stop sink
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CG711PayloadFormatWrite::SinkStopL()
       
   582     {
       
   583     DP_G711_WRITE( "CG711PayloadFormatWrite::SinkStopL" );
       
   584     
       
   585     // Stop state machine
       
   586     iStateMachine->Cancel();
       
   587     iStateMachine->ChangeState( EEncodeIdle );
       
   588     
       
   589     iClip->SinkStopL();
       
   590     }
       
   591 
       
   592 // ---------------------------------------------------------------------------
       
   593 // CG711PayloadFormatWrite::ConfigurePayloadFormatL
       
   594 // Configure payload encoding parameters
       
   595 // ---------------------------------------------------------------------------
       
   596 //
       
   597 void CG711PayloadFormatWrite::ConfigurePayloadFormatL( const TDesC8& aConfigParams, 
       
   598     CMccRtpMediaClock& aClock  )
       
   599     {
       
   600     DP_G711_WRITE( "CG711PayloadFormatWrite::ConfigurePayloadFormatL" );
       
   601     
       
   602     __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
       
   603         User::Leave( KErrArgument ) );
       
   604     
       
   605     TMccCodecInfoBuffer infoBuffer;
       
   606     infoBuffer.Copy( aConfigParams );
       
   607     
       
   608     if ( !infoBuffer().iIsUpdate )
       
   609         {
       
   610         iCInfo = infoBuffer();
       
   611         iRtpMediaClock = &aClock;  
       
   612         iKey = iRtpMediaClock->RegisterMediaFormat( KDefaultSampleRate, iCInfo.iHwFrameTime );
       
   613         
       
   614         if( iCInfo.iHwFrameTime )
       
   615             {
       
   616             iCInfo.iFrameSize = TUint( iCInfo.iHwFrameTime * KDefaultSampleRateInkHz );
       
   617             }
       
   618         else
       
   619             {
       
   620             DP_G711_WRITE( "CG711PayloadFormatWrite::ConfigurePayloadFormatL KErrArgument" );
       
   621             User::Leave( KErrArgument );
       
   622             }
       
   623         
       
   624         DP_G711_WRITE2( "CG711PayloadFormatWrite::ConfigurePayloadFormatL FrameSize: %d", iCInfo.iFrameSize );
       
   625         
       
   626         if ( EGenRedUsed == iCInfo.iAlgoUsed )
       
   627             {
       
   628             DP_G711_WRITE2( "CG711PayloadFormatWrite::ConfigurePayloadFormatL, RED LEVEL: %d",
       
   629                 iCInfo.iRedundancyCount );
       
   630             
       
   631             CPayloadFormatWrite* redEncoder
       
   632                 = static_cast<CMccRedPayloadWrite*>( iClip );
       
   633             
       
   634             TMccRedPayloadWriteConfig config;
       
   635             config.iRedBlockCount = iCInfo.iRedundancyCount;
       
   636             config.iMaxPayloadSize = iCInfo.iPtime * KBitsPerByte;
       
   637             config.iNumOfEncodings = 1;
       
   638             config.iRedPayloadType = iCInfo.iRedundantPayload;
       
   639             config.InitPayloadTypes();
       
   640             config.iEncPayloadTypes[0] = iCInfo.iPayloadType;
       
   641             TMccRedPayloadWritePckg pckg( config );
       
   642             redEncoder->ConfigurePayloadFormatL( pckg, *iRtpMediaClock );
       
   643             }
       
   644         }
       
   645     else
       
   646         {
       
   647         UpdateConfigurationL( infoBuffer() ); 
       
   648         }
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CG711PayloadFormatWrite::UpdateConfigurationL
       
   653 // Update payload encoding parameters
       
   654 // -----------------------------------------------------------------------------
       
   655 //
       
   656 void CG711PayloadFormatWrite::UpdateConfigurationL( TMccCodecInfo& aCodecInfo )
       
   657     {
       
   658     DP_G711_WRITE( "CG711PayloadFormatWrite::UpdateConfigurationL" );
       
   659     
       
   660     iCInfo.iPtime = aCodecInfo.iPtime;
       
   661     iCInfo.iPayloadType = aCodecInfo.iPayloadType;
       
   662     iCInfo.iComfortNoiseGenerationPt = aCodecInfo.iComfortNoiseGenerationPt;
       
   663     
       
   664     // Allocate buffer for data transfer between 
       
   665     // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
   666     delete iSinkBuffer;
       
   667     iSinkBuffer = NULL;
       
   668     iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iPtime * KBitsPerByte );
       
   669     
       
   670     DP_G711_WRITE( "CG711PayloadFormatWrite::UpdateConfigurationL, exit" );
       
   671     }
       
   672 
       
   673 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   674 
       
   675 //  End of File