utilities/ariprocessengine/src/ariprocessengine.cpp
changeset 0 bb31fbe78861
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utilities/ariprocessengine/src/ariprocessengine.cpp	Fri Jul 23 16:58:44 2010 +0100
@@ -0,0 +1,831 @@
+/*
+* Copyright (c) 2009 Aricent and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Aricent - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Implementation of  Base process engine
+*
+*/
+#include "ariprocessengine.h"
+#include <e32def.h>
+
+//---------------------------------------------------------------------------
+//  Default constructor
+//----------------------------------------------------------------------------
+//
+CBaseProcessEngine::CBaseProcessEngine ()
+						: CActive( CActive::EPriorityStandard )
+	{
+	PRINT_ENTRY;
+	iState = EStop;
+	iCurInputBuf = NULL;
+	iCurOutputBuf = NULL;
+
+	iCmdArray.SetOffset( _FOFF( CCmdPckg,iPriorityLink ) );
+
+	iProcEngineObserver = NULL;
+	iCodec = NULL;
+	iCurInputBuf = NULL;
+	iCurOutputBuf = NULL;
+	iCurCmd = NULL;
+	iIsProcessing = EFalse;
+
+	iInputBufsAddedSoFar = 0;
+	iOutputBufsAddedSoFar = 0;
+	iOutputBufferReadyCallBackPending =	EFalse;
+
+	CActiveScheduler::Add( this );
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+//   2 - phase construtor of CBaseEngine
+//----------------------------------------------------------------------------
+//
+EXPORT_C CBaseEngine* CBaseEngine::NewL ( MProcessEngineObserver* aObserver,
+		MBaseCodec* aCodec,
+		TBool aInPlaceProcessing,
+		TBool aProcessingAutomatic )
+	{
+	PRINT_ENTRY;
+	PRINT_EXIT;
+	return CBaseProcessEngine::NewL ( aObserver, aCodec, aInPlaceProcessing,
+									aProcessingAutomatic );
+	}
+
+//---------------------------------------------------------------------------
+//   2 - phase construtor of CBaseProcessEngine
+//----------------------------------------------------------------------------
+//
+CBaseProcessEngine* CBaseProcessEngine::NewL (
+		MProcessEngineObserver* aObserver,
+		MBaseCodec* aCodec,
+		TBool aInPlaceProcessing,
+		TBool aProcessingAutomatic )
+	{
+	PRINT_ENTRY;
+	CBaseProcessEngine* uSelf = new ( ELeave ) CBaseProcessEngine;
+	CleanupStack::PushL( uSelf );
+	uSelf->ConstructL( aObserver, aCodec, aInPlaceProcessing,
+			aProcessingAutomatic);
+	CleanupStack::Pop();
+	PRINT_EXIT;
+	return uSelf;
+	}
+
+//---------------------------------------------------------------------------
+//  Destructor
+//-----------------------------------------------------------------------------
+//
+
+CBaseProcessEngine::~CBaseProcessEngine ()
+	{
+	PRINT_ENTRY;
+	Cancel();
+	//Flushes out all buffers.
+	Reset();
+	iInputArray.Close();
+	iOutputArray.Close();
+	iCmdArray.Reset();
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Second phase constructor
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::ConstructL ( MProcessEngineObserver* aObserver,
+		MBaseCodec* aCodec,
+		TBool aInPlaceProcessing,
+		TBool aProcessingAutomatic )
+	{
+	PRINT_ENTRY;
+	iProcEngineObserver = aObserver;
+	iCodec = aCodec;
+	iInPlaceProc = aInPlaceProcessing;
+	iAutomaticProc = aProcessingAutomatic;
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Starts the engine
+//----------------------------------------------------------------------------
+//
+
+TInt CBaseProcessEngine::Start ()
+	{
+	PRINT_ENTRY;
+	iState = EStart;
+	IssueRequest();
+	return KErrNone;
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+//  Stops the engine
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::Stop ()
+	{
+	PRINT_ENTRY;
+	Cancel();
+	iState = EStop;
+	PRINT_EXIT;
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------
+//  Adds an input buffer to the input q
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::AddInput ( TAny* aInput )
+	{
+	PRINT_ENTRY;
+	if( !aInput )
+		{
+		return KErrArgument;
+		}
+	TInt lError = KErrNone;
+	lError = iInputArray.Append( aInput );
+	if ( lError )
+		{
+		return lError;
+		}
+
+	iInputBufsAddedSoFar++;
+
+	if( iAutomaticProc ) // true
+		{
+		CCmdPckg* lCmd = NULL;
+		TRAP( lError,lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EDoProcess,
+				ENormalPriority ) );
+		if( lError )
+			{
+			return lError;
+			}
+		iCmdArray.Add( *lCmd );
+		}
+	// RunL should be scheduled in Start state. Also, if it is already
+	// processing i.e iIsProcessing is ETrue,RunL should not be scheduled
+
+	if ( ( iState == EStart ) && !iIsProcessing )
+		{
+		IssueRequest();
+		}
+	PRINT_EXIT;
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------
+//  Adds a buffer to the output q
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::AddOutput ( TAny* aOutput )
+	{
+	PRINT_ENTRY;
+	if( !aOutput )
+		{
+		return KErrArgument;
+		}
+	else if( iInPlaceProc )
+		{
+		return KErrNotSupported;
+		}
+	TInt lError = KErrNone;
+	lError = iOutputArray.Append( aOutput );
+	if ( lError )
+		{
+		return lError;
+		}
+
+	iOutputBufsAddedSoFar++;
+
+	// RunL should be scheduled in Start state. Also, if it is already
+	// processing i.e iIsProcessing is ETrue,RunL should not be scheduled
+
+	if ( ( iState == EStart ) && !iIsProcessing )
+		{
+		IssueRequest();
+		}
+	PRINT_EXIT;
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------
+//  Resets the processing engine and flushes all the pending input
+//  and output buffers.Calls InputBufferConsumed and OutputBufferReady
+//  to give pending input & output buffers with aError = KErrCancel.
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::Reset ()
+	{
+	PRINT_ENTRY;
+	Stop();
+
+	iCodec->Reset();
+
+	iIsProcessing	=	EFalse;
+
+	if ( iCurInputBuf )
+		{
+		TAny* lTempBuf	= iCurInputBuf;
+		iCurInputBuf	= NULL;
+
+		delete iCurCmd;
+		iCurCmd = NULL;
+
+		iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel );
+		}
+	while ( iInputArray.Count() )
+		{
+		TAny* lTempBuf	= iInputArray[0];
+		iInputArray.Remove( 0 );
+
+		delete iCurCmd;
+		iCurCmd = NULL;
+
+		iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel );
+		}
+	if ( iCurOutputBuf )
+		{
+		TAny* lTempBuf	= iCurOutputBuf;
+		iCurOutputBuf	= NULL;
+		iProcEngineObserver->OutputBufferReady (lTempBuf, KErrCancel);
+		}
+	while ( iOutputArray.Count() )
+		{
+		TAny* lTempBuf	= iOutputArray[0];
+		iOutputArray.Remove( 0 );
+		iProcEngineObserver->OutputBufferReady( lTempBuf, KErrCancel );
+		}
+	if ( iCurCmd )
+		{
+		if ( iCurCmd->iCmdType != CCmdPckg::EDoProcess )
+			{
+			iProcEngineObserver->CommandProcessed( iCurCmd->iCmd,
+					iCurCmd->iCmdData, KErrCancel );
+			}
+		delete iCurCmd;
+		}
+	while ( !iCmdArray.IsEmpty() )
+		{
+		CCmdPckg* lCurCmd = iCmdArray.First();
+		lCurCmd->iPriorityLink.Deque();
+		if ( lCurCmd->iCmdType != CCmdPckg::EDoProcess )
+			{
+			iProcEngineObserver->CommandProcessed( lCurCmd->iCmd,
+					lCurCmd->iCmdData, KErrCancel );
+			}
+		delete lCurCmd;
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+//  Returns output buffers.
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::ReturnOutputBuffers ()
+	{
+	PRINT_ENTRY;
+	while ( iOutputArray.Count() )
+		{
+		iProcEngineObserver->OutputBufferReady( iOutputArray[0], KErrCancel );
+		iOutputArray.Remove( 0 );
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Returns input buffers
+//----------------------------------------------------------------------------
+//
+
+void CBaseProcessEngine::ReturnInputBuffers ()
+	{
+	PRINT_ENTRY;
+
+	//Cancel any on-going processing
+	if( iIsProcessing )
+		{
+		iCodec->Reset();
+		iIsProcessing = EFalse;
+		}
+
+	// return the current input buffer and delete the corresponding doprocessL
+	// command
+	if ( iCurInputBuf )
+		{
+		TAny* lTempBuf	= iCurInputBuf;
+		iCurInputBuf	= NULL;
+
+		delete iCurCmd;
+		iCurCmd = NULL;
+
+		iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel );
+		}
+
+	//Since processing is canceled, output is not valid.
+	//So add the output buffer back to the queue for reuse
+	if( iCurOutputBuf )
+		{
+		iOutputArray.Append ( iCurOutputBuf );
+		iCurOutputBuf = NULL;
+		}
+
+	RPointerArray<CCmdPckg> lTempCmdArray;
+
+	//Since all the input buffers are going to be returned, delete all
+	// DoProcess commands from the command array.
+	// Other commands should be put into the queue as it is.
+
+	while( !iCmdArray.IsEmpty() )
+		{
+		CCmdPckg* lCurCmd = iCmdArray.First();
+		lCurCmd->iPriorityLink.Deque();
+
+		if ( lCurCmd->iCmdType == CCmdPckg::EDoProcess )
+			{
+			delete lCurCmd;
+			}
+		else
+			{
+			// Store non-DoProcess commands in temporary array. And put them
+			// back in the iCmdArray after all the DoProcess commands are
+			// removed.Appending to the array to keep the order of commands
+			//	intact.
+			lTempCmdArray.Append( lCurCmd );
+			}
+		}
+
+	while ( lTempCmdArray.Count() )
+		{
+		iCmdArray.Add ( *( lTempCmdArray[0] ) );
+		lTempCmdArray.Remove( 0 );
+		}
+
+	lTempCmdArray.Close();
+
+	//return all the input buffers
+	while ( iInputArray.Count() )
+		{
+		TAny* lTempBuf = iInputArray[0];
+		iInputArray.Remove( 0 );
+		iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel );
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Processes the commands
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::DoProcessL( TInt aPriority )
+	{
+	PRINT_ENTRY;
+	CCmdPckg* lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EDoProcess,
+			aPriority );
+	iCmdArray.Add ( *lCmd );
+
+	// RunL should be scheduled in Start state. Also, if it is already
+	// processing i.e iIsProcessing is ETrue,RunL should not be scheduled
+	if ( iState == EStart || !iIsProcessing )
+		{
+		IssueRequest();
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Adds a new command to the priority queue of commands
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::AddCommandL(TInt aPriority, TInt aCmd,
+		TAny* aCmdData )
+	{
+	PRINT_ENTRY;
+	CCmdPckg* lCmd = new ( ELeave ) CCmdPckg( CCmdPckg::EOther, aPriority,
+			aCmd, aCmdData );
+	iCmdArray.Add (*lCmd);
+	// RunL should be scheduled in Start state. Also, if it is already
+	// processing i.e iIsProcessing is ETrue,RunL should not be scheduled
+
+	if ( iState == EStart || !iIsProcessing )
+		{
+		IssueRequest();
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Called by MBaseCodec when processing is complete
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::ProcessingComplete( TAny *aInpBuf, TAny* aOutBuf,
+		MBaseCodec::TCodecState aState, TInt aError )
+	{
+	PRINT_ENTRY;
+	TAny* lTempBuf	=	NULL;
+
+	iError	=	aError;
+	if ( iCurInputBuf != aInpBuf )
+		{
+		/*This should never happen*/
+		User::Panic( _L ( "iCurInputBuf != aInpBuf" ) , 0 );
+										
+		}
+	if ( iCurOutputBuf != aOutBuf )
+		{
+		/*This should never happen*/
+		User::Panic (_L("iCurOutputBuf != aOutBuf" ) , 1 );
+										
+		}
+	if ( !iIsProcessing )
+		{
+		/*This should never happen*/
+		User::Panic (_L("!iIsProcessing " ) , 2 );
+												
+		}
+
+	// error returned by the DoProcessL must be handled here
+	if( aError )
+		{
+		// call fatal error on hw device
+		iProcEngineObserver->FatalErrorFromProcessEngine( aError );
+		return;
+		}
+
+	if ( iState == EStart )
+		{
+		IssueRequest();
+		}
+
+	if ( iInPlaceProc )
+		{
+		switch ( aState )
+			{
+			case MBaseCodec::EInputConsumed :
+			case MBaseCodec::EConsumed :
+				/*Callback should be the last statement*/
+				iIsProcessing = EFalse;
+				lTempBuf		=	iCurInputBuf;
+				iCurInputBuf	=	NULL;
+
+				delete iCurCmd;
+				iCurCmd = NULL;
+
+				iProcEngineObserver->InputBufferConsumed( lTempBuf, iError );
+				return;
+
+			case MBaseCodec::EOutputConsumed :
+			case MBaseCodec::ENotConsumed :
+			default:
+				return;
+			}
+		}
+	else
+		{
+		switch ( aState )
+			{
+			case MBaseCodec::EInputConsumed :
+				/*CallBack should be the last statement*/
+				iIsProcessing	=	EFalse;
+				lTempBuf		=	iCurInputBuf;
+				iCurInputBuf	=	NULL;
+
+				delete iCurCmd;
+				iCurCmd = NULL;
+
+				iProcEngineObserver->InputBufferConsumed( lTempBuf, iError );
+				return;
+
+			case MBaseCodec::EConsumed :
+				/*CallBack should be the last statement*/
+				lTempBuf		=	iCurInputBuf;
+				iCurInputBuf	=	NULL;
+
+				delete iCurCmd;
+				iCurCmd = NULL;
+
+
+				iProcEngineObserver->InputBufferConsumed( lTempBuf, iError );
+				lTempBuf		=	iCurOutputBuf;
+				iCurOutputBuf	=	NULL;
+				iProcEngineObserver->OutputBufferReady( lTempBuf, iError );
+
+				return;
+
+			case MBaseCodec::EOutputConsumed :
+				/*CallBack should be the last statement*/
+				iIsProcessing	=	EFalse;
+				lTempBuf		=	iCurOutputBuf;
+				iCurOutputBuf	=	NULL;
+				iProcEngineObserver->OutputBufferReady ( lTempBuf, iError );
+				return;
+			case MBaseCodec::ENotConsumed :
+			default:
+				return;
+			}
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Called by MBaseCodec when processing of commmands is complete
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::ProcessingCommandComplete( TInt aCommand,
+		TAny* aCmdData, TInt aError )
+	{
+	PRINT_ENTRY;
+	iIsProcessing = EFalse;
+	delete iCurCmd;
+	iCurCmd = NULL;
+	IssueRequest();
+	iProcEngineObserver->CommandProcessed( aCommand, aCmdData, aError );
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Gets the number of input buffers
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::NumInputBuffers ()
+	{
+	PRINT_ENTRY;
+	TInt lCnt = iInputArray.Count();
+	if ( iCurInputBuf )
+		{
+		lCnt	=	lCnt + 1;
+		}
+	PRINT_EXIT;
+	return lCnt;
+	}
+
+//---------------------------------------------------------------------------
+// Gets the number of output buffers
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::NumOutputBuffers ()
+	{
+	PRINT_ENTRY;
+	TInt lCnt = iOutputArray.Count();
+	if ( iCurOutputBuf )
+		{
+		lCnt	=	lCnt + 1;
+		}
+	PRINT_EXIT;
+	return lCnt;
+	}
+
+//---------------------------------------------------------------------------
+// Runl() of CBaseProcessEngine. Scheduled whenever a new command needs to
+// be processed
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::RunL ()
+	{
+	PRINT_ENTRY;
+	/*If in stopped state, or it is already processing, don't do anything*/
+	if ( iState == EStop || iIsProcessing )
+		{
+		return;
+		}
+
+	ProcessNextCommand();
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Processeses the next command in the queue
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::ProcessNextCommand()
+	{
+	PRINT_ENTRY;
+	if( iCurCmd  || !iCmdArray.IsEmpty() )
+		{
+		if( !iCurCmd )
+			{
+			iCurCmd = iCmdArray.First();
+			iCurCmd->iPriorityLink.Deque();
+			}
+
+		if( iCurCmd->iCmdType == CCmdPckg::EDoProcess )
+			{
+			if( IsReadyForProcessing() )
+				{
+				iIsProcessing = ETrue;
+
+				TInt result = KErrNone;
+
+				TRAPD( lError, result = iCodec->DoProcessL( iCurInputBuf,
+						iCurOutputBuf ) );
+
+				// based on the result call
+				ProcessingComplete( iCurInputBuf, iCurOutputBuf,
+						( MBaseCodec::TCodecState )result, lError );
+
+				iIsProcessing = EFalse;
+
+				IssueRequest ();
+				}
+			}
+		else
+			{
+			iIsProcessing = ETrue;
+
+			TInt lError = iCodec->SetParam( iCurCmd->iCmd,
+					iCurCmd->iCmdData );
+
+			ProcessingCommandComplete( iCurCmd->iCmd, iCurCmd->iCmdData,
+					lError );
+
+			iIsProcessing = EFalse;
+			}
+		}
+	PRINT_EXIT;
+	}
+
+
+//---------------------------------------------------------------------------
+// Indicates if process engine is ready for processing a new buffer i.e
+// if process engine has both input and output buffers in its respective
+// queues
+//----------------------------------------------------------------------------
+//
+TBool CBaseProcessEngine::IsReadyForProcessing()
+	{
+	PRINT_ENTRY;
+	if( !iCurInputBuf )
+		{
+		if( iInputArray.Count() )
+			{
+			iCurInputBuf = iInputArray[0];
+			iInputArray.Remove( 0 );
+			if ( iInPlaceProc )
+				{
+				return ETrue;
+				}
+			}
+		else
+			{
+			return EFalse;
+			}
+		}
+	if ( !iCurOutputBuf )
+		{
+		if ( iOutputArray.Count() )
+			{
+			iCurOutputBuf = iOutputArray[0];
+			iOutputArray.Remove( 0 );
+			return ETrue;
+			}
+		return EFalse;
+		}
+	PRINT_EXIT;
+	return ETrue;
+	}
+//---------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::DoCancel ()
+	{
+	PRINT_ENTRY;
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Issue a new request for processing a command i.e schedule Runl()
+//----------------------------------------------------------------------------
+//
+void CBaseProcessEngine::IssueRequest ()
+	{
+	PRINT_ENTRY;
+	if ( IsActive() )
+		{
+		return;
+		}
+
+	TRequestStatus*  uStatus = &iStatus;
+	User::RequestComplete( uStatus, KErrNone );
+	SetActive();
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Indicates whether processing of an input buffer is going on or else
+//----------------------------------------------------------------------------
+//
+TBool CBaseProcessEngine::IsProcessing ()
+	{
+	PRINT_ENTRY;
+	PRINT_EXIT;
+	return iIsProcessing;
+	}
+
+//---------------------------------------------------------------------------
+// This func is called if RunL leaves
+//----------------------------------------------------------------------------
+//
+TInt CBaseProcessEngine::RunError( TInt aError )
+	{
+	PRINT_ENTRY;
+	iProcEngineObserver->FatalErrorFromProcessEngine( aError );
+	PRINT_EXIT;
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------
+// Constructor for CCmdPckg
+//----------------------------------------------------------------------------
+//
+CCmdPckg::CCmdPckg ( TCmdType aCmdType, TInt aPriority, TInt aCmd,
+		TAny* aCmdData )
+	{
+	PRINT_ENTRY;
+	iCmdType = aCmdType;
+	iCmd = aCmd;
+	iCmdData = aCmdData;
+	iPriorityLink.iPriority = aPriority;
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// Destructor for CCmdPckg
+//----------------------------------------------------------------------------
+//
+CCmdPckg::~CCmdPckg ()
+	{
+	PRINT_ENTRY;
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// returns an Input picture back to the client
+//----------------------------------------------------------------------------
+//
+
+void CBaseProcessEngine::ReturnInput()
+	{
+	PRINT_ENTRY;
+	TAny* lTempBuf = 0;
+	if ( iCurInputBuf )
+		{
+		lTempBuf = iCurInputBuf;
+		delete iCurCmd;
+		iCurCmd = NULL;
+		}
+	else
+		{
+		if( iInputArray.Count() )
+			{
+			lTempBuf = iInputArray[0];
+			iInputArray.Remove( 0 );
+			iCurCmd = iCmdArray.First();
+			iCurCmd->iPriorityLink.Deque();
+			delete iCurCmd;
+			iCurCmd = NULL;
+			}
+		}
+	// return input buffer back to the HwDevice and from there to the client
+	if( iProcEngineObserver && lTempBuf )
+		{
+		iProcEngineObserver->InputBufferConsumed( lTempBuf, KErrCancel );
+		}
+	PRINT_EXIT;
+	}
+
+//---------------------------------------------------------------------------
+// returns an output buffer back to the client
+//----------------------------------------------------------------------------
+//
+TAny* CBaseProcessEngine::FetchOutputBuffer()
+	{
+	PRINT_ENTRY;
+	TAny* lTempOutput=NULL;
+	lTempOutput=iCurOutputBuf;
+
+	if ( !iOutputArray.Count() )
+		{
+		iCurOutputBuf =  NULL;
+		return lTempOutput;
+		}
+	TAny* uBuffer = iOutputArray[0];
+	iOutputArray.Remove( 0 );
+
+	iCurOutputBuf = uBuffer;
+	PRINT_EXIT;
+	return lTempOutput;
+
+	}