diff -r c1e808730d6c -r eedf2dcd43c6 omxil/xmltestharness/xmlclient/src/baseprofilehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxil/xmltestharness/xmlclient/src/baseprofilehandler.cpp Fri May 07 16:25:23 2010 +0100 @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* +* Description: +* +*/ + + +#include "baseprofilehandler.h" + +_LIT(KErrDialogInvalidPortIndex, "Base Profile support command called on port not configured for base profile comms, component: %S, port: %d"); +_LIT(KErrDialogBufferNumber, "Test script specified %d buffers, less than the port's minimum of %d, component: %S, port: %d"); +_LIT(KErrDialogFillBufferInvalidBufIndex, "Test script specified invalid buffer index on a FillThisBuffer call, component: %S, port: %d, buffer index passed: %d"); +_LIT(KErrDialogEmptyBufferInvalidBufIndex, "Test script specified invalid buffer index on a EmptyThisBuffer call, component: %S, port: %d, buffer index passed: %d"); + + +CBaseProfileHandler::CBaseProfileHandler(ROmxScriptTest& aTestOwner, RASBreakEventHandler& aParentEventHandler) +: iErrorCallbacks(aTestOwner), iEventHandlerCallbacks(aParentEventHandler) + { + iOmxCallbacks.EmptyBufferDone = EmptyBufferDone; + iOmxCallbacks.EventHandler = EventHandler; + iOmxCallbacks.FillBufferDone = FillBufferDone; + iMutex.CreateLocal(); + } + +CBaseProfileHandler::~CBaseProfileHandler() + { + iMutex.Close(); + delete iXmlName; + iBufferHeaders.ResetAndDestroy(); + iPortsUsingBaseProfile.Close(); + } + +void CBaseProfileHandler::AddPortSupportL(TInt aPortIndex) + { + TPortInfo portInfo; + portInfo.iPortIndex = aPortIndex; + portInfo.iAutoMode = EFalse; + portInfo.iWeAreBufferSupplier = ETrue; + iPortsUsingBaseProfile.AppendL(portInfo); + } + +void CBaseProfileHandler::SetBufferSupplier(TInt aPortIndex, TBool aComponentBufferSupplier) + { + TInt portIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + if (portIndex == KErrNotFound) + { + TBuf<140> errorString; + errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex); + iErrorCallbacks.FailTest(errorString); + return; + } + iPortsUsingBaseProfile[portIndex].iWeAreBufferSupplier = !aComponentBufferSupplier; + } + +void CBaseProfileHandler::SetAutoMode(TInt aPortIndex, TBool aAutoMode) + { + TInt portIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + if (portIndex == KErrNotFound) + { + TBuf<140> errorString; + errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex); + iErrorCallbacks.FailTest(errorString); + return; + } + iPortsUsingBaseProfile[portIndex].iAutoMode = aAutoMode; + } + +TInt CBaseProfileHandler::LocateBufferForPort(TInt aPortIndex, TInt aBufferIndexInPort) + { + //Implementation based on the fact that: + //-All the buffers for a port are allocated and appended to iBufferHeaders + //in a single contiguous block. + //-So once the first relevant buffer is found this index marks the zero index + //for the set of indexed buffers relevant to that port. + + TInt result = -1; + TInt bufferCount = iBufferHeaders.Count(); + for (TInt bufferIndex = 0; bufferIndex < bufferCount; bufferIndex++) + { + if (iBufferHeaders[bufferIndex]->iPortIndex != aPortIndex) + { + continue; + } + + //Safety check that the script hasn't made a manual Fill/Empty call on + //an invalid buffer index + if (iBufferHeaders[bufferIndex]->iPortIndex == iBufferHeaders[(bufferIndex + aBufferIndexInPort)]->iPortIndex) + { + result = bufferIndex + aBufferIndexInPort; + } + break; + } + return result; + } + +void CBaseProfileHandler::FillThisBuffer(TInt aPortIndex, TInt aBufferIndexInPort) + { + TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort); + if (bufHeaderIndex >= 0) + { + iBufferHeaders[bufHeaderIndex]->iBufferAvailable = EFalse; + iOmxComponent->FillThisBuffer(iOmxComponent, iBufferHeaders[bufHeaderIndex]->iBufferHeader); + } + else + { + TBuf<140> errorString; + errorString.Format(KErrDialogFillBufferInvalidBufIndex, iXmlName, aPortIndex, aBufferIndexInPort); + iErrorCallbacks.FailTest(errorString); + } + } + +void CBaseProfileHandler::EmptyThisBuffer(TInt aPortIndex, TInt aBufferIndexInPort) + { + TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort); + if (bufHeaderIndex >= 0) + { + iBufferHeaders[bufHeaderIndex]->iBufferAvailable = EFalse; + iOmxComponent->EmptyThisBuffer(iOmxComponent, iBufferHeaders[bufHeaderIndex]->iBufferHeader); + } + else + { + TBuf<140> errorString; + errorString.Format(KErrDialogEmptyBufferInvalidBufIndex, iXmlName, aPortIndex, aBufferIndexInPort); + iErrorCallbacks.FailTest(errorString); + } + } + +void CBaseProfileHandler::WaitForBufferCompletion(TInt aPortIndex, TInt aBufferIndexInPort) + { + TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort); + iMutex.Wait(); + if (iBufferHeaders[bufHeaderIndex]->iBufferAvailable) + { + //Buffer has already completed either while waiting on another buffer or as a result of test command processing delay, no need to wait + iMutex.Signal(); + } + else + { + iWaitingOnBuffer = iBufferHeaders[bufHeaderIndex]->iBufferHeader; + iMutex.Signal(); + iErrorCallbacks.BeginWait(); + } + + } + +OMX_ERRORTYPE CBaseProfileHandler::EventHandler(OMX_HANDLETYPE /*hComponent*/, OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData) + { + reinterpret_cast(pAppData)->HandleEventReceived(eEvent, nData1, nData2, pEventData); + return OMX_ErrorNone; + } + +OMX_ERRORTYPE CBaseProfileHandler::FillBufferDone(OMX_IN OMX_HANDLETYPE /*hComponent*/, OMX_IN OMX_PTR pAppData, OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) + { + reinterpret_cast(pAppData)->HandleFillBufferDone(pBuffer); + return OMX_ErrorNone; + } + +OMX_ERRORTYPE CBaseProfileHandler::EmptyBufferDone(OMX_IN OMX_HANDLETYPE /*hComponent*/, OMX_IN OMX_PTR pAppData, OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) + { + reinterpret_cast(pAppData)->HandleEmptyBufferDone(pBuffer); + return OMX_ErrorNone; + } + +void CBaseProfileHandler::HandleEventReceived(OMX_EVENTTYPE aeEvent, OMX_U32 anData1, OMX_U32 anData2, OMX_PTR apEventData) + { + DoEventReceived(aeEvent, anData1, anData2, apEventData); + iEventHandlerCallbacks.EventHandler(iOmxComponent, &iEventHandlerCallbacks, aeEvent, anData1, anData2, apEventData); + } + +void CBaseProfileHandler::HandleFillBufferDone(OMX_IN OMX_BUFFERHEADERTYPE* aFilledBuffer) + { + iMutex.Wait(); + DoFillBufferDone(aFilledBuffer); + TInt bufferIndex = iBufferHeaders.Find(*aFilledBuffer, CBaseProfileHandler::BufferHeaderMatchComparison); + iBufferHeaders[bufferIndex]->iBufferAvailable = ETrue; + TInt portIndex = iPortsUsingBaseProfile.Find((*iBufferHeaders[bufferIndex]).iPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + + if (iPortsUsingBaseProfile[portIndex].iAutoMode) + { + iBufferHeaders[bufferIndex]->iBufferAvailable = EFalse; + iOmxComponent->FillThisBuffer(iOmxComponent, aFilledBuffer); + } + + if (iWaitingOnBuffer == iBufferHeaders[bufferIndex]->iBufferHeader) + { + iWaitingOnBuffer = NULL; + iErrorCallbacks.EndWait(); + } + + iMutex.Signal(); + } + +void CBaseProfileHandler::HandleEmptyBufferDone(OMX_IN OMX_BUFFERHEADERTYPE* aEmptiedBuffer) + { + iMutex.Wait(); + DoEmptyBufferDone(aEmptiedBuffer); + TInt bufferIndex = iBufferHeaders.Find(*aEmptiedBuffer, CBaseProfileHandler::BufferHeaderMatchComparison); + iBufferHeaders[bufferIndex]->iBufferAvailable = ETrue; + TInt portIndex = iPortsUsingBaseProfile.Find((*iBufferHeaders[bufferIndex]).iPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + + if (iPortsUsingBaseProfile[portIndex].iAutoMode) + { + iBufferHeaders[bufferIndex]->iBufferAvailable = EFalse; + iOmxComponent->EmptyThisBuffer(iOmxComponent, aEmptiedBuffer); + } + + if (iWaitingOnBuffer == iBufferHeaders[bufferIndex]->iBufferHeader) + { + iWaitingOnBuffer = NULL; + iErrorCallbacks.EndWait(); + } + + iMutex.Signal(); + } + +OMX_COMPONENTTYPE* CBaseProfileHandler::LoadComponentL(const TDesC8& aTestSpecificName, const TDesC8& aOmxName) + { + + iXmlName = HBufC::NewL(aTestSpecificName.Length()); + iXmlName->Des().Copy(aTestSpecificName); + // allow room for the '\0' used in call to OMX_GetHandle + HBufC8* omxNameToLoad = HBufC8::NewL(aOmxName.Length() + 1); + *omxNameToLoad = aOmxName; + + OMX_ERRORTYPE error = OMX_GetHandle((TAny**) &iOmxComponent, (OMX_STRING) omxNameToLoad->Des().PtrZ(), this, &iOmxCallbacks); + delete omxNameToLoad; + if (error != OMX_ErrorNone) + { + iErrorCallbacks.FailWithOmxError(_L("OMX_GetHandle()"), error); + } + + return iOmxComponent; + } + +void CBaseProfileHandler::FreeAllocatedBuffersL() + { + for (TInt i = 0; i < iBufferHeaders.Count(); ++i) + { + delete iBufferHeaders[i]; + } + iBufferHeaders.Reset(); + } + +void CBaseProfileHandler::SetupBuffersL(TInt aPortIndex, TInt aNumberBuffers) + { + TInt portInfoIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + if (portInfoIndex == KErrNotFound) + { + TBuf<140> errorString; + errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex); + iErrorCallbacks.FailTest(errorString); + return; + } + + OMX_PARAM_PORTDEFINITIONTYPE portDef; + portDef.nSize = sizeof(portDef); + portDef.nVersion = KOmxVersion; + portDef.nPortIndex = aPortIndex; + OMX_ERRORTYPE error = iOmxComponent->GetParameter(iOmxComponent, OMX_IndexParamPortDefinition, &portDef); + if(error != OMX_ErrorNone) + { + iErrorCallbacks.FailWithOmxError(_L("GetParameter"), error); + return; + } + + if (aNumberBuffers < portDef.nBufferCountMin) + { + TBuf<140> errorString; + errorString.Format(KErrDialogBufferNumber, aNumberBuffers, portDef.nBufferCountMin, iXmlName, aPortIndex); + iErrorCallbacks.FailTest(errorString); + return; + } + + TInt bufSize = portDef.nBufferSize; + + for (TInt bufIndex=0; bufIndex < aNumberBuffers; bufIndex++) + { + CBufferHeaderInfo* headerInfo = new (ELeave) CBufferHeaderInfo(*this); + iBufferHeaders.AppendL(headerInfo); + headerInfo->iPortIndex = aPortIndex; + + if (iPortsUsingBaseProfile[portInfoIndex].iWeAreBufferSupplier) + { + OMX_U8* buffer = new (ELeave) OMX_U8[bufSize]; + iOmxComponent->UseBuffer(iOmxComponent, &(headerInfo->iBufferHeader), aPortIndex, NULL, bufSize, buffer); + } + else + { + iOmxComponent->AllocateBuffer(iOmxComponent, &(headerInfo->iBufferHeader), aPortIndex, NULL, bufSize); + } + } + } + +void CBaseProfileHandler::DoEventReceived(OMX_EVENTTYPE /*aeEvent*/, OMX_U32 /*anData1*/, OMX_U32 /*anData2*/, OMX_PTR /*apEventData*/) + { + //Uninterested + } + +void CBaseProfileHandler::DoFillBufferDone(OMX_BUFFERHEADERTYPE* /*aFilledBuffer*/) + { + //Uninterested + } + +void CBaseProfileHandler::DoEmptyBufferDone(OMX_BUFFERHEADERTYPE* /*aEmptiedBuffer*/) + { + //Uninterested + } + +CBaseProfileHandler::CBufferHeaderInfo::CBufferHeaderInfo(CBaseProfileHandler& aParent) +: iBufferAvailable(ETrue), iParent(aParent) + { + } + +CBaseProfileHandler::CBufferHeaderInfo::~CBufferHeaderInfo() + { + OMX_U8* buffer = iBufferHeader->pBuffer; + OMX_ERRORTYPE error = iParent.iOmxComponent->FreeBuffer(iParent.iOmxComponent, iPortIndex, iBufferHeader); + if (error != OMX_ErrorNone) + { + iParent.iErrorCallbacks.FailWithOmxError(_L("OMX_FreeBuffer()"), error); + return; + } + + TInt portInfoIndex = iParent.iPortsUsingBaseProfile.Find(iPortIndex, CBaseProfileHandler::PortIndexMatchComparison); + if (iParent.iPortsUsingBaseProfile[portInfoIndex].iWeAreBufferSupplier) + { + delete[] buffer; + } + } + +TBool CBaseProfileHandler::PortIndexMatchComparison(const TInt* aPortIndex, const TPortInfo& aPortInfo) + { + if (*aPortIndex == aPortInfo.iPortIndex) + { + return ETrue; + } + return EFalse; + } + +TBool CBaseProfileHandler::BufferHeaderMatchComparison(const OMX_BUFFERHEADERTYPE* aBufferHeader, const CBufferHeaderInfo& aBufferHeaderInfo) + { + if (aBufferHeader == aBufferHeaderInfo.iBufferHeader) + { + return ETrue; + } + return EFalse; + } +