--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dvrengine/CommonRecordingEngine/src/CCRRtpFileSource.cpp Wed Sep 01 12:20:37 2010 +0100
@@ -0,0 +1,521 @@
+/*
+* 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 that reads RTP packets from propriatary file format.*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "CCRRtpFileSource.h"
+#include <ipvideo/CRtpClipHandler.h>
+#include "CCRPacketBuffer.h"
+#include "videoserviceutilsLogger.h"
+
+// CONSTANTS
+const TInt KGroupsCountPoint( 0 );
+const TInt KBufferThesholdCount( 20 );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCRRtpFileSource* CCRRtpFileSource::NewL(
+ const SCRRtpPlayParams& aParams,
+ CRtpClipHandler*& aClipHandler,
+ MCRStreamObserver& aSessionObs,
+ CCRStreamingSession& aOwningSession )
+ {
+ CCRRtpFileSource* self = new( ELeave )
+ CCRRtpFileSource( aClipHandler, aSessionObs, aOwningSession );
+ CleanupStack::PushL( self );
+ self->ConstructL( aParams );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCRRtpFileSource* CCRRtpFileSource::NewL(
+ const RFile& aRtpHandle,
+ CRtpClipHandler*& aClipHandler,
+ MCRStreamObserver& aSessionObs,
+ CCRStreamingSession& aOwningSession )
+ {
+ CCRRtpFileSource* self = new( ELeave )
+ CCRRtpFileSource( aClipHandler, aSessionObs, aOwningSession );
+ CleanupStack::PushL( self );
+ self->ConstructL( aRtpHandle );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::CCRRtpFileSource
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CCRRtpFileSource::CCRRtpFileSource(
+ CRtpClipHandler*& aClipHandler,
+ MCRStreamObserver& aSessionObs,
+ CCRStreamingSession& aOwningSession )
+ : CCRPacketSourceBase( aOwningSession, CCRStreamingSession::ECRRtpSourceId ),
+ iClipHandler( aClipHandler ),
+ iSessionObs( aSessionObs ),
+ iInitialTime( KMaxTUint ),
+ iClipPauseSent( 0 )
+ {
+ // None
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::ConstructL( const SCRRtpPlayParams& aParams )
+ {
+ const TBool timeShift(
+ aParams.iFileName.Find( KDvrTimeShiftFile ) > KErrNotFound );
+ LOG1( "CCRRtpFileSource::ConstructL() in, timeShift: %d", timeShift );
+
+ // RTP clip handler
+ User::LeaveIfNull( iClipHandler );
+ iClipHandler->RegisterReadObserver( this );
+ iClipHandler->StartPlayBackL( aParams, timeShift );
+
+ LOG( "CCRRtpFileSource::ConstructL() out" );
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::ConstructL( const RFile& aRtpHandle )
+ {
+ LOG( "CCRRtpFileSource::ConstructL() in" );
+
+ User::LeaveIfNull( iClipHandler );
+ iClipHandler->RegisterReadObserver( this );
+ iClipHandler->StartPlayBackL( aRtpHandle );
+
+ LOG( "CCRRtpFileSource::ConstructL() out" );
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::~CCRRtpFileSource
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CCRRtpFileSource::~CCRRtpFileSource()
+ {
+ LOG( "CCRRtpFileSource::~CCRRtpFileSource()" );
+
+ if ( iClipHandler )
+ {
+ iClipHandler->StopPlayBack( KErrNone, 0 );
+ }
+
+ delete iSdp;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::GetSdp
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::GetSdp( TPtrC8& aSdp )
+ {
+ if ( iSdp )
+ {
+ aSdp.Set( iSdp->Des() );
+ return KErrNone;
+ }
+
+ return KErrNotReady;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::SetBuffer
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::SetBuffer( CCRPacketBuffer* aBuffer )
+ {
+ iBuffer = aBuffer;
+ iBuffer->ContinousStream( EFalse );
+ iBuffer->MoreComing( EFalse );
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::PostActionL
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::PostActionL()
+ {
+ LOG( "CCRRtpFileSource::PostActionL(), SDP will be handled !" );
+
+ // SDP
+ if ( iClipHandler )
+ {
+ iSdp = iClipHandler->GetClipSdpL();
+ }
+
+ // Notify that SDP available
+ iSessionObs.StatusChanged( MCRPacketSource::ERtpStateSdpAvailable );
+ delete iSdp; iSdp = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::Restore
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::Restore()
+ {
+ const TInt err( NextClipGroup( ETrue ) );
+ if ( err && err != KErrEof )
+ {
+ LOG1( "CCRRtpFileSource::Restore(), NextClipGroup() err: %d", err );
+ iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::Play
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::Play( const TReal& aStartPos, const TReal& aEndPos )
+ {
+ LOG3( "CCRRtpFileSource::Play(), aStartPos: %f, aEndPos: %f, iClipPauseSent: %d",
+ aStartPos, aEndPos, iClipPauseSent );
+ // Play for player?
+ if ( aStartPos == KRealZero && aEndPos == KRealZero )
+ {
+ iInitialTime = KMaxTUint;
+ return NextClipGroup( EFalse );
+ }
+
+ // Loading started in player?
+ if ( aStartPos == KRealMinusOne && aEndPos == KRealMinusOne )
+ {
+ const TBool pauseSent( iClipPauseSent > 0 );
+ if ( pauseSent )
+ {
+ iClipPauseSent--;
+ iBuffer->ResetBuffer();
+ }
+
+ // Read more from clip
+ TInt err( NextClipGroup( EFalse ) );
+ if ( !err && pauseSent )
+ {
+ iInitialTime = KMaxTUint;
+ err = ECRStreamPauseHanling;
+ LOG( "CCRRtpFileSource::Play(), ECRStreamPauseHanling" );
+ }
+ else
+ {
+ if ( err == KErrEof )
+ {
+ err = KErrNone;
+ if ( iClipHandler )
+ {
+ TRAP( err, iClipHandler->SetSeekPointL( 0 ) );
+ }
+ if ( !err )
+ {
+ err = ECRStreamEndHandling;
+ LOG( "CCRRtpFileSource::Play(), ECRStreamEndHandling" );
+ }
+ }
+ }
+
+ return err;
+ }
+
+ return KErrCompletion;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::Stop
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::Stop()
+ {
+ LOG( "CCRRtpFileSource::Stop()" );
+
+ return RtpPosition( 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::SetPosition
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::SetPosition( const TInt64 aPosition )
+ {
+ TInt err( RtpPosition( TUint( aPosition / KSiKilo ) ) );
+ if ( !err )
+ {
+ err = NextClipGroup( EFalse );
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::GetPosition
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::GetPosition( TInt64& aPosition, TInt64& aDuration )
+ {
+ if ( iBuffer && iClipHandler )
+ {
+ if ( iInitialTime != KMaxTUint )
+ {
+ aPosition += TInt64( iInitialTime ) * KSiKilo;
+ }
+ else
+ {
+ LOG( "CCRRtpFileSource::GetPosition(), iInitialTime not valid !" );
+ }
+
+ aDuration = TInt64( iClipHandler->GetCurrentLength() ) * KSiKilo;
+#ifdef CR_ALL_LOGS
+ LOG2( "CCRRtpFileSource::GetPosition(), aPosition: %u, aDuration: %u",
+ ( TUint )( aPosition / KSiKilo ), ( TUint )( aDuration / KSiKilo ) );
+#endif // CR_ALL_LOGS
+ return KErrNone;
+ }
+
+ return KErrCompletion;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::GroupReadedL
+// Adds packets to the buffer when finished asyncronous group reading.
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::GroupReadedL(
+ const TDesC8& aGroup,
+ const TUint aGroupTime,
+ const TBool aLastGroup )
+ {
+ // Group time
+ if ( iInitialTime == KMaxTUint )
+ {
+ iInitialTime = aGroupTime;
+ }
+
+ // Data valid?
+ TInt point( KGroupsCountPoint + KPacketsCountBytes );
+ const TInt total( aGroup.Length() );
+ if ( point > total )
+ {
+ LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Total Count !" );
+ User::Leave( KErrCorrupt );
+ }
+
+ // Packets total count (PTC)
+ const TInt totalCount( CRtpUtil::GetValueL(
+ aGroup.Mid( KGroupsCountPoint, KPacketsCountBytes ) ) );
+ if ( totalCount > 0 )
+ {
+ iBuffer->MoreComing( ETrue );
+ }
+
+ // Loop all packets
+ for ( TInt i( 0 ); i < totalCount; i++ )
+ {
+ // Corrupted?
+ if ( ( point + KPacketSizeBytesLen ) > total )
+ {
+ LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Size !" );
+ User::Leave( KErrCorrupt );
+ }
+
+ // Packet total Size (PTS)
+ TInt packetSize( CRtpUtil::GetValueL(
+ aGroup.Mid( point, KPacketSizeBytesLen ) ) );
+ // Corrupted?
+ if ( packetSize <= 0 || ( point + packetSize ) > total )
+ {
+ LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Payload !" );
+ User::Leave( KErrCorrupt );
+ }
+
+ // Packet type
+ point += KPacketSizeBytesLen;
+ const MRtpFileWriteObserver::TRtpType type(
+ ( MRtpFileWriteObserver::TRtpType )( aGroup[point] ) );
+ point += KPacketTypeBytesLen;
+ packetSize -= ( KPacketSizeBytesLen + KPacketTypeBytesLen );
+
+ // Insert packet to the buffer
+ const TPtrC8 packet( aGroup.Mid( point, packetSize ) );
+
+#ifdef CR_ALL_LOGS
+ const TUint8* pointer( &packet[2] );
+ TInt seq( BigEndian::Get16( pointer ) );
+ LOG3( "CCRRtpFileSource::GroupReadedL(), type: %d, packet: %d, seq: %d",
+ type, packet.Length(), seq );
+ //RFileLogger::WriteFormat( _L( "livetv" ), _L( "play.log" ), EFileLoggingModeAppend,
+ // _L( "GroupReadedL(), type: %d, packet: %d, seq: %d" ), type, packet.Length(), seq );
+#endif // CR_ALL_LOGS
+
+ MCRPacketSource::TCRPacketStreamId stream( MCRPacketSource::EStreamIdCount );
+ if ( TypeToStream( type, stream ) )
+ {
+ // Last packet in group?
+ if ( i >= ( totalCount - 1 ) )
+ {
+ iBuffer->MoreComing( EFalse );
+ if ( aLastGroup && stream != MCRPacketSource::EStreamEndTag )
+ {
+ LOG( "CCRRtpFileSource::GroupReadedL(), Misses last group from clip !" );
+ stream = MCRPacketSource::EStreamEndTag;
+ }
+ }
+
+ // Packet to buffer
+ iBuffer->AddPacket( stream, packet );
+ }
+
+ point+= packetSize;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::ReadStatus
+// -----------------------------------------------------------------------------
+//
+void CCRRtpFileSource::ReadStatus( TInt aStatus )
+ {
+ LOG1( "CCRRtpFileSource::ReadStatus(), aStatus: %d", aStatus );
+
+ switch ( aStatus )
+ {
+ case MRtpFileReadObserver::ERtpTimeShifTEnd:
+ break;
+
+ default:
+ iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing );
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::NextClipGroup
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::NextClipGroup( const TBool aForce )
+ {
+ if ( iBuffer && iClipHandler )
+ {
+ if ( aForce || iBuffer->PacketsMinCount() < KBufferThesholdCount )
+ {
+ TRAPD( err, iClipHandler->NextClipGroupL() );
+ return err;
+ }
+
+ return KErrNone;
+ }
+
+ return KErrNotReady;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::RtpPosition
+// -----------------------------------------------------------------------------
+//
+TInt CCRRtpFileSource::RtpPosition( const TUint aPosition )
+ {
+ LOG1( "CCRRtpFileSource::RtpPosition(), aPosition: %d", aPosition );
+
+ TInt err( KErrCompletion );
+ if ( iBuffer && iClipHandler )
+ {
+ TRAP( err, iClipHandler->SetSeekPointL( aPosition ) );
+ if ( !err )
+ {
+ iInitialTime = KMaxTUint;
+ iBuffer->ResetBuffer();
+ }
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCRRtpFileSource::TypeToStream
+// -----------------------------------------------------------------------------
+//
+TBool CCRRtpFileSource::TypeToStream(
+ const MRtpFileWriteObserver::TRtpType& aType,
+ MCRPacketSource::TCRPacketStreamId& aStream )
+ {
+ switch ( aType )
+ {
+ case MRtpFileWriteObserver::ERtpAudio:
+ aStream = MCRPacketSource::EAudioStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtcpAudio:
+ aStream = MCRPacketSource::EAudioControlStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtpVideo:
+ aStream = MCRPacketSource::EVideoStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtcpVideo:
+ aStream = MCRPacketSource::EVideoControlStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtpSubTitle:
+ aStream = MCRPacketSource::ESubTitleStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtcpSubTitle:
+ aStream = MCRPacketSource::ESubTitleControlStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtpClipPause:
+ LOG( "CCRRtpFileSource::TypeToStream(), ERtpClipPause" );
+ iClipPauseSent = ETrue;
+ aStream = MCRPacketSource::EDisContinousStream;
+ break;
+
+ case MRtpFileWriteObserver::ERtpClipEnd:
+ LOG( "CCRRtpFileSource::TypeToStream(), ERtpClipEnd" );
+ aStream = MCRPacketSource::EStreamEndTag;
+ break;
+
+ default:
+ LOG1( "CCRRtpFileSource::TypeToStream(), Default case, aType: %d",
+ aType );
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// End of File