dvrengine/CommonRecordingEngine/src/CCRRtpRecordSink.cpp
branchRCL_3
changeset 22 826cea16efd9
parent 21 798ee5f1972c
child 23 13a33d82ad98
--- a/dvrengine/CommonRecordingEngine/src/CCRRtpRecordSink.cpp	Thu Aug 19 10:54:18 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +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:    Class that takes packet from buffer and does not put them*
-*/
-
-
-
-
-// INCLUDES
-#include "CCRRtpRecordSink.h"
-#include "CCRPacketBuffer.h"
-#include "CCRStreamingSession.h"
-#include "MCRConnectionObserver.h"
-#include <ipvideo/CRtpClipHandler.h>
-#include <ipvideo/CRtpClipManager.h>
-#include <ipvideo/CDvrSdpParser.h>
-#include "CRtpTsConverter.h"
-#include "CRtpPacket.h"
-#include <bsp.h>
-#include "videoserviceutilsLogger.h"
-
-// CONSTANTS
-const TInt KDefaultBitRate( 256 + 64 ); // 320 kbps
-const TInt KDefGroupSize( 70 * 1024 );  // 70k
-const TInt KMaxGroupSize( 140 * 1024 ); // 140k
-const TInt KMaxGrouplength( 3000 );		// 3 s
-const TInt KGroupHeaderSize( KGroupHeaderBytes + KPacketsCountBytes );
-const TInt KGroupLenghtAccuracy( 20 );  // 20ms
-
-// ============================ MEMBER FUNCTIONS ===============================
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::NewL
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-//  
-
-CCRRtpRecordSink* CCRRtpRecordSink::NewL(
-    const SCRRecordParams& aRecordParams,
-    CCRStreamingSession::TCRSinkId aSinkId,
-    CCRStreamingSession& aOwningSession,
-    MCRConnectionObserver* aObserver,
-    CRtpClipHandler*& aClipHandler )
-    {
-    CCRRtpRecordSink* self = new( ELeave ) 
-    CCRRtpRecordSink( aSinkId, aOwningSession, aObserver, aClipHandler );
-    CleanupStack::PushL( self );
-    self->ConstructL( aRecordParams );
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::CCRRtpRecordSink
-// C++ default constructor can NOT contain any code, that might leave.
-// -----------------------------------------------------------------------------
-//  
-CCRRtpRecordSink::CCRRtpRecordSink(
-    CCRStreamingSession::TCRSinkId aSinkId,
-    CCRStreamingSession& aOwningSession,
-    MCRConnectionObserver* aObserver,
-    CRtpClipHandler*& aClipHandler )
-  : CCRPacketSinkBase( aOwningSession, aSinkId ),
-    iObserver( aObserver ),
-    iClipHandler( aClipHandler ),
-    iGroupPointer( NULL, 0 ),
-    iGroupSize( KGroupHeaderSize ),
-    iPacketsCount( 0 ),
-    iWantedGroup( KMaxTInt ),
-    iOldestTs( KMaxTUint ),
-    iLatestAudio( NULL, 0 ),
-    iSaveMode( MRtpFileWriteObserver::ESaveNormal ),
-    iGroupMode( MRtpFileWriteObserver::ESaveIdle )
-    {
-    // None
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::ConstructL
-// 2nd phase. 
-// -----------------------------------------------------------------------------
-//  
-void CCRRtpRecordSink::ConstructL( const SCRRecordParams& aRecordParams )
-    {
-    LOG( "CCRRtpRecordSink::ConstructL()" );
-    
-    // Params
-    iRecParams.iClipPath = aRecordParams.iFileName;
-    iRecParams.iSdpData.Set( aRecordParams.iSdpData );
-    iRecParams.iService.Set( aRecordParams.iServiceName );
-    iRecParams.iProgram.Set( aRecordParams.iProgramName );
-    iRecParams.iPostRule = aRecordParams.iPostRule;
-    iRecParams.iParental = aRecordParams.iParental;
-    iRecParams.iEndTime = aRecordParams.iEndTime;
-    
-    if ( aRecordParams.iFormat == ECRRecordTimeShift )
-        {
-        iRecParams.iStartTime = 0;
-        iRecParams.iEndTime = KDvrMaximumTimeShift * 1e6;
-        iSaveMode = MRtpFileWriteObserver::ESaveTimeShift;
-        }
-    
-#if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
-    LOG1( "CCRRtpRecordSink::ConstructL(), iClipPath: %S", &iRecParams.iClipPath );
-    TName buf( KNullDesC ); iRecParams.iStartTime.FormatL( buf, KTimeDateFormat );
-    LOG1( "CCRRtpRecordSink::ConstructL(), iStartTime: %S", &buf );
-    iRecParams.iEndTime.FormatL( buf, KTimeDateFormat );
-    LOG1( "CCRRtpRecordSink::ConstructL(), iEndTime: %S", &buf );
-#endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE
-
-    // Clip handler and group buffer
-    User::LeaveIfNull( iClipHandler );
-    iGroupBuffer = HBufC8::NewL( 0 );
-    iGroupPointer.Set( iGroupBuffer->Des() );
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::~CCRRtpRecordSink
-// Destructor.
-// -----------------------------------------------------------------------------
-//
-CCRRtpRecordSink::~CCRRtpRecordSink()
-    {    
-    LOG( "CCRRtpRecordSink::~CCRRtpRecordSink()" );
-
-    if ( iClipHandler )
-        {
-        iClipHandler->StopRecording( KErrCancel );
-        }
-    
-    delete iGroupBuffer;
-    delete iAudioConv;
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::SetSdpL
-// Sets SDP, parses it and initiates XPS.
-// -----------------------------------------------------------------------------
-//  
-void CCRRtpRecordSink::SetSdpL( const TDesC8& aSdp )
-    {
-    TInt initiated( iRecParams.iSdpData.Length() );
-    LOG2( "CCRRtpRecordSink::SetSdpL(), aSdp len: %d, initiated: %d",
-                                        aSdp.Length(), initiated );
-    if ( !initiated && iClipHandler )
-        {
-        iRecParams.iSdpData.Set( aSdp );
-        iClipHandler->RegisterWriteObserver( this );
-        iClipHandler->StartRecordingL( iRecParams, iSaveMode );
-
-        // SDP parser
-        CDvrSdpParser* sdpParser = CDvrSdpParser::NewLC();
-        sdpParser->TryParseL( aSdp );
-        
-        // Bit rates
-        TUint total( sdpParser->VideoBitrate() + sdpParser->AudioBitrate() );
-        TReal angle( TReal( total ) / KDefaultBitRate );
-        iWantedGroup = TInt( angle * KDefGroupSize );
-        LOG1( "SetSdpL::SetSdpL(), iWantedGroup: %d", iWantedGroup );
-        iGroupBuffer = iGroupBuffer->ReAllocL( iWantedGroup + KGroupHeaderSize );
-        iGroupPointer.Set( iGroupBuffer->Des() );
-        
-        // TS converter
-        delete iAudioConv; iAudioConv = NULL;
-        iAudioConv = CRtpTsConverter::NewL( sdpParser->AudioTimerGranularity() );
-        LOG1( "CCRRtpRecordSink::SetSdpL(), AudioTimerGranularity: %d",
-                                            sdpParser->AudioTimerGranularity() );
-        CleanupStack::PopAndDestroy( sdpParser );
-        
-        // Recording can start
-        iGroupMode = MRtpFileWriteObserver::ESaveNormal;
-        iObserver->ConnectionStatusChange( iOwningSession.SourceChecksum(),
-            MCRConnectionObserver::ECRRecordingStarted, KErrNone );
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::NewPacketAvailable
-// From CCRPacketSinkBase. New packet(s) to a group.
-// -----------------------------------------------------------------------------
-//      
-void CCRRtpRecordSink::NewPacketAvailable()
-    {
-    // Keep group buffer untouch during clip writing
-    if ( iBuffer && iClipHandler && !iClipHandler->WritingActive() )
-        {
-        if ( iGroupMode == MRtpFileWriteObserver::ESaveNormal )
-            {
-            // New packets to a group
-            AddToGroup();
-
-            // Group size big enougth to write to clip?
-            if ( iGroupSize >= iWantedGroup )
-                {
-                SaveGroup( iGroupMode );
-                }
-
-            // Keep buffer size reasonable
-            iBuffer->HandleBufferSize();
-            }
-        else
-            {
-            if ( iGroupMode != MRtpFileWriteObserver::ESaveIdle )
-                {
-                AddToGroup();
-                
-                // Handle user pause
-                if ( iGroupMode == MRtpFileWriteObserver::ESavePause )
-                    {
-                    AddPausePacket();
-                    }
-
-                SaveGroup( iGroupMode );
-                iGroupMode = MRtpFileWriteObserver::ESaveIdle;
-                }
-            }
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::BufferResetting
-// From CCRPacketSinkBase.
-// -----------------------------------------------------------------------------
-//      
-void CCRRtpRecordSink::BufferResetDone()
-    {
-    AddPausePacket();
-    if ( iClipHandler && !iClipHandler->WritingActive() )
-        {
-        SaveGroup( MRtpFileWriteObserver::ESavePause );
-        }
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::Pause
-// -----------------------------------------------------------------------------
-//
-TInt CCRRtpRecordSink::Pause()
-    {
-    LOG1( "CCRRtpRecordSink::Pause(), iGroupMode: %d", iGroupMode );
-    
-    TInt err( KErrCompletion );
-    if ( iClipHandler )
-        {
-        if ( iSaveMode == MRtpFileWriteObserver::ESaveNormal )
-            {
-            // Normal pause
-            err = KErrNone;
-            iGroupMode = MRtpFileWriteObserver::ESavePause;
-            }
-        else
-            {
-            // Time shift pause
-            TRAP( err, iClipHandler->TimeShiftPauseL() );
-            }
-        }
-    
-    return err;
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::Restore
-// -----------------------------------------------------------------------------
-//
-TInt CCRRtpRecordSink::Restore()
-    {
-    LOG1( "CCRRtpRecordSink::Restore(), iGroupMode: %d", iGroupMode );
-    
-    iGroupMode = MRtpFileWriteObserver::ESaveNormal;
-    return KErrNone;
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::Stop
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::Stop()
-    {
-    LOG1( "CCRRtpRecordSink::Stop(), iGroupMode: %d", iGroupMode );
-
-    iGroupMode = MRtpFileWriteObserver::ESaveEnd;
-    if ( iClipHandler && !iClipHandler->WritingActive() )
-        {
-        iWantedGroup = KMaxTInt;
-        SaveGroup( iGroupMode );
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::GroupSaved
-// From MRtpFileWriteObserver.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::GroupSaved()
-    {
-    ResetGroupVariables();
-    if ( iGroupMode != MRtpFileWriteObserver::ESaveNormal )
-        {
-        SaveGroup( iGroupMode );
-        iGroupMode = MRtpFileWriteObserver::ESaveIdle;
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::WriteStatus
-// From MRtpFileWriteObserver.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::WriteStatus( const TInt aStatus )
-    {
-    LOG1( "CCRRtpRecordSink::WriteStatus(), aStatus: %d", aStatus );
-
-    ForceStopRecording( aStatus );
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::AddToGroup
-// Initialises time stamp converter for audio stream and adds packets to a group.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::AddToGroup()
-    {
-    const TInt packets( iBuffer->PacketsCount( iSinkId ) );
-    for ( TInt i( packets ); i > KErrNotFound; i-- )
-        {
-        // Packet
-        TPtr8 packet( NULL, 0 );
-        MCRPacketSource::TCRPacketStreamId streamId(
-            MCRPacketSource::EStreamIdCount );
-        const TInt book( iBuffer->GetStream( iSinkId, streamId ) );
-        iBuffer->GetPacket( book, packet ); 
-        
-        // TS converter
-        if ( streamId == MCRPacketSource::EAudioControlStream &&
-             iAudioConv && !iAudioConv->Initiated() )
-            {
-            iAudioConv->Init( packet );
-            }
-        
-        // Type valid
-        MRtpFileWriteObserver::TRtpType type( MRtpFileWriteObserver::ERtpNone );
-        if ( packet.Length() && StreamToType( streamId, type ) )
-            {
-            TRAPD( err, AddPacketToGroupL( packet, type ) );
-            if ( err )
-                {
-                LOG1( "CCRRtpRecordSink::AddToGroup(), AddPacketToGroupL leaved: %d", err );
-                ForceStopRecording( err );
-                }
-            }
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::AddPacketToGroupL
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::AddPacketToGroupL(
-    const TDesC8& aPacket,
-    const MRtpFileWriteObserver::TRtpType& aType )
-    {
-    const TUint total( KPacketSizeBytesLen + 
-                       KPacketTypeBytesLen + aPacket.Length() );
-    iGroupSize += total;
-    if ( iGroupSize > iGroupPointer.MaxLength() )
-        {
-        iGroupBuffer = iGroupBuffer->ReAllocL( iGroupSize );
-        iGroupPointer.Set( iGroupBuffer->Des() );
-        LOG1( "CCRRtpRecordSink::AddPacketToGroupL(), New iGroupSize: %d", iGroupSize );
-        }
-    
-    // Packet length (PTL), type and data
-    TBuf8<KPacketSizeBytesLen + KPacketTypeBytesLen> header;
-    CRtpUtil::MakeBytesL( total, header );
-    header.Append( KCharSpace );
-    header[KPacketTypeBytePoint] = ( TUint8 )( aType );
-    iGroupPointer.Append( header );
-    iGroupPointer.Append( aPacket );
-    iPacketsCount++;
-
-#ifdef CR_ALL_LOGS
-    const TUint8* pointer( &aPacket[2] );
-    TInt seq( BigEndian::Get16( pointer ) );
-    LOG3( "CCRRtpRecordSink::AddPacketToGroupL(), type: %d, packet: %d, seq: %d", 
-                                                  aType, aPacket.Length(), seq );
-    //RFileLogger::WriteFormat( _L( "livetv" ), _L( "record.log" ), EFileLoggingModeAppend, 
-    //    _L( "AddPacketToGroupL(), type: %d, packet: %d, seq: %d" ), aType, aPacket.Length(), seq );
-    
-#endif // CR_ALL_LOGS
-    
-    // Variables for TS delta
-    if ( aType == MRtpFileWriteObserver::ERtpAudio && 
-         iAudioConv && iAudioConv->Initiated() )
-        {
-        if ( iOldestTs == KMaxTUint )
-            {
-            iOldestTs = TsFromPacketL( aPacket );
-            }
-        else
-            {
-            iLatestAudio.Set( iGroupPointer.Right( aPacket.Length() ) );
-            }
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::SaveGroup
-// Saves RTP packets group to a clip.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::SaveGroup( MRtpFileWriteObserver::TRtpSaveAction aAction )
-    {
-    TRAPD( err, SaveGroupL( aAction ) );
-    if ( err )
-    	{
-        ForceStopRecording( err );
-    	}
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::SaveGroup
-// Saves RTP packets group to a clip.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::SaveGroupL( MRtpFileWriteObserver::TRtpSaveAction aAction )
-    {
-	// TS delta
-    TBool forceSave( aAction != MRtpFileWriteObserver::ESaveNormal );
-    TInt length( TReal( iGroupSize ) / iWantedGroup * KNormalRecGroupLength );
-    if ( iOldestTs != KMaxTUint )
-        {
-        length = TsFromPacketL( iLatestAudio ) - iOldestTs;
-        }
-    if ( length >= ( KNormalRecGroupLength - KGroupLenghtAccuracy ) )
-        {
-        forceSave = ETrue;
-        if ( length <= ( KNormalRecGroupLength + KGroupLenghtAccuracy ) )
-            {
-            iWantedGroup = ( iWantedGroup + iGroupSize ) / 2;
-            }
-        else
-            {
-            TReal angle( TReal( iGroupSize ) / length );
-            TInt wanted(  TReal( KNormalRecGroupLength ) * angle );
-            if ( wanted > ( KDefGroupSize / 2 ) && wanted < KMaxGroupSize )
-                {
-                iWantedGroup = ( iWantedGroup + wanted ) / 2;
-                }
-            }
-        }
-
-	// Group ok to save?
-    if ( forceSave || iGroupSize > KMaxGroupSize )
-        {
-        // Group packets count (PTC)
-        HBufC8* bytes = CRtpUtil::MakeBytesLC( iPacketsCount );
-        iGroupPointer.Insert( 0, bytes->Des() );
-        CleanupStack::PopAndDestroy( bytes );
-
-        // Make sure that nasty length not end to the clip in case TS overflow
-        length = ( length <= KMaxGrouplength )? length: KMaxGrouplength;
-
-        // Save to clip
-        TInt err( KErrNotReady );
-        if ( iClipHandler )
-            {
-            TRAP( err, iClipHandler->SaveNextGroupL( iGroupPointer, 
-                                                     length, aAction ) );
-            }
-        if ( err )
-            {
-            LOG1( "CCRRtpRecordSink::SaveGroup(), SaveNextGroupL Leaved: %d", err );
-            ForceStopRecording( err );
-            }
-        
-        LOG3( "CCRRtpRecordSink::SaveGroup(), iPacketsCount: %d, length: %u, iWantedGroup: %d", 
-                                              iPacketsCount, length, iWantedGroup );
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::StreamToType
-// -----------------------------------------------------------------------------
-//
-TBool CCRRtpRecordSink::StreamToType(
-    const MCRPacketSource::TCRPacketStreamId& aStream,
-    MRtpFileWriteObserver::TRtpType& aType )
-    {
-    switch ( aStream )
-        {
-        case MCRPacketSource::EAudioStream:
-            aType = MRtpFileWriteObserver::ERtpAudio;
-            break;
-
-        case MCRPacketSource::EAudioControlStream:
-            aType = MRtpFileWriteObserver::ERtcpAudio;
-            break;
-
-        case MCRPacketSource::EVideoStream:
-            aType = MRtpFileWriteObserver::ERtpVideo;
-            break;
-
-        case MCRPacketSource::EVideoControlStream:
-            aType = MRtpFileWriteObserver::ERtcpVideo;
-            break;
-
-        case MCRPacketSource::ESubTitleStream:
-            aType = MRtpFileWriteObserver::ERtpSubTitle;
-            break;
-
-        case MCRPacketSource::ESubTitleControlStream:
-            aType = MRtpFileWriteObserver::ERtcpSubTitle;
-            break;
-
-        case MCRPacketSource::EDisContinousStream:
-            LOG( "CCRRtpRecordSink::StreamToType(), ERtpClipPause" );
-            aType = MRtpFileWriteObserver::ERtpClipPause;
-            break;
-        
-        case MCRPacketSource::EStreamEndTag:
-            LOG( "CCRRtpRecordSink::StreamToType(), ERtpClipEnd" );
-            aType = MRtpFileWriteObserver::ERtpClipEnd;
-            break;
-
-        default:
-            return EFalse;
-        }
-    
-    return ETrue;
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::TsFromPacketL
-// -----------------------------------------------------------------------------
-//
-TUint CCRRtpRecordSink::TsFromPacketL( const TDesC8& aPacket )
-    {
-    CRtpPacket* rtpPacket = CRtpPacket::NewLC();
-    TUint ts( KMaxTUint );
-    if ( !rtpPacket->ParseRtp( aPacket ) )
-        {
-        ts = iAudioConv->ConvertTs( rtpPacket->iRtpRecvHeader.iTimestamp, ETrue );
-        }
-    
-    CleanupStack::PopAndDestroy( rtpPacket );
-    return ts;
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::AddPausePacket
-// Wrapper for AddPausePacketL().
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::AddPausePacket()
-    {
-    LOG( "CCRRtpRecordSink::AddPausePacket()");
-
-    TRAPD( err, AddPausePacketL() );
-    if ( err )
-        {
-        ForceStopRecording( err );
-        }
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::AddPausePacketL
-// Adds pause packet to the group.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::AddPausePacketL()
-    {
-    HBufC8* data = CRtpUtil::MakeBytesLC( KMaxTUint );
-    AddPacketToGroupL( data->Des(), MRtpFileWriteObserver::ERtpClipPause );
-    CleanupStack::PopAndDestroy( data );
-    }
-    
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::ForceStopRecording
-// Stops recording on clip handler and destroys the sink.
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::ForceStopRecording( const TInt& aStatus )
-    {
-    LOG2( "CCRRtpRecordSink::ForceStopRecording(), iGroupMode: %d, aStatus: %d",
-                                                   iGroupMode, aStatus );
-    iGroupMode = MRtpFileWriteObserver::ESaveIdle;
-
-    if ( iClipHandler )
-        {
-        iClipHandler->StopRecording( aStatus );
-        }
-    
-    iObserver->ConnectionStatusChange( iOwningSession.SourceChecksum(),
-        MCRConnectionObserver::ECRRecordingEnded, aStatus );
-    iOwningSession.SinkStops( Id() );
-    }
-
-// -----------------------------------------------------------------------------
-// CCRRtpRecordSink::ResetGroupVariables
-// 
-// -----------------------------------------------------------------------------
-//
-void CCRRtpRecordSink::ResetGroupVariables()
-    {
-    iGroupSize = KGroupHeaderSize; // Room for group header and packets count
-    iPacketsCount = 0;
-    iGroupPointer.Zero();
-    iOldestTs = KMaxTUint;
-    iLatestAudio.Set( NULL, 0 );
-    }
-
-//  End of File