dvrengine/CommonRecordingEngine/src/CCRPacketBuffer.cpp
branchRCL_3
changeset 48 13a33d82ad98
parent 0 822a42b6c3f1
equal deleted inserted replaced
47:826cea16efd9 48:13a33d82ad98
       
     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:    Hold rtp packets waiting to be sent*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CCRPacketBuffer.h"
       
    22 #include <e32cmn.h>
       
    23 #include "videoserviceutilsLogger.h"
       
    24 
       
    25 // CONSTANTS
       
    26 // None.
       
    27 
       
    28 // ============================ MEMBER FUNCTIONS ===============================
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // CCRPacketBuffer::NewL
       
    32 // Two-phased constructor.
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 CCRPacketBuffer* CCRPacketBuffer::NewL( const TInt aMaxPackets )
       
    36     {
       
    37     CCRPacketBuffer* self = new( ELeave ) CCRPacketBuffer( aMaxPackets );
       
    38     CleanupStack::PushL( self );
       
    39     self->ConstructL();
       
    40     CleanupStack::Pop( self );
       
    41     return self;
       
    42     }
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CCRPacketBuffer::CCRPacketBuffer
       
    46 // C++ default constructor can NOT contain any code, that might leave.
       
    47 // -----------------------------------------------------------------------------
       
    48 //
       
    49 CCRPacketBuffer::CCRPacketBuffer( const TInt aMaxPackets )
       
    50   : iMaxPackets( aMaxPackets ),
       
    51     iContinousStream( EFalse ),
       
    52     iMoreComing( EFalse )
       
    53     {
       
    54     // None
       
    55     }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CCRPacketBuffer::ConstructL
       
    59 // Symbian 2nd phase constructor can leave.
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 void CCRPacketBuffer::ConstructL()
       
    63     {
       
    64     // None
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CCRPacketBuffer::~CCRPacketBuffer
       
    69 // Destructor.
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 CCRPacketBuffer::~CCRPacketBuffer()
       
    73     {
       
    74     LOG( "CCRPacketBuffer::~CCRPacketBuffer" );
       
    75     
       
    76     iBuffer.ResetAndDestroy(); 
       
    77     iBookKeeping.Close();
       
    78     iSinkArray.Close();
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CCRPacketBuffer::AddSink
       
    83 // 
       
    84 // -----------------------------------------------------------------------------
       
    85 //   
       
    86 TInt CCRPacketBuffer::AddSink( CCRPacketSinkBase* aSink ) 
       
    87     {
       
    88     LOG( "CCRPacketBuffer::AddSink() in" );
       
    89     
       
    90     // Check if sink exist already?
       
    91     TBool exist( EFalse );
       
    92     for ( TInt i( iBookKeeping.Count() - 1 ); i >= 0 && !exist; i-- )
       
    93         {
       
    94         exist = ( aSink->Id() == iBookKeeping[i].iId );
       
    95         }
       
    96     
       
    97     // If not, add sink to list
       
    98     TInt err( KErrNone );
       
    99     if ( !exist )
       
   100         {
       
   101         SBookKeeping book;
       
   102         book.iId = aSink->Id();
       
   103         book.iIndex = KErrNotFound;
       
   104         err = iBookKeeping.Append( book );
       
   105         if ( !err )
       
   106             {
       
   107             err = iSinkArray.Append( aSink );
       
   108             if ( err )
       
   109                 {
       
   110                 // Remove last from book keeping, because sink append failed
       
   111                 LOG1( "CCRPacketBuffer::AddSink(), Sink append error: %d", err );
       
   112                 iBookKeeping.Remove( iBookKeeping.Count() - 1 );
       
   113                 }
       
   114             }
       
   115         }
       
   116 
       
   117     LOG3( "CCRPacketBuffer::AddSink() out, err: %d, iSinkArray count: %d, iBookKeeping count: %d",
       
   118                                            err, iSinkArray.Count(), iBookKeeping.Count() );
       
   119     return err;
       
   120     }
       
   121     
       
   122 // -----------------------------------------------------------------------------
       
   123 // CCRPacketBuffer::AddPacket
       
   124 // Method for add.
       
   125 // -----------------------------------------------------------------------------
       
   126 //  
       
   127 void CCRPacketBuffer::AddPacket( 
       
   128     const MCRPacketSource::TCRPacketStreamId& aStream,
       
   129     const TDesC8& aHeader,
       
   130     const TDesC8& aPacket )
       
   131     {
       
   132     // Room
       
   133     VerifyRoom();
       
   134 
       
   135     // Add packet
       
   136     const TInt total( KStreamTypeBytesLength + 
       
   137                       aHeader.Length() + aPacket.Length() );
       
   138     HBufC8* packet = HBufC8::New( total );
       
   139     if ( packet )
       
   140         {
       
   141         TPtr8 ptr( packet->Des() );
       
   142         ptr.SetLength( KStreamTypeBytesLength );
       
   143         ptr[KStreamTypeBytePoint] = ( TUint8 )( aStream );
       
   144         ptr.Append( aHeader );
       
   145         ptr.Append( aPacket );
       
   146         if ( iBuffer.Insert( packet, 0 ) )
       
   147             {
       
   148             delete packet;
       
   149             }
       
   150         else
       
   151             {
       
   152             PacketToBookKeeping();
       
   153             }
       
   154         }
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CCRPacketBuffer::AddPacket
       
   159 // Method for add.
       
   160 // -----------------------------------------------------------------------------
       
   161 //  
       
   162 void CCRPacketBuffer::AddPacket(
       
   163     const MCRPacketSource::TCRPacketStreamId& aStream,
       
   164     const TDesC8& aPacket )
       
   165     {
       
   166     // Room
       
   167     VerifyRoom();
       
   168 
       
   169     // Add packet
       
   170     const TInt total( KStreamTypeBytesLength + aPacket.Length() );
       
   171     HBufC8* packet = HBufC8::New( total );
       
   172     if ( packet )
       
   173         {
       
   174         TPtr8 ptr( packet->Des() );
       
   175         ptr.SetLength( KStreamTypeBytesLength );
       
   176         ptr[KStreamTypeBytePoint] = ( TUint8 )( aStream );
       
   177         ptr.Append( aPacket );
       
   178         if ( iBuffer.Insert( packet, 0 ) )
       
   179             {
       
   180             delete packet;
       
   181             }
       
   182         else
       
   183             {
       
   184             PacketToBookKeeping();
       
   185             }
       
   186         }
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // CCRPacketBuffer::ContinousStream
       
   191 // Method for set buffer estimate when it ends.
       
   192 // -----------------------------------------------------------------------------
       
   193 //  
       
   194 void CCRPacketBuffer::ContinousStream( const TBool aState )
       
   195     {
       
   196     LOG1( "CCRPacketBuffer::ContinousStream(), aState: %d", aState );
       
   197     iContinousStream = aState;
       
   198     }
       
   199     
       
   200 // -----------------------------------------------------------------------------
       
   201 // CCRPacketBuffer::ContinousStream
       
   202 // Method for get the time when buffer should end.
       
   203 // -----------------------------------------------------------------------------
       
   204 //  
       
   205 TBool CCRPacketBuffer::ContinousStream()
       
   206     {
       
   207     return iContinousStream;
       
   208     }
       
   209     
       
   210 // -----------------------------------------------------------------------------
       
   211 // CCRPacketBuffer:::MoreComing
       
   212 // Method for set more coming state.
       
   213 // -----------------------------------------------------------------------------
       
   214 //  
       
   215 void CCRPacketBuffer::MoreComing( const TBool aState )
       
   216     {
       
   217     iMoreComing = aState;
       
   218     }
       
   219     
       
   220 // -----------------------------------------------------------------------------
       
   221 // CCRPacketBuffer:::MoreComing
       
   222 // Method for get more coming state.
       
   223 // -----------------------------------------------------------------------------
       
   224 //  
       
   225 TBool CCRPacketBuffer::MoreComing()
       
   226     {
       
   227     return iMoreComing;
       
   228     }
       
   229     
       
   230 // -----------------------------------------------------------------------------
       
   231 // CCRPacketBuffer::GetStream
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 TInt CCRPacketBuffer::GetStream(
       
   235     const CCRStreamingSession::TCRSinkId& aId,
       
   236     MCRPacketSource::TCRPacketStreamId& aStreamId )
       
   237     {
       
   238     return GetStream( aId, 0, aStreamId );
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CCRPacketBuffer::GetStream
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 TInt CCRPacketBuffer::GetStream(
       
   246     const CCRStreamingSession::TCRSinkId& aId,
       
   247     const TInt aOffset,
       
   248     MCRPacketSource::TCRPacketStreamId& aStreamId )
       
   249     {
       
   250     const TInt bookKeeping( GetBookKeeping( aId ) );
       
   251     if ( bookKeeping > KErrNotFound  )
       
   252         {
       
   253         const TInt index( GetBufferIndex( bookKeeping ) - aOffset );
       
   254         if ( index > KErrNotFound && index < iBuffer.Count() )
       
   255             {
       
   256             aStreamId = MCRPacketSource::TCRPacketStreamId( 
       
   257                         iBuffer[index]->Des()[KStreamTypeBytePoint] );
       
   258             }
       
   259         }
       
   260     
       
   261     return bookKeeping;    
       
   262     }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // CCRPacketBuffer::GetPacket
       
   266 // Method for remove
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 void CCRPacketBuffer::GetPacket(
       
   270     const CCRStreamingSession::TCRSinkId& aId,
       
   271     TPtr8& aReturnedData )
       
   272     {
       
   273     const TInt bookKeeping( GetBookKeeping( aId ) );
       
   274     GetPacket( bookKeeping, aReturnedData );
       
   275     }
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CCRPacketBuffer::GetPacket
       
   279 // Method for remove
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 void CCRPacketBuffer::GetPacket( const TInt aBookKeeping, TPtr8& aReturnedData )
       
   283     {
       
   284     PeekPacket( aBookKeeping, aReturnedData, 0 );
       
   285     
       
   286     if ( aReturnedData.Ptr() || aReturnedData.Length() > 0 )
       
   287         {
       
   288         // One packet used
       
   289         iBookKeeping[aBookKeeping].iIndex--;        
       
   290         }
       
   291     }
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // CCRPacketBuffer::PeekPacket
       
   295 // Method for peeking
       
   296 // -----------------------------------------------------------------------------
       
   297 //
       
   298 void CCRPacketBuffer::PeekPacket( 
       
   299     const CCRStreamingSession::TCRSinkId& aId,
       
   300     TPtr8& aReturnedData, 
       
   301     const TInt aOffset )
       
   302     {
       
   303     const TInt bookKeeping( GetBookKeeping( aId ) );
       
   304     PeekPacket( bookKeeping, aReturnedData, aOffset );
       
   305     }
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CCRPacketBuffer::PeekPacket
       
   309 // Method for peeking
       
   310 // -----------------------------------------------------------------------------
       
   311 //
       
   312 void CCRPacketBuffer::PeekPacket( 
       
   313     const TInt aBookKeeping, 
       
   314     TPtr8& aReturnedData, 
       
   315     const TInt aOffset )
       
   316     {
       
   317     aReturnedData.Set( NULL, 0, 0 ); 
       
   318     
       
   319     if ( aBookKeeping > KErrNotFound && aBookKeeping < iBookKeeping.Count() )
       
   320         {
       
   321         const TInt index( GetBufferIndex( aBookKeeping ) - aOffset );
       
   322         if ( index > KErrNotFound && index < iBuffer.Count() )
       
   323             {
       
   324             // Data
       
   325             aReturnedData.Set( 
       
   326                 iBuffer[index]->Des().MidTPtr( KStreamTypeBytesLength ) );
       
   327             }
       
   328         }    
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CCRPacketBuffer::PacketsCount
       
   333 // Method for asking count of packet available.
       
   334 // -----------------------------------------------------------------------------
       
   335 //   
       
   336 TInt CCRPacketBuffer::PacketsCount( const CCRStreamingSession::TCRSinkId& aId )
       
   337     {
       
   338     const TInt bookKeeping( GetBookKeeping( aId ) );
       
   339     if ( bookKeeping > KErrNotFound )
       
   340         {
       
   341         return iBookKeeping[bookKeeping].iIndex;
       
   342         }
       
   343     
       
   344     return KErrNotFound;
       
   345     }
       
   346     
       
   347 // -----------------------------------------------------------------------------
       
   348 // CCRPacketBuffer::PacketsMinCount
       
   349 // Method for asking minimum count of packet available in any sink.
       
   350 // -----------------------------------------------------------------------------
       
   351 //   
       
   352 TInt CCRPacketBuffer::PacketsMinCount()
       
   353     {
       
   354     TInt ret( KMaxTInt );
       
   355     for ( TInt i( iBookKeeping.Count() - 1 ); i >= 0 ; i-- )
       
   356         {
       
   357         if ( iBookKeeping[i].iIndex < ret )
       
   358             {
       
   359             ret = iBookKeeping[i].iIndex;
       
   360             }
       
   361         }
       
   362     
       
   363     return ret;
       
   364     }
       
   365     
       
   366 // -----------------------------------------------------------------------------
       
   367 // CCRPacketBuffer::HandleBufferSize
       
   368 // Removes packets which are used in all book keepings.
       
   369 // -----------------------------------------------------------------------------
       
   370 //   
       
   371 void CCRPacketBuffer::HandleBufferSize()
       
   372     {
       
   373     // Find maximum index
       
   374     TInt max( KErrNotFound );
       
   375     for ( TInt i( 0 ); i < iBookKeeping.Count(); i++ )
       
   376         {
       
   377         max = Max( max, iBookKeeping[i].iIndex );
       
   378         }
       
   379     
       
   380     // Delete used packets
       
   381     const TInt oldCount( iBuffer.Count() );
       
   382     for ( TInt i( oldCount - 1 ); ( i > max ) && ( i > KErrNotFound ); i-- )
       
   383         {
       
   384         delete iBuffer[i];
       
   385         iBuffer.Remove( i );
       
   386         }
       
   387     
       
   388     // Compress if packets deleted
       
   389     if ( iBuffer.Count() < oldCount )
       
   390         {
       
   391         iBuffer.Compress();
       
   392         }
       
   393     }
       
   394 
       
   395 // -----------------------------------------------------------------------------
       
   396 // CCRPacketBuffer::AdjustBuffer
       
   397 // Drops packets to 25% of buffers max size. 
       
   398 // -----------------------------------------------------------------------------
       
   399 //
       
   400 void CCRPacketBuffer::AdjustBuffer()
       
   401     {
       
   402     const TInt limit( iMaxPackets / 4 );
       
   403     for ( TInt i( iBookKeeping.Count() - 1 ); i >= 0 ; i-- )
       
   404         {
       
   405         if ( iBookKeeping[i].iIndex > limit )
       
   406         	{
       
   407             LOG3( "CCRPacketBuffer::AdjustBuffer(), book: %d, index: %d, limit: %d",
       
   408                i, iBookKeeping[i].iIndex, limit );
       
   409             iBookKeeping[i].iIndex = limit;
       
   410         	}
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CCRPacketBuffer::ResetBuffer
       
   416 // 
       
   417 // -----------------------------------------------------------------------------
       
   418 //   
       
   419 void CCRPacketBuffer::ResetBuffer()
       
   420     {
       
   421     // Reset book keeping
       
   422     for ( TInt i( iBookKeeping.Count() - 1 ); i >= 0 ; i-- )
       
   423         {
       
   424         LOG2( "CCRPacketBuffer::ResetBuffer(), book: %d, index: %d",
       
   425             i, iBookKeeping[i].iIndex ); 
       
   426         iBookKeeping[i].iIndex = KErrNotFound;
       
   427         }
       
   428     
       
   429     // Notify sinks
       
   430     for ( TInt i( iSinkArray.Count() - 1 ); i >= 0; i-- )
       
   431         {
       
   432         iSinkArray[i]->BufferResetDone();
       
   433         }
       
   434 
       
   435     // Reset items
       
   436     iBuffer.ResetAndDestroy();
       
   437     }
       
   438     
       
   439 // -----------------------------------------------------------------------------
       
   440 // CCRPacketBuffer::RemoveSink
       
   441 // 
       
   442 // -----------------------------------------------------------------------------
       
   443 //   
       
   444 TInt CCRPacketBuffer::RemoveSink( CCRPacketSinkBase* aSink ) 
       
   445     {
       
   446     // Sink
       
   447     for ( TInt i( iSinkArray.Count() - 1 ); i >= 0; i-- )
       
   448         {
       
   449         if ( iSinkArray[i] == aSink ) 
       
   450             {
       
   451             iSinkArray.Remove( i );
       
   452             LOG1( "CCRPacketBuffer::RemoveSink(), removed Sink: %d", i );
       
   453             }   
       
   454         }
       
   455 
       
   456     // Book keeping
       
   457     for ( TInt i( iBookKeeping.Count() - 1 ); i >= 0; i-- )
       
   458         {
       
   459         if ( iBookKeeping[i].iId == aSink->Id() ) 
       
   460             {
       
   461             iBookKeeping.Remove( i ); 
       
   462             LOG1( "CCRPacketBuffer::RemoveSink(), removed Book keeping: %d", i );
       
   463             }   
       
   464         }
       
   465     
       
   466     return iSinkArray.Count();         
       
   467     }
       
   468     
       
   469 // -----------------------------------------------------------------------------
       
   470 // CCRPacketBuffer::VerifyRoom()
       
   471 // Verify maximum packets in buffer. Will drop packets count to 1/4 if maximum
       
   472 // size reached. 
       
   473 // -----------------------------------------------------------------------------
       
   474 //  
       
   475 void CCRPacketBuffer::VerifyRoom()
       
   476     {
       
   477     TInt count( iBuffer.Count() );
       
   478     if ( count >= iMaxPackets )
       
   479         {
       
   480         LOG1( "CCRPacketBuffer::VerifyRoom(), Buffer full ! count: %d", count );
       
   481         AdjustBuffer();
       
   482         
       
   483         // Make sure memory not run out because of asyncronous packets deleting
       
   484         if ( count >= ( iMaxPackets * 2 ) )
       
   485             {
       
   486             ResetBuffer();
       
   487             }
       
   488         }
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // CCRPacketBuffer::GetBookKeeping
       
   493 // Updates book keeping index basing on sink id.
       
   494 // -----------------------------------------------------------------------------
       
   495 //
       
   496 TInt CCRPacketBuffer::GetBookKeeping( const CCRStreamingSession::TCRSinkId& aId )
       
   497     {
       
   498     for ( TInt i( 0 ); i < iBookKeeping.Count(); i++ )
       
   499         {
       
   500         if ( iBookKeeping[i].iId == aId )
       
   501             {
       
   502             return i;
       
   503             }
       
   504         }
       
   505     
       
   506     return KErrNotFound;
       
   507     }
       
   508     
       
   509 // -----------------------------------------------------------------------------
       
   510 // CCRPacketBuffer::GetBufferIndex
       
   511 // Getter for buffer index from book keeping.
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 TInt CCRPacketBuffer::GetBufferIndex( const TInt aBookKeeping )
       
   515     {
       
   516     if ( aBookKeeping > KErrNotFound && aBookKeeping < iBookKeeping.Count() )
       
   517         {
       
   518         return iBookKeeping[aBookKeeping].iIndex;
       
   519         }
       
   520     
       
   521     return KErrNotFound;
       
   522     }
       
   523     
       
   524 // -----------------------------------------------------------------------------
       
   525 // CCRPacketBuffer::PacketToBookKeeping
       
   526 // 
       
   527 // -----------------------------------------------------------------------------
       
   528 //   
       
   529 void CCRPacketBuffer::PacketToBookKeeping()
       
   530     {
       
   531     // New packet to book keeping
       
   532     for ( TInt i( 0 ); i < iBookKeeping.Count(); i++ )
       
   533         {
       
   534         iBookKeeping[i].iIndex++;
       
   535         }
       
   536 
       
   537     // New packet available
       
   538     for ( TInt i( 0 ); i < iSinkArray.Count(); i++ )
       
   539         {
       
   540         iSinkArray[i]->NewPacketAvailable();
       
   541         }
       
   542     }
       
   543 
       
   544 //  End of File