--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dvrengine/CommonRecordingEngine/DvrRtpUtils/src/CRtpTsConverter.cpp Thu Dec 17 09:14:38 2009 +0200
@@ -0,0 +1,222 @@
+/*
+* 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 provide TS conversion for an RTP-stream based on*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "CRtpTsConverter.h"
+#include <ipvideo/CRtpUtil.h>
+#include "videoserviceutilsLogger.h"
+
+// CONSTANTS
+const TInt KValidRtcpType( 200 );
+const TInt KTypeBytesPoint( 1 );
+const TInt KNtpSecBytesPoint( 8 );
+const TInt KNtpFracBytesPoint( 12 );
+const TInt KRtcpTsBytesPoint( 16 );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CRtpTsConverter* CRtpTsConverter::NewL( const TUint aClockRate )
+ {
+ CRtpTsConverter* self = new( ELeave ) CRtpTsConverter( aClockRate );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::CRtpTsConverter
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CRtpTsConverter::CRtpTsConverter( const TUint aClockRate )
+ : iClockRate( aClockRate ),
+ iOffset( 0 ),
+ iInitiated( EFalse )
+ {
+ // None
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CRtpTsConverter::ConstructL()
+ {
+ // None
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::CRtpTsConverter
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CRtpTsConverter::~CRtpTsConverter()
+ {
+ // None
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::Init
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpTsConverter::Init( const TDesC8& aRtcpPkt )
+ {
+ // Verify packet type?
+ if ( aRtcpPkt.Length() > ( KRtcpTsBytesPoint + KIntegerBytes ) &&
+ aRtcpPkt[KTypeBytesPoint] == KValidRtcpType && iClockRate > 0 )
+ {
+ // Handle RTCP packet
+ TUint ntp_sec( 0 );
+ TUint ntp_frac( 0 );
+ TUint rtcp_ts( 0 );
+ TInt err( CRtpUtil::GetValue(
+ aRtcpPkt.Mid( KNtpSecBytesPoint, KIntegerBytes ), ntp_sec ) );
+ if ( !err )
+ {
+ LOG1( "CRtpTsConverter::Init(), NTP Timestamp, MSW: %u", ntp_sec );
+ err = CRtpUtil::GetValue(
+ aRtcpPkt.Mid( KNtpFracBytesPoint, KIntegerBytes ), ntp_frac );
+ }
+ if ( !err )
+ {
+ LOG1( "CRtpTsConverter::Init(), NTP Timestamp, LSW: %u", ntp_frac );
+ err = CRtpUtil::GetValue(
+ aRtcpPkt.Mid( KRtcpTsBytesPoint, KIntegerBytes ), rtcp_ts );
+ }
+
+ if ( !err )
+ {
+ LOG1( "CRtpTsConverter::Init(), RTP Timestamp: %u", rtcp_ts );
+ // Calculate the wallclock time when this RTCP packet is generated
+ TUint wallClock( ( ntp_sec & 0x00FF ) * 1000 );
+ wallClock += ( ( ( ntp_frac >> 16 ) & 0x0000FFFF ) * 1000 ) >> 16;
+
+ // Compute the proper time offset
+ iOffset = ComputeOffset( rtcp_ts, wallClock, iClockRate );
+ }
+ }
+ }
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::Init
+// Compute the proper time offset. No wallclok time available.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpTsConverter::Init( const TUint& aTs )
+ {
+ iOffset = ComputeOffset( aTs, 0, iClockRate );
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::Initiated
+// Returns: initiated status of converter.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CRtpTsConverter::Initiated()
+ {
+ return iInitiated;
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::UnInitiate
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpTsConverter::UnInitiate()
+ {
+ iInitiated = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::ConvertTs
+// Returns: converted unsigned integer value of timestamp.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TUint CRtpTsConverter::ConvertTs(
+ const TUint aTimestamp,
+ TBool aUseWallClock )
+ {
+ TUint ret( KMaxTUint );
+
+ if ( iClockRate == KPipelineClockRate )
+ {
+ ret = aTimestamp - iOffset;
+ }
+ else
+ {
+ if ( iClockRate > 0 )
+ {
+ ret = aTimestamp - iOffset;
+
+ if ( aUseWallClock )
+ {
+ TUint sec( ret / iClockRate );
+ TUint subSec( ret % iClockRate );
+ ret = ( ( sec * KPipelineClockRate ) +
+ ( subSec * KPipelineClockRate ) / iClockRate );
+ }
+ }
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CRtpTsConverter::ComputeOffset
+// Returns: offset of the RTP timestamp.
+// -----------------------------------------------------------------------------
+//
+TUint CRtpTsConverter::ComputeOffset(
+ TUint aRtpTime,
+ TUint aSeekTime,
+ TInt aClockRate )
+ {
+ TUint ret( KMaxTUint );
+
+ if ( aClockRate )
+ {
+ TUint rtpSec( aRtpTime / aClockRate );
+ TUint rtpFracSecTU( aRtpTime % aClockRate ); // transport units
+ TUint seekSec( aSeekTime / 1000 );
+ TUint seekFracSecTU( ( ( aSeekTime % 1000) * aClockRate ) / 1000 );
+
+ TUint offsetSec( rtpSec - seekSec );
+ TUint offsetFracSecTU( rtpFracSecTU - seekFracSecTU );
+
+ if ( rtpFracSecTU < seekFracSecTU )
+ {
+ offsetSec--;
+ offsetFracSecTU = aClockRate + rtpFracSecTU - seekFracSecTU;
+ }
+
+ ret = ( offsetSec * aClockRate ) + offsetFracSecTU;
+ iInitiated = ETrue;
+ }
+
+ return ret;
+ }
+
+// End of File