--- a/dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpFromFile.cpp Thu Aug 19 10:54:18 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,663 +0,0 @@
-/*
-* 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 the DVB-H Recording Manager RTP read class.*
-*/
-
-
-
-
-// INCLUDE FILES
-#include "CRtpToFile.h"
-#include "CRtpFromFile.h"
-#include <ipvideo/CRtpMetaHeader.h>
-#include <ipvideo/CRtpClipManager.h>
-#include "CRtpTimer.h"
-#include <bsp.h>
-#include "videoserviceutilsLogger.h"
-
-// CONSTANTS
-const TInt KReadTimerInterval( 1000 );
-
-// ============================ MEMBER FUNCTIONS ===============================
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::NewL
-// Static two-phased constructor. Leaves object to cleanup stack.
-// -----------------------------------------------------------------------------
-//
-CRtpFromFile* CRtpFromFile::NewL(
- MRtpFileReadObserver& aReadObs,
- CRtpToFile* aToFile )
- {
- CRtpFromFile* self = new( ELeave ) CRtpFromFile( aReadObs, aToFile );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::CRtpFromFile
-// C++ default constructor can NOT contain any code, that might leave.
-// -----------------------------------------------------------------------------
-//
-CRtpFromFile::CRtpFromFile( MRtpFileReadObserver& aReadObs, CRtpToFile* aToFile )
- : CRtpFileBase(),
- iReadObs( aReadObs ),
- iToFile( aToFile ),
- iSkippedRead( EFalse ),
- iDuration( 0 )
- {
- // None
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ConstructL
-// Symbian 2nd phase constructor can leave.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::ConstructL()
- {
- LOG( "CRtpFromFile::ConstructL()" );
-
- CRtpFileBase::ConstructL();
- }
-
-// -----------------------------------------------------------------------------
-// Destructor
-//
-CRtpFromFile::~CRtpFromFile()
-// -----------------------------------------------------------------------------
- {
- LOG( "CRtpFromFile::~CRtpFromFile()" );
-
- Cancel();
- delete iTimer; iTimer = NULL;
- delete iFileData; iFileData = NULL;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::InitRtpReadL
-// Sets path of RTP file.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::InitRtpReadL(
- const TDesC& aClipPath,
- TInt8& aVersion,
- const TBool aTimeShift )
- {
- LOG1( "CRtpFromFile::InitRtpReadL(), aClipPath: %S", &aClipPath );
-
- // File server
- if ( !iFs.Handle() )
- {
- User::LeaveIfError( iFs.Connect() );
- }
-
- // Open clip
- aVersion = SwapClipL( aClipPath );
-
- // Mode
- iMode = ( aTimeShift )? EModeTimeShift: EModeNormal;
-
-#ifdef CR_ALL_LOGS
- LogVariables( _L( "InitRtpReadL()" ) );
-#endif // CR_ALL_LOGS
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::InitRtpReadL
-// Sets path of RTP file.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::InitRtpReadL(
- const RFile& aFileHandle,
- TInt8& aVersion )
- {
- LOG( "CRtpFromFile::InitRtpReadL(), with handle" );
-
- // File handle
- if ( !iFs.Handle() )
- {
- User::LeaveIfError( iFs.Connect() );
- }
-
- // Duplicate handle
- iFile.Close();
- iFile.Duplicate( aFileHandle );
-
- // File header
- ReadClipHeaderL( aVersion );
- delete iCurrentPath; iCurrentPath = NULL;
- TFileName name( KNullDesC );
- iFile.FullName( name );
- iCurrentPath = name.AllocL();
-
- // Mode
- iMode = EModeNormal;
-
-#ifdef CR_ALL_LOGS
- LogVariables( _L( "InitRtpReadL()" ) );
-#endif // CR_ALL_LOGS
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::SwapClipL
-// Sets new path of RTP file.
-// -----------------------------------------------------------------------------
-//
-TInt8 CRtpFromFile::SwapClipL( const TDesC& aClipPath )
- {
- LOG1( "CRtpFromFile::SwapClipL(), aClipPath: %S", &aClipPath );
-
- iFile.Close();
- if ( !iFs.Handle() )
- {
- User::Leave( KErrBadHandle );
- }
-
- // Delete used clip
- if ( iMode == EModeTimeShift )
- {
- iFs.Delete( *iCurrentPath );
- }
-
- // Open new
- User::LeaveIfError( iFile.Open( iFs, aClipPath,
- EFileShareAny | EFileStream | EFileRead ) );
- // File header
- TInt8 version( 0 );
- ReadClipHeaderL( version );
- delete iCurrentPath; iCurrentPath = NULL;
- iCurrentPath = aClipPath.AllocL();
-
- return version;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ReadNextGroupL
-// Reads next RTP packets group from a specified file.
-// -----------------------------------------------------------------------------
-//
-TInt CRtpFromFile::ReadNextGroupL( const TInt aGroupPoint )
- {
- User::LeaveIfError( iMode );
- TBool delayedRead( EFalse );
-
- // Allready active??
- if ( iFileData )
- {
- if ( iTimer || IsActive() )
- {
- return KErrInUse; // Read already started, indication, not error
- }
- else
- {
- // Packet read may happen during iReadObs.RtpGroupReaded() call
- LOG( "CRtpFromFile::ReadNextGroupL(), Delayed read !" );
- delayedRead = ETrue;
- }
- }
-
- // Is watch during recording too close to live?
- if ( iToFile && iNextGroupPoint >= LastSeekAddr() )
- {
- iSkippedRead = ETrue;
- LOG( "CRtpFromFile::ReadNextGroupL(), Too close to live !" );
- return KErrEof; // No read actions now, indication, not error
- }
-
- // Group
- iThisGroup = ( aGroupPoint > KErrNotFound )? aGroupPoint: iNextGroupPoint;
-
- // Ok to read more?
- if ( iThisGroup > iLastSeekAddr || iGroupTime >= iDuration )
- {
- LOG( "CRtpFromFile::ReadNextGroupL(), All packets readed !" );
- User::Leave( KErrEof );
- }
-
- // Read group
- if ( delayedRead )
- {
- delete iTimer; iTimer = NULL;
- iTimer = CRtpTimer::NewL( *this );
- iTimer->After( KReadTimerInterval );
- }
- else
- {
- ReadGroupHeaderL();
- ReadNextGroupFromFileL();
- }
-
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::GetClipSdpL
-// Reads SDP from a current clip. SDP is stored to meta header during recording.
-// -----------------------------------------------------------------------------
-//
-HBufC8* CRtpFromFile::GetClipSdpL()
- {
- User::LeaveIfError( iMode );
- CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC(
- iFile, CRtpMetaHeader::EMetaRead );
- HBufC8* sdp = metaheader->ReadSdpDataL();
- CleanupStack::PopAndDestroy( metaheader );
- return sdp;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ReadSkippedGroup
-// Reads one RTP packet from a specified file if previous read was skipped.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::ReadSkippedGroup()
- {
- if ( iSkippedRead && iNextGroupPoint < LastSeekAddr() &&
- iMode != EModeNone && iFileData != NULL )
- {
- iSkippedRead = EFalse;
- iThisGroup = iNextGroupPoint;
- TRAP_IGNORE( ReadGroupHeaderL();
- ReadNextGroupFromFileL() );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::UpdateLastSeekAddr
-// Updates final last seek addres from clip write when recording stopped.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::UpdateLastSeekAddr()
- {
- if ( iToFile )
- {
- iDuration = iToFile->GetCurrentLength();
- iLastSeekAddr = iToFile->LastSeekAddr();
-
- LOG2( "CRtpFromFile::UpdateLastSeekAddr(), iLastSeekAddr: %d, iDuration: %d",
- iLastSeekAddr, iDuration );
- // Recording is stopped
- iToFile = NULL;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::SetSeekPointL
-// Sets the seek point of the clip.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::SetSeekPointL( const TUint aTime )
- {
- Cancel();
- delete iTimer; iTimer = NULL;
- delete iFileData; iFileData = NULL;
- User::LeaveIfError( iMode );
-
- // Group from the seek array, accuracy 30s
- iThisGroup = FindSeekGroup( aTime, ( iToFile )? iToFile->SeekArray(): iSeekArray );
- LOG2( "CRtpFromFile::SetSeekPointL(), aTime: %d, group from seek array: %d",
- aTime, iThisGroup );
- if ( iThisGroup == KErrNotFound )
- {
- iThisGroup = iFirstSeekAddr;
- }
- ReadGroupHeaderL();
-
- // Find group basing on the seek time, accuracy 0 - 3 s
- if ( aTime > 0 )
- {
- while ( aTime > iGroupTime && iNextGroupPoint < iLastSeekAddr )
- {
- // Next group
- iThisGroup = iNextGroupPoint;
- ReadGroupHeaderL();
-#ifdef CR_ALL_LOGS
- LOG2( "CRtpFromFile::SetSeekPointL(), iThisGroup: %u, iGroupTime: %u",
- iThisGroup, iGroupTime );
-#endif // CR_ALL_LOGS
- }
- }
-
- // Prepare for next read, one extra group back looks better
- iNextGroupPoint = ( iPrevGroupPoint > iFirstSeekAddr ) ?
- iPrevGroupPoint : iThisGroup;
- delete iFileData; iFileData = NULL;
-
- LOG1( "CRtpFromFile::SetSeekPointL(), iNextGroupPoint: %d",
- iNextGroupPoint );
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::StopRtpRead
-// Stops file reading.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::StopRtpRead( const TInt aStatus, const TUint aPlayerBuf )
- {
- LOG2( "CRtpFromFile::StopRtpRead(), aStatus: %d, aPlayerBuf: %u",
- aStatus, aPlayerBuf );
- LOG2( "CRtpFromFile::StopRtpRead(), iMode: %d, iGroupTime: %d",
- iMode, iGroupTime );
- Cancel();
- if ( iMode != EModeNone )
- {
- iFile.ReadCancel();
-
-#ifdef CR_ALL_LOGS
- LogVariables( _L( "StopRtpRead()" ) );
-#endif // CR_ALL_LOGS
- }
-
- delete iTimer; iTimer = NULL;
- delete iFileData; iFileData = NULL;
- if ( iMode == EModeNormal || iMode == EModeHandle )
- {
- // Try to seek back to what user sees for continue play spot
- if ( !aStatus & iThisGroup > 0 && iThisGroup < iLastSeekAddr )
- {
- const TInt thisGroup( iThisGroup );
- TRAPD( err, SetSeekPointL( iGroupTime - aPlayerBuf ) );
- if ( err )
- {
- LOG1( "CRtpFromFile::StopRtpRead(), SetSeekPointL Leaved: %d", err );
- iThisGroup = thisGroup;
- }
- }
-
- // Update meta header if no error
- if ( !aStatus )
- {
- TInt err ( KErrNone );
- if ( iToFile )
- {
- TRAP( err, iToFile->UpdatePlayAttL( iThisGroup ) );
- }
- else
- {
- TRAP( err, UpdatePlayAttL() );
- }
-
- // Possible error ignored
- if ( err )
- {
- LOG1( "CRtpFromFile::StopRtpRead(), UpdatePlayAttL Leaved: %d", err );
- }
- }
- }
-
- iMode = EModeNone;
- iFile.Close();
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::RunL
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::RunL()
- {
- User::LeaveIfError( iStatus.Int() );
-
- // All groups readed?
- if ( iThisGroup >= iLastSeekAddr ||
- ( iNextGroupPoint >= iLastSeekAddr &&
- iToFile && iToFile->Action() == MRtpFileWriteObserver::ESavePause ) )
- {
- LOG2( "CRtpFromFile::RunL(), All groups readed ! total: %d, iDuration: %d",
- iThisGroup, iDuration );
- iGroupTime = iDuration;
- }
-
- iReadObs.GroupReadedL( iDataPtr, iGroupTime, ( iGroupTime >= iDuration ) );
- delete iFileData; iFileData = NULL;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::RunError
-// -----------------------------------------------------------------------------
-//
-TInt CRtpFromFile::RunError( TInt aError )
- {
- LOG1( "CRtpFromFile::RunError(), RunL Leaved: %d", aError );
-
- iReadObs.ReadStatus( aError );
- StopRtpRead( aError, 0 );
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::DoCancel
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::DoCancel()
- {
- LOG( "CRtpFromFile::DoCancel()" );
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::TimerEventL
-// Internal timer call this when triggered.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::TimerEventL()
- {
- LOG( "CRtpFromFile::TimerEventL() in" );
-
- ReadGroupHeaderL();
- ReadNextGroupFromFileL();
- delete iTimer; iTimer = NULL;
-
- LOG( "CRtpFromFile::TimerEventL() out" );
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::TimerError
-// Internal timer call this when TimerEventL() leaves.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::TimerError( const TInt aError )
- {
- LOG1( "CRtpFromFile::TimerError(), TimerEventL Leaved: %d", aError );
-
- StopRtpRead( aError, 0 );
- delete iTimer; iTimer = NULL;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ReadClipHeaderL
-// Reads meta data and seek header from the beginning of the file.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::ReadClipHeaderL( TInt8& aVersion )
- {
- LOG1( "CRtpFromFile::ReadClipHeaderL(), iToFile: %d", iToFile );
-
- if ( !iToFile )
- {
- TInt seekArrayPoint( KErrNotFound );
- aVersion = ReadMetaHeaderL( iSeekHeaderPoint, seekArrayPoint );
- ReadSeekHeaderL();
-
- // Read seek array if exist
- if ( seekArrayPoint > iLastSeekAddr )
- {
- ReadSeekArrayL( seekArrayPoint );
- }
- }
- else // Recording ongoing with the same clip
- {
- aVersion = KCurrentClipVersion;
- iSeekHeaderPoint = iToFile->SeekHeaderPoint();
- iGroupsTotalCount = iToFile->GroupsTotalCount();
- iFirstSeekAddr = iToFile->FirstSeekAddr();
- iLastSeekAddr = iToFile->LastSeekAddr();
- }
-
- iNextGroupPoint = iFirstSeekAddr;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ReadMetaHeaderL
-// Reads meta data header from the beginning of the file.
-// -----------------------------------------------------------------------------
-//
-TInt8 CRtpFromFile::ReadMetaHeaderL(
- TInt& aSeekHeaderPoint,
- TInt& aSeekArrayPoint )
- {
- CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC(
- iFile, CRtpMetaHeader::EMetaRead );
- aSeekHeaderPoint = metaheader->SeekHeaderPoint();
- metaheader->ReadSeekArrayPointL( aSeekArrayPoint );
- LOG2( "CRtpFromFile::ReadMetaHeaderL(), aSeekHeaderPoint: %d, aSeekArrayPoint: %d",
- aSeekHeaderPoint, aSeekArrayPoint );
- // Clip version
- CRtpMetaHeader::SAttributes att;
- metaheader->ReadAttributesL( att );
- metaheader->ReadDurationL( iDuration );
-
- // Verify post rule
- CRtpClipManager* clipManager = CRtpClipManager::NewLC();
- clipManager->VerifyPostRuleL( att.iPostRule, metaheader );
- CleanupStack::PopAndDestroy( clipManager );
- CleanupStack::PopAndDestroy( metaheader );
-
- LOG2( "CRtpFromFile::ReadMetaHeaderL(), Version: %d, Duration: %d",
- att.iVersion, iDuration );
- return att.iVersion;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::ReadNextGroupFromFileL
-// Reads RTP payload from a file.
-// Payload is allways after data header, so read position set is not needed.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::ReadNextGroupFromFileL()
- {
- LOG2( "CRtpFromFile::ReadNextGroupFromFileL(), iThisGroup: %d, iGroupTime: %u",
- iThisGroup, iGroupTime );
-#ifdef CR_ALL_LOGS
- LogVariables( _L( "ReadNextGroupFromFileL()" ) );
-#endif // CR_ALL_LOGS
-
- const TInt len( iGroupTotalLen - KGroupHeaderBytes );
- if ( len <= 0 || iThisGroup < iFirstSeekAddr || iThisGroup > iLastSeekAddr )
- {
-#ifdef CR_ALL_LOGS
- LogVariables( _L( "ReadNextGroupFromFileL()" ) );
-#endif // CR_ALL_LOGS
-
- LOG( "CRtpFromFile::ReadNextGroupFromFileL(), No More Groups" );
- User::Leave( KErrEof );
- }
-
- // Reading should never be active at this point
- if ( iFileData != NULL )
- {
- LOG( "CRtpFromFile::ReadNextGroupFromFileL(), Invalid usage of class !" );
- User::Leave( KErrGeneral );
- }
-
- // Start reading group
- iFileData = HBufC8::NewL( len );
- iDataPtr.Set( iFileData->Des() );
- iFile.Read( iThisGroup + KGroupHeaderBytes, iDataPtr, len, iStatus );
- SetActive();
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::FindSeekGroup
-// Finds closes point with seek array, accuracy about 0 - 30 s.
-// -----------------------------------------------------------------------------
-//
-TInt CRtpFromFile::FindSeekGroup( const TUint aTime, CArrayFix<SSeek>* aArray )
- {
- if ( aArray->Count() && aTime >= aArray->At( 0 ).iTime )
- {
- for ( TInt i( aArray->Count() - 1 ); i > 0 ; i-- )
- {
-#ifdef CR_ALL_LOGS
- LOG3( "CRtpFromFile::FindSeekGroup(), ind: %d, aTime: %u, array time: %u",
- i, aTime, aArray->At( i ).iTime );
-#endif //CR_ALL_LOGS
-
- if ( aTime > aArray->At( i ).iTime )
- {
- return aArray->At( i ).iPoint;
- }
- }
-
- return aArray->At( 0 ).iPoint;
- }
-
- return KErrNotFound;
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::UpdatePlayAttL
-// Updates clip's playback count and spot attributes after watching.
-// -----------------------------------------------------------------------------
-//
-void CRtpFromFile::UpdatePlayAttL()
- {
- // Update attributes
- if ( iMode == EModeNormal )
- {
- iFile.Close();
- User::LeaveIfError( iFile.Open( iFs, *iCurrentPath,
- EFileShareAny | EFileStream | EFileWrite ) );
- }
-
- CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC(
- iFile, CRtpMetaHeader::EMetaUpdate );
- TTime startTime( 0 );
- metaheader->ReadStartTimeL( startTime );
-
- CRtpMetaHeader::SAttributes att;
- metaheader->ReadAttributesL( att );
-
- // Step playback counter by one
- att.iPlayCount++;
- // Update play spot
- att.iPlaySpot = ( iThisGroup > 0 && iThisGroup < iLastSeekAddr )? iThisGroup:
- KErrNone;
- metaheader->WriteAttributesL( att );
- CleanupStack::PopAndDestroy( metaheader );
- LOG2( "CRtpFromFile::UpdatePlayAttL(), New play count: %d, spot: %d",
- att.iPlayCount, att.iPlaySpot );
- // Set start time to file date
- iFile.SetModified( startTime );
- }
-
-// -----------------------------------------------------------------------------
-// CRtpFromFile::LastSeekAddr
-// Gets last seek addres.
-// It is either from opened clip or from file writer when recording is ongoing.
-// -----------------------------------------------------------------------------
-//
-TInt CRtpFromFile::LastSeekAddr()
- {
- if ( iToFile )
- {
- iLastSeekAddr = iToFile->LastSeekAddr();
- }
-
- return iLastSeekAddr;
- }
-
-// End of File
-