multimediacommscontroller/mmccMsrppayloadformat/src/Msrppayloadformatwrite.cpp
branchrcs
changeset 49 64c62431ac08
child 50 1d8943dd8be6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccMsrppayloadformat/src/Msrppayloadformatwrite.cpp	Mon Sep 06 17:32:13 2010 +0530
@@ -0,0 +1,1052 @@
+/*
+* Copyright (c) 2004-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    Provides a comfort noise generator class
+*
+*/
+
+// INCLUDE FILES
+
+#include    <rtpheader.h> 
+#include 	<e32cmn.h>
+#include 	<utf.h> // charconv.lib
+ 
+#include    "msrppayloadformatwrite.h" 
+#include    "mccrtpdatasink.h"
+#include 	"Mccrtpinterface.h"
+
+#include    "mccmsrpformatlogs.h"
+#include    "mccuids.hrh"
+#include    "mccdef.h"
+#include    "mccrtpmediaclock.h"
+#include    "mccinternaldef.h"
+#include 	"msrppayloadformatdefs.h"
+#include    "mmccinterfacedef.h"
+#include    "mccmsrpsink.h"
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatRead::CMsrpPayloadFormatRead
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// 
+// iIdleMode is set to ETrue, because when starting we are in IdleMode
+// -----------------------------------------------------------------------------
+//
+CMsrpPayloadFormatWrite::CMsrpPayloadFormatWrite(): iIdleMode(ETrue)
+    {    
+    }
+    
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::ConstructL ( MDataSink* aSink )
+    {
+     
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::ConstructL");
+    
+    // Set default values
+    iFourCC = KMccFourCCIdMSRP ;
+    //iFourCC.Set( TFourCC( 'T','1','4','0' ) );
+
+	//we are going upstream, so our source is the datapath and
+	// sink is the clip. If we use RTP, which  we do, 
+	// our sink is of cource the RTPSink
+    iClip = aSink;    
+    iIsRtpSink = ( KMccRtpSinkUid  == aSink->DataSinkType() );
+    iIsMsrpSink = (KMccMsrpSinkUid == aSink->DataSinkType() );
+    
+    // two levels of redundancy is allways assumed, not necessarily used
+    // RFC4103 RECOMMENDED
+    iRedData = new(ELeave)CArrayFixFlat<TStringElement>(3);
+    
+    //userBuffer, handles all data put in by user
+    iUserBuffer = new(ELeave)CArrayFixFlat<TStringElement>(3);
+    
+    // init data to null
+    TStringElement one;
+    TStringElement two;
+    TStringElement three;
+    iRedData->AppendL(one);
+    iRedData->AppendL(two); 
+    iRedData->AppendL(three);
+     
+    // maxsize of the packet
+    iBuf = HBufC8::NewL( KRedHeaderSize + KDataSize );
+    iData = const_cast<TUint8*>( iBuf->Des().Ptr() );
+  	
+    if ( iIsRtpSink )
+        {
+        CMccRtpDataSink* tmp = static_cast<CMccRtpDataSink*>( aSink );
+        iRtpDataSink = static_cast<MMccRtpDataSink*>( tmp );
+        }
+    else if(iIsMsrpSink)
+        {
+        CMccMsrpSink *tmp = static_cast<CMccMsrpSink*>( aSink );
+        iMsrpDataSink = static_cast<CMccMsrpSink*>( tmp );
+        }
+    else
+        {
+    	DP_MSRP_WRITE("CMsrpPayloadFormatWrite::ConstructL Leaving: No RTPSink!");
+    	User::Leave(KErrNotSupported);	
+        }
+
+    // Initialize state machine
+    iStateMachine = CFormatEncodeStateMachine::NewL( this );
+    
+    //init state machine to idle state
+    iStateMachine->ChangeState( EEncodeIdle );
+    
+    // Construct Timer for redundant generations.
+    iTimer = CSendStateMachine::NewL( this ); 
+    
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMsrpPayloadFormatWrite* CMsrpPayloadFormatWrite::NewL ( MDataSink* aSink )
+    {
+ 	
+ 	
+ 	DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::NewL" );
+    __ASSERT_ALWAYS( aSink, User::Leave( KErrArgument ) );
+    
+    CMsrpPayloadFormatWrite* self = new (ELeave) CMsrpPayloadFormatWrite;
+    CleanupStack::PushL( self );
+    self->ConstructL( aSink );
+    CleanupStack::Pop( self );
+    return self;
+    
+    }
+
+// Destructor 
+CMsrpPayloadFormatWrite::~CMsrpPayloadFormatWrite ()
+    {
+    
+    if ( iStateMachine )
+        {
+        iStateMachine->Cancel();
+        delete iStateMachine;
+        }
+    
+    if(iTimer) 
+	    {
+	    	iTimer->Cancel();
+	    	delete iTimer;	
+	    }
+	   
+    
+    iRtpMediaClock = NULL;
+    iClip = NULL;
+    
+    delete iSourceBuffer;
+    delete iSinkBuffer;
+    delete iRedData;
+    delete iUserBuffer;
+    delete iBuf;
+   
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkThreadLogon
+// Passes the logon command to the sink clip
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatWrite::SinkThreadLogon(MAsyncEventHandler& aEventHandler)
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkThreadLogon");
+    iClip->SinkThreadLogon( aEventHandler );
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkThreadLogoff
+// Passes the logoff command to the sink clip
+// -----------------------------------------------------------------------------
+void CMsrpPayloadFormatWrite::SinkThreadLogoff()
+    {   
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkThreadLogoff");
+    iClip->SinkThreadLogoff();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::CreateSinkBufferL
+// Create a sink buffer
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CMsrpPayloadFormatWrite::CreateSinkBufferL( TMediaId /*aMediaId*/,
+                                                        TBool &aReference )
+    { 
+    	
+   	DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::CreateSinkBufferL" );
+
+	/* TODO: Remove me when platform supports
+    if ( KUidMediaTypeText != aMediaId.iMediaType ) 
+    {
+    User::Leave( KErrNotSupported ); 
+    }
+    */    
+    aReference = ETrue;
+    return CreateSinkBufferOfSizeL( KMaxRTTChunkSize + KRedHeaderSize );
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::CreateSinkBufferOfSizeL
+// Create a sink buffer of the given size.
+// -----------------------------------------------------------------------------
+//
+CMMFDataBuffer* CMsrpPayloadFormatWrite::CreateSinkBufferOfSizeL( TUint aSize )
+    {
+	
+	DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::CreateSinkBufferOfSizeL" );
+  
+    if ( !iSourceBuffer )
+	    {
+	    iSourceBuffer = CMMFDataBuffer::NewL( aSize );
+    	iSourceBuffer->Data().FillZ( aSize );
+    	iSourceBuffer->SetRequestSizeL( aSize );
+	    }
+	    
+    return iSourceBuffer;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::EmptyBufferL
+// Empty the given source buffer
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::EmptyBufferL( CMMFBuffer* aBuffer, 
+                                            MDataSource* aSupplier, 
+                                            TMediaId /*aMediaId*/ )
+    {
+    
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::EmptyBufferL");
+  
+    __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS ( aBuffer == iSourceBuffer, User::Leave( KErrArgument ) );
+    __ASSERT_ALWAYS( aSupplier, User::Leave( KErrArgument ) );
+    
+   	// TODO: Remove me when platform supports
+	// __ASSERT_ALWAYS( KUidMediaTypeAudio == aMediaId.iMediaType,
+	// User::Leave( KErrNotSupported ) );
+    
+    // Cancel timer, so timer does not interrupt our current sending.
+    // Timer enables empty blocks to be appended when redundancy is on.
+    iTimer->Cancel();
+       
+    iDataPath = aSupplier;
+    iSourceBuffer = static_cast<CMMFDataBuffer*>( aBuffer );
+    
+    if ( !iSinkBuffer )
+        {        
+        iStateMachine->ChangeState( ESourceBufferEmptied );
+        return;
+        }
+        
+	if ( !iSinkBuffer->Data().Length() ) 
+	    {
+		//User::LeaveIfError( iRtpMediaClock->GetTimeStamp( iKey, iCurrentTimestamp ) );
+   		iSinkBuffer->SetTimeToPlay( TInt64( iCurrentTimestamp ) );
+   		iSinkBuffer->SetFrameNumber( aBuffer->FrameNumber() );	
+	    }
+       
+       
+      // We signal StateMachine to ChangeState() 
+      // this calls back EmptySourceBufferL 
+      iStateMachine->ChangeState( EEmptySourceBuffer );
+   
+    } 
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SetSinkDataTypeCode
+// Set the sink data type to the given four CC code for the given media
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatWrite::SetSinkDataTypeCode( TFourCC aSinkFourCC,
+                                                   TMediaId /*aMediaId*/ )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SetSinkDataTypeCode");
+	/* TODO: Remove me when platform supports
+    if ( KUidMediaTypeText != aMediaId.iMediaType )
+    {
+    User::Leave( KErrNotSupported );
+    }
+    */
+    iFourCC = aSinkFourCC;
+    return KErrNone;
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkDataTypeCode
+// Return the sink data type (four CC code) for the given media ID
+// -----------------------------------------------------------------------------
+//
+TFourCC CMsrpPayloadFormatWrite::SinkDataTypeCode( TMediaId /*aMediaId*/ )
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkDataTypeCode");
+  	/* TODO: Remove me when platform supports
+    if ( KUidMediaTypeText == aMediaId.iMediaType )
+        {
+        return iFourCC;
+        }
+    else
+        {
+        return TFourCC(); //defaults to 'NULL' fourCC
+        }
+        */
+	return iFourCC;
+        
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::BufferEmptiedL
+// Called after payload buffer is completely emptied by RtpDataSink.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
+    {
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::BufferEmptiedL" );
+	// nothing to be done
+	
+	//NOTE: 14.12.2007 - LeaveScan causes warning, but this is a interface method
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::FrameTimeInterval
+// Return the frame time interval for the given media
+// Return allways 0
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds 
+    CMsrpPayloadFormatWrite::FrameTimeInterval( TMediaId /*aMediaId*/ ) const
+    {
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::FrameTimeInterval" );
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::Duration
+// Return the frame time interval for the given media
+// NOT SUPPORTED
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds 
+    CMsrpPayloadFormatWrite::Duration( TMediaId /*aMediaType*/ ) const
+    {
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::Duration" );
+    return TTimeIntervalMicroSeconds( TInt64( 0 ) );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::EmptySourceBufferL
+// Empty the given sourcebuffer
+// Sourcebuffer is given in iSourceBuffer
+// Called by StateMachine
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::EmptySourceBufferL()
+	{
+				
+	  	DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::EmptySourceBufferL" );
+	 
+	  	const TDesC8& srcDes( iSourceBuffer->Data() );
+    	const TUint8* srcPtr = srcDes.Ptr();
+  		TInt length = iSourceBuffer->Data().Length();
+  		
+  		if ( iSourceBuffer->Data().Length() ) 
+	  		{
+	  		
+		  		if( KMaxRTTChunkSize < length )
+				  	{
+				  		DP_MSRP_WRITE( "ERR - RTT Payload Length exceeded MaxChunkSize" );
+				  		User::Leave(KErrArgument);
+				  	}
+			  	
+		  		TBuf16<KMaxRTTChunkSize> unicode;
+		    	User::LeaveIfError(
+		    			CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode, TPtrC8(srcPtr)));			
+					
+				//buffer the user data
+				TStringElement buffer;
+				buffer.iData = unicode;
+				iUserBuffer->AppendL(buffer);
+				
+				FormUserDataL();
+				ForwardDataL();
+					
+			}
+}   
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::TimerExpiredL()
+// Sends Redundant data after buffer period, if no user data 
+// appeared before that.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::TimerExpiredL()
+{		
+	DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::TimerExpiredL" );
+	
+	// Because timer expired, we must send redundant data anyway
+	TStringElement nullData;
+	iUserBuffer->AppendL(nullData);
+	
+	FormUserDataL();
+	//TODO:Handle other Errors if any
+	TInt err = SendRedundantDataL();
+	if ( err != KErrNone )
+		{
+			GotoIdleL(); 
+		}
+}
+ 
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::ForwardDataL()
+// Sends Redundant data after buffer period, if no user data 
+// appeared before that.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::ForwardDataL()
+{
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::ForwardDataL" );
+    
+    // Just Send Data
+    TInt err = SendRedundantDataL();
+    
+    if ( err == KErrNone )
+        {
+            iStateMachine->ChangeState( ESourceBufferEmptied ); 
+        }
+} 
+
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SendRedundantDataL()
+// A Method that sends the redundant buffer to Sink
+// Calls CMsrpPayloadFormatWrite::DeliverPacketL
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatWrite::SendRedundantDataL()
+	{
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::SendRedundantDataL" );
+    
+	TStringElement zero = iRedData->At(0);
+	TStringElement one = iRedData->At(1);
+	TStringElement two = iRedData->At(2);
+ 	
+ 	DP_MSRP_WRITE( "******************");
+ 	DP_MSRP_WRITE2( "SendRedundantDataL - Zero Lenght: %d", zero.iData.Length() ); 
+ 	DP_MSRP_WRITE2( "SendRedundantDataL - R1 Lenght: %d", one.iData.Length() );
+ 	DP_MSRP_WRITE2( "SendRedundantDataL - R2 lenght: %d", two.iData.Length() );
+ 	
+	if ( zero.iData.Length() == 0 && one.iData.Length() == 0 && two.iData.Length() == 0 )
+	 {
+	 	DP_MSRP_WRITE( "ERR - SendRedundantDataL - All Data is 0 lenght returning, KErrArgument!"); 
+	 	return KErrArgument;
+	 }
+		 
+	TDes8& destDes( iSinkBuffer->Data() );
+	
+ 	// Assemble redundant data
+    AssembleRedPacket();
+    // Append current data to buffer
+    TPtr8 ptr = iBuf->Des();
+    destDes.Append(  ptr );
+    
+    DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite HeapData size: %d", ptr.Size() );
+    DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite HeapData Length: %d", ptr.Length() );
+    DP_MSRP_WRITE ("CMsrpPayloadFormatWrite::DeliverPacketL, Packet Assembled" );
+	DP_MSRP_WRITE( "******************");
+	
+    DeliverPacketL( *iSinkBuffer );	
+	return KErrNone;
+		
+	}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::FormUserDataL()
+//
+// A function that refreshes the RedundantData Buffer, so that
+// We just can send data that is there.
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatWrite::FormUserDataL()
+{
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::SendRedundantDataL" );
+	
+    TStringElement primary;
+
+    // if there is data
+    if ( iUserBuffer->Count() )
+        {
+            primary = iUserBuffer->At(0);
+        }
+        
+    //set timestamp to primary data, this is used to calculate offset
+    primary.iTimestamp = iSinkBuffer->TimeToPlay().Int64();
+    
+    // can now reset user buffer
+    iUserBuffer->Reset();
+    
+    // get current redundants
+    TStringElement zero = iRedData->At(0);
+    TStringElement one = iRedData->At(1); 
+    
+    // we can now reset old redundant also
+    iRedData->Reset();
+    
+    // re-order redundant data, this must be always present, 
+    // if redundancy changes on-fly from e.g 0 to 2
+    iRedData->AppendL(primary);
+    iRedData->AppendL(zero);
+    iRedData->AppendL(one);
+    
+    return KErrNone;
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::GoToIdleL()
+//
+// When there is no data to send, we must go to idle mode
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::GotoIdleL()
+	{
+	
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::GoToIdleL()");
+    //reset redundancy buffer
+    iRedData->Reset();
+    //add default data  
+    TStringElement empty;
+    iRedData->AppendL(empty);
+    iRedData->AppendL(empty);
+    iRedData->AppendL(empty);
+    iIdleMode = ETrue;
+    
+    //Set State that we are waiting for Data
+    iStateMachine->ChangeState( EWaitForSourceData );
+    
+    // Cancel the Timer also
+    iTimer->Cancel();
+		 	
+	}
+ 
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::AssembleRedPacket()
+//
+// In AssembleRedPacket we must assemble right kind of
+// payload. We switch between redundant and plain data.
+// If redundancy is used a redundant datapacket is generated!
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::AssembleRedPacket()
+	{
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::AssembleRedPacket" );
+    switch( iCodecInfo.iRedundancyCount )
+    {
+        case 0:
+            // just append the primary data and no headers
+            iBuf->Des().Append( iRedData->At(0).iData );
+        break;
+        
+        case 2:
+             TInt err = GenerateRedPacket(); 
+             //TODO: Handle Errors in Creating packet
+        break;
+        
+    }
+
+	}
+
+	
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::GenerateRedPacket() 
+//
+// In GenerateRedPacket we must assemble right kind of
+// payload according to RFC 4103. Level 2 redundancy is used.
+// -----------------------------------------------------------------------------
+//
+TInt CMsrpPayloadFormatWrite::GenerateRedPacket() 
+{
+		
+		DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::GenerateRedPacket()" );
+		
+		TStringElement primary = iRedData->At(0);
+		TStringElement r1 = iRedData->At(1);
+		TStringElement r2 = iRedData->At(2);
+
+		DP_MSRP_WRITE( "*******************************");
+		DP_MSRP_WRITE2("CMsrpPayloadFormatWrite::GenerateRedPacket PR Length: %d", primary.iData.Length() );
+		DP_MSRP_WRITE2("CMsrpPayloadFormatWrite::GenerateRedPacket R1 Length: %d", r1.iData.Length() );
+		DP_MSRP_WRITE2("CMsrpPayloadFormatWrite::GenerateRedPacket R2 Length: %d", r2.iData.Length() );
+
+		// pointer to data
+		TUint8* dataP = iData;
+		TInt count(0);
+		//Fill Data with binary zeroes and zero old
+		Mem::FillZ( dataP, KRedHeaderSize + KDataSize ); 
+		iBuf->Des().Zero();
+    
+    	
+		/*************
+		data[0] = 8 bit
+		1 bit - redundancy marker bit 1
+		7 bit - payloadtype
+		***************/
+		
+		iData[0] |= ( 1 << 7 );
+		iData[0] |= iCodecInfo.iRedundantPayload; 
+		//iData[0] |= 106; 
+		dataP += 1;
+		count ++;
+			
+			
+		/**************
+		data[1-3] = 24 bit
+		14 bit - timestamp offset of R2
+		10 bit - length of  R2
+		***************/
+		
+		TUint32 temp(0);
+		temp |= ( SetTimeOffset(primary.iTimestamp, r2.iTimestamp ) << 10  ); 
+		
+		TUint16 size(r2.iData.Length()); 
+		temp |= size; 
+			
+		Write24(dataP, temp); 
+		dataP += 3;
+		count += 3; 
+		
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[0]: %x", iData[0] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[1]: %x", iData[1] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[2]: %x", iData[2] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[3]: %x", iData[3] );
+		
+			
+		/**************
+		data[4] = 8 bit
+		1 bit - redundancy marker bit 1
+		7 bit - payloadtype
+		***************/
+		
+		iData[4] |= ( 1 << 7 );
+		iData[4] |= iCodecInfo.iRedundantPayload;
+		//iData[4] |= 106;
+		dataP += 1; 
+		count ++;
+	
+		/**************
+		data[5-7] = 24 bit
+		14 bit - timestamp offset of R1
+		10 bit - length of  R1
+		***************/			
+		
+		temp = 0;
+		temp |= ( SetTimeOffset(primary.iTimestamp, r1.iTimestamp ) << 10  );
+	
+		size = r1.iData.Length();  
+		temp |= size; 
+			
+		Write24(dataP, temp);
+		dataP += 3;
+		count += 3;
+				
+		/**************
+		data[8] = 8 bit
+		1 bit - normal marker bit 0
+		7 bit - payloadtype 
+		***************/
+		iData[8] |= ( 0 << 7 );
+		iData[8] |= iCodecInfo.iPayloadType;
+		//iData[8] |= 105;
+		dataP += 1;
+		count ++;
+	
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[4]: %x", iData[4] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[5]: %x", iData[5] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[6]: %x", iData[6] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[7]: %x", iData[7] );
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket DATA[8]: %x", iData[8] );
+		DP_MSRP_WRITE( "*******************************");
+		
+		//TODO: When IOP-Tests Are done, Write me properly using Append, or some other method
+		TInt forHere = count+r2.iData.Length();
+		TInt index(0);
+		if ( r2.iData.Length() )
+		{
+			for ( TInt i = count; i < forHere; i++ )
+			  	{
+				iData[i] = r2.iData[index];
+				index++,
+				RDebug::Print( _L("	X Writing R2 DATA[i]: %x"), iData[i] );
+				}
+			
+		dataP += r2.iData.Length();
+		count += r2.iData.Length();		
+		}
+			
+			
+		forHere = count+r1.iData.Length();
+		index = 0;
+		if ( r1.iData.Length() )
+		{
+			for ( TInt i = count; i < forHere; i++ )
+			  	{
+				iData[i] = r1.iData[index];
+				index++;
+				RDebug::Print( _L("	X Writing R1 DATA[i]: %x"), iData[i] );
+				}
+			
+		dataP += r1.iData.Length();		
+		count += r1.iData.Length();
+		}
+ 
+		
+		forHere = count+primary.iData.Length();
+		index = 0;
+		if ( primary.iData.Length() )
+		{
+			for ( TInt i = count; i < forHere; i++ )
+			  	{
+				iData[i] = primary.iData[index];
+				index++;
+				RDebug::Print( _L("	X Writing PRIMARY DATA[i]: %x"), iData[i] );
+				}
+			
+		dataP += primary.iData.Length();		
+		count += primary.iData.Length();
+		}
+				
+				
+		DP_MSRP_WRITE2( "CMsrpPayloadFormatWrite::GenerateRedPacket Writing Lenght: %d", count );
+		iBuf->Des().Append( iData, count );
+		return KErrNone;
+		
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::DeliverPacketL
+// Prepare the packet header and deliver the packet to the datasink.
+// -----------------------------------------------------------------------------
+void CMsrpPayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload )
+    {
+    
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::DeliverPacketL"); 
+   
+    if ( !iClip )
+        {
+        User::Leave( KErrNotReady ); 
+        }
+    const TMediaId mediaId( KUidMediaTypeAudio );
+    const TInt dataSize( aPayload.Data().Size() );
+    DP_MSRP_WRITE2( "MSRP Payload SIZE : %d", dataSize );
+    
+    if ( dataSize )
+        {           
+        if (iIsMsrpSink)
+            {
+            iMsrpDataSink->EmptyBufferL( &aPayload, this, mediaId );
+            }
+        }       
+    aPayload.Data().Zero();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SourceBufferEmptiedL
+// Handle the event that sourcebuffer has been emptied.
+// Sourcebuffer is given in "iSourceBuffer".
+// Called by the statemachine.
+// -----------------------------------------------------------------------------
+void CMsrpPayloadFormatWrite::SourceBufferEmptiedL()
+    { 
+    
+    
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::SourceBufferEmptiedL" ); 
+    
+    //Empty all
+    iSourceBuffer->Data().FillZ();  
+	iSourceBuffer->Data().Zero();
+	iSinkBuffer->Data().FillZ();  
+	iSinkBuffer->Data().Zero();
+    iBuf->Des().FillZ();
+    iBuf->Des().Zero();
+    iDataPath->BufferEmptiedL( iSourceBuffer );
+
+	//Finally we set the timer if we are in red mode 	
+	switch( iCodecInfo.iRedundancyCount )
+	{
+		case 0:
+				// do nothing 
+		break;
+		
+		case 2:
+			if ( iIdleMode )
+				{
+				iTimer->Cancel();
+				iTimer->Start();	
+				}
+		break;
+	}
+	
+	// we are no more in idle,
+	iIdleMode = EFalse;
+	
+}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkPrimeL
+// Prime the sink
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::SinkPrimeL()
+    {
+	DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkPrimeL()");
+	iClip->SinkPrimeL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkPrimeL
+// Prime the sink
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::CancelUlRequest() 
+    {
+    
+	DP_MSRP_WRITE("CMsrpPayloadFormatWrite::CancelUlRequest()" );
+    iStateMachine->Cancel();
+    iStateMachine->ChangeState( EEncodeIdle );
+
+    // Reset the payload buffer
+    if ( iSinkBuffer )
+        {
+        TDes8& dataDes = static_cast<CMMFDataBuffer*>( iSinkBuffer )->Data();
+        dataDes.SetLength( 0 );
+        }
+        
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkPlayL
+// Start playing.
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::SinkPlayL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkPlayL" );
+    // Allocate buffer for data transfer between 
+    // FormatWrite - MDataSink
+    delete iSinkBuffer;
+    iSinkBuffer = NULL;
+    iSinkBuffer = CMMFDataBuffer::NewL( KRedHeaderSize + KDataSize );
+    
+    // Start state machine
+    iStateMachine->ChangeState( EWaitForSourceData );
+    
+    iFirstPacketFinished = EFalse;
+
+    // Start a new cycle of frame collecting
+    if ( iSinkBuffer )
+        {
+        iSinkBuffer->SetLastBuffer( EFalse );
+        }
+
+    iClip->SinkPlayL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkPauseL
+// Pause sink
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::SinkPauseL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkPauseL" );
+	this->CancelUlRequest();
+    iClip->SinkPauseL();
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SinkStopL
+// Stop sink
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::SinkStopL()
+    {
+    DP_MSRP_WRITE("CMsrpPayloadFormatWrite::SinkPauseL" ); 
+    // Stop state machine
+   	this->CancelUlRequest();
+    iClip->SinkStopL(); 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::ConfigurePayloadFormatL
+// Configure payload encoding parameters
+// ---------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::ConfigurePayloadFormatL( const TDesC8& aConfigParams, 
+    CMccRtpMediaClock& /*aClock*/  )
+    {
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::ConfigurePayloadFormatL()" );
+   	
+   //Check that buffer is same size, so we can assume data is correct type
+    __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
+        User::Leave( KErrArgument ) );
+     
+    //instantiate correct CodecInfo Structure
+    TMccCodecInfoBuffer infoBuffer;
+    infoBuffer.Copy( aConfigParams );
+    TMccCodecInfo codecInfo( infoBuffer() ); 
+    
+	if ( !codecInfo.iIsUpdate )
+		{
+
+		//iCodecInfo = codecInfo;
+		//iRtpMediaClock = &aClock;  
+		//iKey = iRtpMediaClock->RegisterMediaFormat( KDefaultSampleRate, iCodecInfo.iHwFrameTime );
+		}
+	else
+		{
+		UpdateConfigurationL( aConfigParams );
+		} 
+
+    }
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::UpdateConfigurationL
+// Update payload encoding parameters
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::UpdateConfigurationL( const TDesC8& aConfigParams )
+    { 
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::UpdateConfigurationL" );
+    __ASSERT_ALWAYS( aConfigParams.Size() == sizeof( TMccCodecInfo ),
+        User::Leave( KErrArgument ) );
+    
+    TMccCodecInfoBuffer infoBuffer;
+    infoBuffer.Copy( aConfigParams );
+    TMccCodecInfo codecInfo = infoBuffer();
+    
+    iCodecInfo = codecInfo;
+    //iCodecInfo.iPtime = codecInfo.iPtime;
+    //iCodecInfo.iRedundancyCount = 0;
+    
+    //iCodecInfo.iPayloadType = codecInfo.iPayloadType;
+    //iCodecInfo.iRedundancyCount = codecInfo.iRedundancyCount;
+    //iCodecInfo.iCodecMode = codecInfo.iCodecMode;
+    
+    //TODO: move me to right variable and update buffering time
+    //iTimer->Cancel();
+    //iTimer->SetTimeOut( iCodecInfo.iCodecMode * 1000);
+    
+    // Allocate buffer for data transfer between 
+    // FormatWrite - MDataSink
+    delete iSinkBuffer;
+    iSinkBuffer = NULL;
+    iSinkBuffer = CMMFDataBuffer::NewL( KRedHeaderSize + KDataSize );
+    
+    }
+
+
+
+// ==========================    HELPER FUNCTIONS    =========================
+// ========================== 						 =========================
+// ========================== 						 =========================
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::Write24
+// Simple helper function, that writes a 24-bit value to databuffer, 
+// using pointer
+// -----------------------------------------------------------------------------
+//
+void CMsrpPayloadFormatWrite::Write24( TUint8* const aPointer, TUint32 aValue )
+    {
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::Write24" );
+    aPointer[0] = static_cast<TUint8>( ( aValue & 0xFF0000 ) >> 16 );
+    aPointer[1] = static_cast<TUint8>( ( aValue & 0x00FF00 ) >> 8 );
+    aPointer[2] = static_cast<TUint8>( aValue & 0x0000FF );
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::Write32
+// Simple helper function, that writes a 32-bit value to databuffer, 
+// using pointer
+// -----------------------------------------------------------------------------
+//    
+void CMsrpPayloadFormatWrite::Write32( TUint8* const aPointer, TUint32 aValue )
+	{
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::Write32" );
+	aPointer[0] = static_cast<TUint8>( ( aValue & 0xFF000000 ) >> 24 );
+	aPointer[1] = static_cast<TUint8>( ( aValue & 0x00FF0000 ) >> 16 );
+	aPointer[2] = static_cast<TUint8>( ( aValue & 0x0000FF00 ) >> 8 );
+	aPointer[3] = static_cast<TUint8>( aValue & 0x000000FF );
+	}
+
+
+// -----------------------------------------------------------------------------
+// CMsrpPayloadFormatWrite::SetTimeOffset
+// Calculates TimeOffset to RedundancyHeader according to 
+// RFC 4103. Actually RFC 4103 does not accurately state how ( and where )
+// timeoffset should be calculated. This calculation is based conversations
+// with authors of RFC 4103
+// -----------------------------------------------------------------------------
+//
+TUint16 CMsrpPayloadFormatWrite::SetTimeOffset( TInt64& aPrim, TInt64& aSecond  )
+{	
+    DP_MSRP_WRITE( "CMsrpPayloadFormatWrite::SetTimeOffset" );
+	TInt pOffset = aPrim - aSecond; 
+	TUint16 aRet = TUint16(pOffset) & KHighestTimeStampOffset;
+	if( aRet > KHighestTimeStampOffset )
+	{
+		aRet = KHighestTimeStampOffset;
+	}
+	return aRet; 
+}
+
+
+TStringElement::TStringElement()
+{
+}
+
+
+//  End of File