dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpClipHandler.cpp
branchRCL_3
changeset 23 13a33d82ad98
parent 0 822a42b6c3f1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpClipHandler.cpp	Wed Sep 01 12:20:37 2010 +0100
@@ -0,0 +1,584 @@
+/*
+* 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:    Implementation of RTP clip handler class.*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <ipvideo/CRtpClipHandler.h>
+#include "CRtpToFile.h"
+#include "CRtpFromFile.h"
+#include "videoserviceutilsLogger.h"
+
+// CONSTANTS
+const TInt KDvrMaxTimeshiftDelta( 1 * 60 * 60 ); //  1 hour
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CRtpClipHandler* CRtpClipHandler::NewL()
+    {
+    CRtpClipHandler* self = new( ELeave ) CRtpClipHandler();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::CRtpClipHandler
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CRtpClipHandler::CRtpClipHandler()
+  : iClipVersion( 0 ),
+    iSaveNameIndex( KErrNotFound ),
+    iReadNameIndex( KErrNotFound ),
+    iTsPauseState( EFalse )
+    {
+    // None
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CRtpClipHandler::ConstructL()
+    {
+    LOG( "CRtpClipHandler::ConstructL()" );
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::~CRtpClipHandler
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CRtpClipHandler::~CRtpClipHandler()
+    {
+    LOG( "CRtpClipHandler::~CRtpClipHandler() in" );
+    
+    StopRecording( KErrCancel );
+    StopPlayBack( KErrCancel, 0 );
+
+    LOG( "CRtpClipHandler::~CRtpClipHandler() out" );
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::RegisterWriteObserver
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::RegisterWriteObserver(
+    MRtpFileWriteObserver* aObs )
+    {
+    LOG1( "CRtpClipHandler::RegisterWriteObserver(), aObs: %d", aObs );
+    iWriteObs = aObs;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::RegisterReadObserver
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::RegisterReadObserver( MRtpFileReadObserver* aObs )
+    {
+    LOG1( "CRtpClipHandler::RegisterReadObserver(), aObs: %d", aObs );
+
+    iReadObs = aObs;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::StartRecordingL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::StartRecordingL(
+    const MRtpFileWriteObserver::SRtpRecParams& aRecParams,
+    const MRtpFileWriteObserver::TRtpSaveAction& aAction )
+    {
+    LOG1( "CRtpClipHandler::StartRecordingL() in, aAction: %d", aAction );
+    
+    // Stop possible existing recording
+    StopRecording( KErrNone );
+    iSaveNameIndex = 0;
+    
+    // If InitRtpSaveL leaves, iRtpSave is not NULL, but is in undefined state.
+    // This causes problems - may crash when StopRecording is called.
+    // Better to trap and cleanup here.
+    TRAPD( err,
+         // Init recording ( iRtpSave deleted in StopRecording() )
+         iRtpSave = CRtpToFile::NewL( *this, *iWriteObs );
+         iRtpSave->InitRtpSaveL( aRecParams, aAction );
+         );
+    if ( err )
+        {
+        delete iRtpSave; iRtpSave = NULL;
+        User::Leave( err );
+        }
+    
+    LOG( "CRtpClipHandler::StartRecordingL() out" );
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::SaveNextGroupL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::SaveNextGroupL(
+    TPtr8& aGroup,
+    TUint aGroupLength,
+    const MRtpFileWriteObserver::TRtpSaveAction& aAction )
+    {
+    User::LeaveIfNull( iWriteObs );
+    User::LeaveIfNull( iRtpSave );
+    
+    // Passes save action to ring buffer
+    const TUint seekPoint( iRtpSave->SaveNextGroupL( 
+                           aGroup, aGroupLength, aAction ) ); 
+    
+    // aGroupLength is set to non zero if time shift ongoing?
+    if ( aGroupLength > 0 )
+        {
+        CRtpFileBase::STimeShiftSeek shiftSeek;
+        shiftSeek.iGroupTime = aGroupLength;
+        shiftSeek.iSeekpoint = seekPoint;
+        shiftSeek.iNameIndex = iSaveNameIndex;
+        iShiftSeek.Append( shiftSeek );
+        
+        // Time shift max length
+        if ( ( ( iShiftSeek.Count() - 1 ) *  KNormalRecGroupLength ) > 
+                                             KDvrMaxTimeshiftDelta )
+            {
+            LOG( "CRtpClipHandler::SaveNextGroupL(), Timeshift max time !" );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::WritingActive
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CRtpClipHandler::WritingActive( void ) const
+    {
+    if ( iRtpSave )
+        {
+        return iRtpSave->IsActive();
+        }
+    
+    return EFalse;
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::GetCurrentLength
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TUint CRtpClipHandler::GetCurrentLength( void ) const
+    {
+    TUint length( 0 );
+    if ( iRtpRead )
+        {
+        length = iRtpRead->Duration();
+        }
+    else
+        {
+        if ( iRtpSave )
+            {
+            const TInt count( iShiftSeek.Count() );
+            if ( count > 0 )
+                {
+                // Time shift
+                for ( TInt i( 0 ); i < count; i++ )
+                    {
+                    length += iShiftSeek[i].iGroupTime;
+                    }
+                }
+            else
+                {
+                // Rec ongoing
+                length = iRtpSave->GetCurrentLength();
+                }
+            }
+        }
+
+    return length;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::TimeShiftPauseL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::TimeShiftPauseL()
+    {
+    LOG2( "CRtpClipHandler::TimeShiftPauseL(), iRtpSave: %d, iTsPauseState: %d", 
+                                               iRtpSave, iTsPauseState ); 
+    User::LeaveIfNull( iRtpSave );
+    if ( !iTsPauseState )
+        {
+        // Use clip as a ring buffer
+        iRtpSave->ActivateGroupsReuseL();
+        iTsPauseState = ETrue;
+        }
+    else
+        {
+        // Switch to next file
+        iSaveNameIndex++;
+        MRtpFileWriteObserver::SRtpRecParams recParams;
+        DefaultRecParams( recParams, iSaveNameIndex );
+        iRtpSave->SwapClipL( recParams );
+        iTsPauseState = EFalse;
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::DefaultRecParams
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::DefaultRecParams(
+    MRtpFileWriteObserver::SRtpRecParams& aParams,
+    const TInt aIndex )
+    {
+    aParams.iClipPath = KDvrTimeShiftFile;
+    aParams.iClipPath.AppendNum( aIndex );
+    aParams.iSdpData.Set( NULL, 0 );
+    aParams.iService.Set( KNullDesC );
+    aParams.iProgram.Set( KNullDesC );
+    aParams.iPostRule = 0;
+    aParams.iParental = 0;
+    aParams.iStartTime = 0;
+    aParams.iEndTime = TInt64( KDvrMaximumTimeShift ) * 1e6;
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::UpdateRecordEndTime
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::UpdateRecordEndTime( const TTime& aEndTime ) 
+    {
+    if ( iRtpSave )
+        {
+        iRtpSave->UpdateRecordEndTime( aEndTime );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::ResumeRecordingL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::ResumeRecordingL( void )
+    {
+    LOG1( "CRtpClipHandler::ResumeRecordingL(), iRtpSave: %d", iRtpSave ); 
+    
+    if ( iRtpSave )
+        {
+        iRtpSave->UpdatePreviousTimeL();
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::StopRecording
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::StopRecording( const TInt aError )
+    {
+    LOG2( "CRtpClipHandler::StopRecording(), aError: %d, iRtpSave: %d",
+                                             aError, iRtpSave );
+    
+    if ( iRtpSave )
+        {
+        // Update clip end point if watching sametime
+        if ( iRtpRead )
+            {
+            iRtpRead->UpdateLastSeekAddr();
+            }
+        
+        // Stop recording
+        iRtpSave->StopRtpSave( aError );
+
+        // Delete possible time shift files
+        if ( !iRtpRead )
+            {
+            iRtpSave->DeleteTimeShiftFiles( iShiftSeek );
+            }
+        }
+    
+    delete iRtpSave; iRtpSave = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::StartPlayBackL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::StartPlayBackL(
+    const SCRRtpPlayParams& aParams,
+    const TBool aTimeShift )
+    {
+    LOG1( "CRtpClipHandler::StartPlayBackL(), path: %S", &aParams.iFileName );
+    LOG1( "CRtpClipHandler::StartPlayBackL(), aTimeShift: %d", aTimeShift );
+
+    // Stop possible existing
+    StopPlayBack( KErrNone, 0 );
+    
+    // Time shift mode?
+    if ( aTimeShift )
+        {
+        // Open file for time shift mode
+        User::LeaveIfNull( iRtpSave );
+        iRtpRead = CRtpFromFile::NewL( *iReadObs, iRtpSave );
+        iReadNameIndex = ( iShiftSeek.Count() )? iShiftSeek[0].iNameIndex: 0;
+        TPath clipPath( KDvrTimeShiftFile );
+        clipPath.AppendNum( iReadNameIndex );
+        iRtpRead->InitRtpReadL( clipPath, iClipVersion, aTimeShift );
+        }
+    else
+        {
+        // Open file, during recording?
+        if ( iRtpSave && iRtpSave->ClipPath() )
+            {
+            if ( !aParams.iFileName.Compare( iRtpSave->ClipPath()->Des() ) )
+                {
+                iRtpRead = CRtpFromFile::NewL( *iReadObs, iRtpSave );
+                }
+            }
+        
+        // Open file, normal playback?
+        if ( !iRtpRead )
+            {
+            iRtpRead = CRtpFromFile::NewL( *iReadObs, NULL );
+            }
+        
+        iRtpRead->InitRtpReadL( aParams.iFileName, iClipVersion, EFalse );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::StartPlayBackL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::StartPlayBackL( const RFile& aFileHandle )
+    {
+    LOG( "CRtpClipHandler::StartPlayBackL(), with handle" );
+
+    // Stop possible existing
+    StopPlayBack( KErrNone, 0 );
+    
+    // Open file, during recording?
+    if ( iRtpSave && iRtpSave->ClipPath() )
+        {
+        TPath name( KNullDesC );
+        aFileHandle.FullName( name );
+        if ( !name.Compare( iRtpSave->ClipPath()->Des() ) )
+            {
+            iRtpRead = CRtpFromFile::NewL( *iReadObs, iRtpSave );
+            }
+        }
+    
+    // Open file, normal playback?
+    if ( !iRtpRead )
+        {
+        iRtpRead = CRtpFromFile::NewL( *iReadObs, NULL );
+        }
+    
+    iRtpRead->InitRtpReadL( aFileHandle, iClipVersion );
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::GetClipSdpL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC8* CRtpClipHandler::GetClipSdpL( void ) const
+    {
+    HBufC8* sdp = NULL;
+    if ( iRtpRead )
+        {
+        sdp = iRtpRead->GetClipSdpL();
+        }
+    
+    return sdp;
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::NextClipGroupL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::NextClipGroupL( void ) 
+    {
+    User::LeaveIfNull( iRtpRead );
+    if ( !iRtpRead->IsTimeShift() )
+        {
+        iRtpRead->ReadNextGroupL( KErrNotFound );
+        }
+    else 
+        {
+        // Handle time shift
+        TInt err( KErrNotFound );
+        if ( iShiftSeek.Count() )
+            {
+            // Need swap file?
+            SwapClipIfNeededL();
+
+            // Read next group
+            TRAP( err, iRtpRead->ReadNextGroupL( iShiftSeek[0].iSeekpoint ) );
+            if ( err != KErrInUse  )
+                {
+                iShiftSeek.Remove( 0 );
+                }
+            }
+        
+        // End time shift?
+        if ( err == KErrEof )
+            {
+            LOG( "CRtpClipHandler::NextClipGroupL(), Time shift play reached live !" );
+            User::LeaveIfNull( iReadObs );
+            iReadObs->ReadStatus( MRtpFileReadObserver::ERtpTimeShifTEnd );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::SetSeekPointL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::SetSeekPointL( const TUint aTime ) 
+    {
+    LOG1( "CRtpClipHandler::SetSeekPointL(), aTime: %u", aTime );
+
+    User::LeaveIfNull( iRtpRead );
+    if ( !iShiftSeek.Count() )
+        {
+        iRtpRead->SetSeekPointL( aTime );
+        }
+    else
+        {
+        const TInt count( iShiftSeek.Count() );
+        if ( count > 0 )
+            {
+            TUint total( 0 );
+            for ( TInt index( 0 ); index < count && aTime > total; index++ )
+                {
+                total += iShiftSeek[0].iGroupTime;
+                SwapClipIfNeededL();
+                iShiftSeek.Remove( 0 );
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::StopPlayBack
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CRtpClipHandler::StopPlayBack(
+    const TInt aError,
+    const TUint aPlayerBuf )
+    {
+    LOG2( "CRtpClipHandler::StopPlayBack(), aError: %d, iRtpRead: %d",
+                                            aError, iRtpRead );
+    if ( iRtpRead )
+        {
+        iRtpRead->StopRtpRead( aError, aPlayerBuf );
+
+        // Delete possible time shift files
+        if ( !iRtpSave )
+            {
+            iRtpRead->DeleteTimeShiftFiles( iShiftSeek );
+            }
+        }
+
+    delete iRtpRead; iRtpRead = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::RtpGroupSaved
+// Indicates that RPT packet save is ready.
+// -----------------------------------------------------------------------------
+//
+void CRtpClipHandler::RtpGroupSaved( const TInt aAction ) 
+    {
+    // Inform file reader that new group saved
+    if ( iRtpRead && aAction >= KErrNone )
+        {
+        iRtpRead->ReadSkippedGroup();
+        }
+
+    // Group saved
+    if ( iWriteObs )
+        {
+        if ( aAction != MRtpFileWriteObserver::ESaveEnd )
+            {
+            // Ready for next group
+            iWriteObs->GroupSaved();
+            }
+        else
+            {
+            // Recording full time
+            iWriteObs->WriteStatus( KErrNone );
+            }
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::CurrentFileReadPoint
+// Getter for file reader current point.
+// -----------------------------------------------------------------------------
+//
+TInt CRtpClipHandler::CurrentFileReadPoint( const TInt aIndex )
+    {
+    if ( iShiftSeek.Count() > aIndex )
+        {
+        if ( iShiftSeek[aIndex].iNameIndex == iSaveNameIndex )
+            {
+            return iShiftSeek[aIndex].iSeekpoint;
+            }
+        
+        return KErrNone;
+        }
+
+    return KErrNotFound;
+    }
+    
+// -----------------------------------------------------------------------------
+// CRtpClipHandler::SwapClipIfNeededL
+// Swap to next available clip in time shift array if needed.
+// -----------------------------------------------------------------------------
+//
+void CRtpClipHandler::SwapClipIfNeededL( void )
+    {
+    if ( iShiftSeek[0].iNameIndex != iReadNameIndex )
+        {
+        iReadNameIndex = iShiftSeek[0].iNameIndex;
+        TPath clipPath( KDvrTimeShiftFile );
+        clipPath.AppendNum( iReadNameIndex );
+        iRtpRead->SwapClipL( clipPath );
+        }
+    }
+    
+//  End of File