multimediacommscontroller/mmccilbcpayloadformat/src/ilbcpayloadformatread.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:    PayloadFormat component capable to read RTP payload containing
       
    15 *                ILBC audio.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include    "ilbcpayloadformatread.h"
       
    24 #include    "mccrtpdatasource.h"
       
    25 #include    "ilbcpayloadformatutil.h"
       
    26 #include    "mccinternaldef.h"
       
    27 #include    "mccdef.h"
       
    28 #include    "mccredpayloadread.h"
       
    29 
       
    30 // MACROS
       
    31 #ifdef _DEBUG
       
    32 #define TRACE_ILBC_PAYLOAD_FORMAT_READ
       
    33 #endif
       
    34 
       
    35 
       
    36 // FORWARD DECLARATIONS
       
    37 
       
    38 // ============================= LOCAL FUNCTIONS ===============================
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CIlbcPayloadFormatRead::CIlbcPayloadFormatRead
       
    44 // C++ default constructor can NOT contain any code, that
       
    45 // might leave.
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CIlbcPayloadFormatRead::CIlbcPayloadFormatRead () : 
       
    49         iMediaId( KUidMediaTypeAudio )
       
    50     {
       
    51     
       
    52     };
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CIlbcPayloadFormatRead::ConstructL
       
    56 // Symbian 2nd phase constructor can leave.
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 void CIlbcPayloadFormatRead::ConstructL( MDataSource* aSource )
       
    60     {
       
    61     __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
       
    62     
       
    63     iClip = aSource;
       
    64     iBufferToReadExists = EFalse;
       
    65     
       
    66     iFourCC.Set( KMccFourCCIdILBC );
       
    67     
       
    68     // Initialize decoding state machine
       
    69     iStateMachine = CFormatDecodeStateMachine::NewL( this );
       
    70     iStateMachine->ChangeState( EDecodeIdle );
       
    71     
       
    72     iCurrentBuffer = EBufferOne;
       
    73     }
       
    74     
       
    75 // -----------------------------------------------------------------------------
       
    76 // CIlbcPayloadFormatRead::NewL
       
    77 // Two-phased constructor.
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 CIlbcPayloadFormatRead* CIlbcPayloadFormatRead::NewL( MDataSource* aSource )
       
    81     {
       
    82     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
    83         RDebug::Print( _L("CIlbcPayloadFormatRead::NewL") );
       
    84     #endif
       
    85     
       
    86     __ASSERT_ALWAYS( aSource, User::Leave( KErrArgument ) );
       
    87 
       
    88     CIlbcPayloadFormatRead* self = new ( ELeave ) CIlbcPayloadFormatRead();
       
    89     CleanupStack::PushL( self );
       
    90     self->ConstructL( aSource );
       
    91     CleanupStack::Pop( self );
       
    92     return self;
       
    93     };
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CIlbcPayloadFormatRead::~CIlbcPayloadFormatRead()
       
    97 // Destructor.
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 CIlbcPayloadFormatRead::~CIlbcPayloadFormatRead()
       
   101     {
       
   102     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   103         RDebug::Print( _L("CIlbcPayloadFormatRead::~CIlbcPayloadFormatRead") );
       
   104     #endif
       
   105     
       
   106     delete iFrameBufferOne;
       
   107     delete iFrameBufferTwo;
       
   108     if ( iSourceBufOwnership )
       
   109         {
       
   110         delete iSourceBuffer;
       
   111         }
       
   112     else
       
   113         {
       
   114         iSourceBuffer = NULL;
       
   115         }
       
   116     
       
   117     delete iStateMachine;
       
   118     iClip = NULL;
       
   119 	iFrameArray.Close();
       
   120     };
       
   121     
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CIlbcPayloadFormatRead::SendDataToSinkL
       
   125 // Send full frame buffer to DataPath.
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 void CIlbcPayloadFormatRead::SendDataToSinkL()
       
   129     {
       
   130     if ( iCurrentBuffer == EBufferOne )
       
   131         {
       
   132         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   133             RDebug::Print( _L( "CIlbcPayloadFormatRead::SendDataToSinkL - BufferOne") );
       
   134         #endif
       
   135         
       
   136         iDataPath->BufferFilledL( iFrameBufferOne );
       
   137         iCurrentBuffer = EBufferTwo;
       
   138         if ( iBufferToReadExists && !iFrameBufferOne->LastBuffer() )
       
   139             {
       
   140             // More payload buffer is ready
       
   141             iStateMachine->ChangeState( ESourceDataReady );
       
   142             }
       
   143         }
       
   144     else
       
   145         {
       
   146         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   147             RDebug::Print( _L( "CIlbcPayloadFormatRead::SendDataToSinkL - BufferTwo") );
       
   148         #endif
       
   149 
       
   150         iDataPath->BufferFilledL( iFrameBufferTwo );
       
   151         iCurrentBuffer = EBufferOne;
       
   152         if ( iBufferToReadExists && !iFrameBufferTwo->LastBuffer() )
       
   153             {
       
   154             // More payload buffer is ready
       
   155             iStateMachine->ChangeState( ESourceDataReady );
       
   156             }
       
   157         }
       
   158     }
       
   159 
       
   160 // -----------------------------------------------------------------------------
       
   161 // CIlbcPayloadFormatRead::FillSinkBuffer
       
   162 // Fill SinkBuffer.
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 void CIlbcPayloadFormatRead::FillSinkBufferL()
       
   166     {
       
   167     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   168         RDebug::Print( _L( "CIlbcPayloadFormatRead::FillSinkBuffer" ) );
       
   169     #endif
       
   170 
       
   171     CMMFDataBuffer* curFrameBuffer;
       
   172     if ( EBufferOne == iCurrentBuffer )
       
   173         {
       
   174         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   175             RDebug::Print( _L( "IlbcPayloadFormatRead: Filling EBufferOne reqsize: %d"),
       
   176                 iFrameBufferOne->RequestSize() );
       
   177         #endif
       
   178             
       
   179         curFrameBuffer = iFrameBufferOne;
       
   180         }
       
   181     else
       
   182         {
       
   183         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   184             RDebug::Print( _L("IlbcPayloadFormatRead: Filling EBufferTwo reqsize: %d"),
       
   185                 iFrameBufferTwo->RequestSize() );
       
   186         #endif
       
   187 
       
   188         curFrameBuffer = iFrameBufferTwo;
       
   189         }
       
   190     
       
   191     TDes8& dataDes = curFrameBuffer->Data();
       
   192        
       
   193     dataDes.Zero();
       
   194     dataDes.SetLength( KiLBCNumOfHeaderBytes );
       
   195 
       
   196     // Put next frame decoded from RTP payload to the framebuffer
       
   197     iBufferToReadExists = GetNextFrame( dataDes );
       
   198     
       
   199     if ( iCnFrame )
       
   200         {
       
   201         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   202             RDebug::Print( _L ("CIlbcPayloadFormatRead::FillSinkBuffer - ADD CNOISE FRAME HEADER") );
       
   203         #endif
       
   204         dataDes[0] = KCNoiseFrameHeaderByte;
       
   205         dataDes[1] = 0;
       
   206         }
       
   207     else
       
   208         {
       
   209         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   210             RDebug::Print( _L ("CIlbcPayloadFormatRead::FillSinkBuffer - ADD AUDIO FRAME HEADER") );
       
   211         #endif        
       
   212         dataDes[0] = KAudioFrameHeaderByte;
       
   213         dataDes[1] = 0;
       
   214         }
       
   215 
       
   216     curFrameBuffer->SetFrameNumber( iRecvHeader.iTimestamp + ( ( iFrameIndex - 1 )
       
   217                                     * TUint( iCInfo.iHwFrameTime * KiLBCSampleRate * 0.001 ) ) );
       
   218 
       
   219     if ( KIlbcMode20msFrame == iCInfo.iCodecMode  )
       
   220         {
       
   221         dataDes.SetLength( KiLBCFrameSize20ms + KiLBCNumOfHeaderBytes );
       
   222         }
       
   223     else if( KIlbcMode30msFrame == iCInfo.iCodecMode )
       
   224         {
       
   225         dataDes.SetLength( KiLBCFrameSize30ms + KiLBCNumOfHeaderBytes );
       
   226         }
       
   227     else
       
   228         {
       
   229         // Make PC-LINT happy
       
   230         }        
       
   231         
       
   232     curFrameBuffer->SetStatus( EFull );
       
   233     iStateMachine->ChangeState( EEmptyDataToSink );
       
   234 
       
   235     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   236         RDebug::Print( _L ("CIlbcPayloadFormatRead::FillSinkBuffer - DONE") );
       
   237     #endif
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // CIlbcPayloadFormatRead::FillSourceBufferL
       
   242 // Send fill buffer request to RTP Data Source.
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 void CIlbcPayloadFormatRead::FillSourceBufferL()
       
   246     {
       
   247     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   248         RDebug::Print ( _L("CIlbcPayloadFormatRead::FillSourceBufferL") );
       
   249     #endif
       
   250 
       
   251     // RtpSourceSink doesn't really need the Media Id.        
       
   252     iClip->FillBufferL( iSourceBuffer, this, iMediaId );
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CIlbcPayloadFormatRead::SourcePrimeL
       
   257 // Prime source.
       
   258 // -----------------------------------------------------------------------------
       
   259 //
       
   260 void CIlbcPayloadFormatRead::SourcePrimeL()
       
   261     {
       
   262     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   263         RDebug::Print (_L ("CIlbcPayloadFormatRead::SourcePrimeL()"));
       
   264     #endif
       
   265     
       
   266     iClip->SourcePrimeL();
       
   267     }
       
   268 
       
   269 // -----------------------------------------------------------------------------
       
   270 // CIlbcPayloadFormatRead::SourcePlayL
       
   271 // Start playing.
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 void CIlbcPayloadFormatRead::SourcePlayL()
       
   275     {
       
   276     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   277         RDebug::Print (_L ("CIlbcPayloadFormatRead::SourcePlayL()"));
       
   278     #endif
       
   279 
       
   280     iClip->SourcePlayL();
       
   281     }
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 // CIlbcPayloadFormatRead::SourcePauseL
       
   285 // Pause source.
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 void CIlbcPayloadFormatRead::SourcePauseL()
       
   289     {
       
   290     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   291         RDebug::Print( _L("CIlbcPayloadFormatRead::SourcePauseL") );
       
   292     #endif
       
   293     
       
   294     iStateMachine->Cancel();
       
   295     iStateMachine->ChangeState( EDecodeIdle );
       
   296     
       
   297     iFrameBufferOne->SetLastBuffer( EFalse );
       
   298     iFrameBufferTwo->SetLastBuffer( EFalse );
       
   299 
       
   300     iFrameBufferOne->SetStatus( EAvailable );
       
   301     iFrameBufferTwo->SetStatus( EAvailable );
       
   302 
       
   303     iBufferToReadExists = EFalse;
       
   304     iCurrentBuffer = EBufferOne;
       
   305     
       
   306     iClip->SourcePauseL();
       
   307     }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 // CIlbcPayloadFormatRead::SourceStopL
       
   311 // Stop source.
       
   312 // -----------------------------------------------------------------------------
       
   313 //
       
   314 void CIlbcPayloadFormatRead::SourceStopL()
       
   315     {
       
   316     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   317         RDebug::Print( _L("CIlbcPayloadFormatRead::SourceStopL") );
       
   318     #endif
       
   319     
       
   320     // DO NOT RESET PACKET COUNT BACK TO ZERO HERE
       
   321     // UPPER LAYER MAY CALL LastDlPacketCount LATER
       
   322     iStateMachine->Cancel();
       
   323     iStateMachine->ChangeState( EDecodeIdle );
       
   324     
       
   325     iFrameBufferOne->SetLastBuffer( EFalse );
       
   326     iFrameBufferTwo->SetLastBuffer( EFalse );
       
   327 
       
   328     iFrameBufferOne->SetStatus( EAvailable );
       
   329     iFrameBufferTwo->SetStatus( EAvailable );
       
   330 
       
   331     iBufferToReadExists = EFalse;
       
   332     iCurrentBuffer = EBufferOne;
       
   333 
       
   334     iClip->SourceStopL();
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CIlbcPayloadFormatRead::BufferFilledL
       
   339 // RTP data source has filled buffer.
       
   340 // NOTE: Although redundancy is negotiated, sender may deside to send audio 
       
   341 // packets without redundancy (RFC2198, ch5).
       
   342 // -----------------------------------------------------------------------------
       
   343 //
       
   344 void CIlbcPayloadFormatRead::DataBufferFilledL( CMMFBuffer* aBuffer,
       
   345                                             const TRtpRecvHeader& aRecvHeader )
       
   346     {
       
   347     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   348         RDebug::Print (_L ("CIlbcPayloadFormatRead::DataBufferFilledL - TSTAMP: %u"),
       
   349             aRecvHeader.iTimestamp );
       
   350     #endif
       
   351     
       
   352     __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
       
   353     __ASSERT_ALWAYS( KUidMmfDataBuffer == aBuffer->Type(), 
       
   354         User::Leave( KErrNotSupported ) );
       
   355     __ASSERT_ALWAYS( iSourceBuffer == aBuffer, User::Leave( KErrArgument ) );
       
   356     
       
   357     iRecvHeader = aRecvHeader;
       
   358     if ( KComfortNoisePT == iRecvHeader.iPayloadType 
       
   359         || KOldComfortNoisePT == iRecvHeader.iPayloadType )
       
   360         {
       
   361         iCnFrame = ETrue;
       
   362         }
       
   363     else 
       
   364         {
       
   365         iCnFrame = EFalse;
       
   366         }
       
   367 
       
   368     iNumOfFrames = DecodePayload( iSourceBuffer->Data() );
       
   369 
       
   370     // Whenever BufferFilledL is called from RtpSourceSink
       
   371     // Set the state machine to fillsinkbuffer
       
   372     if ( iNumOfFrames )
       
   373         {
       
   374         iBufferToReadExists = ETrue;
       
   375         iSourceBuffer->SetFrameNumber( iRecvHeader.iTimestamp );
       
   376         iStateMachine->ChangeState( ESourceDataReady );
       
   377         }
       
   378     else
       
   379         {
       
   380         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   381         RDebug::Print ( _L("CIlbcPayloadFormatRead::BufferFilledL, decode failed" ) );
       
   382         #endif
       
   383         
       
   384         FillSourceBufferL();
       
   385         }
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CIlbcPayloadFormatRead::SampleRate
       
   390 // Returns samplerate.
       
   391 // -----------------------------------------------------------------------------
       
   392 //
       
   393 TUint CIlbcPayloadFormatRead::SampleRate()
       
   394     {
       
   395     return KiLBCSampleRate;
       
   396     }  
       
   397 
       
   398 // -----------------------------------------------------------------------------
       
   399 // CIlbcPayloadFormatRead::SetSampleRate
       
   400 // Set samplerate.
       
   401 // -----------------------------------------------------------------------------
       
   402 //
       
   403 TInt CIlbcPayloadFormatRead::SetSampleRate( TUint aSampleRate )
       
   404     {
       
   405     return ( KiLBCSampleRate == aSampleRate ) ? KErrNone : KErrNotSupported;
       
   406     }
       
   407 
       
   408 // -----------------------------------------------------------------------------
       
   409 // CIlbcPayloadFormatRead::NumChannels
       
   410 // Returns number of channels.
       
   411 // -----------------------------------------------------------------------------
       
   412 //
       
   413 TUint CIlbcPayloadFormatRead::NumChannels()
       
   414     {
       
   415     return KMono;
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // CIlbcPayloadFormatRead::SourceThreadLogoff
       
   420 // Logout the source thread.
       
   421 // -----------------------------------------------------------------------------
       
   422 //
       
   423 void CIlbcPayloadFormatRead::SourceThreadLogoff()
       
   424     {
       
   425     iClip->SourceThreadLogoff();
       
   426     }
       
   427     
       
   428 // -----------------------------------------------------------------------------
       
   429 // CIlbcPayloadFormatRead::NegotiateSourceL
       
   430 // Negotiate Source. Not used.
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 void CIlbcPayloadFormatRead::NegotiateSourceL( MDataSink& aDataSink )
       
   434     {
       
   435     iSink = &aDataSink;
       
   436     iClip->NegotiateSourceL( *this );
       
   437     }
       
   438 
       
   439 // -----------------------------------------------------------------------------
       
   440 // CIlbcPayloadFormatRead::SourceThreadLogon
       
   441 // Logon the source thread.
       
   442 // -----------------------------------------------------------------------------
       
   443 //
       
   444 TInt CIlbcPayloadFormatRead::SourceThreadLogon(
       
   445                                         MAsyncEventHandler& aEventHandler
       
   446                                         )
       
   447     {
       
   448     if ( iClip )
       
   449         {
       
   450         iClip->SourceThreadLogon( aEventHandler );
       
   451 		return KErrNone;
       
   452         }
       
   453     else
       
   454         {
       
   455         return KErrNotReady;
       
   456         }        
       
   457     }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // CIlbcPayloadFormatRead::SetSourceDataTypeCode
       
   461 // Sets source datatype fourCC code.
       
   462 // -----------------------------------------------------------------------------
       
   463 //
       
   464 TInt CIlbcPayloadFormatRead::SetSourceDataTypeCode( TFourCC aSourceFourCC,
       
   465     TMediaId aMediaId )
       
   466     {
       
   467     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   468         RDebug::Print (_L ("CIlbcPayloadFormatRead::SetSourceDataTypeCode()"));
       
   469     #endif
       
   470     
       
   471     if ( KUidMediaTypeAudio != aMediaId.iMediaType ) 
       
   472         {
       
   473         return KErrNotSupported;
       
   474         }
       
   475 
       
   476     iFourCC = aSourceFourCC;
       
   477     iMediaId = aMediaId;
       
   478 
       
   479     iClip->SetSourceDataTypeCode( iFourCC, aMediaId );
       
   480     
       
   481     return KErrNone;
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CIlbcPayloadFormatRead::SourceDataTypeCode
       
   486 // Returns the current datatype FourCC code.
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 TFourCC CIlbcPayloadFormatRead::SourceDataTypeCode( TMediaId aMediaId )
       
   490     {
       
   491     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   492         {
       
   493         return iFourCC;
       
   494         }
       
   495     else
       
   496         {
       
   497         return TFourCC(); //defaults to 'NULL' fourCC
       
   498         }
       
   499     }
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CIlbcPayloadFormatRead::SinkDataTypeCode
       
   503 // Returns the current datatype FourCC code.
       
   504 // -----------------------------------------------------------------------------
       
   505 //
       
   506 TFourCC CIlbcPayloadFormatRead::SinkDataTypeCode( TMediaId aMediaId )
       
   507     {
       
   508     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   509         {
       
   510         return iFourCC;
       
   511         }
       
   512     else
       
   513         {
       
   514         return TFourCC(); //defaults to 'NULL' fourCC
       
   515         }
       
   516     }
       
   517     
       
   518 // -----------------------------------------------------------------------------
       
   519 // CIlbcPayloadFormatRead::CreateSourceBufferL
       
   520 // Create a source buffer for the given media and indicate in aReference 
       
   521 // if buffer is created.
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 CMMFBuffer* CIlbcPayloadFormatRead::CreateSourceBufferL( TMediaId aMediaId,
       
   525     TBool &aReference )
       
   526     {
       
   527     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   528         {
       
   529         User::Leave( KErrNotSupported );
       
   530         }
       
   531 
       
   532     // the source buffers belong to IlbcPayloadFormatRead, not to datapath
       
   533     // reference should be set to ETrue and destroyed by IlbcPayloadFormatRead
       
   534     // itself.
       
   535     aReference = ETrue;
       
   536     return iFrameBufferOne; 
       
   537     }
       
   538 
       
   539 // -----------------------------------------------------------------------------
       
   540 // CIlbcPayloadFormatRead::CreateSourceBufferL
       
   541 // Create a source buffer for the given media, setting frame size to match
       
   542 // the given sink buffer.
       
   543 // -----------------------------------------------------------------------------
       
   544 //
       
   545 CMMFBuffer* CIlbcPayloadFormatRead::CreateSourceBufferL(TMediaId aMediaId,
       
   546     CMMFBuffer& /*aSinkBuffer*/, TBool& aReference)
       
   547     {
       
   548     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   549         {
       
   550         User::Leave( KErrNotSupported );
       
   551         }
       
   552         
       
   553     return CreateSourceBufferL( aMediaId, aReference );
       
   554     }
       
   555 
       
   556 // -----------------------------------------------------------------------------
       
   557 // CIlbcPayloadFormatRead::FillBufferL
       
   558 // Fill Buffer.
       
   559 // -----------------------------------------------------------------------------
       
   560 //
       
   561 void CIlbcPayloadFormatRead::FillBufferL( CMMFBuffer* aBuffer, 
       
   562     MDataSink* aConsumer, TMediaId aMediaId )
       
   563     {
       
   564     if ( !aBuffer ) 
       
   565         {
       
   566         User::Leave( KErrGeneral );
       
   567         }
       
   568 
       
   569     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   570     RDebug::Print( _L("CIlbcPayloadFormatRead::FillBufferL aBuffer 0x%x length %d bytes"),
       
   571         aBuffer, aBuffer->BufferSize() );
       
   572     #endif
       
   573 
       
   574     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   575         {
       
   576         User::Leave( KErrNotSupported );
       
   577         }
       
   578 
       
   579     if ( KUidMmfDataBuffer != aBuffer->Type() )
       
   580         {
       
   581         User::Leave( KErrNotSupported );
       
   582         }
       
   583 
       
   584     iDataPath = aConsumer;
       
   585 
       
   586     // aBuffer is a reference to those frame buffers that 
       
   587     // IlbcPayloadFormatRead owns
       
   588     aBuffer->SetLastBuffer( EFalse );
       
   589 
       
   590     if ( EBufferOne == iCurrentBuffer )
       
   591         {
       
   592         iFrameBufferTwo->SetStatus( EAvailable );
       
   593         }
       
   594     else
       
   595         {
       
   596         iFrameBufferOne->SetStatus( EAvailable );
       
   597         }
       
   598 
       
   599     if ( iBufferToReadExists )
       
   600         {
       
   601         // All decoded frame are not passed to the datapath
       
   602         iStateMachine->ChangeState( ESourceDataReady );
       
   603         }
       
   604     else
       
   605         {
       
   606         // Time to ask more payload from datasource
       
   607         FillSourceBufferL();
       
   608         } 
       
   609     }
       
   610 
       
   611 // -----------------------------------------------------------------------------
       
   612 // CIlbcPayloadFormatRead::Streams
       
   613 // Return number of audio streams for the given media.
       
   614 // -----------------------------------------------------------------------------
       
   615 //
       
   616 TUint CIlbcPayloadFormatRead::Streams( TUid aMediaType ) const
       
   617     {
       
   618     // Need to check aMediaType for audio
       
   619     if ( KUidMediaTypeAudio == aMediaType )
       
   620         {
       
   621         return 1;
       
   622         }
       
   623     else
       
   624         {
       
   625         return 0;
       
   626         }
       
   627     }
       
   628 
       
   629 // -----------------------------------------------------------------------------
       
   630 // CIlbcPayloadFormatRead::FrameTimeInterval
       
   631 // Return the frame time interval for the given media.
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 TTimeIntervalMicroSeconds CIlbcPayloadFormatRead::FrameTimeInterval(
       
   635     TMediaId aMediaId ) const
       
   636     {
       
   637     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   638         {
       
   639         return iFrameTimeInterval;
       
   640         }
       
   641     else
       
   642         {
       
   643         return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   644         }
       
   645     }
       
   646 
       
   647 // -----------------------------------------------------------------------------
       
   648 // CIlbcPayloadFormatRead::Duration
       
   649 // Return the frame time interval for the given media
       
   650 // NOT SUPPORTED
       
   651 // -----------------------------------------------------------------------------
       
   652 //
       
   653 TTimeIntervalMicroSeconds CIlbcPayloadFormatRead::Duration(
       
   654     TMediaId /*aMediaType*/) const
       
   655     {
       
   656     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   657     }
       
   658     
       
   659 // -----------------------------------------------------------------------------
       
   660 // CIlbcPayloadFormatRead::DecodePayload
       
   661 // Decodes all audio frames from the received RTP payload buffer. Decoded
       
   662 // audio frames are saved to the internal array so that audio frames can be
       
   663 // requested one at a time with GetNextFrame() -method.
       
   664 // No assumption about frame count in RTP packet is done.
       
   665 // -----------------------------------------------------------------------------
       
   666 //
       
   667 TInt CIlbcPayloadFormatRead::DecodePayload( const TDesC8& aSourceBuffer )
       
   668     {
       
   669     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   670         RDebug::Print( _L("CIlbcPayloadFormatRead::DecodePayload Src Size: %d" ),
       
   671             aSourceBuffer.Size() );
       
   672     #endif
       
   673     
       
   674     iFrameIndex = 0;
       
   675     
       
   676     const TUint8* framePtr = aSourceBuffer.Ptr();
       
   677     const TUint payloadSize( aSourceBuffer.Size() );
       
   678     const TUint8* endPtr = aSourceBuffer.Ptr() + payloadSize;
       
   679     
       
   680     // Calculate parameters for frame ripping
       
   681     TInt frames( 0 );
       
   682     TUint frameSize( 0 );
       
   683     
       
   684     // Frames of different modes MUST NOT be included within the same payload
       
   685     frameSize = payloadSize % KiLBCFrameSize20ms ? KiLBCFrameSize30ms : KiLBCFrameSize20ms;
       
   686     frames = payloadSize / frameSize;
       
   687     
       
   688     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   689         RDebug::Print( _L("CILBCPayloadFormatRead::DecodePayload framesize: %d, frames: %d" ),
       
   690             frameSize, frames );
       
   691     #endif
       
   692     
       
   693     // Construct pointers to frames in payload
       
   694     while ( frames-- )
       
   695         {
       
   696         TPtr8 bufPtr( const_cast<TUint8*>(framePtr), frameSize, frameSize );
       
   697         iFrameArray.Append( bufPtr );
       
   698 
       
   699         framePtr += frameSize;
       
   700         
       
   701         if ( framePtr >= endPtr )
       
   702             {
       
   703             frames = 0;
       
   704             }
       
   705         }
       
   706         
       
   707     return iFrameArray.Count();
       
   708     }
       
   709 
       
   710 // -----------------------------------------------------------------------------
       
   711 // CIlbcPayloadFormatRead::GetNextFrameL
       
   712 // Passes next audio frame decoded with DecodePayload(). Return ETrue if decoded
       
   713 // frames are remaining.
       
   714 // -----------------------------------------------------------------------------
       
   715 //
       
   716 TBool CIlbcPayloadFormatRead::GetNextFrame( TDes8& aToBuffer )
       
   717     {
       
   718     iFrameIndex++;
       
   719     
       
   720     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   721         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame - FrameCount: %d"),
       
   722             iFrameArray.Count() );
       
   723         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame - FrameIndex: %d"),
       
   724             iFrameIndex );
       
   725     #endif    
       
   726     
       
   727     const TInt frmCount = iFrameArray.Count();
       
   728     const TInt toMax = aToBuffer.MaxLength();
       
   729     if ( iFrameIndex < frmCount &&
       
   730         ( iFrameArray[iFrameIndex - 1].MaxLength() <= toMax ) )
       
   731         {
       
   732         aToBuffer.Append( iFrameArray[iFrameIndex - 1] );
       
   733         return ETrue;
       
   734         }
       
   735     else if ( iFrameIndex == frmCount &&
       
   736         ( iFrameArray[iFrameIndex - 1].MaxLength() <= toMax ) )
       
   737         {
       
   738         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   739         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame SRC_LEN: %d"),
       
   740             iFrameArray[iFrameIndex - 1].Length() );
       
   741         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame SRC_MAX: %d"),
       
   742             iFrameArray[iFrameIndex - 1].MaxLength() );
       
   743         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame DEST_LEN: %d"),
       
   744             aToBuffer.Length() );
       
   745         RDebug::Print( _L("CILBCPayloadFormatRead::GetNextFrame DEST_MAX: %d"),
       
   746             aToBuffer.MaxLength() );
       
   747         #endif
       
   748 
       
   749         aToBuffer.Append( iFrameArray[iFrameIndex - 1] );
       
   750         iFrameArray.Reset();
       
   751         return EFalse;
       
   752         }
       
   753     else
       
   754         {
       
   755         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   756             RDebug::Print( _L ( "CILBCPayloadFormatRead::GetNextFrame FALSE" ));
       
   757         #endif
       
   758         
       
   759         iFrameArray.Reset(); 
       
   760         return EFalse;
       
   761         }        
       
   762     }
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // CIlbcPayloadFormatRead::ConfigurePayloadFormatL
       
   766 // Configure payload decoding parameters.
       
   767 // -----------------------------------------------------------------------------
       
   768 //
       
   769 void CIlbcPayloadFormatRead::ConfigurePayloadFormatL(
       
   770     const TDesC8& aConfigParams )
       
   771     {
       
   772     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   773         RDebug::Print( _L("CIlbcPayloadFormatRead::ConfigurePayloadFormatL IN") );
       
   774     #endif
       
   775     
       
   776     __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
       
   777         User::Leave( KErrArgument ) );
       
   778         
       
   779     TMccCodecInfoBuffer infoBuffer;
       
   780     infoBuffer.Copy( aConfigParams );
       
   781     
       
   782     if ( !infoBuffer().iIsUpdate )
       
   783         {
       
   784         DoConfigurePayloadFormatL( infoBuffer() );
       
   785         }
       
   786     else
       
   787         {
       
   788         UpdateConfigurationL( infoBuffer() );
       
   789         }
       
   790     
       
   791     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   792     RDebug::Print( _L("CIlbcPayloadFormatRead::ConfigurePayloadFormatL OUT") );
       
   793     #endif
       
   794     }
       
   795 
       
   796 // -----------------------------------------------------------------------------
       
   797 // CIlbcPayloadFormatRead::UpdateConfigurationL
       
   798 // Update payload decoder parameters
       
   799 // -----------------------------------------------------------------------------
       
   800 //
       
   801 void CIlbcPayloadFormatRead::UpdateConfigurationL(
       
   802     const TMccCodecInfo& aCodecInfo )
       
   803     {
       
   804     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   805     RDebug::Print( _L("CIlbcPayloadFormatRead::UpdateConfigurationL IN") );
       
   806     #endif
       
   807     
       
   808     if ( iCInfo.iMaxPtime != aCodecInfo.iMaxPtime ||
       
   809          iCInfo.iPtime != aCodecInfo.iPtime ||
       
   810          iCInfo.iHwFrameTime != aCodecInfo.iHwFrameTime ||
       
   811          iCInfo.iBitrate != aCodecInfo.iBitrate )
       
   812         {
       
   813         // Reconfigure payload formatter and update the sourcebuffer fill
       
   814         // request so that multiplexer gets a update to the possibly changed
       
   815         // buffer.
       
   816         DoConfigurePayloadFormatL( aCodecInfo );
       
   817         FillSourceBufferL();
       
   818         }
       
   819     
       
   820     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   821     RDebug::Print( _L("CIlbcPayloadFormatRead::UpdateConfigurationL OUT") );
       
   822     #endif
       
   823     }
       
   824 
       
   825 // -----------------------------------------------------------------------------
       
   826 // CIlbcPayloadFormatRead::DoConfigurePayloadFormatL
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 void CIlbcPayloadFormatRead::DoConfigurePayloadFormatL( const TMccCodecInfo& aCodecInfo )
       
   830     {
       
   831     __ASSERT_ALWAYS( aCodecInfo.iHwFrameTime != 0, User::Leave( KErrArgument ) );
       
   832     
       
   833     iCInfo = aCodecInfo;
       
   834     
       
   835     // Maximum number of frames in RTP payload
       
   836     const TUint pktCount = TUint8( iCInfo.iMaxPtime / iCInfo.iHwFrameTime );
       
   837     
       
   838     if ( KiLBCBitrateWith20ms == iCInfo.iBitrate )
       
   839         {
       
   840         iCInfo.iHwFrameTime = KiLBCFrameTime20ms;    
       
   841         iCInfo.iFrameSize = KiLBCFrameSize20ms;
       
   842         iFrameTimeInterval = (TInt64) KiLBCFrameTime20ms * pktCount;
       
   843         }
       
   844     else if ( KiLBCBitrateWith30ms == iCInfo.iBitrate )
       
   845         {
       
   846         iCInfo.iHwFrameTime = KiLBCFrameTime30ms;
       
   847         iCInfo.iFrameSize = KiLBCFrameSize30ms;
       
   848         iFrameTimeInterval = (TInt64) KiLBCFrameTime30ms * pktCount;
       
   849 		}
       
   850     else
       
   851         {
       
   852         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   853             RDebug::Print( _L("CIlbcPayloadFormatRead::DoConfigurePayloadFormatL KErrNotSupported") );
       
   854         #endif
       
   855         User::Leave( KErrNotSupported );
       
   856         }        
       
   857     
       
   858     // Create two frame buffers used in data transfer with datapath.
       
   859     // Space for two byte additional header needed by HW codec is reserved.
       
   860     // 30ms mode buffers can be used also for 20ms mode
       
   861     if ( !iFrameBufferOne && !iFrameBufferTwo )
       
   862         {
       
   863         iFrameBufferOne = 
       
   864             CMMFDataBuffer::NewL( KiLBCFrameSize30ms + KiLBCNumOfHeaderBytes );
       
   865         iFrameBufferTwo = 
       
   866             CMMFDataBuffer::NewL( KiLBCFrameSize30ms + KiLBCNumOfHeaderBytes );
       
   867         }
       
   868     
       
   869     // PayloadBuffer contains data received from network
       
   870     TInt plSize = iCInfo.iFrameSize * pktCount;
       
   871     
       
   872     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   873         RDebug::Print( _L("CILBCPayloadFormatRead::DoConfigurePayloadFormatL FramesPerPacket: %d" ), pktCount );
       
   874         RDebug::Print( _L("CILBCPayloadFormatRead::DoConfigurePayloadFormatL FrameSize: %d" ), iCInfo.iFrameSize );
       
   875     #endif
       
   876     
       
   877     if ( EGenRedUsed == iCInfo.iAlgoUsed )
       
   878         {
       
   879         #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   880         RDebug::Print( _L("CG711PayloadFormatRead::DoConfigurePayloadFormatL, RED LEVEL: %d"),
       
   881             iCInfo.iRedundancyCount );
       
   882         #endif
       
   883         if ( iCInfo.iRedundancyCount )
       
   884             {
       
   885             plSize *= iCInfo.iRedundancyCount;
       
   886             }
       
   887         
       
   888         CPayloadFormatRead* redDecoder 
       
   889             = static_cast<CPayloadFormatRead*>( iClip );
       
   890         
       
   891         TMccRedPayloadReadConfig config;
       
   892         config.iRedBlockCount = iCInfo.iRedundancyCount;
       
   893         config.iMaxPayloadSize = iCInfo.iFrameSize * pktCount;
       
   894         config.iNumOfEncodings = 1;
       
   895         config.iRedPayloadType = iCInfo.iRedundantPayload;
       
   896         config.InitPayloadTypes();
       
   897         config.iEncPayloadTypes[0] = iCInfo.iPayloadType;
       
   898         TMccRedPayloadReadPckg pckg( config );
       
   899         redDecoder->ConfigurePayloadFormatL( pckg );
       
   900         }
       
   901     
       
   902     // PayloadBuffer contains data received from network
       
   903     if ( iSourceBufOwnership )
       
   904         {
       
   905         delete iSourceBuffer;
       
   906         }
       
   907         
       
   908     iSourceBuffer = NULL;
       
   909     iSourceBuffer = CreateClipBufferL( plSize, iSourceBufOwnership );
       
   910     }
       
   911     
       
   912 // -----------------------------------------------------------------------------
       
   913 // CIlbcPayloadFormatRead::CreateClipBufferL
       
   914 // Creates buffer needed in data transfer with format readers clip.
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 CMMFDataBuffer* CIlbcPayloadFormatRead::CreateClipBufferL( 
       
   918         TUint aSize, TBool& aIsOwnBuffer )
       
   919     {
       
   920     #ifdef TRACE_ILBC_PAYLOAD_FORMAT_READ
       
   921         RDebug::Print( _L("CIlbcPayloadFormatRead::CreateClipBufferL") );
       
   922     #endif
       
   923     
       
   924     CMMFDataBuffer* buffer( NULL );
       
   925     if ( iClip->CanCreateSourceBuffer() )
       
   926         {
       
   927         static_cast<CMMFFormatDecode*>( iClip )->SuggestSourceBufferSize( aSize );
       
   928         
       
   929         TBool reference( EFalse );
       
   930         CMMFBuffer* sourceBuf 
       
   931             = iClip->CreateSourceBufferL( KUidMediaTypeAudio, reference );
       
   932         TBool isSupportedBuf 
       
   933             = CMMFBuffer::IsSupportedDataBuffer( sourceBuf->Type() );
       
   934         TBool isOwnBuffer = reference ? EFalse : ETrue;
       
   935         
       
   936         if ( !isSupportedBuf )
       
   937             {
       
   938             if ( isOwnBuffer )
       
   939                 {
       
   940                 delete sourceBuf;
       
   941                 }
       
   942             
       
   943             User::Leave( KErrNotSupported );
       
   944             }
       
   945         
       
   946         aIsOwnBuffer = isOwnBuffer;
       
   947         buffer = static_cast<CMMFDataBuffer*>( sourceBuf );
       
   948         }
       
   949     else
       
   950         {
       
   951         aIsOwnBuffer = ETrue;
       
   952         buffer = CMMFDataBuffer::NewL( aSize );
       
   953         }
       
   954     
       
   955     return buffer;
       
   956     }
       
   957     
       
   958 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   959 
       
   960 //  End of File