diff -r 000000000000 -r bb31fbe78861 utilities/ariprocessengine/src/ariprocessengine.cpp --- /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 + +//--------------------------------------------------------------------------- +// 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 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; + + }