dvrengine/CommonRecordingEngine/src/CCRRtpFileSource.cpp
branchRCL_3
changeset 23 13a33d82ad98
parent 0 822a42b6c3f1
--- /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