videoeditorengine/vedengine/videoprocessor/src/activequeue.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "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 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Data buffering and queuing support definitions, class CActiveQueue.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 //  EXTERNAL RESOURCES  
       
    22 
       
    23 
       
    24 //  Include Files  
       
    25 
       
    26 #include "dataprocessor.h"
       
    27 #include "activequeue.h"
       
    28 
       
    29 
       
    30 //  MEMBER FUNCTIONS
       
    31 
       
    32 
       
    33 //=============================================================================
       
    34 
       
    35 
       
    36 /*
       
    37 -----------------------------------------------------------------------------
       
    38 
       
    39     CActiveQueue
       
    40 
       
    41     CActiveQueue()
       
    42 
       
    43     Standard C++ constructor
       
    44 
       
    45 -----------------------------------------------------------------------------
       
    46 */
       
    47 
       
    48 CActiveQueue::CActiveQueue(TUint aNumberOfBlocks, TUint aBlockLength)
       
    49 {
       
    50     // Remember the number of blocks and initial new block length
       
    51     iInitialBlocks = aNumberOfBlocks;
       
    52     iNewBlockLength = aBlockLength;   
       
    53     iStreamEnd = EFalse;
       
    54 }
       
    55 
       
    56 
       
    57 
       
    58 /*
       
    59 -----------------------------------------------------------------------------
       
    60 
       
    61     CActiveQueue
       
    62 
       
    63     ~CActiveQueue()
       
    64 
       
    65     Standard C++ destructor
       
    66 
       
    67 -----------------------------------------------------------------------------
       
    68 */
       
    69 
       
    70 CActiveQueue::~CActiveQueue()
       
    71 {
       
    72     // Deallocate all blocks:
       
    73     while ( iBlocks )
       
    74     {
       
    75         TRAPD( error, FreeBlockL(iBlocks) );
       
    76         if (error != KErrNone) { }
       
    77     }
       
    78 
       
    79     __ASSERT_DEBUG(iNumBlocks == 0,
       
    80                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
    81 }
       
    82 
       
    83 
       
    84 
       
    85 /*
       
    86 -----------------------------------------------------------------------------
       
    87 
       
    88     CActiveQueue
       
    89 
       
    90     ConstructL()
       
    91 
       
    92     Standard Symbian OS second-phase constructor, prepares the object for use
       
    93 
       
    94 -----------------------------------------------------------------------------
       
    95 */
       
    96 
       
    97 void CActiveQueue::ConstructL()
       
    98 {
       
    99     // Allocate initial blocks
       
   100     while ( iInitialBlocks-- )
       
   101     {
       
   102         // Get block
       
   103         TActiveQueueBlock *block = AllocateBlockL();
       
   104 
       
   105         // Add it to the free block list
       
   106         block->iNextList = iFreeList;
       
   107         iFreeList = block;
       
   108         iNumFreeBlocks++;
       
   109     }
       
   110 }
       
   111 
       
   112 
       
   113 
       
   114 /*
       
   115 -----------------------------------------------------------------------------
       
   116 
       
   117     CActiveQueue
       
   118 
       
   119     SetReader()
       
   120 
       
   121     Sets a reader for the queue
       
   122 
       
   123 -----------------------------------------------------------------------------
       
   124 */
       
   125 
       
   126 void CActiveQueue::SetReader(CDataProcessor *aReader, TAny *aUserPointer)
       
   127 {
       
   128     iReader = aReader;
       
   129     iReaderUserPointer = aUserPointer;
       
   130 }
       
   131 
       
   132 
       
   133 
       
   134 /*
       
   135 -----------------------------------------------------------------------------
       
   136 
       
   137     CActiveQueue
       
   138 
       
   139     RemoveReader()
       
   140 
       
   141     Removes a reader from the queue
       
   142 
       
   143 -----------------------------------------------------------------------------
       
   144 */
       
   145 
       
   146 void CActiveQueue::RemoveReader()
       
   147 {
       
   148     __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
       
   149     iReader = 0;
       
   150 }
       
   151 
       
   152 
       
   153 
       
   154 /*
       
   155 -----------------------------------------------------------------------------
       
   156 
       
   157     CActiveQueue
       
   158 
       
   159     SetWriter()
       
   160 
       
   161     Sets a writer for the queue
       
   162 
       
   163 -----------------------------------------------------------------------------
       
   164 */
       
   165 
       
   166 void CActiveQueue::SetWriter(CDataProcessor *aWriter, TAny *aUserPointer)
       
   167 {
       
   168     iWriter = aWriter;
       
   169     iWriterUserPointer = aUserPointer;
       
   170 }
       
   171 
       
   172 
       
   173 
       
   174 /*
       
   175 -----------------------------------------------------------------------------
       
   176 
       
   177     CActiveQueue
       
   178 
       
   179     RemoveWriter()
       
   180 
       
   181     Removes a writer from the queue
       
   182 
       
   183 -----------------------------------------------------------------------------
       
   184 */
       
   185 
       
   186 void CActiveQueue::RemoveWriter()
       
   187 {
       
   188     __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
       
   189     iWriter = 0;
       
   190 }
       
   191 
       
   192 /*
       
   193 -----------------------------------------------------------------------------
       
   194 
       
   195     CActiveQueue
       
   196 
       
   197     ResetStreamEnd()
       
   198 
       
   199     Reset the status of the queue
       
   200 
       
   201 -----------------------------------------------------------------------------
       
   202 */
       
   203 
       
   204 void CActiveQueue::ResetStreamEnd()
       
   205 {
       
   206     iStreamEnd = EFalse;
       
   207     // we should not have any blocks in full queue if we have reached stream end
       
   208 }
       
   209 
       
   210 
       
   211 
       
   212 /*
       
   213 -----------------------------------------------------------------------------
       
   214 
       
   215     CActiveQueue
       
   216 
       
   217     NumFreeBlocks()
       
   218 
       
   219     Get the number of free blocks available for new data
       
   220 
       
   221 -----------------------------------------------------------------------------
       
   222 */
       
   223 
       
   224 TUint CActiveQueue::NumFreeBlocks()
       
   225 {
       
   226     return iNumFreeBlocks;
       
   227 }
       
   228 
       
   229 
       
   230 
       
   231 /*
       
   232 -----------------------------------------------------------------------------
       
   233 
       
   234     CActiveQueue
       
   235 
       
   236     NumDataBlocks()
       
   237 
       
   238     Get the number of blocks with data queued
       
   239 
       
   240 -----------------------------------------------------------------------------
       
   241 */
       
   242 
       
   243 TUint CActiveQueue::NumDataBlocks()
       
   244 {
       
   245     return iNumDataBlocks;
       
   246 }
       
   247 
       
   248 
       
   249 
       
   250 /*
       
   251 -----------------------------------------------------------------------------
       
   252 
       
   253     CActiveQueue
       
   254 
       
   255     GetFreeBlockL()
       
   256 
       
   257     Get a free block for writing data into the queue (writer)
       
   258 
       
   259 -----------------------------------------------------------------------------
       
   260 */
       
   261 
       
   262 TPtr8 *CActiveQueue::GetFreeBlockL(TUint aBlockLength)
       
   263 {
       
   264     __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
       
   265     TActiveQueueBlock *block = 0;
       
   266     
       
   267     // If the requested block size is larger than the currently used length
       
   268     // for new blocks, use the new size for all new blocks
       
   269     if ( aBlockLength > iNewBlockLength )
       
   270         iNewBlockLength = aBlockLength;
       
   271 
       
   272     // Do we have free blocks?
       
   273     if ( iNumFreeBlocks )
       
   274     {
       
   275         // Yes, get a block from the queue:
       
   276         __ASSERT_DEBUG(iFreeList != 0,
       
   277                        User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   278         block = iFreeList;
       
   279         iFreeList = block->iNextList;
       
   280         iNumFreeBlocks--;
       
   281 
       
   282         // If the block isn't large enough, discard it so that we'll allocate a
       
   283         // new one. Don't discard more than one block to keep the number of
       
   284         // blocks allocated constant.
       
   285         if ( block->MaxLength() < (TInt) aBlockLength )
       
   286         {
       
   287             FreeBlockL(block);
       
   288             block = 0;
       
   289         }
       
   290     }
       
   291 
       
   292     // If we didn't get a suitable block, allocate a new one
       
   293     if ( !block )
       
   294         block = AllocateBlockL();
       
   295 
       
   296     __ASSERT_DEBUG(block->MaxLength() >= (TInt) aBlockLength,
       
   297                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   298 
       
   299     block->SetLength(0);
       
   300 
       
   301     return block;
       
   302 }
       
   303 
       
   304 
       
   305 
       
   306 /*
       
   307 -----------------------------------------------------------------------------
       
   308 
       
   309     CActiveQueue
       
   310 
       
   311     WriteBlock()
       
   312 
       
   313     Add a data block to the queue (writer)
       
   314 
       
   315 -----------------------------------------------------------------------------
       
   316 */
       
   317 
       
   318 void CActiveQueue::WriteBlock(TPtr8 *aBlock)
       
   319 {
       
   320     __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
       
   321     __ASSERT_DEBUG(!iStreamEnd,
       
   322                    User::Panic(_L("CActiveQueue"), EWriteAfterStreamEnd));
       
   323                    
       
   324     // The block is really a TActiveQueueBlock
       
   325     TActiveQueueBlock *block = (TActiveQueueBlock*) aBlock;
       
   326 
       
   327 
       
   328     // Add the block to the queue:
       
   329     if ( iDataQueueTail )
       
   330     {
       
   331         // The queue is not empty
       
   332         __ASSERT_DEBUG(iDataQueueHead && iNumDataBlocks,
       
   333                        User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   334         iDataQueueTail->iNextList = block;
       
   335         iDataQueueTail = block;
       
   336         block->iNextList = 0;
       
   337     }
       
   338     else
       
   339     {
       
   340         // The queue is empty -> this will be the first block
       
   341         __ASSERT_DEBUG((!iDataQueueHead) && (!iNumDataBlocks),
       
   342                        User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   343         iDataQueueHead = block;
       
   344         iDataQueueTail = block;
       
   345         block->iNextList = 0;
       
   346     }
       
   347     iNumDataBlocks++;
       
   348 
       
   349     // If we have a reader, notify it about the new data
       
   350     if ( iReader )
       
   351         iReader->InputDataAvailable(iReaderUserPointer);
       
   352 }
       
   353 
       
   354 
       
   355 
       
   356 /*
       
   357 -----------------------------------------------------------------------------
       
   358 
       
   359     CActiveQueue
       
   360 
       
   361     ReadBlock()
       
   362 
       
   363     Read a data block from the queue (reader)
       
   364 
       
   365 -----------------------------------------------------------------------------
       
   366 */
       
   367 
       
   368 TPtr8 *CActiveQueue::ReadBlock()
       
   369 {
       
   370     __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
       
   371     __ASSERT_DEBUG(((iNumDataBlocks && iDataQueueHead) ||
       
   372                     ((!iNumDataBlocks) && (!iDataQueueHead))),
       
   373                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   374 
       
   375     // If we don't have a block, return NULL
       
   376     if ( !iNumDataBlocks )
       
   377         return 0;
       
   378 
       
   379     // Get the block from the queue head
       
   380     TActiveQueueBlock *block = iDataQueueHead;
       
   381     iDataQueueHead = block->iNextList;
       
   382     iNumDataBlocks--;
       
   383     if ( !iNumDataBlocks )
       
   384     {
       
   385         // It was the only block in the queue
       
   386         __ASSERT_DEBUG((!iDataQueueHead) && (iDataQueueTail == block),
       
   387                        User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   388         iDataQueueTail = 0;                       
       
   389     }
       
   390     __ASSERT_DEBUG((iDataQueueHead != block) && (iDataQueueTail != block),
       
   391                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   392 
       
   393     // If it was the last block and the stream end has been signaled, notify
       
   394     // the reader
       
   395     if ( iStreamEnd && (!iNumDataBlocks) )
       
   396         iReader->StreamEndReached(iReaderUserPointer);
       
   397 
       
   398     // Return the block
       
   399     return ((TPtr8*) block);
       
   400 }
       
   401 
       
   402 
       
   403 /*
       
   404 -----------------------------------------------------------------------------
       
   405 
       
   406     CActiveQueue
       
   407 
       
   408     ReturnBlock()
       
   409 
       
   410     Return a read block back to the empty block list (reader)
       
   411 
       
   412 -----------------------------------------------------------------------------
       
   413 */
       
   414 
       
   415 void CActiveQueue::ReturnBlock(TPtr8 *aBlock)
       
   416 {
       
   417     __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
       
   418                    
       
   419     // The block is really a TActiveQueueBlock
       
   420     TActiveQueueBlock *block = (TActiveQueueBlock*) aBlock;
       
   421 
       
   422 
       
   423     // Add it to the free list:
       
   424     __ASSERT_DEBUG((((!iNumFreeBlocks) && (!iFreeList)) ||
       
   425                     (iNumFreeBlocks && iFreeList)),
       
   426                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   427 
       
   428     if ( block->MaxLength() == 0 )
       
   429     {
       
   430         block->MaxLength();
       
   431     }
       
   432 
       
   433     block->iNextList = iFreeList;
       
   434     iFreeList = block;
       
   435     iNumFreeBlocks++;
       
   436 
       
   437     // If we have a writer, notify it about the empty block
       
   438     if ( iWriter )
       
   439         iWriter->OutputSpaceAvailable(iWriterUserPointer);
       
   440 }
       
   441 
       
   442 
       
   443 
       
   444 /*
       
   445 -----------------------------------------------------------------------------
       
   446 
       
   447     CActiveQueue
       
   448 
       
   449     WriteStreamEnd()
       
   450 
       
   451     Notify that the stream has ended (writer)
       
   452 
       
   453 -----------------------------------------------------------------------------
       
   454 */
       
   455 
       
   456 void CActiveQueue::WriteStreamEnd()
       
   457 {
       
   458     __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
       
   459 
       
   460     // Mark that the stream has ended
       
   461     iStreamEnd = ETrue;
       
   462 
       
   463     // If we have a reader and there are no more blocks in the queue, signal
       
   464     // the reader
       
   465     if ( iReader && (!iNumDataBlocks) )
       
   466         iReader->StreamEndReached(iReaderUserPointer);
       
   467 }
       
   468 
       
   469 
       
   470 
       
   471 /*
       
   472 -----------------------------------------------------------------------------
       
   473 
       
   474     CActiveQueue
       
   475 
       
   476     StreamEnded()
       
   477 
       
   478     Check if the writer has notified that the stream has ended (reader)
       
   479 
       
   480 -----------------------------------------------------------------------------
       
   481 */
       
   482 
       
   483 TBool CActiveQueue::StreamEnded()
       
   484 {
       
   485     return iStreamEnd;
       
   486 }
       
   487 
       
   488 
       
   489 
       
   490 /*
       
   491 -----------------------------------------------------------------------------
       
   492 
       
   493     CActiveQueue
       
   494 
       
   495     AllocateBlockL()
       
   496 
       
   497     Allocates a new data block of size iNewBlockLengh
       
   498 
       
   499 -----------------------------------------------------------------------------
       
   500 */
       
   501 
       
   502 TActiveQueueBlock *CActiveQueue::AllocateBlockL()
       
   503 {
       
   504     // Allocate the data area for the block
       
   505     TUint8 *data = (TUint8*) User::AllocLC(iNewBlockLength);    
       
   506 
       
   507     // Allocate the block
       
   508     TActiveQueueBlock *block = new (ELeave) TActiveQueueBlock(data,
       
   509                                                               iNewBlockLength);
       
   510 
       
   511     CleanupStack::Pop(data);
       
   512 
       
   513     // Add the block to the list of all blocks:
       
   514     if ( iBlocks )
       
   515     {
       
   516         block->iNextBlock = iBlocks;
       
   517         block->iPrevBlock = 0;
       
   518         iBlocks->iPrevBlock = block;
       
   519         iBlocks = block;
       
   520     }
       
   521     else
       
   522     {
       
   523         block->iNextBlock = 0;
       
   524         block->iPrevBlock = 0;
       
   525         iBlocks = block;
       
   526     }
       
   527 
       
   528     __ASSERT_DEBUG((iBlocks &&
       
   529                     ((iBlocks->iNextBlock == 0) ||
       
   530                      (iBlocks->iNextBlock != iBlocks))),
       
   531                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   532 
       
   533     return block;
       
   534 }
       
   535 
       
   536 
       
   537 
       
   538 /*
       
   539 -----------------------------------------------------------------------------
       
   540 
       
   541     CActiveQueue
       
   542 
       
   543     FreeBlockL()
       
   544 
       
   545     Deallocates a block allocated with AllocateBlockL()
       
   546 
       
   547 -----------------------------------------------------------------------------
       
   548 */
       
   549 
       
   550 void CActiveQueue::FreeBlockL(TActiveQueueBlock *aBlock)
       
   551 {
       
   552     __ASSERT_DEBUG((((aBlock->iPrevBlock != aBlock->iNextBlock) ||
       
   553                      (aBlock->iNextBlock == 0)) &&
       
   554                     ((aBlock == iBlocks) || (aBlock->iPrevBlock != 0))),
       
   555                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   556     
       
   557     // Remove the block from the list of all blocks:
       
   558     if ( aBlock->iPrevBlock )
       
   559         aBlock->iPrevBlock->iNextBlock = aBlock->iNextBlock;
       
   560     else
       
   561         iBlocks = aBlock->iNextBlock;
       
   562     if ( aBlock->iNextBlock )
       
   563         aBlock->iNextBlock->iPrevBlock = aBlock->iPrevBlock;
       
   564 
       
   565     // Free the data area
       
   566     TUint8 *data = (TUint8*) aBlock->Ptr();    
       
   567     User::Free(data);
       
   568 
       
   569     // Free the block:
       
   570     delete aBlock;
       
   571 
       
   572     __ASSERT_DEBUG(((!iBlocks) ||
       
   573                     (((iBlocks->iNextBlock == 0) ||
       
   574                       (iBlocks->iNextBlock != iBlocks)) &&
       
   575                      (iBlocks->iPrevBlock == 0))),
       
   576                    User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
       
   577 }
       
   578 
       
   579 
       
   580 
       
   581 
       
   582 
       
   583 // End of File