multimediacommscontroller/mmccavcpayloadformat/src/rfc3984decode.cpp
changeset 0 1bce908db942
--- /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) TBuf8<aBuffer.Size());    		// allocating memory for data
+    	pBuffer = HBufC8::New(aBuffer.Size());
+    	if(!pBuffer)
+    	{
+    		User::Leave(KErrNoMemory);
+    	}
+    	CleanupStack::Pop();
+    	TPtr8 pDes = pBuffer->Des( );					
+    	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) TBuf8<aBuffer.Size());    		// allocating memory for data
+    			//pBuffer = HBufC8::New(aBuffer.Size());
+    			pBuffer = HBufC8::New(nalSize);
+    			if(!pBuffer)
+    			{
+    				User::Leave(KErrNoMemory);
+    			}
+    			CleanupStack::Pop();
+    			TPtr8 pDes1 = pBuffer->Des( );
+    			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