dvrengine/CommonRecordingEngine/src/CCRRtpRecordSink.cpp
branchRCL_3
changeset 22 826cea16efd9
parent 21 798ee5f1972c
child 23 13a33d82ad98
equal deleted inserted replaced
21:798ee5f1972c 22:826cea16efd9
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    Class that takes packet from buffer and does not put them*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include "CCRRtpRecordSink.h"
       
    22 #include "CCRPacketBuffer.h"
       
    23 #include "CCRStreamingSession.h"
       
    24 #include "MCRConnectionObserver.h"
       
    25 #include <ipvideo/CRtpClipHandler.h>
       
    26 #include <ipvideo/CRtpClipManager.h>
       
    27 #include <ipvideo/CDvrSdpParser.h>
       
    28 #include "CRtpTsConverter.h"
       
    29 #include "CRtpPacket.h"
       
    30 #include <bsp.h>
       
    31 #include "videoserviceutilsLogger.h"
       
    32 
       
    33 // CONSTANTS
       
    34 const TInt KDefaultBitRate( 256 + 64 ); // 320 kbps
       
    35 const TInt KDefGroupSize( 70 * 1024 );  // 70k
       
    36 const TInt KMaxGroupSize( 140 * 1024 ); // 140k
       
    37 const TInt KMaxGrouplength( 3000 );		// 3 s
       
    38 const TInt KGroupHeaderSize( KGroupHeaderBytes + KPacketsCountBytes );
       
    39 const TInt KGroupLenghtAccuracy( 20 );  // 20ms
       
    40 
       
    41 // ============================ MEMBER FUNCTIONS ===============================
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CCRRtpRecordSink::NewL
       
    45 // Two-phased constructor.
       
    46 // -----------------------------------------------------------------------------
       
    47 //  
       
    48 
       
    49 CCRRtpRecordSink* CCRRtpRecordSink::NewL(
       
    50     const SCRRecordParams& aRecordParams,
       
    51     CCRStreamingSession::TCRSinkId aSinkId,
       
    52     CCRStreamingSession& aOwningSession,
       
    53     MCRConnectionObserver* aObserver,
       
    54     CRtpClipHandler*& aClipHandler )
       
    55     {
       
    56     CCRRtpRecordSink* self = new( ELeave ) 
       
    57     CCRRtpRecordSink( aSinkId, aOwningSession, aObserver, aClipHandler );
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL( aRecordParams );
       
    60     CleanupStack::Pop( self );
       
    61     return self;
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CCRRtpRecordSink::CCRRtpRecordSink
       
    66 // C++ default constructor can NOT contain any code, that might leave.
       
    67 // -----------------------------------------------------------------------------
       
    68 //  
       
    69 CCRRtpRecordSink::CCRRtpRecordSink(
       
    70     CCRStreamingSession::TCRSinkId aSinkId,
       
    71     CCRStreamingSession& aOwningSession,
       
    72     MCRConnectionObserver* aObserver,
       
    73     CRtpClipHandler*& aClipHandler )
       
    74   : CCRPacketSinkBase( aOwningSession, aSinkId ),
       
    75     iObserver( aObserver ),
       
    76     iClipHandler( aClipHandler ),
       
    77     iGroupPointer( NULL, 0 ),
       
    78     iGroupSize( KGroupHeaderSize ),
       
    79     iPacketsCount( 0 ),
       
    80     iWantedGroup( KMaxTInt ),
       
    81     iOldestTs( KMaxTUint ),
       
    82     iLatestAudio( NULL, 0 ),
       
    83     iSaveMode( MRtpFileWriteObserver::ESaveNormal ),
       
    84     iGroupMode( MRtpFileWriteObserver::ESaveIdle )
       
    85     {
       
    86     // None
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CCRRtpRecordSink::ConstructL
       
    91 // 2nd phase. 
       
    92 // -----------------------------------------------------------------------------
       
    93 //  
       
    94 void CCRRtpRecordSink::ConstructL( const SCRRecordParams& aRecordParams )
       
    95     {
       
    96     LOG( "CCRRtpRecordSink::ConstructL()" );
       
    97     
       
    98     // Params
       
    99     iRecParams.iClipPath = aRecordParams.iFileName;
       
   100     iRecParams.iSdpData.Set( aRecordParams.iSdpData );
       
   101     iRecParams.iService.Set( aRecordParams.iServiceName );
       
   102     iRecParams.iProgram.Set( aRecordParams.iProgramName );
       
   103     iRecParams.iPostRule = aRecordParams.iPostRule;
       
   104     iRecParams.iParental = aRecordParams.iParental;
       
   105     iRecParams.iEndTime = aRecordParams.iEndTime;
       
   106     
       
   107     if ( aRecordParams.iFormat == ECRRecordTimeShift )
       
   108         {
       
   109         iRecParams.iStartTime = 0;
       
   110         iRecParams.iEndTime = KDvrMaximumTimeShift * 1e6;
       
   111         iSaveMode = MRtpFileWriteObserver::ESaveTimeShift;
       
   112         }
       
   113     
       
   114 #if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
       
   115     LOG1( "CCRRtpRecordSink::ConstructL(), iClipPath: %S", &iRecParams.iClipPath );
       
   116     TName buf( KNullDesC ); iRecParams.iStartTime.FormatL( buf, KTimeDateFormat );
       
   117     LOG1( "CCRRtpRecordSink::ConstructL(), iStartTime: %S", &buf );
       
   118     iRecParams.iEndTime.FormatL( buf, KTimeDateFormat );
       
   119     LOG1( "CCRRtpRecordSink::ConstructL(), iEndTime: %S", &buf );
       
   120 #endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE
       
   121 
       
   122     // Clip handler and group buffer
       
   123     User::LeaveIfNull( iClipHandler );
       
   124     iGroupBuffer = HBufC8::NewL( 0 );
       
   125     iGroupPointer.Set( iGroupBuffer->Des() );
       
   126     }
       
   127     
       
   128 // -----------------------------------------------------------------------------
       
   129 // CCRRtpRecordSink::~CCRRtpRecordSink
       
   130 // Destructor.
       
   131 // -----------------------------------------------------------------------------
       
   132 //
       
   133 CCRRtpRecordSink::~CCRRtpRecordSink()
       
   134     {    
       
   135     LOG( "CCRRtpRecordSink::~CCRRtpRecordSink()" );
       
   136 
       
   137     if ( iClipHandler )
       
   138         {
       
   139         iClipHandler->StopRecording( KErrCancel );
       
   140         }
       
   141     
       
   142     delete iGroupBuffer;
       
   143     delete iAudioConv;
       
   144     }
       
   145     
       
   146 // -----------------------------------------------------------------------------
       
   147 // CCRRtpRecordSink::SetSdpL
       
   148 // Sets SDP, parses it and initiates XPS.
       
   149 // -----------------------------------------------------------------------------
       
   150 //  
       
   151 void CCRRtpRecordSink::SetSdpL( const TDesC8& aSdp )
       
   152     {
       
   153     TInt initiated( iRecParams.iSdpData.Length() );
       
   154     LOG2( "CCRRtpRecordSink::SetSdpL(), aSdp len: %d, initiated: %d",
       
   155                                         aSdp.Length(), initiated );
       
   156     if ( !initiated && iClipHandler )
       
   157         {
       
   158         iRecParams.iSdpData.Set( aSdp );
       
   159         iClipHandler->RegisterWriteObserver( this );
       
   160         iClipHandler->StartRecordingL( iRecParams, iSaveMode );
       
   161 
       
   162         // SDP parser
       
   163         CDvrSdpParser* sdpParser = CDvrSdpParser::NewLC();
       
   164         sdpParser->TryParseL( aSdp );
       
   165         
       
   166         // Bit rates
       
   167         TUint total( sdpParser->VideoBitrate() + sdpParser->AudioBitrate() );
       
   168         TReal angle( TReal( total ) / KDefaultBitRate );
       
   169         iWantedGroup = TInt( angle * KDefGroupSize );
       
   170         LOG1( "SetSdpL::SetSdpL(), iWantedGroup: %d", iWantedGroup );
       
   171         iGroupBuffer = iGroupBuffer->ReAllocL( iWantedGroup + KGroupHeaderSize );
       
   172         iGroupPointer.Set( iGroupBuffer->Des() );
       
   173         
       
   174         // TS converter
       
   175         delete iAudioConv; iAudioConv = NULL;
       
   176         iAudioConv = CRtpTsConverter::NewL( sdpParser->AudioTimerGranularity() );
       
   177         LOG1( "CCRRtpRecordSink::SetSdpL(), AudioTimerGranularity: %d",
       
   178                                             sdpParser->AudioTimerGranularity() );
       
   179         CleanupStack::PopAndDestroy( sdpParser );
       
   180         
       
   181         // Recording can start
       
   182         iGroupMode = MRtpFileWriteObserver::ESaveNormal;
       
   183         iObserver->ConnectionStatusChange( iOwningSession.SourceChecksum(),
       
   184             MCRConnectionObserver::ECRRecordingStarted, KErrNone );
       
   185         }
       
   186     }
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 // CCRRtpRecordSink::NewPacketAvailable
       
   190 // From CCRPacketSinkBase. New packet(s) to a group.
       
   191 // -----------------------------------------------------------------------------
       
   192 //      
       
   193 void CCRRtpRecordSink::NewPacketAvailable()
       
   194     {
       
   195     // Keep group buffer untouch during clip writing
       
   196     if ( iBuffer && iClipHandler && !iClipHandler->WritingActive() )
       
   197         {
       
   198         if ( iGroupMode == MRtpFileWriteObserver::ESaveNormal )
       
   199             {
       
   200             // New packets to a group
       
   201             AddToGroup();
       
   202 
       
   203             // Group size big enougth to write to clip?
       
   204             if ( iGroupSize >= iWantedGroup )
       
   205                 {
       
   206                 SaveGroup( iGroupMode );
       
   207                 }
       
   208 
       
   209             // Keep buffer size reasonable
       
   210             iBuffer->HandleBufferSize();
       
   211             }
       
   212         else
       
   213             {
       
   214             if ( iGroupMode != MRtpFileWriteObserver::ESaveIdle )
       
   215                 {
       
   216                 AddToGroup();
       
   217                 
       
   218                 // Handle user pause
       
   219                 if ( iGroupMode == MRtpFileWriteObserver::ESavePause )
       
   220                     {
       
   221                     AddPausePacket();
       
   222                     }
       
   223 
       
   224                 SaveGroup( iGroupMode );
       
   225                 iGroupMode = MRtpFileWriteObserver::ESaveIdle;
       
   226                 }
       
   227             }
       
   228         }
       
   229     }
       
   230 
       
   231 // -----------------------------------------------------------------------------
       
   232 // CCRRtpRecordSink::BufferResetting
       
   233 // From CCRPacketSinkBase.
       
   234 // -----------------------------------------------------------------------------
       
   235 //      
       
   236 void CCRRtpRecordSink::BufferResetDone()
       
   237     {
       
   238     AddPausePacket();
       
   239     if ( iClipHandler && !iClipHandler->WritingActive() )
       
   240         {
       
   241         SaveGroup( MRtpFileWriteObserver::ESavePause );
       
   242         }
       
   243     }
       
   244     
       
   245 // -----------------------------------------------------------------------------
       
   246 // CCRRtpRecordSink::Pause
       
   247 // -----------------------------------------------------------------------------
       
   248 //
       
   249 TInt CCRRtpRecordSink::Pause()
       
   250     {
       
   251     LOG1( "CCRRtpRecordSink::Pause(), iGroupMode: %d", iGroupMode );
       
   252     
       
   253     TInt err( KErrCompletion );
       
   254     if ( iClipHandler )
       
   255         {
       
   256         if ( iSaveMode == MRtpFileWriteObserver::ESaveNormal )
       
   257             {
       
   258             // Normal pause
       
   259             err = KErrNone;
       
   260             iGroupMode = MRtpFileWriteObserver::ESavePause;
       
   261             }
       
   262         else
       
   263             {
       
   264             // Time shift pause
       
   265             TRAP( err, iClipHandler->TimeShiftPauseL() );
       
   266             }
       
   267         }
       
   268     
       
   269     return err;
       
   270     }
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // CCRRtpRecordSink::Restore
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 TInt CCRRtpRecordSink::Restore()
       
   277     {
       
   278     LOG1( "CCRRtpRecordSink::Restore(), iGroupMode: %d", iGroupMode );
       
   279     
       
   280     iGroupMode = MRtpFileWriteObserver::ESaveNormal;
       
   281     return KErrNone;
       
   282     }
       
   283 
       
   284 // -----------------------------------------------------------------------------
       
   285 // CCRRtpRecordSink::Stop
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 void CCRRtpRecordSink::Stop()
       
   289     {
       
   290     LOG1( "CCRRtpRecordSink::Stop(), iGroupMode: %d", iGroupMode );
       
   291 
       
   292     iGroupMode = MRtpFileWriteObserver::ESaveEnd;
       
   293     if ( iClipHandler && !iClipHandler->WritingActive() )
       
   294         {
       
   295         iWantedGroup = KMaxTInt;
       
   296         SaveGroup( iGroupMode );
       
   297         }
       
   298     }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CCRRtpRecordSink::GroupSaved
       
   302 // From MRtpFileWriteObserver.
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 void CCRRtpRecordSink::GroupSaved()
       
   306     {
       
   307     ResetGroupVariables();
       
   308     if ( iGroupMode != MRtpFileWriteObserver::ESaveNormal )
       
   309         {
       
   310         SaveGroup( iGroupMode );
       
   311         iGroupMode = MRtpFileWriteObserver::ESaveIdle;
       
   312         }
       
   313     }
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CCRRtpRecordSink::WriteStatus
       
   317 // From MRtpFileWriteObserver.
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 void CCRRtpRecordSink::WriteStatus( const TInt aStatus )
       
   321     {
       
   322     LOG1( "CCRRtpRecordSink::WriteStatus(), aStatus: %d", aStatus );
       
   323 
       
   324     ForceStopRecording( aStatus );
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CCRRtpRecordSink::AddToGroup
       
   329 // Initialises time stamp converter for audio stream and adds packets to a group.
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CCRRtpRecordSink::AddToGroup()
       
   333     {
       
   334     const TInt packets( iBuffer->PacketsCount( iSinkId ) );
       
   335     for ( TInt i( packets ); i > KErrNotFound; i-- )
       
   336         {
       
   337         // Packet
       
   338         TPtr8 packet( NULL, 0 );
       
   339         MCRPacketSource::TCRPacketStreamId streamId(
       
   340             MCRPacketSource::EStreamIdCount );
       
   341         const TInt book( iBuffer->GetStream( iSinkId, streamId ) );
       
   342         iBuffer->GetPacket( book, packet ); 
       
   343         
       
   344         // TS converter
       
   345         if ( streamId == MCRPacketSource::EAudioControlStream &&
       
   346              iAudioConv && !iAudioConv->Initiated() )
       
   347             {
       
   348             iAudioConv->Init( packet );
       
   349             }
       
   350         
       
   351         // Type valid
       
   352         MRtpFileWriteObserver::TRtpType type( MRtpFileWriteObserver::ERtpNone );
       
   353         if ( packet.Length() && StreamToType( streamId, type ) )
       
   354             {
       
   355             TRAPD( err, AddPacketToGroupL( packet, type ) );
       
   356             if ( err )
       
   357                 {
       
   358                 LOG1( "CCRRtpRecordSink::AddToGroup(), AddPacketToGroupL leaved: %d", err );
       
   359                 ForceStopRecording( err );
       
   360                 }
       
   361             }
       
   362         }
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CCRRtpRecordSink::AddPacketToGroupL
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 void CCRRtpRecordSink::AddPacketToGroupL(
       
   370     const TDesC8& aPacket,
       
   371     const MRtpFileWriteObserver::TRtpType& aType )
       
   372     {
       
   373     const TUint total( KPacketSizeBytesLen + 
       
   374                        KPacketTypeBytesLen + aPacket.Length() );
       
   375     iGroupSize += total;
       
   376     if ( iGroupSize > iGroupPointer.MaxLength() )
       
   377         {
       
   378         iGroupBuffer = iGroupBuffer->ReAllocL( iGroupSize );
       
   379         iGroupPointer.Set( iGroupBuffer->Des() );
       
   380         LOG1( "CCRRtpRecordSink::AddPacketToGroupL(), New iGroupSize: %d", iGroupSize );
       
   381         }
       
   382     
       
   383     // Packet length (PTL), type and data
       
   384     TBuf8<KPacketSizeBytesLen + KPacketTypeBytesLen> header;
       
   385     CRtpUtil::MakeBytesL( total, header );
       
   386     header.Append( KCharSpace );
       
   387     header[KPacketTypeBytePoint] = ( TUint8 )( aType );
       
   388     iGroupPointer.Append( header );
       
   389     iGroupPointer.Append( aPacket );
       
   390     iPacketsCount++;
       
   391 
       
   392 #ifdef CR_ALL_LOGS
       
   393     const TUint8* pointer( &aPacket[2] );
       
   394     TInt seq( BigEndian::Get16( pointer ) );
       
   395     LOG3( "CCRRtpRecordSink::AddPacketToGroupL(), type: %d, packet: %d, seq: %d", 
       
   396                                                   aType, aPacket.Length(), seq );
       
   397     //RFileLogger::WriteFormat( _L( "livetv" ), _L( "record.log" ), EFileLoggingModeAppend, 
       
   398     //    _L( "AddPacketToGroupL(), type: %d, packet: %d, seq: %d" ), aType, aPacket.Length(), seq );
       
   399     
       
   400 #endif // CR_ALL_LOGS
       
   401     
       
   402     // Variables for TS delta
       
   403     if ( aType == MRtpFileWriteObserver::ERtpAudio && 
       
   404          iAudioConv && iAudioConv->Initiated() )
       
   405         {
       
   406         if ( iOldestTs == KMaxTUint )
       
   407             {
       
   408             iOldestTs = TsFromPacketL( aPacket );
       
   409             }
       
   410         else
       
   411             {
       
   412             iLatestAudio.Set( iGroupPointer.Right( aPacket.Length() ) );
       
   413             }
       
   414         }
       
   415     }
       
   416 
       
   417 // -----------------------------------------------------------------------------
       
   418 // CCRRtpRecordSink::SaveGroup
       
   419 // Saves RTP packets group to a clip.
       
   420 // -----------------------------------------------------------------------------
       
   421 //
       
   422 void CCRRtpRecordSink::SaveGroup( MRtpFileWriteObserver::TRtpSaveAction aAction )
       
   423     {
       
   424     TRAPD( err, SaveGroupL( aAction ) );
       
   425     if ( err )
       
   426     	{
       
   427         ForceStopRecording( err );
       
   428     	}
       
   429     }
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CCRRtpRecordSink::SaveGroup
       
   433 // Saves RTP packets group to a clip.
       
   434 // -----------------------------------------------------------------------------
       
   435 //
       
   436 void CCRRtpRecordSink::SaveGroupL( MRtpFileWriteObserver::TRtpSaveAction aAction )
       
   437     {
       
   438 	// TS delta
       
   439     TBool forceSave( aAction != MRtpFileWriteObserver::ESaveNormal );
       
   440     TInt length( TReal( iGroupSize ) / iWantedGroup * KNormalRecGroupLength );
       
   441     if ( iOldestTs != KMaxTUint )
       
   442         {
       
   443         length = TsFromPacketL( iLatestAudio ) - iOldestTs;
       
   444         }
       
   445     if ( length >= ( KNormalRecGroupLength - KGroupLenghtAccuracy ) )
       
   446         {
       
   447         forceSave = ETrue;
       
   448         if ( length <= ( KNormalRecGroupLength + KGroupLenghtAccuracy ) )
       
   449             {
       
   450             iWantedGroup = ( iWantedGroup + iGroupSize ) / 2;
       
   451             }
       
   452         else
       
   453             {
       
   454             TReal angle( TReal( iGroupSize ) / length );
       
   455             TInt wanted(  TReal( KNormalRecGroupLength ) * angle );
       
   456             if ( wanted > ( KDefGroupSize / 2 ) && wanted < KMaxGroupSize )
       
   457                 {
       
   458                 iWantedGroup = ( iWantedGroup + wanted ) / 2;
       
   459                 }
       
   460             }
       
   461         }
       
   462 
       
   463 	// Group ok to save?
       
   464     if ( forceSave || iGroupSize > KMaxGroupSize )
       
   465         {
       
   466         // Group packets count (PTC)
       
   467         HBufC8* bytes = CRtpUtil::MakeBytesLC( iPacketsCount );
       
   468         iGroupPointer.Insert( 0, bytes->Des() );
       
   469         CleanupStack::PopAndDestroy( bytes );
       
   470 
       
   471         // Make sure that nasty length not end to the clip in case TS overflow
       
   472         length = ( length <= KMaxGrouplength )? length: KMaxGrouplength;
       
   473 
       
   474         // Save to clip
       
   475         TInt err( KErrNotReady );
       
   476         if ( iClipHandler )
       
   477             {
       
   478             TRAP( err, iClipHandler->SaveNextGroupL( iGroupPointer, 
       
   479                                                      length, aAction ) );
       
   480             }
       
   481         if ( err )
       
   482             {
       
   483             LOG1( "CCRRtpRecordSink::SaveGroup(), SaveNextGroupL Leaved: %d", err );
       
   484             ForceStopRecording( err );
       
   485             }
       
   486         
       
   487         LOG3( "CCRRtpRecordSink::SaveGroup(), iPacketsCount: %d, length: %u, iWantedGroup: %d", 
       
   488                                               iPacketsCount, length, iWantedGroup );
       
   489         }
       
   490     }
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // CCRRtpRecordSink::StreamToType
       
   494 // -----------------------------------------------------------------------------
       
   495 //
       
   496 TBool CCRRtpRecordSink::StreamToType(
       
   497     const MCRPacketSource::TCRPacketStreamId& aStream,
       
   498     MRtpFileWriteObserver::TRtpType& aType )
       
   499     {
       
   500     switch ( aStream )
       
   501         {
       
   502         case MCRPacketSource::EAudioStream:
       
   503             aType = MRtpFileWriteObserver::ERtpAudio;
       
   504             break;
       
   505 
       
   506         case MCRPacketSource::EAudioControlStream:
       
   507             aType = MRtpFileWriteObserver::ERtcpAudio;
       
   508             break;
       
   509 
       
   510         case MCRPacketSource::EVideoStream:
       
   511             aType = MRtpFileWriteObserver::ERtpVideo;
       
   512             break;
       
   513 
       
   514         case MCRPacketSource::EVideoControlStream:
       
   515             aType = MRtpFileWriteObserver::ERtcpVideo;
       
   516             break;
       
   517 
       
   518         case MCRPacketSource::ESubTitleStream:
       
   519             aType = MRtpFileWriteObserver::ERtpSubTitle;
       
   520             break;
       
   521 
       
   522         case MCRPacketSource::ESubTitleControlStream:
       
   523             aType = MRtpFileWriteObserver::ERtcpSubTitle;
       
   524             break;
       
   525 
       
   526         case MCRPacketSource::EDisContinousStream:
       
   527             LOG( "CCRRtpRecordSink::StreamToType(), ERtpClipPause" );
       
   528             aType = MRtpFileWriteObserver::ERtpClipPause;
       
   529             break;
       
   530         
       
   531         case MCRPacketSource::EStreamEndTag:
       
   532             LOG( "CCRRtpRecordSink::StreamToType(), ERtpClipEnd" );
       
   533             aType = MRtpFileWriteObserver::ERtpClipEnd;
       
   534             break;
       
   535 
       
   536         default:
       
   537             return EFalse;
       
   538         }
       
   539     
       
   540     return ETrue;
       
   541     }
       
   542     
       
   543 // -----------------------------------------------------------------------------
       
   544 // CCRRtpRecordSink::TsFromPacketL
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 TUint CCRRtpRecordSink::TsFromPacketL( const TDesC8& aPacket )
       
   548     {
       
   549     CRtpPacket* rtpPacket = CRtpPacket::NewLC();
       
   550     TUint ts( KMaxTUint );
       
   551     if ( !rtpPacket->ParseRtp( aPacket ) )
       
   552         {
       
   553         ts = iAudioConv->ConvertTs( rtpPacket->iRtpRecvHeader.iTimestamp, ETrue );
       
   554         }
       
   555     
       
   556     CleanupStack::PopAndDestroy( rtpPacket );
       
   557     return ts;
       
   558     }
       
   559     
       
   560 // -----------------------------------------------------------------------------
       
   561 // CCRRtpRecordSink::AddPausePacket
       
   562 // Wrapper for AddPausePacketL().
       
   563 // -----------------------------------------------------------------------------
       
   564 //
       
   565 void CCRRtpRecordSink::AddPausePacket()
       
   566     {
       
   567     LOG( "CCRRtpRecordSink::AddPausePacket()");
       
   568 
       
   569     TRAPD( err, AddPausePacketL() );
       
   570     if ( err )
       
   571         {
       
   572         ForceStopRecording( err );
       
   573         }
       
   574     }
       
   575     
       
   576 // -----------------------------------------------------------------------------
       
   577 // CCRRtpRecordSink::AddPausePacketL
       
   578 // Adds pause packet to the group.
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CCRRtpRecordSink::AddPausePacketL()
       
   582     {
       
   583     HBufC8* data = CRtpUtil::MakeBytesLC( KMaxTUint );
       
   584     AddPacketToGroupL( data->Des(), MRtpFileWriteObserver::ERtpClipPause );
       
   585     CleanupStack::PopAndDestroy( data );
       
   586     }
       
   587     
       
   588 // -----------------------------------------------------------------------------
       
   589 // CCRRtpRecordSink::ForceStopRecording
       
   590 // Stops recording on clip handler and destroys the sink.
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 void CCRRtpRecordSink::ForceStopRecording( const TInt& aStatus )
       
   594     {
       
   595     LOG2( "CCRRtpRecordSink::ForceStopRecording(), iGroupMode: %d, aStatus: %d",
       
   596                                                    iGroupMode, aStatus );
       
   597     iGroupMode = MRtpFileWriteObserver::ESaveIdle;
       
   598 
       
   599     if ( iClipHandler )
       
   600         {
       
   601         iClipHandler->StopRecording( aStatus );
       
   602         }
       
   603     
       
   604     iObserver->ConnectionStatusChange( iOwningSession.SourceChecksum(),
       
   605         MCRConnectionObserver::ECRRecordingEnded, aStatus );
       
   606     iOwningSession.SinkStops( Id() );
       
   607     }
       
   608 
       
   609 // -----------------------------------------------------------------------------
       
   610 // CCRRtpRecordSink::ResetGroupVariables
       
   611 // 
       
   612 // -----------------------------------------------------------------------------
       
   613 //
       
   614 void CCRRtpRecordSink::ResetGroupVariables()
       
   615     {
       
   616     iGroupSize = KGroupHeaderSize; // Room for group header and packets count
       
   617     iPacketsCount = 0;
       
   618     iGroupPointer.Zero();
       
   619     iOldestTs = KMaxTUint;
       
   620     iLatestAudio.Set( NULL, 0 );
       
   621     }
       
   622 
       
   623 //  End of File