dvrengine/CommonRecordingEngine/DvrRtpUtils/src/CRtpPacket.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:37 +0100
branchRCL_3
changeset 23 13a33d82ad98
parent 0 822a42b6c3f1
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201029 Kit: 201035

/*
* 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