multimediacommscontroller/mmcch263payloadformat/src/mcch263oldpayloadencoder.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmcch263payloadformat/src/mcch263oldpayloadencoder.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,377 @@
+/*
+* Copyright (c) 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:    
+*
+*/
+
+
+
+// ============================ INCLUDES =======================================
+
+#include "mcch263oldpayloadencoder.h"
+#include "mcch263formatlogs.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+
+// -----------------------------------------------------------------------------
+// CIPMediaVideoSink::NewL()
+// First stage constructor
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CMccH263OldPayloadEncoder* CMccH263OldPayloadEncoder::NewL()
+    {
+    return new ( ELeave ) CMccH263OldPayloadEncoder();
+    }
+
+CMccH263OldPayloadEncoder::~CMccH263OldPayloadEncoder()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CIPMediaVideoSink::WriteBufferL()
+// Write media buffer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMccH263OldPayloadEncoder::EncodeL( 
+	CMMFBuffer* aMMFBuffer,
+    RPointerArray<CBufferContainer>& aDesBuffers )
+    {
+    __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, enter")
+
+    CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>( aMMFBuffer );
+ 	iSendHeader.iMarker = 0;
+
+	// Get timestamp to RTP header. conversion to 90kHz clock
+	TInt64 tmpStamp = ( buf->TimeToPlay().Int64() + iTimeStamp.Int64() ) /  KConst100 * KConst9 ;
+	iSendHeader.iTimestamp = TRtpTimeStamp( tmpStamp ) ;
+  
+    __H263FORMAT_MEDIA_INT2( "CMccH263OldPayloadEncoder::EncodeL, TimeStamp:", 
+    iSendHeader.iTimestamp, "Length:", buf->BufferSize() )
+    
+    // Reset marker from last frame
+	iSendHeader.iMarker = 0;
+	
+	// Get pointer to raw data
+	TPtrC8 frame = buf->Data();
+	
+    // Check that descriptor length is included. 
+    // Missing length causes panic in frame.Mid() function
+    if ( frame.Length() == 0 || buf->BufferSize() != frame.Length() )
+        {
+        __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, ERROR Buffer corrupted")
+        User::Leave( KErrBadDescriptor );
+        }
+        
+	const TUint8 *dataPtr = buf->Data().Ptr();
+	// Get buffer length
+	TUint frameLength = buf->BufferSize();
+    
+    // Get frame header information
+	GetHeaderInfoL( frame );
+	
+    // If packet is smaller than max Packet size. Send right away
+    if ( frame.Length() <= TInt( KVideoPacketSize ) )
+        {
+        __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, Sending whole frame...")
+
+		// Set marker to indicate last packet of current frame
+        CreateNewBufferL( aMMFBuffer,  
+                          aDesBuffers, 
+                          frame, 
+                          frameLength + KConst4, 
+                          1 );
+		
+        __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, exit" )
+        return;
+        }
+    
+	// Initialize splitting variables
+	TInt lastGOB = 0;
+	TInt lastsend = 0;
+	
+	// Scan frame for GOBs
+	for( TUint i= 0; i < frameLength; i++ )
+	    {   
+		dataPtr += i;
+		if ( *dataPtr == TUint8( 0x00 ) )
+		    {
+			dataPtr++;
+			if ( *dataPtr == TUint8( 0x00 ) )
+			    { 
+				dataPtr++;
+				if ( TUint8( *dataPtr&0xfc )>0x80 )
+				    {
+					if ( ( i - lastsend ) >= KVideoPacketSize && lastGOB )
+					    {
+                       	__H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(scan gobs), Sending packet f",
+                       	lastsend, "len", ( lastGOB - lastsend ) )
+
+						// Packet size exceeded send new RTP Packet
+						TPtrC8 packetData = 
+							frame.Mid( lastsend, ( lastGOB - lastsend ) );
+							
+						CreateNewBufferL( aMMFBuffer,  
+                                          aDesBuffers, 
+                                          packetData, 
+                                          packetData.Length() + KConst4, 
+                                          iSendHeader.iMarker );
+
+						lastsend = lastGOB;
+					    }
+					lastGOB = i;
+				    }
+			    }
+		    } 
+		// Return pointer to begining of frame
+		dataPtr = frame.Ptr();
+	    }
+	    
+	// Check that last packet does not exceed packet size
+	if ( ( frameLength - lastsend ) >= KVideoPacketSize && lastsend != 0 )
+	    {
+    	__H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(last packet check), Sending packet f", 
+    	lastsend, "len", ( lastGOB - lastsend ) )
+
+		TPtrC8 packetData = 
+			frame.Mid( lastsend, ( lastGOB - lastsend ) );
+			
+	    CreateNewBufferL( aMMFBuffer,  
+                          aDesBuffers, 
+                          packetData, 
+                          packetData.Length() + KConst4, 
+                          iSendHeader.iMarker );
+		
+		lastsend = lastGOB;
+	    }
+	    
+	// Send last packet to RTP API
+	if ( lastsend != 0 )
+	    {
+	    __H263FORMAT_MEDIA_INT2("CMccH263OldPayloadEncoder::EncodeL(last packet), Sending packet f", 
+	    lastsend, "len", ( frameLength - lastsend ) )
+	
+		TPtrC8 packetData = 
+			frame.Mid( lastsend, ( frameLength - lastsend ) );
+
+		// Set marker to indicate last packet of current frame
+	    CreateNewBufferL( aMMFBuffer,  
+                          aDesBuffers, 
+                          packetData, 
+                          packetData.Length() + KConst4, 
+                          1 );
+		
+		}
+		
+	// Special case no GOBs found try to send whole frame
+	else
+	    {       
+        __H263FORMAT_MEDIA_INT1("CMccH263OldPayloadEncoder::EncodeL(no gobs), Sending whole packet len", 
+        frameLength )
+	    
+		if ( buf->BufferSize() > TInt( KVideoPacketSize + KConst4 ) )
+            {
+            __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, ERROR, too big frame, exit")
+
+            return;
+            }
+
+		// Set marker to indicate last packet of current frame
+        CreateNewBufferL( aMMFBuffer,  
+                          aDesBuffers, 
+                          frame, 
+                          frameLength + KConst4, 
+                          1 );
+		
+		}
+
+    __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::EncodeL, exit")
+ 
+    }
+
+// -----------------------------------------------------------------------------
+// CMccH263OldPayloadEncoder::WriteHeaderData()
+// Write payload header information byte
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CMccH263OldPayloadEncoder::WriteHeaderData( TInt aByte )
+    {
+    __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::WriteHeaderData")
+
+    //byte to be written
+    TUint8 wbyte = 0;
+	//construct needed byte
+    switch ( aByte )
+	    {
+	    case 0:
+		    {
+			wbyte |= TUint8( headerA.F << KConst7 );
+			wbyte |= TUint8( headerA.P << KConst6 );
+			wbyte |= TUint8( headerA.SBIT << KConst3 );
+			wbyte |= TUint8( headerA.EBIT );
+		    }break;
+	    case 1:
+		    {
+			wbyte |= TUint8( headerA.SRC << KConst5 );
+			wbyte |= TUint8( headerA.I << KConst4 );
+			wbyte |= TUint8( headerA.U << KConst3 );
+			wbyte |= TUint8( headerA.S << KConst2 );
+			wbyte |= TUint8( headerA.A << 1 );
+		    }break;
+	    case KConst2:
+		    {
+			wbyte |= TUint8( headerA.DBQ << KConst3 );
+			wbyte |= TUint8( headerA.TRB );
+		    }break;
+	    case KConst3:
+		    {
+			wbyte = headerA.TR;
+		    }break;
+	    default:
+		    {
+		    }break;
+	    }
+	//return constructed byte
+    return wbyte;
+    }
+
+// -----------------------------------------------------------------------------
+// CMccH263OldPayloadEncoder::GetHeaderInfoL()
+// Get video frame header information
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMccH263OldPayloadEncoder::GetHeaderInfoL( TDesC8& aFrame )
+    {
+    __H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::GetHeaderInfoL")
+
+	//fill in default values = 0
+	headerA.F = 0;
+	headerA.P = 0;
+	headerA.SBIT = 0;
+	headerA.EBIT = 0;
+	headerA.SRC = 0;
+	headerA.I = 0;
+	headerA.U = 0;
+	headerA.S = 0;
+	headerA.A = 0;
+	headerA.R = 0;
+	headerA.DBQ = 0;
+	headerA.TRB = 0;
+	headerA.TR = 0;
+
+	//A S S U M I N G that aFrame begins with PSC
+	const TUint8 *help;
+	help = aFrame.Ptr();
+	//goto PTYPE-field
+	help += KConst4;
+	TUint8 test = 0;
+	//get SRC
+	test = TUint8( *help & 0x1c );
+	test >>= KConst2;
+	headerA.SRC = test;
+	if( headerA.SRC == KConst7 )
+	    {
+        #ifdef LOG
+	        IPUL_LOGC( 1, "VSink::GetHeaderInfoL> ERROR: Picture format unsupported" );
+        #endif
+	    }
+	//get I parameter
+	test = 0;
+	test = TUint8( *help & 0x02 );
+	test >>= 1;
+	headerA.I = test;
+	//get U parameter
+	test = 0;
+	test = TUint8( *help & 0x01 );
+	headerA.U = test;
+	//get S parameter
+	help++;
+	test = 0;
+	test = TUint8( *help & 0x80 );
+	test >>= KConst7;
+	headerA.S = test;
+	//get A parameter
+	test = 0;
+	test = TUint8( *help & 0x40 );
+	test >>= KConst6;
+	headerA.A = test;
+	//get P parameter
+	test = 0;
+	test = TUint8( *help & 0x20 );
+	test >>= KConst5;
+	headerA.P = test;
+	//check for correct file format
+	if ( headerA.P != 0 )
+	    {
+        #ifdef LOG
+	    IPUL_LOGC( 1 , "VSink::GetHeaderInfoL> ERROR: Unsupported file format" );
+        #endif
+	    }
+    }
+    
+// -----------------------------------------------------------------------------
+// CMccH263OldPayloadEncoder::SetPayloadType()
+// -----------------------------------------------------------------------------
+//
+void CMccH263OldPayloadEncoder::SetPayloadType( TUint8 aPayloadType )
+	{
+	__H263FORMAT_MEDIA("CMccH263OldPayloadEncoder::SetPayloadType")
+	
+	iSendHeader.iPayloadType = aPayloadType;
+	}
+
+// -----------------------------------------------------------------------------
+// CMccH263OldPayloadEncoder::CreateNewBufferL()
+// -----------------------------------------------------------------------------
+//
+void CMccH263OldPayloadEncoder::CreateNewBufferL( 
+	CMMFBuffer* aMMFBuffer,  
+	RPointerArray<CBufferContainer>& aDesBuffers,
+	const TDesC8& aPacketData,
+	TInt aLength,
+	TInt aMarker )
+	{
+	CMMFDataBuffer* newBuffer = 
+		CMMFDataBuffer::NewL( aLength );                          
+	CleanupStack::PushL( newBuffer );
+	newBuffer->Data().Append( WriteHeaderData( 0 ) );
+	newBuffer->Data().Append( WriteHeaderData( 1 ) );
+	newBuffer->Data().Append( WriteHeaderData( KConst2 ) );
+	newBuffer->Data().Append( WriteHeaderData( KConst3 ) );
+	newBuffer->Data().Append( aPacketData );
+	newBuffer->SetTimeToPlay( aMMFBuffer->TimeToPlay() );
+	newBuffer->SetFrameNumber( aMMFBuffer->FrameNumber() + iSequenceNumIncrementer );
+	
+	// If frame is divided in several packets, sequence numbers of following
+	// packets have to be modified
+	if ( aMarker == 0 )
+	    {
+	    iSequenceNumIncrementer++;
+	    }
+
+	CBufferContainer* cont = new (ELeave) CBufferContainer();
+	CleanupStack::Pop( newBuffer );
+	cont->iBuffer = newBuffer;
+	iSendHeader.iMarker = aMarker;
+	cont->iSendHeader = iSendHeader;
+	CleanupStack::PushL( cont );	    
+	aDesBuffers.AppendL( cont );
+	CleanupStack::Pop( cont );
+    }
+