diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccavcpayloadformat/src/rfc3984decode.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccavcpayloadformat/src/rfc3984decode.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,311 @@ +/* +* Copyright (c) 2005 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: AVC De-Payloadization class +* +*/ + + + + +// ============================ INCLUDES ======================================= + +#include"rfc3984decode.h" + +// ============================ MEMBER FUNCTIONS =============================== +_LIT8(AVCPSC1, "\x0\x0\x0\x1"); + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::CRFC3984Decode() +// Default Constructor +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CRFC3984Decode::CRFC3984Decode() +{ + iNalCount = 0; + iVirtualDON = 0; + +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::~CRFC3984Decode() +// Default Destructor +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CRFC3984Decode::~CRFC3984Decode() +{ + // TODO :: cleanup iBuffer in this destructor +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::NewL() +// First stage constructor +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +CRFC3984Decode * CRFC3984Decode::NewL() +{ + CRFC3984Decode * self = new(ELeave) CRFC3984Decode; + CleanupStack::PushL( self ); + self->ConstructL( ); + CleanupStack::Pop(); + return self; +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::ConstructL() +// Initializing common members +// ----------------------------------------------------------------------------- +// + +void CRFC3984Decode::ConstructL() +{ + iNalCount = 0; + iVirtualDON = 0; +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::DePayloadizeFrame() +// Purpose : This function receives the encoded frame and payloadizes it based on the packetization_mode value +// Parameters : aBuffer - Buffer containing the received NAL unit +// aTimeStamp - Timestamp to go into RTP +// aMarkerBit - Marker Bit indication (this function sets it for key frames) +// aNalCount - Returns the NAL count through this reference +// Return Value: ETrue if correct parsing done, EFalse if an error occured +// ----------------------------------------------------------------------------- +// + +TBool CRFC3984Decode::DePayloadizeFrameL(TDes8 & aBuffer, TUint aTimeStamp, TUint aArrivalTime, TUint16 aSeqNo, TUint8 & aMarkerBit, TInt & aNalCount) +{ + + TInt index = 0; + CAvcRtpStruct * pRtpStruct = NULL; + HBufC8 * pBuffer = NULL; + TInt16 lowerSeqNo = aSeqNo; + + + TUint8 header = aBuffer[index]; + TUint8 type = header & 0x1f; + + if(type <= PACKET_NAL_UNIT){ // SNALU packet -- add as they are + // storing reference as it is + pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer + pRtpStruct->iMarkerBit = aMarkerBit; + pRtpStruct->iArrivalTime = aArrivalTime; + pRtpStruct->iTimeStamp = aTimeStamp; + pRtpStruct->iSeqNo = aSeqNo; + pRtpStruct->iPacketType = type; + pRtpStruct->iDon = (iVirtualDON++)%65535; // Since 1 NAL/slice, no need for virtual DON and keeping it constant. + + CleanupStack::PushL( pRtpStruct ); // pushing to stack for leave operation + //pDes = new (ELeave) TBuf8Des( ); + pDes.Copy(aBuffer); // copying data + pRtpStruct->iDes = pBuffer; + pBuffer = NULL; + iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on + iNalCount += 1; // incrementing total NAL count by 1 + } + else if(type == PACKET_STAP_A){ // STAP-A packet -- seperate and add using a virtual don number + TUint accumSize = 0; + TUint16 nalSize = 0; + + accumSize += 1; // incrementing to point ahead of header + while(accumSize != aBuffer.Size()){ + nalSize = Read16(aBuffer, accumSize); + accumSize += 2; + if(nalSize > 0 && nalSize <= aBuffer.Size()){ // valid size, copy data + // storing reference as it is + pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer + pRtpStruct->iMarkerBit = aMarkerBit; + pRtpStruct->iArrivalTime = aArrivalTime; + pRtpStruct->iTimeStamp = aTimeStamp; + pRtpStruct->iSeqNo = aSeqNo; + pRtpStruct->iPacketType = type; + pRtpStruct->iDon = (iVirtualDON++)%65535; // virtual DON, wrapping around at 65K (it spans over many NAL units) + + CleanupStack::PushL( pRtpStruct ); // pushing to stack for leave operation + // pDes = new (ELeave) TBuf8Des( ); + TPtr8 pStart = aBuffer.MidTPtr(accumSize); + pDes1.Copy(pStart.Ptr(), nalSize); // copying data + pRtpStruct->iDes = pBuffer; + pBuffer = NULL; + iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on + iNalCount += 1; // incrementing total NAL count by 1 + + accumSize += nalSize; + + } + } + } + else if(type == PACKET_FU_A){ // FU-A packet -- add as they are, the jitter buffer removal side will assemble them + // storing reference as it is, since FU-A and FU-B will be depacketized at removal time from the jitter buffer + // however, for FU-B extract the DON number + + // reading from FU-header byte the start bit + index++; // going to FU-Header Byte start bit, end bit and R bit + TUint8 startBit = 0; + const TUint8 * FUHeader = NULL; + TUint8 FUHeader1 = 0; + TInt bufSize = aBuffer.Size(); + startBit = aBuffer[index]; + startBit &= 0x80; // keeping just the start bit + startBit = startBit >> 7; + if(startBit == 1) + { + pBuffer = HBufC8::New(aBuffer.Size( )+3); // excluding FU NAL Header byte and adding size of AVCPSC1 + if(!pBuffer) + { + User::Leave(KErrNoMemory); + } + + TPtr8 pDesBuf = pBuffer->Des(); + TPtr8 headerPtr = aBuffer.MidTPtr(index); + FUHeader = headerPtr.Ptr(); + FUHeader1 = *FUHeader; + header &= 0xE0; // making lower bits 0 i.e. type field + header |= (*FUHeader & 0x1F); // now header has the actual NAL unit header values. + pDesBuf.Append(AVCPSC1); // appending start code + pDesBuf.Append(&header, 1); // appending reconstructed header + TPtr8 startPtr = aBuffer.MidTPtr(index+1); // getting pointer to start of NAL unit + pDesBuf.Append(startPtr.Ptr(), bufSize-2); // copying NAL data + } + else + { + + pBuffer = HBufC8::New(aBuffer.Size( )-1); // excluding FU NAL Header byte + if(!pBuffer) + { + User::Leave(KErrNoMemory); + } + + TPtr8 pDesBuf = pBuffer->Des(); + TPtr8 startPtr = aBuffer.MidTPtr(index); // pointing to FUHeader byte + FUHeader = startPtr.Ptr(); + FUHeader1 = *FUHeader; + startPtr = aBuffer.MidTPtr(index+1); // pointing to start of actual data + pDesBuf.Append(startPtr.Ptr( ), bufSize-2); // copying FU-Header and data + } + + pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer + pRtpStruct->iMarkerBit = aMarkerBit; + pRtpStruct->iArrivalTime = aArrivalTime; + pRtpStruct->iTimeStamp = aTimeStamp; + pRtpStruct->iSeqNo = aSeqNo; + pRtpStruct->iPacketType = type; + pRtpStruct->iDon = (iVirtualDON++)%65535; // keeping virtual DON for FU-A as zero too + pRtpStruct->iDes = pBuffer; + pRtpStruct->iFUHeader = FUHeader1; // index currently pointing to FU-Header Byte + pBuffer = NULL; + iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on + iNalCount += 1; + } + + aNalCount = iNalCount; + return ETrue; +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::Write16() +// Purpose : This function writes the 16 bit value in network byte order in buffer aDes (appends it to the next location) +// Parameters : aDes - Buffer to which value has to be written +// aValue - Value to be written +// Return Value: +// ----------------------------------------------------------------------------- +// + +void CRFC3984Decode::Write16(TDes8 & aDes, TUint16 aValue) +{ + TUint8 firstByte = (aValue & 0xFF00) >> 8; + TUint8 secondByte = (aValue & 0xFF); + aDes.Append(&firstByte, 1); + aDes.Append(&secondByte, 1); + +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::Read16() +// Purpose : This function reads the 16 bit value in network byte order in buffer aDes (appends it to the next location) +// Parameters : aDes - Buffer to read from +// aIndex - Buffer index where to read from +// Return Value: Returns the 16-bit value +// ----------------------------------------------------------------------------- +// + +TUint16 CRFC3984Decode::Read16(TDes8 & aDes, TInt aIndex) +{ + TUint16 value; + + value = (aDes[aIndex+1]) + (aDes[aIndex] << 8); + + return value; +} + +// ----------------------------------------------------------------------------- +// CRFC3984Decode::GetNalUnit(TInt aIndex) +// Purpose : This function returns the depayloadized NAL unit with RTP header information +// Parameters : aIndex - Index of the entry +// +// Return Value: Returns a pointer to the CAvcRtpStruct structure. +// ----------------------------------------------------------------------------- +// + +CAvcRtpStruct * CRFC3984Decode::GetNalUnit(TInt aIndex) +{ + CAvcRtpStruct * ptr; + if(aIndex >= iNalCount) + return 0; + + ptr = iBuffers[aIndex]; + return ptr; +} + + +void CRFC3984Decode::ClearBuffer() +{ + if(iNalCount == 0) + return; + + TInt count = 0; + CAvcRtpStruct * ptr = NULL; + for(count = 0; count < iNalCount; count++){ + ptr = iBuffers[count]; + + if(ptr->iDes) delete ptr->iDes; + if(ptr) delete ptr; + ptr = NULL; + + } + iBuffers.Reset( ); + iNalCount = 0; +} + + +// EOF \ No newline at end of file