multimediacommscontroller/mmccilbcpayloadformat/src/ilbcpayloadformatwrite.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 ILBC audio.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include    "ilbcpayloadformatwrite.h"
       
    24 #include    "mccrtpdatasink.h"
       
    25 #include    "ilbcpayloadformatutil.h"
       
    26 #include    "mccuids.hrh"
       
    27 #include    "mccdef.h"
       
    28 #include    "mccinternaldef.h"
       
    29 #include    "mccrtpmediaclock.h" 
       
    30 #include    "mccredpayloadwrite.h"
       
    31 
       
    32 // MACROS
       
    33 #ifdef _DEBUG
       
    34 #define TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
    35 #endif
       
    36 
       
    37 // ============================= LOCAL FUNCTIONS ===============================
       
    38 
       
    39 // ============================ MEMBER FUNCTIONS ===============================
       
    40 
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CIlbcPayloadFormatWrite::CIlbcPayloadFormatWrite
       
    44 // C++ default constructor can NOT contain any code, that
       
    45 // might leave.
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CIlbcPayloadFormatWrite::CIlbcPayloadFormatWrite()
       
    49     {
       
    50     
       
    51     };
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CIlbcPayloadFormatWrite::ConstructL
       
    55 // Symbian 2nd phase constructor can leave.
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 void CIlbcPayloadFormatWrite::ConstructL( MDataSink* aSink )
       
    59     {
       
    60     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
    61         RDebug::Print( _L("CIlbcPayloadFormatWrite::ConstructL") );
       
    62     #endif
       
    63     
       
    64     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
    65     
       
    66     // Set default values
       
    67     iFramesPerPacket = 1;
       
    68     iFourCC.Set( KMccFourCCIdILBC );
       
    69 
       
    70     // Set data sink
       
    71     iIsRtpSink = ( KMccRtpSinkUid  == aSink->DataSinkType() );
       
    72     TBool isRedEncoder 
       
    73         = ( TUid::Uid( KImplUidRedPayloadFormatEncode ) == aSink->DataSinkType() );
       
    74     
       
    75     if ( iIsRtpSink )
       
    76         {
       
    77         CMccRtpDataSink* tmp = static_cast<CMccRtpDataSink*>( aSink );
       
    78         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    79         }
       
    80     else if ( isRedEncoder )
       
    81         {
       
    82         CMccRedPayloadWrite* tmp = static_cast<CMccRedPayloadWrite*>( aSink );
       
    83         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    84         iIsRtpSink = ETrue;
       
    85         }
       
    86     else
       
    87         {
       
    88         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
    89             RDebug::Print( _L("CG711PayloadFormatWrite::ConstructL, sink not RTP one") );
       
    90         #endif
       
    91         }
       
    92     
       
    93     iClip = aSink;
       
    94 
       
    95     // Initialize state machine
       
    96     iStateMachine = CFormatEncodeStateMachine::NewL( this );
       
    97     iStateMachine->ChangeState( EEncodeIdle );
       
    98     };
       
    99         
       
   100 // -----------------------------------------------------------------------------
       
   101 // CIlbcPayloadFormatWrite::NewL
       
   102 // Two-phased constructor.
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 CIlbcPayloadFormatWrite* CIlbcPayloadFormatWrite::NewL( MDataSink* aSink )
       
   106     {
       
   107     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   108         RDebug::Print( _L("CIlbcPayloadFormatWrite::NewL") );
       
   109     #endif
       
   110 
       
   111     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
   112     
       
   113     CIlbcPayloadFormatWrite* self = new ( ELeave ) CIlbcPayloadFormatWrite();
       
   114     CleanupStack::PushL( self );
       
   115     self->ConstructL ( aSink );
       
   116     CleanupStack::Pop( self );
       
   117     return self;
       
   118     };
       
   119 
       
   120 // Destructor
       
   121 CIlbcPayloadFormatWrite::~CIlbcPayloadFormatWrite()
       
   122     {
       
   123     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   124         RDebug::Print( _L("CIlbcPayloadFormatWrite::~CIlbcPayloadFormatWrite") );
       
   125     #endif
       
   126 
       
   127     if ( iStateMachine )
       
   128         {
       
   129         iStateMachine->Cancel();
       
   130         }
       
   131 
       
   132     // Media clock is not owned
       
   133     if ( iRtpMediaClock )
       
   134         {
       
   135         iRtpMediaClock->UnregisterMediaFormat( iKey );
       
   136         }
       
   137     
       
   138     delete iSourceBuffer;
       
   139     delete iSinkBuffer;
       
   140     delete iStateMachine;
       
   141     }
       
   142 
       
   143 // -----------------------------------------------------------------------------
       
   144 // CIlbcPayloadFormatWrite::SinkThreadLogon
       
   145 // Passes the logon command to the sink clip
       
   146 // -----------------------------------------------------------------------------
       
   147 //
       
   148 TInt CIlbcPayloadFormatWrite::SinkThreadLogon( 
       
   149     MAsyncEventHandler& aEventHandler )
       
   150     {
       
   151     iClip->SinkThreadLogon( aEventHandler );
       
   152     return KErrNone;
       
   153     }
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // CIlbcPayloadFormatWrite::SinkThreadLogoff
       
   157 // Passes the logoff command to the sink clip
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 void CIlbcPayloadFormatWrite::SinkThreadLogoff()
       
   161     {
       
   162     iClip->SinkThreadLogoff();
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CIlbcPayloadFormatWrite::CreateSinkBufferL
       
   167 // Create a sink buffer
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 CMMFBuffer* CIlbcPayloadFormatWrite::CreateSinkBufferL( TMediaId aMediaId, 
       
   171         TBool &aReference )
       
   172     {
       
   173     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   174         {
       
   175         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   176             RDebug::Print (_L ("CIlbcPayloadFormatWrite::CreateSinkBufferL KErrNotSupported"));
       
   177         #endif
       
   178         
       
   179         User::Leave( KErrNotSupported );
       
   180         return NULL;
       
   181         }
       
   182     else
       
   183         {
       
   184         aReference = ETrue;
       
   185         
       
   186         // Create buffer for data transfer between UL datapth and FormatWrite.
       
   187         // 30ms mode buffers can be used also for 20ms mode.
       
   188         if ( KiLBCBitrateWith30ms == iCInfo.iBitrate ||
       
   189              KiLBCBitrateWith20ms == iCInfo.iBitrate )
       
   190             {
       
   191             return CreateSinkBufferOfSizeL( 
       
   192                     KiLBCNumOfHeaderBytes + KiLBCFrameSize30ms );
       
   193             }
       
   194         else
       
   195             {
       
   196             #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   197                 RDebug::Print (_L ("CIlbcPayloadFormatWrite::CreateSinkBufferL KErrNotReady"));
       
   198             #endif
       
   199         
       
   200             User::Leave( KErrNotReady );
       
   201             return NULL;
       
   202             }
       
   203         }
       
   204     }
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CIlbcPayloadFormatWrite::CreateSinkBufferOfSizeL
       
   208 // Create a sink buffer of the given size.
       
   209 // -----------------------------------------------------------------------------
       
   210 //
       
   211 CMMFDataBuffer* CIlbcPayloadFormatWrite::CreateSinkBufferOfSizeL( TUint aSize )
       
   212     {
       
   213     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   214         RDebug::Print( _L("CIlbcPayloadFormatWrite::CreateSinkBufferOfSizeL") );
       
   215     #endif
       
   216     
       
   217     // Needs to create source buffer
       
   218     if ( !iSourceBuffer )
       
   219 	    {  
       
   220 	    iSourceBuffer = CMMFDataBuffer::NewL( aSize );
       
   221     	iSourceBuffer->Data().FillZ( aSize );
       
   222     	iSourceBuffer->SetRequestSizeL( aSize );
       
   223 	    }
       
   224 	    
       
   225     return iSourceBuffer;
       
   226     }
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CIlbcPayloadFormatWrite::EmptyBufferL
       
   230 // Empty the given source buffer
       
   231 // -----------------------------------------------------------------------------
       
   232 //
       
   233 void CIlbcPayloadFormatWrite::EmptyBufferL( CMMFBuffer* aBuffer, 
       
   234         MDataSource* aSupplier, TMediaId aMediaId )
       
   235     {
       
   236     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   237         RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptyBufferL aBuffer = 0x%x"),
       
   238             aBuffer );
       
   239     #endif
       
   240     
       
   241     __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
       
   242     __ASSERT_ALWAYS ( aBuffer == iSourceBuffer, User::Leave( KErrArgument ) );
       
   243     __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) );
       
   244     __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType,
       
   245         User::Leave( KErrNotSupported ) );
       
   246     
       
   247     // Save source buffer parameters and change the state.
       
   248     iDataPath = aSupplier;
       
   249     iMediaId = aMediaId;
       
   250     iSourceBuffer = static_cast<CMMFDataBuffer*>( aBuffer );
       
   251     
       
   252     if ( !iSinkBuffer )
       
   253         {
       
   254         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   255             RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptyBufferL, sink not ready!") );
       
   256         #endif
       
   257         iStateMachine->ChangeState( ESourceBufferEmptied );
       
   258         return;
       
   259         }
       
   260     
       
   261     TUint32 ts = 0;
       
   262     User::LeaveIfError( iRtpMediaClock->GetTimeStamp( iKey, ts ) );
       
   263 
       
   264     if ( iRtpMediaClock->TimeBasedIncrement() )
       
   265     	{
       
   266     	iFirstPacketFinished = EFalse;
       
   267     	}
       
   268     
       
   269     if ( 0 == iFrameIndex )
       
   270         {
       
   271         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   272             RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptyBufferL, SetTimeToPlay") );
       
   273         #endif
       
   274         
       
   275         iSinkBuffer->SetTimeToPlay( TInt64( ts ) );
       
   276         iSinkBuffer->SetFrameNumber( aBuffer->FrameNumber() );
       
   277         }
       
   278     else
       
   279         {
       
   280         iSourceBuffer->SetTimeToPlay( TInt64( ts ) );
       
   281         }
       
   282     
       
   283     iStateMachine->ChangeState( EEmptySourceBuffer );
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CIlbcPayloadFormatWrite::SetSinkDataTypeCode
       
   288 // Set the sink data type to the given four CC code for the given media
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 TInt CIlbcPayloadFormatWrite::SetSinkDataTypeCode( TFourCC aSinkFourCC, 
       
   292     TMediaId aMediaId )
       
   293     {
       
   294     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   295         RDebug::Print (_L ("CIlbcPayloadFormatWrite::SetSinkDataTypeCode()"));
       
   296     #endif
       
   297 
       
   298     if ( KUidMediaTypeAudio != aMediaId.iMediaType ) 
       
   299         {
       
   300         return KErrNotSupported;
       
   301         }
       
   302     
       
   303     iFourCC = aSinkFourCC;
       
   304     return KErrNone;
       
   305     }
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CIlbcPayloadFormatWrite::SinkDataTypeCode
       
   309 // Return the sink data type (four CC code) for the given media
       
   310 // -----------------------------------------------------------------------------
       
   311 //
       
   312 TFourCC CIlbcPayloadFormatWrite::SinkDataTypeCode( TMediaId aMediaId )
       
   313     {
       
   314     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   315         {
       
   316         return iFourCC;
       
   317         }
       
   318     else
       
   319         {
       
   320         return TFourCC(); //defaults to 'NULL' fourCC
       
   321         }
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CIlbcPayloadFormatWrite::BufferEmptiedL
       
   326 // Called after payload buffer is completely emptied by RtpDataSink.
       
   327 // -----------------------------------------------------------------------------
       
   328 //
       
   329 void CIlbcPayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
       
   330     {
       
   331     
       
   332     }
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // CIlbcPayloadFormatWrite::NumChannels
       
   336 // Returns number of channels
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 TUint CIlbcPayloadFormatWrite::NumChannels()
       
   340     {
       
   341     return KMono;
       
   342     }
       
   343 
       
   344 // -----------------------------------------------------------------------------
       
   345 // CIlbcPayloadFormatWrite::SampleRate
       
   346 // Returns SampleRate
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 TUint CIlbcPayloadFormatWrite::SampleRate()
       
   350     {
       
   351     return KiLBCSampleRate;
       
   352     }
       
   353 
       
   354 // -----------------------------------------------------------------------------
       
   355 // CIlbcPayloadFormatWrite::SetSampleRate
       
   356 // Set SampleRate
       
   357 // -----------------------------------------------------------------------------
       
   358 //
       
   359 TInt CIlbcPayloadFormatWrite::SetSampleRate( TUint aSampleRate )
       
   360     {
       
   361     return ( KiLBCSampleRate == aSampleRate ) ? KErrNone : KErrNotSupported;
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CIlbcPayloadFormatWrite::FrameTimeInterval
       
   366 // Return the frame time interval for the given media
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 TTimeIntervalMicroSeconds CIlbcPayloadFormatWrite::FrameTimeInterval(
       
   370     TMediaId aMediaId ) const
       
   371     {
       
   372     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   373         {
       
   374         return iFrameTimeInterval;
       
   375         }
       
   376     else
       
   377         {
       
   378         return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   379         }
       
   380     }
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CIlbcPayloadFormatWrite::Duration
       
   384 // Return the frame time interval for the given media
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 TTimeIntervalMicroSeconds CIlbcPayloadFormatWrite::Duration(
       
   388     TMediaId /*aMediaType*/) const
       
   389     {
       
   390     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   391     }
       
   392 
       
   393 
       
   394 // -----------------------------------------------------------------------------
       
   395 // CIlbcPayloadFormatWrite::EmptySourceBufferL
       
   396 // Empty the given sourcebuffer
       
   397 // Sourcebuffer is given in iSourceBuffer
       
   398 // Called by statemachine
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 void CIlbcPayloadFormatWrite::EmptySourceBufferL()
       
   402     {
       
   403     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   404         RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptySourceBufferL - SIZE OF SRC BUF: %d"), 
       
   405             iSourceBuffer->Data().Size() );
       
   406     #endif
       
   407 
       
   408     TPtrC8 audioFrame( iSourceBuffer->Data().Mid( KiLBCNumOfHeaderBytes ) );
       
   409     TPtrC8 frameHeader = iSourceBuffer->Data().Left( KiLBCNumOfHeaderBytes );
       
   410     TDes8& destDes = iSinkBuffer->Data();
       
   411     
       
   412     if ( audioFrame.Size() > destDes.MaxSize() - destDes.Size() || !frameHeader.Length() )
       
   413         {
       
   414         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   415         RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptySourceBufferL \
       
   416             AUDIOFRAME DOES NOT FIT TO SINK BUF") );
       
   417         RDebug::Print( _L("%d > %d || !%d"), audioFrame.Size(), destDes.MaxSize()-destDes.Size(),
       
   418             !frameHeader.Length() );
       
   419         #endif
       
   420         }
       
   421     else
       
   422         {
       
   423         if ( KAudioFrameHeaderByte == frameHeader[0] )
       
   424             {
       
   425             #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   426                 RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptySourceBufferL AUDIO FRAME") );
       
   427             #endif
       
   428             if ( iCNModeON )
       
   429                 {
       
   430                 iCNModeON = EFalse;
       
   431                 iFirstPacketFinished = EFalse;
       
   432                 }
       
   433 
       
   434             destDes.Append( audioFrame );
       
   435             iFrameIndex++;
       
   436             }
       
   437         else if ( KCNoiseFrameHeaderByte == frameHeader[0] )
       
   438             {
       
   439             #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   440                 RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptySourceBufferL CNOISE FRAME") );
       
   441             #endif
       
   442             if ( destDes.Size() )
       
   443                 {
       
   444                 // Send audio frames first
       
   445                 DeliverPacketL( *iSinkBuffer );
       
   446                 iSinkBuffer->SetTimeToPlay( iSourceBuffer->TimeToPlay() );
       
   447                 }
       
   448             
       
   449             iCNModeON = ETrue;
       
   450             destDes.Append( audioFrame );
       
   451 
       
   452             // Only one comfort noise frame per RTP packet
       
   453             iFrameIndex = iFramesPerPacket;
       
   454             }
       
   455         else
       
   456             {
       
   457             #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   458                 RDebug::Print( _L("CIlbcPayloadFormatWrite::EmptySourceBufferL NULL BIT RATE FRAME") );
       
   459             #endif
       
   460             }        
       
   461         }
       
   462     
       
   463     if ( iFrameIndex == iFramesPerPacket )
       
   464         {
       
   465         // Reset variables
       
   466         iFrameIndex = 0;
       
   467         this->DeliverPacketL( *iSinkBuffer );
       
   468         destDes.Zero();
       
   469         }
       
   470 
       
   471     iStateMachine->ChangeState( ESourceBufferEmptied );
       
   472     }
       
   473 
       
   474 // -----------------------------------------------------------------------------
       
   475 // CIlbcPayloadFormatWrite::DeliverPacketL
       
   476 // Prepare the packet header and deliver the packet to the datasink.
       
   477 // -----------------------------------------------------------------------------
       
   478 //
       
   479 void CIlbcPayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload )
       
   480     {
       
   481     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   482         RDebug::Print( _L("CIlbcPayloadFormatWrite::DeliverPacketL - TSTAMP: %u"),
       
   483             static_cast<TUint32>( aPayload.TimeToPlay().Int64() ) );
       
   484     #endif
       
   485     
       
   486     if ( !iClip )
       
   487         {
       
   488         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   489             RDebug::Print( _L("CIlbcPayloadFormatWrite::DeliverPacketL - NO DATASINK") );
       
   490         #endif
       
   491         User::Leave( KErrNotReady );
       
   492         }
       
   493     
       
   494     // Construct RTP header.
       
   495     if ( !iFirstPacketFinished && !iCNModeON )
       
   496         {
       
   497         iRtpSendHeader.iMarker = 1;
       
   498         iFirstPacketFinished = ETrue;
       
   499         }
       
   500     else
       
   501         {
       
   502         iRtpSendHeader.iMarker = 0;
       
   503         }
       
   504     
       
   505     if ( !iRtpDataSink )
       
   506         {
       
   507         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   508             RDebug::Print( _L("CIlbcPayloadFormatWrite::DeliverPacketL - NO DATASINK") );
       
   509         #endif
       
   510         User::Leave( KErrNotReady );
       
   511         }
       
   512     
       
   513     iRtpSendHeader.iTimestamp 
       
   514         = static_cast<TUint32>( aPayload.TimeToPlay().Int64() );
       
   515     
       
   516     if ( iCNModeON )
       
   517         {
       
   518         if ( iCInfo.iComfortNoiseGenerationPt != KPayloadTypeUndefined )
       
   519             {
       
   520             iRtpSendHeader.iPayloadType = iCInfo.iComfortNoiseGenerationPt;
       
   521             
       
   522             if ( aPayload.Data().Size() )
       
   523                 {
       
   524                 if ( iIsRtpSink )
       
   525                     {
       
   526                     iRtpDataSink->EmptyBufferL( &aPayload, this, iMediaId, iRtpSendHeader );
       
   527                     }
       
   528                 else
       
   529                     {
       
   530             	    aPayload.SetLastBuffer( iRtpSendHeader.iMarker );
       
   531                     iClip->EmptyBufferL( &aPayload, this, iMediaId );
       
   532                     }
       
   533                 }
       
   534             }
       
   535         }
       
   536     else
       
   537         {
       
   538         iRtpSendHeader.iPayloadType = iCInfo.iPayloadType;
       
   539         
       
   540         if ( aPayload.Data().Size() )
       
   541             {
       
   542             if ( iIsRtpSink )
       
   543                 {
       
   544                 iRtpDataSink->EmptyBufferL( &aPayload, this, iMediaId, iRtpSendHeader );
       
   545                 }
       
   546             else
       
   547                 {
       
   548         	    aPayload.SetLastBuffer( iRtpSendHeader.iMarker );
       
   549                 iClip->EmptyBufferL( &aPayload, this, iMediaId );
       
   550                 }
       
   551             }
       
   552 
       
   553         }          
       
   554 
       
   555     // Reset the payload buffer -- only if previous EmptyBufferL() is a 
       
   556     // synchronous call
       
   557     aPayload.Data().Zero();
       
   558     }
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // CIlbcPayloadFormatWrite::SourceBufferEmptiedL
       
   562 // Handle the event that sourcebuffer has been emptied.
       
   563 // Sourcebuffer is given in "iSourceBuffer".
       
   564 // Called by the statemachine.
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 void CIlbcPayloadFormatWrite::SourceBufferEmptiedL()
       
   568     {
       
   569     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   570         RDebug::Print( _L("CIlbcPayloadFormatWrite::SourceBufferEmptiedL") );
       
   571     #endif
       
   572 
       
   573     iDataPath->BufferEmptiedL( iSourceBuffer );
       
   574     }
       
   575 
       
   576 // -----------------------------------------------------------------------------
       
   577 // CIlbcPayloadFormatWrite::SinkPrimeL
       
   578 // Prime sink
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CIlbcPayloadFormatWrite::SinkPrimeL()
       
   582     {
       
   583     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   584         RDebug::Print (_L ("CIlbcPayloadFormatWrite::SinkPrimeL()"));
       
   585     #endif
       
   586     
       
   587     iClip->SinkPrimeL();
       
   588     }
       
   589 
       
   590 // -----------------------------------------------------------------------------
       
   591 // CIlbcPayloadFormatWrite::SinkPlayL
       
   592 // Start playing
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 void CIlbcPayloadFormatWrite::SinkPlayL()
       
   596     {
       
   597     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   598         RDebug::Print (_L ("CIlbcPayloadFormatWrite::SinkPlayL()"));
       
   599     #endif
       
   600     
       
   601     // Allocate buffer for data transfer between 
       
   602     // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
   603     delete iSinkBuffer;
       
   604     iSinkBuffer = NULL;
       
   605     iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iFrameSize * iFramesPerPacket );
       
   606     
       
   607     // Start state machine
       
   608     iStateMachine->ChangeState( EEncodeIdle );
       
   609     // RTP Header marker-bit must be set to 1 when starting stream
       
   610     iFirstPacketFinished = EFalse;
       
   611     
       
   612     // Start a new cycle of frame collecting
       
   613     iFrameIndex = 0;
       
   614     
       
   615     if ( iSinkBuffer )
       
   616         {
       
   617         iSinkBuffer->SetLastBuffer( EFalse );
       
   618         }
       
   619 
       
   620     iClip->SinkPlayL();
       
   621     }
       
   622 
       
   623 // -----------------------------------------------------------------------------
       
   624 // CIlbcPayloadFormatWrite::SinkPauseL
       
   625 // Pause sink
       
   626 // -----------------------------------------------------------------------------
       
   627 //
       
   628 void CIlbcPayloadFormatWrite::SinkPauseL()
       
   629     {
       
   630     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   631         RDebug::Print( _L("CIlbcPayloadFormatWrite::SinkPauseL") );
       
   632     #endif
       
   633     
       
   634     iStateMachine->Cancel();
       
   635     iStateMachine->ChangeState( EEncodeIdle );
       
   636     
       
   637     iClip->SinkPauseL();
       
   638     }
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 // CIlbcPayloadFormatWrite::SinkStopL
       
   642 // Stop sink
       
   643 // -----------------------------------------------------------------------------
       
   644 //
       
   645 void CIlbcPayloadFormatWrite::SinkStopL()
       
   646     {
       
   647     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   648         RDebug::Print( _L("CIlbcPayloadFormatWrite::SinkStopL") );
       
   649     #endif
       
   650     
       
   651     // Stop state machine
       
   652     iStateMachine->Cancel();
       
   653     iStateMachine->ChangeState( EEncodeIdle );
       
   654     iClip->SinkStopL();
       
   655     }
       
   656  
       
   657 // -----------------------------------------------------------------------------
       
   658 // CIlbcPayloadFormatWrite::ConfigurePayloadFormatL
       
   659 // Configure payload encoding parameters.
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 void CIlbcPayloadFormatWrite::ConfigurePayloadFormatL( const TDesC8& aConfigParams, 
       
   663     CMccRtpMediaClock& aClock )
       
   664     {
       
   665     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   666         RDebug::Print( _L("CIlbcPayloadFormatWrite::ConfigurePayloadFormatL IN") );
       
   667     #endif    
       
   668     __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
       
   669         User::Leave( KErrArgument ) );
       
   670         
       
   671     iRtpMediaClock = &aClock; 
       
   672     
       
   673     TMccCodecInfoBuffer infoBuffer;
       
   674     infoBuffer.Copy( aConfigParams );
       
   675     
       
   676     if ( !infoBuffer().iIsUpdate )
       
   677         {
       
   678         DoConfigurePayloadFormatL( infoBuffer() );
       
   679         }
       
   680     else
       
   681         {
       
   682         UpdateConfigurationL( infoBuffer() );
       
   683         }  
       
   684     
       
   685     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   686     RDebug::Print( _L("CIlbcPayloadFormatWrite::ConfigurePayloadFormatL OUT") );
       
   687     #endif 
       
   688     }
       
   689 
       
   690 // -----------------------------------------------------------------------------
       
   691 // CIlbcPayloadFormatWrite::UpdateConfigurationL
       
   692 // Update payload encoding parameters
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 void CIlbcPayloadFormatWrite::UpdateConfigurationL( const TMccCodecInfo& aCodecInfo )
       
   696     {
       
   697     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   698         RDebug::Print( _L("CIlbcPayloadFormatWrite::UpdateConfigurationL") );
       
   699     #endif
       
   700     
       
   701     iCInfo.iPayloadType = aCodecInfo.iPayloadType;
       
   702     
       
   703     if ( iCInfo.iMaxPtime != aCodecInfo.iMaxPtime ||
       
   704          iCInfo.iPtime != aCodecInfo.iPtime ||
       
   705          iCInfo.iHwFrameTime != aCodecInfo.iHwFrameTime ||
       
   706          iCInfo.iBitrate != aCodecInfo.iBitrate ||
       
   707          iCInfo.iComfortNoiseGenerationPt != aCodecInfo.iComfortNoiseGenerationPt )
       
   708         {
       
   709         DoConfigurePayloadFormatL( aCodecInfo );
       
   710         
       
   711         // Allocate buffer for data transfer between 
       
   712         // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
   713         delete iSinkBuffer;
       
   714         iSinkBuffer = NULL;
       
   715         iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iFrameSize * iFramesPerPacket );
       
   716         
       
   717         // Start a new cycle of frame collecting
       
   718         iFrameIndex = 0; 
       
   719         }
       
   720 
       
   721     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   722     RDebug::Print( _L("CIlbcPayloadFormatWrite::UpdateConfigurationL OUT") );
       
   723     #endif
       
   724     } 
       
   725 
       
   726 // -----------------------------------------------------------------------------
       
   727 // CIlbcPayloadFormatWrite::DoConfigurePayloadFormatL
       
   728 // -----------------------------------------------------------------------------
       
   729 //   
       
   730 void CIlbcPayloadFormatWrite::DoConfigurePayloadFormatL( const TMccCodecInfo& aCodecInfo )
       
   731     {
       
   732     __ASSERT_ALWAYS( aCodecInfo.iHwFrameTime != 0, User::Leave( KErrArgument ) );
       
   733     
       
   734     iCInfo = aCodecInfo;   
       
   735     iKey = iRtpMediaClock->RegisterMediaFormat( KiLBCSampleRate, iCInfo.iHwFrameTime ); 
       
   736 
       
   737     if ( KiLBCBitrateWith20ms == iCInfo.iBitrate )
       
   738         {
       
   739         iCInfo.iHwFrameTime = KiLBCFrameTime20ms;
       
   740         // Maximum number of frames in RTP payload
       
   741         iFramesPerPacket = iCInfo.iPtime / iCInfo.iHwFrameTime;
       
   742         iCInfo.iFrameSize = KiLBCFrameSize20ms;
       
   743         iFrameTimeInterval = TInt64( KiLBCFrameTime20ms * TUint8( iFramesPerPacket ) );
       
   744         }
       
   745     else if ( KiLBCBitrateWith30ms == iCInfo.iBitrate )
       
   746         {
       
   747         iCInfo.iHwFrameTime = KiLBCFrameTime30ms;
       
   748         // Maximum number of frames in RTP payload
       
   749         iFramesPerPacket = iCInfo.iPtime / iCInfo.iHwFrameTime;
       
   750         iCInfo.iFrameSize = KiLBCFrameSize30ms;
       
   751         iFrameTimeInterval = TInt64( KiLBCFrameTime30ms * TUint8( iFramesPerPacket ) );
       
   752         }
       
   753     else
       
   754         {
       
   755         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   756             RDebug::Print( _L("CIlbcPayloadFormatWrite::ConfigurePayloadFormatL - BITRATE INVALID: %d"), iCInfo.iBitrate );
       
   757         #endif 
       
   758         User::Leave( KErrArgument );
       
   759         }
       
   760 
       
   761     if ( EGenRedUsed == iCInfo.iAlgoUsed )
       
   762         {
       
   763         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_WRITE
       
   764             RDebug::Print( _L("CIlbcPayloadFormatWrite::ConfigurePayloadFormatL, RED LEVEL: %d"), 
       
   765                 iCInfo.iRedundancyCount );
       
   766         #endif 
       
   767         
       
   768         CPayloadFormatWrite* redEncoder
       
   769             = static_cast<CMccRedPayloadWrite*>( iClip );
       
   770         
       
   771         TMccRedPayloadWriteConfig config;
       
   772         config.iRedBlockCount = iCInfo.iRedundancyCount;
       
   773         config.iMaxPayloadSize = iCInfo.iFrameSize * iFramesPerPacket;
       
   774         config.iNumOfEncodings = 1;
       
   775         config.iRedPayloadType = iCInfo.iRedundantPayload;
       
   776         config.InitPayloadTypes();
       
   777         config.iEncPayloadTypes[0] = iCInfo.iPayloadType;
       
   778         TMccRedPayloadWritePckg pckg( config );
       
   779         redEncoder->ConfigurePayloadFormatL( pckg, *iRtpMediaClock );
       
   780         }
       
   781     }
       
   782     
       
   783 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   784 
       
   785 //  End of File