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