multimediacommscontroller/mmccamrpayloadformat/src/amrpayloadformatwrite.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2004-2007 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 AMR audio.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include <e32base.h>
       
    24 #include <mmf/common/mmffourcc.h>
       
    25 #include "amrpayloadformatwrite.h"
       
    26 #include "amrpayloadencoder.h"
       
    27 #include "amrpayloadencoderoa.h"
       
    28 #include "amrpayloaddecoder.h"
       
    29 #include "amrcommonutil.h"
       
    30 #include "mccrtpdatasink.h"
       
    31 #include "mccuids.hrh"
       
    32 #include "mccdef.h"
       
    33 #include "mccinternaldef.h"
       
    34 #include "amrpayloadformatter.h"
       
    35 #include "mccrtpmediaclock.h" 
       
    36 #include "mccredpayloadwrite.h"
       
    37 
       
    38 const TUint KSampleRate8kHz = 8;
       
    39 const TUint KSampleRate16kHz = 16;
       
    40 const TReal KTimeMultiplier = 0.001;
       
    41 
       
    42 // MACROS
       
    43 
       
    44 #define MCC_AUDIO_TIMESTAMP( a ) \
       
    45 TUint32( iFramesPerPacket * a * iChannels * \
       
    46          (iIsNb?KSampleRate8kHz:KSampleRate16kHz) * KTimeMultiplier )
       
    47 
       
    48 
       
    49 // ============================= LOCAL FUNCTIONS ===============================
       
    50 
       
    51 // ============================ MEMBER FUNCTIONS ===============================
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CAmrPayloadFormatWrite::CAmrPayloadFormatWrite
       
    55 // C++ default constructor can NOT contain any code, that
       
    56 // might leave.
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 CAmrPayloadFormatWrite::CAmrPayloadFormatWrite( )
       
    60     : iIsNb( ETrue ), iSamplingRate( KAmrNbSampleRate ), iChannels( 1 )
       
    61     {
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CAmrPayloadFormatWrite::ConstructL
       
    66 // Symbian 2nd phase constructor can leave.
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 void CAmrPayloadFormatWrite::ConstructL ( MDataSink* aSink )
       
    70     {
       
    71     // Set default values
       
    72     iFramesPerPacket = 1;
       
    73     iFourCC.Set( TFourCC( ' ','A','M','R' ) );
       
    74     
       
    75     // Set data sink
       
    76     iIsRtpSink = ( KMccRtpSinkUid == aSink->DataSinkType() );
       
    77     TBool isRedEncoder 
       
    78         = ( TUid::Uid( KImplUidRedPayloadFormatEncode ) == aSink->DataSinkType() );
       
    79     
       
    80     if ( iIsRtpSink )
       
    81         {
       
    82         CMccRtpDataSink* tmp = static_cast<CMccRtpDataSink*>( aSink );
       
    83         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    84         }
       
    85     else if ( isRedEncoder )
       
    86         {
       
    87         CMccRedPayloadWrite* tmp = static_cast<CMccRedPayloadWrite*>( aSink );
       
    88         iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
       
    89         iIsRtpSink = ETrue;
       
    90         }
       
    91     else
       
    92         {
       
    93         AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::ConstructL, not RTP sink" )
       
    94         }
       
    95     
       
    96     iClip = aSink;
       
    97     
       
    98     // Set default set of modes
       
    99     for ( TInt i = 0; i < KNumberOfNbModes; i++ )
       
   100         {
       
   101         iModes.Append( KAmrNbModes[i] );
       
   102         }
       
   103     
       
   104     // Initialize state machine
       
   105     iStateMachine = CFormatEncodeStateMachine::NewL( this );
       
   106     iStateMachine->ChangeState( EEncodeIdle );
       
   107     }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CAmrPayloadFormatWrite::NewL
       
   111 // Two-phased constructor.
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 CAmrPayloadFormatWrite* CAmrPayloadFormatWrite::NewL( MDataSink* aSink )
       
   115     {
       
   116     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   117         RDebug::Print( _L("CAmrPayloadFormatWrite::NewL") );
       
   118     #endif
       
   119     
       
   120     __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
       
   121 
       
   122     CAmrPayloadFormatWrite* self = new ( ELeave ) CAmrPayloadFormatWrite;
       
   123     CleanupStack::PushL( self );
       
   124     self->ConstructL( aSink );
       
   125     CleanupStack::Pop( self );
       
   126     return self;
       
   127     }
       
   128 
       
   129 // -----------------------------------------------------------------------------
       
   130 // CAmrPayloadFormatWrite::~CAmrPayloadFormatWrite
       
   131 // Destructor.
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 CAmrPayloadFormatWrite::~CAmrPayloadFormatWrite ( )
       
   135     {
       
   136     delete iSourceBuffer;
       
   137     delete iSinkBuffer;
       
   138     delete iStateMachine;
       
   139     delete iPayloadEncoder;
       
   140     iModes.Close();
       
   141     
       
   142     // Media clock is not owned
       
   143     if ( iRtpMediaClock )
       
   144         {
       
   145         iRtpMediaClock->UnregisterMediaFormat( iKey );
       
   146         }
       
   147     }
       
   148 
       
   149  
       
   150 // -----------------------------------------------------------------------------
       
   151 // CAmrPayloadFormatWrite::FrameTimeInterval
       
   152 // Return the frame time interval for the given media
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 TTimeIntervalMicroSeconds CAmrPayloadFormatWrite::FrameTimeInterval( 
       
   156         TMediaId aMediaId ) const
       
   157     {
       
   158     if ( KUidMediaTypeAudio == aMediaId.iMediaType )
       
   159         {
       
   160         TInt hwFrametime = static_cast<TInt>( iCInfo.iHwFrameTime );
       
   161         return TTimeIntervalMicroSeconds( TInt64( hwFrametime ) );
       
   162         }
       
   163     else
       
   164         {
       
   165         return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   166         }
       
   167     }
       
   168 
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CAmrPayloadFormatWrite::CreateSinkBufferL
       
   172 //
       
   173 // Create a source buffer for the given media and indicate in aReference if buffer
       
   174 // is created.
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 CMMFBuffer* CAmrPayloadFormatWrite::CreateSinkBufferL( TMediaId aMediaId, 
       
   178                                                        TBool &aReference )
       
   179     {
       
   180     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   181         AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::CreateSinkBufferL( )" );
       
   182     #endif
       
   183 
       
   184     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   185         {
       
   186         User::Leave( KErrNotSupported );
       
   187         }
       
   188     // the ownership of iSourceBuffer is in CAmrPayloadFormatWrite
       
   189     aReference = ETrue;
       
   190     return CreateSinkBufferOfSizeL( iCInfo.iFrameSize );
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CAmrPayloadFormatWrite::SinkDataTypeCode
       
   195 // Return the sink data type ( four CC code ) for the given media
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 TFourCC CAmrPayloadFormatWrite::SinkDataTypeCode( TMediaId aMediaId )
       
   199     {
       
   200     if ( KUidMediaTypeAudio == aMediaId.iMediaType ) 
       
   201         {
       
   202          #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   203         	AMR_PAYLOAD_FORMAT_WRITE2( 
       
   204         		"CAmrPayloadFormatWrite::SinkDataTypeCode: 0x%x", iFourCC.FourCC() );
       
   205         #endif
       
   206         return iFourCC;
       
   207         }
       
   208     else 
       
   209         {
       
   210         return TFourCC( ); //defaults to 'NULL' fourCC
       
   211         }
       
   212     }
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // CAmrPayloadFormatWrite::SetSinkDataTypeCode
       
   216 // Set the sink data type to the given four CC code for the given media
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 TInt CAmrPayloadFormatWrite::SetSinkDataTypeCode( TFourCC aSinkFourCC, 
       
   220                                                   TMediaId aMediaId )
       
   221     {
       
   222     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   223         	AMR_PAYLOAD_FORMAT_WRITE2( 
       
   224         		"CAmrPayloadFormatWrite::SetSinkDataTypeCode: 0x%x", 
       
   225         		aSinkFourCC.FourCC() );
       
   226     #endif
       
   227     if ( KUidMediaTypeAudio != aMediaId.iMediaType )
       
   228         {
       
   229         return KErrNotSupported;
       
   230         }
       
   231     else if ( aSinkFourCC == KMccFourCCIdAMRNB )
       
   232         {
       
   233         iFourCC = aSinkFourCC;
       
   234         }
       
   235     else if ( aSinkFourCC == KMccFourCCIdAMRWB )
       
   236         {
       
   237         iFourCC = aSinkFourCC;
       
   238         // Nb modes were set in the construtor. We need to replace them with wb modes.
       
   239         iIsNb = EFalse; 
       
   240         iModes.Reset();
       
   241 	    for ( TInt i = 0; i < KNumberOfWbModes; i++ )
       
   242 	        {
       
   243 	        iModes.Append( KAmrWbModes[i] );
       
   244 	        }
       
   245 	    SetSampleRate( KAmrWbSampleRate );
       
   246         }
       
   247     else
       
   248         {
       
   249         return KErrNotSupported;
       
   250         }
       
   251 
       
   252     return KErrNone;
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CAmrPayloadFormatWrite::SinkThreadLogon
       
   257 // Passes the logon command to the sink clip
       
   258 // -----------------------------------------------------------------------------
       
   259 //
       
   260 TInt CAmrPayloadFormatWrite::SinkThreadLogon( MAsyncEventHandler& aEventHandler )
       
   261     {
       
   262     iClip->SinkThreadLogon( aEventHandler );
       
   263     return KErrNone;
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CAmrPayloadFormatWrite::SinkThreadLogoff
       
   268 // Log out of the sink thread.
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 void CAmrPayloadFormatWrite::SinkThreadLogoff( )
       
   272     {
       
   273     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   274         AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::SinkThreadLogoff " );
       
   275     #endif   
       
   276     
       
   277     iClip->SinkThreadLogoff( );
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CAmrPayloadFormatWrite::ProcessFramesL
       
   282 // Packetize the AMR frames received from AMR codec and deliver the packets.
       
   283 // The AMR frames are stored in "iSourceBuffer".
       
   284 // return value - Current talk spurt finished, ETrue. Otherwise, EFalse.
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 TBool CAmrPayloadFormatWrite::ProcessFramesL()
       
   288     {
       
   289     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   290         AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::ProcessFramesL( ) Begin" );
       
   291     #endif
       
   292 
       
   293     TBool payloadReady( EFalse );
       
   294     TBool isDone( EFalse );
       
   295     TAmrFrameInfo frameInfo;
       
   296 
       
   297     CMMFBuffer* buffer = iSourceBuffer;
       
   298     TDes8& srcDes = ( static_cast<CMMFDataBuffer*>( buffer )->Data() );
       
   299     TInt readLen = srcDes.Length();
       
   300     TInt byteIndex = 0;
       
   301     TInt seekLen = readLen - byteIndex;
       
   302 
       
   303     const TUint8* seekPtr = srcDes.Ptr() + byteIndex;
       
   304 
       
   305     while ( seekLen >= CAmrCommonUtility::FrameHeaderSize() )
       
   306         {
       
   307         // Scan frame by frame until free format frame or EOB detected.
       
   308         TInt length = CAmrCommonUtility::FrameInfo( seekPtr, seekLen, frameInfo, iIsNb );
       
   309         if ( length > 0 && frameInfo.iBitrate > 0 ) // got a frame
       
   310             {
       
   311             TStreamDecoder decoder;
       
   312             decoder.Initialize( seekPtr, 0, 0 );
       
   313             decoder.Decode( 1 );                              // Skip first Padding bit
       
   314             TInt frameType( decoder.Decode( KNumValue4 ) ); // FT value
       
   315             TUint8 qualityInd = TUint8( decoder.Decode( 1 ) );// QualityInd value
       
   316 
       
   317             // Encode a frame, speech data starts from the second byte in a frame
       
   318             TPtr8 dataPtr( const_cast<TUint8*>( seekPtr+1 ), seekLen - 1, seekLen - 1 );
       
   319             
       
   320             #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   321                 RDebug::Print( _L("CAmrPayloadFormatWrite::ProcessFramesL frameType: %d"), frameType );
       
   322             #endif
       
   323             
       
   324             // frameType 8 (SID) or 15 (NO_DATA) tells us that we can set the 
       
   325             // CMR to NO_REQUEST, otherwise we can keep the CMR in which ever
       
   326             // the frameType is as they map directly to each other.
       
   327             // NOTE: There is no clear information on how to set the CMR field
       
   328             // regarding SID or NO_DATA frames. So there might be a possibility
       
   329             // that we should keep the original CMR also for SID and NO_DATA 
       
   330             // frames.
       
   331             
       
   332             // In the old implementation, the iPayloadEncoder used always the
       
   333             // same (moderequest for 12.2kbps) but this should be the correct
       
   334             // way of things.
       
   335             TAmrModeRequest modeReq;
       
   336             if ( ( iIsNb && ( frameType == EAmrFrameNoData || frameType == EAmrFrameSid ) ) ||
       
   337                  ( !iIsNb && ( frameType == EAmrWbFrameNoData || frameType == EAmrWbFrameSid  ) ) )
       
   338                 {
       
   339                 #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   340                     RDebug::Print( _L("CAmrPayloadFormatWrite::ProcessFramesL CMR NO_REQ") );
       
   341                 #endif
       
   342             
       
   343                 modeReq = EAmrModeReqNone;
       
   344                 }
       
   345             else
       
   346                 {
       
   347                 #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   348                     RDebug::Print( _L("CAmrPayloadFormatWrite::ProcessFramesL CMR: %d"), frameType );
       
   349                 #endif
       
   350 
       
   351                 modeReq = static_cast<TAmrModeRequest>( frameType );
       
   352                 }
       
   353                 
       
   354             iPayloadEncoder->SetModeRequest( modeReq );
       
   355             payloadReady = iPayloadEncoder->EncodeFrame( TInt( iCurrentChannel ),
       
   356                     TAmrFrameType( frameType ), qualityInd, dataPtr );
       
   357                     
       
   358      		#ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   359         		AMR_PAYLOAD_FORMAT_WRITE2 ( "CAmrPayloadFormatWrite::ProcessFramesL( ): payloadReady1 = %d ", payloadReady );
       
   360     		#endif
       
   361 
       
   362             // Increase current channel
       
   363             iCurrentChannel++;
       
   364             if ( iCurrentChannel == iChannels )
       
   365                 {
       
   366                 // All channel frames for a frame block are received
       
   367                 iCurrentChannel = 0;
       
   368                 }
       
   369 
       
   370             seekPtr += length; // update byte positions
       
   371             seekLen -= length; // update seek length
       
   372             byteIndex += length;
       
   373             
       
   374             iFramesEncoded++;
       
   375             }
       
   376         else
       
   377             {
       
   378             if ( frameInfo.iBitrate < 0 )
       
   379                 {
       
   380                 #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   381         		AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::ProcessFramesL( ): frameInfo.iBitrate < 0 ");
       
   382     			#endif
       
   383                 break;
       
   384                 }
       
   385             else
       
   386                 {
       
   387                 //  No data frame
       
   388                 TStreamDecoder decoder;
       
   389                 decoder.Initialize( seekPtr, 0, 0 );
       
   390                 decoder.Decode( 1 );                        // Skip first Padding bit
       
   391                 TInt frameType = decoder.Decode( KNumValue4 );       // FT value
       
   392 
       
   393                 if ( frameType != TInt( EAmrFrameNoData ) ) // bad frame
       
   394                     {
       
   395                     #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   396         				AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::ProcessFramesL( ): bad frame ");
       
   397     				#endif
       
   398                     break;
       
   399                     }
       
   400 
       
   401                 // QualityIndicator value
       
   402                 TUint8 qualityInd = TUint8( decoder.Decode( 1 ) );
       
   403                 TPtr8 dummy( 0,0,0 );
       
   404                 payloadReady = iPayloadEncoder->EncodeFrame( TInt( iCurrentChannel ),
       
   405                             TAmrFrameType( frameType ), qualityInd, dummy );
       
   406                             
       
   407                 #ifdef TRACE_AMR_PAYLOAD_FORMAT_WRITE
       
   408         				AMR_PAYLOAD_FORMAT_WRITE2 ( "CAmrPayloadFormatWrite::ProcessFramesL( ): payloadReady2 = %d ", payloadReady);
       
   409     			#endif   
       
   410                 // Increase current channel
       
   411                 iCurrentChannel++;
       
   412                 if ( iCurrentChannel == iChannels )
       
   413                     {
       
   414                     // All channel frames for a frame block are received
       
   415                     iCurrentChannel = 0;
       
   416                     }
       
   417 
       
   418                 seekPtr++;
       
   419                 seekLen--;
       
   420                 byteIndex++;
       
   421 
       
   422                 iFramesEncoded++;
       
   423                 }
       
   424             }
       
   425 
       
   426         if ( payloadReady )
       
   427             {
       
   428             AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::ProcessFramesL: iSinkBuffer1 = %X ", iSinkBuffer );
       
   429             AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::ProcessFramesL: iSourceBuffer = %X ", iSourceBuffer );
       
   430     	    
       
   431     	    if ( !iSinkBuffer )
       
   432                 {
       
   433                 return EFalse;
       
   434                 }
       
   435                 
       
   436             // Payload has been constructed; deliver it to RTP datasink
       
   437             // Update length info of payload buffer.
       
   438             if ( seekLen < CAmrCommonUtility::FrameHeaderSize( ) 
       
   439                 &&  ( iSourceBuffer->LastBuffer( ) || iNeedToFlush ) )
       
   440                 {
       
   441                 // No more AMR frames
       
   442                 iSinkBuffer->SetLastBuffer( ETrue );    
       
   443                 isDone = ETrue;
       
   444                 }
       
   445 
       
   446             TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data( );
       
   447             TDesC8& payloadDes = iPayloadEncoder->PayloadBuffer( );
       
   448             dataDes.SetLength( payloadDes.Length( ) );
       
   449             DeliverPacketL( *iSinkBuffer );
       
   450             }            
       
   451         }
       
   452 
       
   453     // If this is the last buffer, 
       
   454     // Set from datapath or by AmrPayloadFormatWrite itself
       
   455     if ( iSourceBuffer->LastBuffer( ) || iNeedToFlush ) 
       
   456         {
       
   457         AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::ProcessFramesL: iSinkBuffer2 = %X ", iSinkBuffer );
       
   458         
       
   459         isDone = ETrue;
       
   460         if ( iPayloadEncoder->ReEncodeFrameL( ) )
       
   461             {
       
   462             // added for last buffer  
       
   463             // length can not be zero.
       
   464             if ( !iSinkBuffer )
       
   465                 {
       
   466                 return EFalse;
       
   467                 }
       
   468 
       
   469             TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data( );
       
   470             TDesC8& payloadDes = iPayloadEncoder->PayloadBuffer( );
       
   471             dataDes.SetLength( payloadDes.Length( ) );
       
   472             iSinkBuffer->SetLastBuffer( ETrue );   
       
   473             DeliverPacketL( *iSinkBuffer );
       
   474             }
       
   475         }
       
   476 
       
   477     return isDone;
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // CAmrPayloadFormatWrite::DeliverPacketL
       
   482 //
       
   483 // Prepare packet header and deliver the packet to the datasink.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 void CAmrPayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload )
       
   487     {
       
   488     AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::DeliverPacketL - TSTAMP: %u",
       
   489         static_cast<TUint32>( aPayload.TimeToPlay().Int64() ) );
       
   490     
       
   491     // Construct RTP header.
       
   492     if ( !iFirstPacketFinished )
       
   493         {
       
   494         iRtpSendHeader.iMarker = 1;
       
   495         iFirstPacketFinished = ETrue;
       
   496         }
       
   497     else
       
   498         {
       
   499         iRtpSendHeader.iMarker = 0;
       
   500         }
       
   501     
       
   502     iRtpSendHeader.iPayloadType = iCInfo.iPayloadType;
       
   503     iRtpSendHeader.iTimestamp 
       
   504         = static_cast<TUint32>( aPayload.TimeToPlay().Int64() );
       
   505     
       
   506     if ( aPayload.BufferSize() )
       
   507         {  
       
   508         if ( iIsRtpSink )
       
   509             {
       
   510             iRtpDataSink->EmptyBufferL( &aPayload, this, iMediaId, iRtpSendHeader );
       
   511             }
       
   512         else
       
   513             {
       
   514 		    aPayload.SetLastBuffer( iRtpSendHeader.iMarker );
       
   515             iClip->EmptyBufferL( &aPayload, this, iMediaId );
       
   516             }
       
   517         }
       
   518     
       
   519     // Reset the payload buffer as previous EmptyBufferL() is a synchronous call.
       
   520     aPayload.Data().Zero();
       
   521     iPayloadEncoder->ResetPayloadBuffer();
       
   522     }
       
   523 
       
   524 
       
   525 // -----------------------------------------------------------------------------
       
   526 // CAmrPayloadFormatWrite::EmptyBufferL
       
   527 // Empty the given source buffer by formatting the AMR frames into RTP payload.
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 void CAmrPayloadFormatWrite::EmptyBufferL( CMMFBuffer* aBuffer, 
       
   531                                            MDataSource* aSupplier, 
       
   532                                            TMediaId aMediaId )
       
   533     {
       
   534     AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::EmptyBufferL aBuffer = 0x%x", aBuffer );
       
   535     
       
   536     __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
       
   537     __ASSERT_ALWAYS( aBuffer == iSourceBuffer, User::Leave( KErrArgument ) );
       
   538     __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) );
       
   539     __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType, 
       
   540         User::Leave( KErrNotSupported ) );
       
   541     
       
   542     // Save source buffer parameters and change the state.
       
   543     iDataPath = aSupplier;
       
   544     iMediaId = aMediaId;
       
   545     iSourceBuffer = static_cast<CMMFDataBuffer*>( aBuffer );
       
   546     
       
   547     TUint32 ts = 0;
       
   548     if ( iCInfo.iSourceDefinedTimeStamps )
       
   549         {
       
   550         AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::EmptyBufferL source has defined timestamp" );
       
   551         
       
   552         ts = MCC_AUDIO_TIMESTAMP( iSourceBuffer->TimeToPlay().Int64() );
       
   553         iSinkBuffer->SetTimeToPlay( TInt64( ts ) );
       
   554         iSinkBuffer->SetFrameNumber( aBuffer->FrameNumber() );
       
   555         }
       
   556     else if ( iPayloadEncoder->IsStartOfPeriod() )
       
   557         {
       
   558         AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::EmptyBufferL SetTimeToPlay" );
       
   559         
       
   560         User::LeaveIfError( iRtpMediaClock->GetTimeStamp( iKey, ts ) );
       
   561 
       
   562         if ( iRtpMediaClock->TimeBasedIncrement() )
       
   563 	    	{
       
   564     		iFirstPacketFinished = EFalse;
       
   565     		}
       
   566         
       
   567         iSinkBuffer->SetTimeToPlay( TInt64( ts ) );
       
   568         iSinkBuffer->SetFrameNumber( aBuffer->FrameNumber() );
       
   569         }
       
   570     else if( !iCInfo.iSourceDefinedTimeStamps &&
       
   571              !iPayloadEncoder->IsStartOfPeriod() )
       
   572         {
       
   573         User::LeaveIfError( iRtpMediaClock->GetTimeStamp( iKey, ts ) );
       
   574         
       
   575         if ( iRtpMediaClock->TimeBasedIncrement() )
       
   576 	    	{
       
   577     		iFirstPacketFinished = EFalse;
       
   578     		}
       
   579         
       
   580         }
       
   581     else
       
   582         {
       
   583         // nop
       
   584         }
       
   585     
       
   586     iStateMachine->ChangeState( EEmptySourceBuffer );
       
   587     }
       
   588 
       
   589 // -----------------------------------------------------------------------------
       
   590 // CAmrPayloadFormatWrite::EmptySourceBufferL
       
   591 // Empty the given source buffer by formatting the AMR frames into RTP payload.
       
   592 // Source buffer is given in "iSourceBuffer".
       
   593 // Called by the state machine.
       
   594 // -----------------------------------------------------------------------------
       
   595 //
       
   596 void CAmrPayloadFormatWrite::EmptySourceBufferL( )
       
   597     {
       
   598     AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::EmptySourceBufferL SRCBUFLEN:%d", iSourceBuffer->Data().Length() );
       
   599 
       
   600     if ( ProcessFramesL() )
       
   601         {
       
   602         // Current talk spurt is finished. Either last buffer or iNeedToFlush
       
   603         iStateMachine->ChangeState( EEncodeIdle );
       
   604         iClip->SinkStopL();
       
   605         }
       
   606     else
       
   607         {
       
   608         // Just one step in a talk spurt
       
   609         iStateMachine->ChangeState( ESourceBufferEmptied );
       
   610         }
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CAmrPayloadFormatWrite::SourceBufferEmptiedL
       
   615 //
       
   616 // Hanlde the event that source buffer has been emptied.
       
   617 // Source buffer is given in "iSourceBuffer".
       
   618 // Called by the state machine.
       
   619 // -----------------------------------------------------------------------------
       
   620 //
       
   621 void CAmrPayloadFormatWrite::SourceBufferEmptiedL()
       
   622     {
       
   623     AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::SourceBufferEmptiedL" );
       
   624 
       
   625     iDataPath->BufferEmptiedL( iSourceBuffer );
       
   626     }
       
   627 
       
   628 
       
   629 // -----------------------------------------------------------------------------
       
   630 // CAmrPayloadFormatWrite::BufferEmptiedL
       
   631 // Called after payload buffer is completely emptied by RtpDataSink.
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 void CAmrPayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
       
   635     {
       
   636     /* 
       
   637     * We're using synchronous EmptyBufferL( aBuffer ) function call to RTP Sink.
       
   638     * The aBuffer is ready to be used again when the EmptyBufferL returns back.
       
   639     * So BufferEmptiedL( aBuffer ) is not really used.
       
   640     */
       
   641     }
       
   642 
       
   643 
       
   644 // -----------------------------------------------------------------------------
       
   645 // CAmrPayloadFormatWrite::NumChannels
       
   646 // Get the number of channels
       
   647 // -----------------------------------------------------------------------------
       
   648 //
       
   649 TUint CAmrPayloadFormatWrite::NumChannels( )
       
   650     {
       
   651     return KMono;
       
   652     }
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CAmrPayloadFormatWrite::SampleRate
       
   656 // Returns the samplerate
       
   657 // -----------------------------------------------------------------------------
       
   658 //
       
   659 TUint CAmrPayloadFormatWrite::SampleRate( )
       
   660     {
       
   661     return iSamplingRate;
       
   662     }
       
   663 
       
   664 // -----------------------------------------------------------------------------
       
   665 // CAmrPayloadFormatWrite::SetSampleRate
       
   666 // Sets the sample rate, AMR-NB is always 8000Hz
       
   667 // -----------------------------------------------------------------------------
       
   668 //
       
   669 TInt CAmrPayloadFormatWrite::SetSampleRate ( TUint aSampleRate )
       
   670     {
       
   671     if( (iIsNb && KAmrNbSampleRate != aSampleRate) ||
       
   672         (!iIsNb && KAmrWbSampleRate != aSampleRate) )
       
   673         {
       
   674         return KErrNotSupported;
       
   675         }
       
   676     else
       
   677         {
       
   678         iSamplingRate = aSampleRate;
       
   679         return KErrNone;
       
   680         }
       
   681     }
       
   682 
       
   683 // -----------------------------------------------------------------------------
       
   684 // CAmrPayloadFormatWrite::Duration
       
   685 // Return the clip duration for the given media.
       
   686 // -----------------------------------------------------------------------------
       
   687 //
       
   688 TTimeIntervalMicroSeconds CAmrPayloadFormatWrite::Duration( 
       
   689         TMediaId /*aMediaType*/ ) const
       
   690     {
       
   691     return TTimeIntervalMicroSeconds( TInt64( 0 ) );
       
   692     }
       
   693 
       
   694 
       
   695 // -----------------------------------------------------------------------------
       
   696 // CAmrPayloadFormatWrite::CreateSinkBufferOfSizeL
       
   697 // Create a sink buffer of the given size.
       
   698 // -----------------------------------------------------------------------------
       
   699 //
       
   700 CMMFDataBuffer* CAmrPayloadFormatWrite::CreateSinkBufferOfSizeL( TUint aSize )
       
   701     {
       
   702     AMR_PAYLOAD_FORMAT_WRITE ( "CAmrPayloadFormatWrite::CreateSinkBufferOfSizeL" );
       
   703 
       
   704     if ( !iSourceBuffer )
       
   705 	    {  
       
   706 	    iSourceBuffer = CMMFDataBuffer::NewL( aSize );
       
   707     	iSourceBuffer->Data().FillZ( aSize );
       
   708     	iSourceBuffer->SetRequestSizeL( aSize );
       
   709 	    }
       
   710     return iSourceBuffer;
       
   711     }
       
   712 
       
   713 
       
   714 // -----------------------------------------------------------------------------
       
   715 // CAmrPayloadFormatWrite::IsBitrateChangeValid
       
   716 // Checks if codec mode change request is valid.
       
   717 // -----------------------------------------------------------------------------
       
   718 //
       
   719 TBool CAmrPayloadFormatWrite::IsBitrateChangeValid( TInt aBitRate ) 
       
   720     {
       
   721     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::IsBitrateChangeValid" );
       
   722     
       
   723     TInt currentModeIndex = iModes.Find( iCInfo.iBitrate ); 
       
   724     TInt desiredModeIndex = iModes.Find( aBitRate );  
       
   725     
       
   726     TBool modechangeperiodvalid( EFalse );
       
   727     
       
   728     if ( iFirstCmrHandled )
       
   729         {
       
   730         modechangeperiodvalid = !TBool( iFramesEncoded % iCInfo.iModeChangePeriod );
       
   731         }
       
   732     else
       
   733         {
       
   734         // Initialize counter
       
   735         iFramesEncoded = 0;
       
   736         }
       
   737      
       
   738     if ( KErrNotFound == currentModeIndex )            
       
   739         {                        
       
   740         if ( ( modechangeperiodvalid || !iFirstCmrHandled ) &&
       
   741             ( KErrNotFound != desiredModeIndex ) )        
       
   742             {                                         
       
   743             iCInfo.iBitrate = aBitRate;
       
   744             iFirstCmrHandled = ETrue;
       
   745             return ETrue;
       
   746             }
       
   747         else                                          
       
   748             {
       
   749             return EFalse;        
       
   750             }            
       
   751         }
       
   752          
       
   753     if ( ( modechangeperiodvalid || !iFirstCmrHandled ) && ( ( ( iCInfo.iNeighbor ) &&
       
   754         ( desiredModeIndex == currentModeIndex + 1 ) ||
       
   755         ( desiredModeIndex == currentModeIndex - 1 && currentModeIndex != 0 ) ) ||
       
   756         ( !iCInfo.iNeighbor && KErrNotFound != desiredModeIndex  ) ) )
       
   757         {
       
   758         iCInfo.iBitrate = aBitRate;
       
   759         iFirstCmrHandled = ETrue;
       
   760         return ETrue;
       
   761         }
       
   762     else
       
   763         {
       
   764         return EFalse;
       
   765         }               
       
   766     }
       
   767     
       
   768     
       
   769 // -----------------------------------------------------------------------------
       
   770 // CAmrPayloadFormatWrite::CancelUlRequest
       
   771 // Cancel UL Request
       
   772 // -----------------------------------------------------------------------------
       
   773 //
       
   774 void CAmrPayloadFormatWrite::CancelUlRequest( )
       
   775     {
       
   776     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::CancelUlRequest" );
       
   777 
       
   778     iStateMachine->Cancel();
       
   779     iStateMachine->ChangeState( EEncodeIdle );
       
   780 
       
   781     // Reset the payload buffer
       
   782     if ( iSinkBuffer )
       
   783         {
       
   784         TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data();
       
   785         dataDes.SetLength( 0 );
       
   786         // Reset iFrameEncoder
       
   787         iPayloadEncoder->InitializeFrameEncoder();
       
   788         iPayloadEncoder->ResetPayloadBuffer();
       
   789         }
       
   790     };
       
   791 
       
   792 // -----------------------------------------------------------------------------
       
   793 // CAmrPayloadFormatWrite::SinkPrimeL()
       
   794 // Primes sink
       
   795 // -----------------------------------------------------------------------------
       
   796 //
       
   797 void CAmrPayloadFormatWrite::SinkPrimeL()
       
   798     {
       
   799     iClip->SinkPrimeL();
       
   800     };
       
   801 
       
   802 // -----------------------------------------------------------------------------
       
   803 // CAmrPayloadFormatWrite::SinkPlayL()
       
   804 // Plays sink
       
   805 // -----------------------------------------------------------------------------
       
   806 //
       
   807 void CAmrPayloadFormatWrite::SinkPlayL()
       
   808     {
       
   809     AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::SinkPlayL RedCount: %d", iCInfo.iRedundancyCount );
       
   810 
       
   811     // Allocate buffer for data transfer between
       
   812     // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
   813     delete iSinkBuffer;
       
   814     iSinkBuffer = NULL;
       
   815     iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iFrameSize * iFramesPerPacket
       
   816         * ( 1 + iCInfo.iRedundancyCount ) + KNumValue2 );
       
   817 
       
   818     // Initialize payload encoder
       
   819     iPayloadEncoder->Initialize();
       
   820     TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data( );
       
   821     dataDes.SetLength( 0 );   // for first packet length
       
   822     iPayloadEncoder->SetPayloadBuffer( dataDes );
       
   823 	iPayloadEncoder->SetChannelCount( iChannels );
       
   824 
       
   825     // Reset flag
       
   826     iNeedToFlush = EFalse;
       
   827 
       
   828     // Start state machine
       
   829     iStateMachine->ChangeState( EEncodeIdle );
       
   830     iFirstPacketFinished = EFalse;
       
   831 
       
   832     if ( iSinkBuffer )
       
   833         {
       
   834         iSinkBuffer->SetLastBuffer( EFalse );
       
   835         }
       
   836 
       
   837     iClip->SinkPlayL();
       
   838     };
       
   839 
       
   840 // -----------------------------------------------------------------------------
       
   841 // CAmrPayloadFormatWrite::SinkPauseL()
       
   842 // Pauses sink
       
   843 // -----------------------------------------------------------------------------
       
   844 //
       
   845 void CAmrPayloadFormatWrite::SinkPauseL()
       
   846     {
       
   847     this->CancelUlRequest();
       
   848     iClip->SinkPauseL();
       
   849     };
       
   850 
       
   851 // -----------------------------------------------------------------------------
       
   852 // CAmrPayloadFormatWrite::SinkStopL()
       
   853 // Stops sink
       
   854 // -----------------------------------------------------------------------------
       
   855 //
       
   856 void CAmrPayloadFormatWrite::SinkStopL()
       
   857     {
       
   858     if ( EEmptySourceBuffer == iStateMachine->CurrentState() )
       
   859         {
       
   860         iNeedToFlush = ETrue; 
       
   861         return;
       
   862         }
       
   863 
       
   864     if ( ESourceBufferEmptied == iStateMachine->CurrentState() )
       
   865         {
       
   866         // Finished emptying current buffer to RTP
       
   867         // check whether there is internal buffer left
       
   868         if ( iPayloadEncoder->ReEncodeFrameL() )
       
   869             {
       
   870             // length can not be zero.
       
   871             if ( !iSinkBuffer )
       
   872                 {
       
   873                 return;
       
   874                 }
       
   875                 
       
   876             TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data();
       
   877             TDesC8& payloadDes = iPayloadEncoder->PayloadBuffer();
       
   878             dataDes.SetLength( payloadDes.Length() );
       
   879             iSinkBuffer->SetLastBuffer( ETrue );
       
   880 
       
   881             this->DeliverPacketL( *iSinkBuffer );
       
   882 
       
   883             AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::StopUlStream ReEncodeFrame done" );
       
   884             }
       
   885         }
       
   886 
       
   887     // Stop state machine
       
   888     this->CancelUlRequest();
       
   889     iClip->SinkStopL();
       
   890     };
       
   891 
       
   892 // -----------------------------------------------------------------------------
       
   893 // CAmrPayloadFormatWrite::ConfigurePayloadFormatL
       
   894 // Configure payload encoding parameters.
       
   895 // -----------------------------------------------------------------------------
       
   896 //
       
   897 void CAmrPayloadFormatWrite::ConfigurePayloadFormatL( 
       
   898         const TDesC8& aConfigParams, 
       
   899         CMccRtpMediaClock& aClock  )
       
   900     {
       
   901     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::ConfigurePayloadFormatL (NB/WB)" )
       
   902     __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
       
   903         User::Leave( KErrArgument ) );
       
   904     
       
   905     TMccCodecInfoBuffer infoBuffer;
       
   906     infoBuffer.Copy( aConfigParams );  
       
   907         
       
   908     if ( !infoBuffer().iIsUpdate )
       
   909         {
       
   910         __ASSERT_ALWAYS( infoBuffer().iHwFrameTime, User::Leave( KErrArgument ) );
       
   911         __ASSERT_ALWAYS( infoBuffer().iModeChangePeriod, User::Leave( KErrArgument ) );
       
   912         
       
   913         iCInfo = infoBuffer();
       
   914         iRtpMediaClock = &aClock;
       
   915 
       
   916         TUint tempMask(0x0001);
       
   917         // Reset old iModes array if new modes exist
       
   918         if ( iCInfo.iBitrateMask != 0x0000 )
       
   919             {
       
   920             iModes.Reset();
       
   921             }
       
   922         
       
   923         if ( iIsNb )
       
   924         	{
       
   925         	iKey = iRtpMediaClock->RegisterMediaFormat( KAmrNbSampleRate,
       
   926         	                                            iCInfo.iHwFrameTime );
       
   927 
       
   928 	        for ( TInt ii = KNumValue0; ii < KNumberOfNbModes; ii++ )
       
   929 	            {
       
   930 	            if( iCInfo.iBitrateMask & tempMask )
       
   931 	                {
       
   932 	                iModes.AppendL( KAmrNbModes[ii] );
       
   933 	                }
       
   934 	            tempMask*=2;
       
   935 	            }           
       
   936         	}
       
   937         else // Wb
       
   938         	{
       
   939         	iKey = iRtpMediaClock->RegisterMediaFormat( KAmrWbSampleRate, 
       
   940         	                                            iCInfo.iHwFrameTime );
       
   941 
       
   942 	        for ( TInt ii = 0; ii < KNumberOfWbModes; ii++ )
       
   943 	            {
       
   944 	            if( iCInfo.iBitrateMask & tempMask )
       
   945 	                {
       
   946 	                iModes.AppendL( KAmrWbModes[ii] );
       
   947 	                }
       
   948 	            tempMask*=2;
       
   949 	            }           
       
   950         	}
       
   951                                     
       
   952         if ( !iPayloadEncoder )
       
   953             {
       
   954             if( KAmrCodecModeBandwidthEfficient == iCInfo.iCodecMode )
       
   955                 {
       
   956                 iPayloadEncoder = CAmrPayloadEncoder::NewL( iIsNb );
       
   957                 }
       
   958             else if( KAmrCodecModeOctetAlign == iCInfo.iCodecMode )
       
   959                 {
       
   960                 iPayloadEncoder = CAmrPayloadEncoderOA::NewL( iIsNb );
       
   961                 }
       
   962             else
       
   963                 {
       
   964                 User::Leave( KErrArgument );
       
   965                 }    
       
   966             }
       
   967         
       
   968         iFramesPerPacket = iCInfo.iPtime / iCInfo.iHwFrameTime;
       
   969         iPayloadEncoder->SetFrameBlockCount( iFramesPerPacket );
       
   970   
       
   971         if ( EAmrFecUsed == iCInfo.iAlgoUsed && iCInfo.iRedundancyCount > 0 )
       
   972             {
       
   973             AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::ConfigurePayloadFormatL - Using AMR FEC" );
       
   974             iPayloadEncoder->Initialize();
       
   975             User::LeaveIfError( iPayloadEncoder
       
   976                 ->SetRedFrameBlockCount( iCInfo.iRedundancyCount ) );
       
   977             }
       
   978         else if ( EGenRedUsed == iCInfo.iAlgoUsed )
       
   979             {
       
   980             AMR_PAYLOAD_FORMAT_WRITE2( "CAmrPayloadFormatWrite::ConfigurePayloadFormatL, RED LEVEL: %d",
       
   981                 iCInfo.iRedundancyCount );
       
   982             
       
   983             CPayloadFormatWrite* redEncoder
       
   984                 = static_cast<CMccRedPayloadWrite*>( iClip );
       
   985             
       
   986             TMccRedPayloadWriteConfig config;
       
   987             config.iRedBlockCount = iCInfo.iRedundancyCount;
       
   988             config.iMaxPayloadSize = iCInfo.iFrameSize * iFramesPerPacket;
       
   989             config.iNumOfEncodings = 1;
       
   990             config.iRedPayloadType = iCInfo.iRedundantPayload;
       
   991             config.InitPayloadTypes();
       
   992             config.iEncPayloadTypes[0] = iCInfo.iPayloadType;
       
   993             TMccRedPayloadWritePckg pckg( config );
       
   994             redEncoder->ConfigurePayloadFormatL( pckg, *iRtpMediaClock );
       
   995             }
       
   996         else
       
   997             {
       
   998             // NOP
       
   999             }
       
  1000         }
       
  1001     else
       
  1002         {
       
  1003         UpdateConfigurationL( infoBuffer() );            
       
  1004         } 
       
  1005                
       
  1006     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::ConfigurePayloadFormatL OUT" );
       
  1007     }
       
  1008 
       
  1009 
       
  1010 // -----------------------------------------------------------------------------
       
  1011 // CAmrPayloadFormatWrite::UpdateConfigurationL
       
  1012 // Update payload encoding parameters
       
  1013 // -----------------------------------------------------------------------------
       
  1014 //
       
  1015 void CAmrPayloadFormatWrite::UpdateConfigurationL( const TMccCodecInfo& aCodecInfo )
       
  1016     {
       
  1017     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::UpdateConfigurationL" )
       
  1018     
       
  1019     __ASSERT_ALWAYS( aCodecInfo.iModeChangePeriod, User::Leave( KErrArgument ) );
       
  1020     
       
  1021     iCInfo.iNeighbor = aCodecInfo.iNeighbor;                            
       
  1022     iCInfo.iModeChangePeriod = aCodecInfo.iModeChangePeriod;          
       
  1023     iCInfo.iRedundancyCount = aCodecInfo.iRedundancyCount;
       
  1024     iCInfo.iPtime = aCodecInfo.iPtime;
       
  1025     iCInfo.iSourceDefinedTimeStamps = aCodecInfo.iSourceDefinedTimeStamps;
       
  1026     iCInfo.iPayloadType = aCodecInfo.iPayloadType;
       
  1027     
       
  1028     TUint tempMask(0x0001);
       
  1029     
       
  1030     // Reset old iModes array if new modes exist
       
  1031     if ( iCInfo.iBitrateMask != 0x0000 )
       
  1032         {
       
  1033         iModes.Reset();
       
  1034         }
       
  1035     
       
  1036     if ( iIsNb )
       
  1037     	{
       
  1038 	    for ( TInt ii = 0; ii < KNumberOfNbModes; ii++ )
       
  1039 	        {
       
  1040 	        if( iCInfo.iBitrateMask & tempMask )
       
  1041 	            {
       
  1042 	            iModes.AppendL( KAmrNbModes[ii] );
       
  1043 	            }
       
  1044 	        tempMask*=2;
       
  1045 	        } 
       
  1046     	}
       
  1047 	else // Wb
       
  1048 		{
       
  1049 	    for ( TInt ii = 0; ii < KNumberOfWbModes; ii++ )
       
  1050 	        {
       
  1051 	        if( iCInfo.iBitrateMask & tempMask )
       
  1052 	            {
       
  1053 	            iModes.AppendL( KAmrWbModes[ii] );
       
  1054 	            }
       
  1055 	        tempMask*=2;
       
  1056 	        } 
       
  1057 		}	        
       
  1058     
       
  1059     iFramesPerPacket = iCInfo.iPtime / iCInfo.iHwFrameTime;
       
  1060     iPayloadEncoder->SetFrameBlockCount( iFramesPerPacket );
       
  1061     
       
  1062     if ( EAmrFecUsed == iCInfo.iAlgoUsed )
       
  1063         {                           
       
  1064         iPayloadEncoder->Initialize();
       
  1065         User::LeaveIfError( iPayloadEncoder
       
  1066             ->SetRedFrameBlockCount( iCInfo.iRedundancyCount ) );
       
  1067         }
       
  1068     else
       
  1069         {
       
  1070         AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::ConfigurePayloadFormatL - Not using AMR FEC" );
       
  1071         }
       
  1072     
       
  1073     // Allocate buffer for data transfer between
       
  1074     // FormatWrite - MDataSink AND FormatWrite - redundancy payload encoder
       
  1075     delete iSinkBuffer;
       
  1076     iSinkBuffer = NULL;
       
  1077     iSinkBuffer = CMMFDataBuffer::NewL( iCInfo.iFrameSize * iFramesPerPacket
       
  1078         * ( 1 + iCInfo.iRedundancyCount ) + KNumValue2 );
       
  1079     
       
  1080     iPayloadEncoder->Initialize();
       
  1081     TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data( );
       
  1082     dataDes.SetLength( 0 );   // for first packet length
       
  1083     iPayloadEncoder->SetPayloadBuffer( dataDes );
       
  1084     iPayloadEncoder->SetChannelCount( iChannels );
       
  1085     
       
  1086     // Reset flag
       
  1087     iNeedToFlush = EFalse;
       
  1088     
       
  1089     AMR_PAYLOAD_FORMAT_WRITE( "CAmrPayloadFormatWrite::UpdateConfigurationL OUT" )
       
  1090     }
       
  1091 
       
  1092 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1093 
       
  1094 //  End of File