--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmcch263payloadformat/src/mcch263newpayloadencoder.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,318 @@
+/*
+* 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 "mcch263newpayloadencoder.h"
+#include "mcch263formatlogs.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMccH263NewPayloadEncoder::NewL()
+// First stage constructor
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CMccH263NewPayloadEncoder* CMccH263NewPayloadEncoder::NewL()
+ {
+ return new ( ELeave ) CMccH263NewPayloadEncoder();
+ }
+
+CMccH263NewPayloadEncoder::~CMccH263NewPayloadEncoder()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMccH263NewPayloadEncoder::WriteBufferL()
+// Write media buffer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMccH263NewPayloadEncoder::EncodeL(
+ CMMFBuffer* aMMFBuffer,
+ RPointerArray<CBufferContainer>& aDesBuffers )
+ {
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL, enter")
+
+ const TInt KMccValZero = 0;
+ const TInt KMccValOne = 1;
+
+ 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("CMccH263NewPayloadEncoder::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 ("CMccH263NewPayloadEncoder::EncodeL, ERROR Buffer corrupted")
+ User::Leave( KErrBadDescriptor );
+ }
+ const TUint8 *dataPtr = buf->Data().Ptr();
+
+ // Get buffer length
+ TUint frameLength = buf->BufferSize();
+
+ // Initialize splitting variables
+ TInt lastGOB = 0;
+ TInt lastsend = 0;
+ TPtrC8 packetData;
+
+ // Scan frame for GOBs
+ for( TUint i= 0; i < frameLength - KConst2; i++ )
+ {
+ dataPtr += i;
+ if ( *dataPtr == TUint8( 0x00 ) )
+ {
+ dataPtr++;
+ if ( *dataPtr == TUint8( 0x00 ) )
+ {
+ dataPtr++;
+ if ( TUint8( *dataPtr&0xfc ) > 0x80 )
+ {
+ if ( ( i - lastsend ) >= KVideoPacketSize &&
+ ( i - lastsend ) <= KMaxPacketSize &&
+ lastGOB )
+ {
+ __H263FORMAT_MEDIA_INT2(
+ "CMccH263NewPayloadEncoder::EncodeL(scan gobs), Sending packet f:",
+ lastsend, "len:", ( lastGOB - lastsend ) )
+
+ // Packet size exceeded send new RTP Packet
+ // +2 exclude first 2 0-bytes
+ packetData.Set(
+ frame.Mid( ( lastsend + KConst2 ),
+ ( lastGOB - lastsend ) - KConst2 ) );
+
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,
+ packetData.Length() + KConst4,
+ KMccValZero,
+ KMccValZero,
+ KMccValOne );
+
+ 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(
+ "CMccH263NewPayloadEncoder::EncodeL(last packet check), Sending packet f:",
+ lastsend, "len:", ( lastGOB - lastsend ) )
+
+ // +2 exlude first 2 0-bytes
+ packetData.Set(
+ frame.Mid( ( lastsend + KConst2 ), ( lastGOB - lastsend ) - KConst2 ) );
+
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,
+ packetData.Length() + KConst4,
+ KMccValZero,
+ KMccValZero,
+ KMccValOne );
+
+ lastsend = lastGOB;
+ }
+
+ // Send last packet to RTP API
+ if ( lastsend != 0 )
+ {
+ __H263FORMAT_MEDIA_INT2(
+ "CMccH263NewPayloadEncoder::EncodeL(last packet), Sending packet f:",
+ lastsend, "len:", ( frameLength - lastsend ) )
+
+ // +2 exlude first 2 0-bytes
+ packetData.Set(
+ frame.Mid( ( lastsend + KConst2 ),( frameLength - lastsend ) - KConst2 ) );
+
+ // Set marker to indicate last packet of current frame
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,
+ packetData.Length() + KConst4,
+ KMccValOne,
+ KMccValZero,
+ KMccValOne );
+
+ }
+
+ // Special case no GOBs found try to send whole frame
+ else
+ {
+ if ( buf->BufferSize() > TInt( KVideoPacketSize + KConst2 ) )
+ {
+ __H263FORMAT_MEDIA(
+ "CMccH263NewPayloadEncoder::EncodeL(no gobs), divide to multiple packets")
+
+ // First packet
+ // 2 exlude first 2 0-bytes
+ packetData.Set( frame.Mid( KConst2, ( KVideoPacketSize - KConst2 ) ) );
+
+ // Set marker to indicate last packet of current frame
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,
+ KVideoPacketSize,
+ KMccValZero,
+ KMccValZero,
+ KMccValOne );
+
+ // Other pieces
+ TUint index = KVideoPacketSize, size;
+ while (index < buf->BufferSize())
+ {
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL(no gobs), looping")
+
+ size= buf->BufferSize() - index;
+ packetData.Set(
+ frame.Mid( index, Min( TInt( KVideoPacketSize - KConst2 ), size ) ) );
+
+ // Set marker to indicate last packet of current frame
+ TInt marker = size > TInt( KVideoPacketSize ) ? KMccValZero : KMccValOne;
+
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,
+ Min( TInt( KVideoPacketSize ), size + KConst2 ),
+ marker,
+ KMccValOne,
+ KMccValOne );
+
+ index += KVideoPacketSize - KConst2;
+ }
+ }
+ else
+ {
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL(no gobs), fits one packet")
+
+ // 2 exlude first 2 0-bytes
+ packetData.Set( frame.Mid( KConst2, ( frameLength - KConst2 ) ) );
+
+ CreateNewBufferL( aMMFBuffer,
+ aDesBuffers,
+ packetData,frameLength,
+ KMccValOne,
+ KMccValZero,
+ KMccValOne );
+
+ }
+ }
+
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL, exit")
+
+ }
+// -----------------------------------------------------------------------------
+// CMccH263NewPayloadEncoder::WriteHeaderData()
+// Write payload header information byte
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CMccH263NewPayloadEncoder::WriteHeaderData( TInt aByte )
+ {
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::WriteHeaderData")
+
+ TUint8 wbyte = 0;
+ switch ( aByte )
+ {
+ case 0:
+ {
+ wbyte |= TUint8( 1 << KConst2 ); //indicate that fist 2 0-bytes are excluded
+ }break; //from start codes
+ case 1:
+ {
+ }break;
+ default:
+ {
+ }break;
+ }
+ return wbyte;
+ }
+// -----------------------------------------------------------------------------
+// CMccH263NewPayloadEncoder::SetPayloadType()
+// -----------------------------------------------------------------------------
+//
+void CMccH263NewPayloadEncoder::SetPayloadType( TUint8 aPayloadType )
+ {
+ __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::SetPayloadType")
+ iSendHeader.iPayloadType = aPayloadType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccH263NewPayloadEncoder::CreateNewBufferL()
+// -----------------------------------------------------------------------------
+//
+void CMccH263NewPayloadEncoder::CreateNewBufferL(
+ CMMFBuffer* aMMFBuffer,
+ RPointerArray<CBufferContainer>& aDesBuffers,
+ const TDesC8& aPacketData,
+ TInt aLength,
+ TInt aMarker,
+ TInt aHeaderDataByteOne,
+ TInt aHeaderDataByteTwo )
+ {
+ CMMFDataBuffer* newBuffer =
+ CMMFDataBuffer::NewL( aLength );
+ CleanupStack::PushL( newBuffer );
+ newBuffer->Data().Append( WriteHeaderData( aHeaderDataByteOne ) );
+ newBuffer->Data().Append( WriteHeaderData( aHeaderDataByteTwo ) );
+ 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 );
+ }
+