dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpFromFile.cpp
branchRCL_3
changeset 47 826cea16efd9
parent 45 798ee5f1972c
child 48 13a33d82ad98
--- 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
-