diff -r 826cea16efd9 -r 13a33d82ad98 dvrengine/CommonRecordingEngine/DvrRtpUtils/src/CRtpPacket.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dvrengine/CommonRecordingEngine/DvrRtpUtils/src/CRtpPacket.cpp Wed Sep 01 12:20:37 2010 +0100 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Class to RTP packet parsing.* +*/ + + + + +// INCLUDE FILES +#include "CRtpPacket.h" + +// CONSTANTS +const TInt KRtpPacketVersion( 2 ); +const TInt KRtpMinHeaderLength( 12 ); + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CRtpPacket::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CRtpPacket* CRtpPacket::NewL() + { + CRtpPacket* self = CRtpPacket::NewLC(); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CRtpPacket* CRtpPacket::NewLC() + { + CRtpPacket* self = new( ELeave ) CRtpPacket(); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::CRtpPacket +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CRtpPacket::CRtpPacket() : iPayload( NULL, 0 ) + { + // None + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CRtpPacket::ConstructL() + { + // None + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::CRtpPacket +// Destructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CRtpPacket::~CRtpPacket() + { + if ( iRtpRecvHeader.iHeaderExtension ) + { + // Remove iData + delete[] ( iRtpRecvHeader.iHeaderExtension )->iData; + delete iRtpRecvHeader.iHeaderExtension; + } + + if ( iRtpRecvHeader.iCsrcList ) + { + delete[] iRtpRecvHeader.iCsrcList; + } + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::ParseRtcp +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CRtpPacket::ParseRtp( const TDesC8& aPktBuf ) + { + if ( aPktBuf.Length() < KRtpMinHeaderLength ) + { + SetTimeStamp( 0 ); + iPayload.Set( NULL, 0 ); + return KErrUnderflow; + } + + // 1st byte + TInt byte( 0 ); + TUint8 version_flag( ( aPktBuf[byte] & 0xc0 ) >> 6 ); + // v=2 is mandatory + if ( version_flag != KRtpPacketVersion ) + { + SetTimeStamp( 0 ); + iPayload.Set( NULL, 0 ); + return KErrNotSupported; + } + + iRtpRecvHeader.iPadding = ( aPktBuf[byte] >> 5 ) & 1; + iRtpRecvHeader.iExtension = ( aPktBuf[byte] >> 4 ) & 1; + iRtpRecvHeader.iCsrcCount = aPktBuf[byte++] & 0xf; + + // 2nd byte + iRtpRecvHeader.iMarker = ( aPktBuf[byte] >> 7 ) & 1; + iRtpRecvHeader.iPayloadType = aPktBuf[byte++] & 0x7f; + + // 3rd - 4th bytes + TUint16 seq_no( aPktBuf[byte++] << 8 ); + seq_no |= aPktBuf[byte++]; + iRtpRecvHeader.iSeqNum = seq_no; + + // 5th - 8th bytes + TUint32 timestamp( Read32Bits( aPktBuf, byte ) ); + iRtpRecvHeader.iTimestamp = timestamp; + + // 9th - 12th bytes + TInt32 ssrc( Read32Bits( aPktBuf, byte ) ); + + // 13th - bytes (optional) + // total len = 4 * csrc_len (bytes) + if ( iRtpRecvHeader.iCsrcCount > 0 ) + { + iRtpRecvHeader.iCsrcList = new TUint32[iRtpRecvHeader.iCsrcCount]; + //TInt32* csrc = new TInt32[csrc_len]; + for ( TInt i( 0 ); i < iRtpRecvHeader.iCsrcCount; i++ ) + { + iRtpRecvHeader.iCsrcList[i] = Read32Bits( aPktBuf, byte ); + } + } + + // optional extension field + if ( iRtpRecvHeader.iExtension == 1 ) + { + /* + iRtpRecvHeader.iHeaderExtension = new TRtpHeaderExtension(); + // 16 bits + TInt16 op_code( aPktBuf[byte++] << 8 ); + op_code |= aPktBuf[byte++]; + iRtpRecvHeader.iHeaderExtension->iType = op_code; + + // 16 bits + TInt16 op_code_data_length = aPktBuf[byte++] << 8; + op_code_data_length |= aPktBuf[byte++]; + iRtpRecvHeader.iHeaderExtension->iLength = op_code_data_length; + + op_code_data_length * 4 bytes of extension data + op_code_data = new TInt32[op_code_data_length]; + iRtpRecvHeader.iHeaderExtension->iData = new TInt32[op_code_data_length]; + for ( TInt i( 0 ); i < op_code_data_length; i++ ) + { + iRtpRecvHeader.iHeaderExtension)->iData[i] = Read32Bits( aPktBuf, byte ); + } + */ + } + + // The rest is payload data + iPayload.Set( aPktBuf.Mid( byte ) ); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::SetTimeStamp +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CRtpPacket::SetTimeStamp( const TUint32 aTs ) + { + iRtpRecvHeader.iTimestamp = aTs; + } + +// ----------------------------------------------------------------------------- +// CRtpPacket::Read32Bits +// +// ----------------------------------------------------------------------------- +// +TUint CRtpPacket::Read32Bits( const TPtrC8& aPktBuf, TInt& aByte ) + { + TUint ret( ( ( TUint )( aPktBuf[aByte++] ) ) << 24 ); + ret |= ( ( TUint )( aPktBuf[aByte++] ) ) << 16; + ret |= ( ( TUint )( aPktBuf[aByte++] ) ) << 8; + ret |= ( ( TUint )( aPktBuf[aByte++] ) ); + + return ret; + } + +// End of File