--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/vedengine/videoprocessor/src/activequeue.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,583 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "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:
+* Ixonos Plc
+*
+* Description:
+* Data buffering and queuing support definitions, class CActiveQueue.
+*
+*/
+
+
+// EXTERNAL RESOURCES
+
+
+// Include Files
+
+#include "dataprocessor.h"
+#include "activequeue.h"
+
+
+// MEMBER FUNCTIONS
+
+
+//=============================================================================
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ CActiveQueue()
+
+ Standard C++ constructor
+
+-----------------------------------------------------------------------------
+*/
+
+CActiveQueue::CActiveQueue(TUint aNumberOfBlocks, TUint aBlockLength)
+{
+ // Remember the number of blocks and initial new block length
+ iInitialBlocks = aNumberOfBlocks;
+ iNewBlockLength = aBlockLength;
+ iStreamEnd = EFalse;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ ~CActiveQueue()
+
+ Standard C++ destructor
+
+-----------------------------------------------------------------------------
+*/
+
+CActiveQueue::~CActiveQueue()
+{
+ // Deallocate all blocks:
+ while ( iBlocks )
+ {
+ TRAPD( error, FreeBlockL(iBlocks) );
+ if (error != KErrNone) { }
+ }
+
+ __ASSERT_DEBUG(iNumBlocks == 0,
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ ConstructL()
+
+ Standard Symbian OS second-phase constructor, prepares the object for use
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::ConstructL()
+{
+ // Allocate initial blocks
+ while ( iInitialBlocks-- )
+ {
+ // Get block
+ TActiveQueueBlock *block = AllocateBlockL();
+
+ // Add it to the free block list
+ block->iNextList = iFreeList;
+ iFreeList = block;
+ iNumFreeBlocks++;
+ }
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ SetReader()
+
+ Sets a reader for the queue
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::SetReader(CDataProcessor *aReader, TAny *aUserPointer)
+{
+ iReader = aReader;
+ iReaderUserPointer = aUserPointer;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ RemoveReader()
+
+ Removes a reader from the queue
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::RemoveReader()
+{
+ __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
+ iReader = 0;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ SetWriter()
+
+ Sets a writer for the queue
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::SetWriter(CDataProcessor *aWriter, TAny *aUserPointer)
+{
+ iWriter = aWriter;
+ iWriterUserPointer = aUserPointer;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ RemoveWriter()
+
+ Removes a writer from the queue
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::RemoveWriter()
+{
+ __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
+ iWriter = 0;
+}
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ ResetStreamEnd()
+
+ Reset the status of the queue
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::ResetStreamEnd()
+{
+ iStreamEnd = EFalse;
+ // we should not have any blocks in full queue if we have reached stream end
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ NumFreeBlocks()
+
+ Get the number of free blocks available for new data
+
+-----------------------------------------------------------------------------
+*/
+
+TUint CActiveQueue::NumFreeBlocks()
+{
+ return iNumFreeBlocks;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ NumDataBlocks()
+
+ Get the number of blocks with data queued
+
+-----------------------------------------------------------------------------
+*/
+
+TUint CActiveQueue::NumDataBlocks()
+{
+ return iNumDataBlocks;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ GetFreeBlockL()
+
+ Get a free block for writing data into the queue (writer)
+
+-----------------------------------------------------------------------------
+*/
+
+TPtr8 *CActiveQueue::GetFreeBlockL(TUint aBlockLength)
+{
+ __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
+ TActiveQueueBlock *block = 0;
+
+ // If the requested block size is larger than the currently used length
+ // for new blocks, use the new size for all new blocks
+ if ( aBlockLength > iNewBlockLength )
+ iNewBlockLength = aBlockLength;
+
+ // Do we have free blocks?
+ if ( iNumFreeBlocks )
+ {
+ // Yes, get a block from the queue:
+ __ASSERT_DEBUG(iFreeList != 0,
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+ block = iFreeList;
+ iFreeList = block->iNextList;
+ iNumFreeBlocks--;
+
+ // If the block isn't large enough, discard it so that we'll allocate a
+ // new one. Don't discard more than one block to keep the number of
+ // blocks allocated constant.
+ if ( block->MaxLength() < (TInt) aBlockLength )
+ {
+ FreeBlockL(block);
+ block = 0;
+ }
+ }
+
+ // If we didn't get a suitable block, allocate a new one
+ if ( !block )
+ block = AllocateBlockL();
+
+ __ASSERT_DEBUG(block->MaxLength() >= (TInt) aBlockLength,
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ block->SetLength(0);
+
+ return block;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ WriteBlock()
+
+ Add a data block to the queue (writer)
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::WriteBlock(TPtr8 *aBlock)
+{
+ __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
+ __ASSERT_DEBUG(!iStreamEnd,
+ User::Panic(_L("CActiveQueue"), EWriteAfterStreamEnd));
+
+ // The block is really a TActiveQueueBlock
+ TActiveQueueBlock *block = (TActiveQueueBlock*) aBlock;
+
+
+ // Add the block to the queue:
+ if ( iDataQueueTail )
+ {
+ // The queue is not empty
+ __ASSERT_DEBUG(iDataQueueHead && iNumDataBlocks,
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+ iDataQueueTail->iNextList = block;
+ iDataQueueTail = block;
+ block->iNextList = 0;
+ }
+ else
+ {
+ // The queue is empty -> this will be the first block
+ __ASSERT_DEBUG((!iDataQueueHead) && (!iNumDataBlocks),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+ iDataQueueHead = block;
+ iDataQueueTail = block;
+ block->iNextList = 0;
+ }
+ iNumDataBlocks++;
+
+ // If we have a reader, notify it about the new data
+ if ( iReader )
+ iReader->InputDataAvailable(iReaderUserPointer);
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ ReadBlock()
+
+ Read a data block from the queue (reader)
+
+-----------------------------------------------------------------------------
+*/
+
+TPtr8 *CActiveQueue::ReadBlock()
+{
+ __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
+ __ASSERT_DEBUG(((iNumDataBlocks && iDataQueueHead) ||
+ ((!iNumDataBlocks) && (!iDataQueueHead))),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ // If we don't have a block, return NULL
+ if ( !iNumDataBlocks )
+ return 0;
+
+ // Get the block from the queue head
+ TActiveQueueBlock *block = iDataQueueHead;
+ iDataQueueHead = block->iNextList;
+ iNumDataBlocks--;
+ if ( !iNumDataBlocks )
+ {
+ // It was the only block in the queue
+ __ASSERT_DEBUG((!iDataQueueHead) && (iDataQueueTail == block),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+ iDataQueueTail = 0;
+ }
+ __ASSERT_DEBUG((iDataQueueHead != block) && (iDataQueueTail != block),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ // If it was the last block and the stream end has been signaled, notify
+ // the reader
+ if ( iStreamEnd && (!iNumDataBlocks) )
+ iReader->StreamEndReached(iReaderUserPointer);
+
+ // Return the block
+ return ((TPtr8*) block);
+}
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ ReturnBlock()
+
+ Return a read block back to the empty block list (reader)
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::ReturnBlock(TPtr8 *aBlock)
+{
+ __ASSERT_DEBUG(iReader, User::Panic(_L("CActiveQueue"), ENoReader));
+
+ // The block is really a TActiveQueueBlock
+ TActiveQueueBlock *block = (TActiveQueueBlock*) aBlock;
+
+
+ // Add it to the free list:
+ __ASSERT_DEBUG((((!iNumFreeBlocks) && (!iFreeList)) ||
+ (iNumFreeBlocks && iFreeList)),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ if ( block->MaxLength() == 0 )
+ {
+ block->MaxLength();
+ }
+
+ block->iNextList = iFreeList;
+ iFreeList = block;
+ iNumFreeBlocks++;
+
+ // If we have a writer, notify it about the empty block
+ if ( iWriter )
+ iWriter->OutputSpaceAvailable(iWriterUserPointer);
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ WriteStreamEnd()
+
+ Notify that the stream has ended (writer)
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::WriteStreamEnd()
+{
+ __ASSERT_DEBUG(iWriter, User::Panic(_L("CActiveQueue"), ENoWriter));
+
+ // Mark that the stream has ended
+ iStreamEnd = ETrue;
+
+ // If we have a reader and there are no more blocks in the queue, signal
+ // the reader
+ if ( iReader && (!iNumDataBlocks) )
+ iReader->StreamEndReached(iReaderUserPointer);
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ StreamEnded()
+
+ Check if the writer has notified that the stream has ended (reader)
+
+-----------------------------------------------------------------------------
+*/
+
+TBool CActiveQueue::StreamEnded()
+{
+ return iStreamEnd;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ AllocateBlockL()
+
+ Allocates a new data block of size iNewBlockLengh
+
+-----------------------------------------------------------------------------
+*/
+
+TActiveQueueBlock *CActiveQueue::AllocateBlockL()
+{
+ // Allocate the data area for the block
+ TUint8 *data = (TUint8*) User::AllocLC(iNewBlockLength);
+
+ // Allocate the block
+ TActiveQueueBlock *block = new (ELeave) TActiveQueueBlock(data,
+ iNewBlockLength);
+
+ CleanupStack::Pop(data);
+
+ // Add the block to the list of all blocks:
+ if ( iBlocks )
+ {
+ block->iNextBlock = iBlocks;
+ block->iPrevBlock = 0;
+ iBlocks->iPrevBlock = block;
+ iBlocks = block;
+ }
+ else
+ {
+ block->iNextBlock = 0;
+ block->iPrevBlock = 0;
+ iBlocks = block;
+ }
+
+ __ASSERT_DEBUG((iBlocks &&
+ ((iBlocks->iNextBlock == 0) ||
+ (iBlocks->iNextBlock != iBlocks))),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ return block;
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CActiveQueue
+
+ FreeBlockL()
+
+ Deallocates a block allocated with AllocateBlockL()
+
+-----------------------------------------------------------------------------
+*/
+
+void CActiveQueue::FreeBlockL(TActiveQueueBlock *aBlock)
+{
+ __ASSERT_DEBUG((((aBlock->iPrevBlock != aBlock->iNextBlock) ||
+ (aBlock->iNextBlock == 0)) &&
+ ((aBlock == iBlocks) || (aBlock->iPrevBlock != 0))),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+
+ // Remove the block from the list of all blocks:
+ if ( aBlock->iPrevBlock )
+ aBlock->iPrevBlock->iNextBlock = aBlock->iNextBlock;
+ else
+ iBlocks = aBlock->iNextBlock;
+ if ( aBlock->iNextBlock )
+ aBlock->iNextBlock->iPrevBlock = aBlock->iPrevBlock;
+
+ // Free the data area
+ TUint8 *data = (TUint8*) aBlock->Ptr();
+ User::Free(data);
+
+ // Free the block:
+ delete aBlock;
+
+ __ASSERT_DEBUG(((!iBlocks) ||
+ (((iBlocks->iNextBlock == 0) ||
+ (iBlocks->iNextBlock != iBlocks)) &&
+ (iBlocks->iPrevBlock == 0))),
+ User::Panic(_L("CActiveQueue"), EInternalAssertionFailure));
+}
+
+
+
+
+
+// End of File