diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmcch263payloadformat/src/mcch263newpayloadencoder.cpp --- /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& aDesBuffers ) + { + __H263FORMAT_MEDIA("CMccH263NewPayloadEncoder::EncodeL, enter") + + const TInt KMccValZero = 0; + const TInt KMccValOne = 1; + + CMMFDataBuffer* buf = static_cast( 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& 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 ); + } +