tsrc/xmltestharness/xmlclient/src/nontunneledhandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 25 Aug 2010 12:40:50 +0300
changeset 0 0e4a32b9112d
permissions -rw-r--r--
Revision: 201033

/*
* Copyright (c) 2008 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 "nontunneledhandler.h"

CNonTunneledHandler::CNonTunneledHandler()
	{
	}

CNonTunneledHandler::~CNonTunneledHandler()
	{
	}

void CNonTunneledHandler::AddLinkL(OMX_COMPONENTTYPE* aSourceComp,
                                   TInt aSourcePort,
                                   OMX_COMPONENTTYPE* aSinkComp,
                                   TInt aSinkPort,
                                   OMX_BUFFERSUPPLIERTYPE aSupplier,
                                   TInt aNumBufs, TInt aBufSize)
	{
	CComponentInfo* compInfo = NULL;
	TInt pos = iComponents.Find(*aSourceComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		compInfo = iComponents[pos];
		}
	else
		{
		compInfo = new (ELeave) CComponentInfo(aSourceComp);
		CleanupStack::PushL(compInfo);
		iComponents.AppendL(compInfo);
		CleanupStack::Pop(compInfo);
		}

	CPortInfo* sourcePortInfo = compInfo->AddPortL(aSourcePort, ETrue, aNumBufs, aBufSize, aSupplier);

	pos = iComponents.Find(*aSinkComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		compInfo = iComponents[pos];
		}
	else
		{
		compInfo = new (ELeave) CComponentInfo(aSinkComp);
		CleanupStack::PushL(compInfo);
		iComponents.AppendL(compInfo);
		CleanupStack::Pop(compInfo);
		}

	CPortInfo* sinkPortInfo = compInfo->AddPortL(aSinkPort, EFalse, aNumBufs, aBufSize, aSupplier);

	sourcePortInfo->SetPeer(sinkPortInfo);
	sinkPortInfo->SetPeer(sourcePortInfo);
	}

void CNonTunneledHandler::AllocateBuffersL(OMX_COMPONENTTYPE* aComp)
	{
	TInt pos = iComponents.Find(*aComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		iComponents[pos]->AllocateBuffersL();
		}
	}

void CNonTunneledHandler::FillBuffers(OMX_COMPONENTTYPE* aComp)
	{
	TInt pos = iComponents.Find(*aComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		iComponents[pos]->FillBuffers();
		}	
	}

void CNonTunneledHandler::BufferDone(OMX_COMPONENTTYPE* aComp, OMX_BUFFERHEADERTYPE* aBufHdr, TBool aSource)
	{
	TInt pos = iComponents.Find(*aComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		iComponents[pos]->BufferDone(aBufHdr, aSource);
		}
	}

void CNonTunneledHandler::HoldBuffers(OMX_COMPONENTTYPE* aComp)
	{
	TInt pos = iComponents.Find(*aComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		iComponents[pos]->HoldBuffers();
		}	
	}

void CNonTunneledHandler::FreeBuffers(OMX_COMPONENTTYPE* aComp)
	{
	TInt pos = iComponents.Find(*aComp, CComponentInfo::CompareComp);
	if (pos >= 0)
		{
		iComponents[pos]->FreeBuffers();
		}	
	}

CNonTunneledHandler::CComponentInfo::CComponentInfo(OMX_COMPONENTTYPE* aComp) :
 iComp(aComp)
	{
	}

CNonTunneledHandler::CComponentInfo::~CComponentInfo()
	{
	iPorts.ResetAndDestroy();
	}

CNonTunneledHandler::CPortInfo* CNonTunneledHandler::CComponentInfo::AddPortL(TInt aPortNum, TBool aSource, TInt aNumBufs, TInt aBufSize, OMX_BUFFERSUPPLIERTYPE aSupplier)
	{
	__ASSERT_ALWAYS(iPorts.Find(aPortNum, CPortInfo::ComparePortNum) == KErrNotFound, User::Invariant());

	CPortInfo* portInfo = new (ELeave) CPortInfo(iComp, aPortNum, aSource, aNumBufs, aBufSize, aSupplier);
	CleanupStack::PushL(portInfo);
	iPorts.AppendL(portInfo);
	CleanupStack::Pop(portInfo);

	return portInfo;
	}

void CNonTunneledHandler::CComponentInfo::AllocateBuffersL()
	{
	TInt numPorts = iPorts.Count();
	
	for (TInt port = 0; port < numPorts; ++port)
		{
		iPorts[port]->AllocateBuffersL();
		}
	}

void CNonTunneledHandler::CComponentInfo::FillBuffers()
	{
	TInt numPorts = iPorts.Count();
	
	for (TInt port = 0; port < numPorts; ++port)
		{
		iPorts[port]->FillBuffers();
		}
	}

void CNonTunneledHandler::CComponentInfo::BufferDone(OMX_BUFFERHEADERTYPE* aBufHdr, TBool aSource)
	{
	TInt pos = KErrNotFound;

	if (aSource)
		{
		pos = iPorts.Find(static_cast<TInt>(aBufHdr->nOutputPortIndex), CPortInfo::ComparePortNum);
		}
	else
		{
		pos = iPorts.Find(static_cast<TInt>(aBufHdr->nInputPortIndex), CPortInfo::ComparePortNum);
		}

	__ASSERT_ALWAYS(pos != KErrNotFound, User::Invariant());

	iPorts[pos]->BufferDone(aBufHdr);
	}

void CNonTunneledHandler::CComponentInfo::HoldBuffers()
	{
	for (TInt port = 0; port < iPorts.Count(); ++port)
		{
		iPorts[port]->HoldBuffers();
		}
	}

void CNonTunneledHandler::CComponentInfo::FreeBuffers()
	{
	for (TInt port = 0; port < iPorts.Count(); ++port)
		{
		iPorts[port]->FreeBuffers();
		}
	}

TBool CNonTunneledHandler::CComponentInfo::CompareComp(const OMX_COMPONENTTYPE* aComp, const CComponentInfo& aComponentInfo)
	{
	return (aComp == aComponentInfo.iComp);
	}

CNonTunneledHandler::CPortInfo::CPortInfo(OMX_COMPONENTTYPE* aComp, TInt aPortNum, TBool aSource, TInt aNumBufs, TInt aBufSize, OMX_BUFFERSUPPLIERTYPE aSupplier) :
 iComp(aComp),
 iPortNum(aPortNum),
 iSource(aSource),
 iNumBufs(aNumBufs),
 iBufSize(aBufSize),
 iSupplier(aSupplier),
 iEosSignalledtoInput(FALSE)
	{
	}

CNonTunneledHandler::CPortInfo::~CPortInfo()
	{
	DeleteAllBuffers();
	}

void CNonTunneledHandler::CPortInfo::SetPeer(CPortInfo* aPeer)
	{
	iPeer = aPeer;
	}

void CNonTunneledHandler::CPortInfo::AllocateBuffersL()
	{
	OMX_BUFFERHEADERTYPE* bufHdr = NULL;

	if (iSource)
		{
		if (iSupplier == OMX_BufferSupplyUnspecified)
			{
			OMX_U8* newBuffer = NULL;

			for (TInt buf = 0; buf < iNumBufs; ++buf)
				{
				newBuffer = new (ELeave) OMX_U8[iBufSize];
				CleanupStack::PushL(newBuffer);
				iBuffers.AppendL(newBuffer);
				CleanupStack::Pop(newBuffer);
				iComp->UseBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize, newBuffer);
				iBufferHeaders.AppendL(bufHdr);
				SendAllocatedBufferToPeerL(newBuffer);
				}
			}
		else if (iSupplier == OMX_BufferSupplyOutput)
			{
			for (TInt buf = 0; buf < iNumBufs; ++buf)
				{			
				iComp->AllocateBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize);
				iBufferHeaders.AppendL(bufHdr);
				SendAllocatedBufferToPeerL(bufHdr->pBuffer);
				}
			}
		else
			{
			TInt bufCount = iBuffers.Count();

			for (TInt buf = 0; buf < bufCount; ++buf)
				{
				iComp->UseBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize, iBuffers[buf]);
				iBufferHeaders.AppendL(bufHdr);
				}

			if (bufCount < iNumBufs)
				{
				iWaitingForBuffers = ETrue;
				}
			}
		}
	else
		{
		if (iSupplier == OMX_BufferSupplyInput)
			{
			for (TInt buf = 0; buf < iNumBufs; ++buf)
				{
				iComp->AllocateBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize);
				iBufferHeaders.AppendL(bufHdr);
				SendAllocatedBufferToPeerL(bufHdr->pBuffer);
				}
			}
		else
			{
			TInt bufCount = iBuffers.Count();

			for (TInt buf = 0; buf < bufCount; ++buf)
				{
				iComp->UseBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize, iBuffers[buf]);
				iBufferHeaders.AppendL(bufHdr);
				}

			if (bufCount < iNumBufs)
				{
				iWaitingForBuffers = ETrue;
				}
			}
		}
	}

void CNonTunneledHandler::CPortInfo::SendAllocatedBufferToPeerL(OMX_U8* aBuffer)
	{
	__ASSERT_ALWAYS(iPeer, User::Invariant());

	iPeer->ReceiveAllocatedBufferFromPeerL(aBuffer);
	}

void CNonTunneledHandler::CPortInfo::ReceiveAllocatedBufferFromPeerL(OMX_U8* aBuffer)
	{
	if (iWaitingForBuffers)
		{
		OMX_BUFFERHEADERTYPE* bufHdr = NULL;

		iComp->UseBuffer(iComp, &bufHdr, iPortNum, NULL, iBufSize, aBuffer);
		iBufferHeaders.AppendL(bufHdr);
		
		if (iBufferHeaders.Count() == iNumBufs)
			{
			iWaitingForBuffers = EFalse;
			}
		}
	else
		{
		iBuffers.AppendL(aBuffer);
		}
	}

void CNonTunneledHandler::CPortInfo::FillBuffers()
	{
	iHoldingBuffers = EFalse;
	if (iSource)
		{
		for (TInt buf = 0; buf < iNumBufs; ++buf)
			{
			iComp->FillThisBuffer(iComp, iBufferHeaders[buf]);
			}
		}
	}

void CNonTunneledHandler::CPortInfo::BufferDone(OMX_BUFFERHEADERTYPE* aBufHdr)
	{
	for (TInt buf = 0; buf < iNumBufs; ++buf)
		{
		if (iBufferHeaders[buf] == aBufHdr)
			{
			iPeer->ReceiveBufferFromPeer(buf, aBufHdr);
			}
		}
	}

void CNonTunneledHandler::CPortInfo::SendBufferToPeer(TInt aBufHdrOffset, OMX_BUFFERHEADERTYPE* aPeerBufHdr)
	{
	__ASSERT_ALWAYS(iPeer, User::Invariant());

	iPeer->ReceiveBufferFromPeer(aBufHdrOffset, aPeerBufHdr);
	}

void CNonTunneledHandler::CPortInfo::ReceiveBufferFromPeer(TInt aBufHdrOffset, OMX_BUFFERHEADERTYPE* aPeerBufHdr)
	{
	__ASSERT_ALWAYS(aBufHdrOffset < iNumBufs, User::Invariant());

	if (!iHoldingBuffers)
		{
		iBufferHeaders[aBufHdrOffset]->nOffset = aPeerBufHdr->nOffset;
		iBufferHeaders[aBufHdrOffset]->nFilledLen = aPeerBufHdr->nFilledLen;

		if (iSource)
			{
			iComp->FillThisBuffer(iComp, iBufferHeaders[aBufHdrOffset]);
			}
		else
			{
			iBufferHeaders[aBufHdrOffset]->hMarkTargetComponent = aPeerBufHdr->hMarkTargetComponent;
			iBufferHeaders[aBufHdrOffset]->pMarkData = aPeerBufHdr->pMarkData;
			iBufferHeaders[aBufHdrOffset]->nTimeStamp = aPeerBufHdr->nTimeStamp;
			iBufferHeaders[aBufHdrOffset]->nFlags = aPeerBufHdr->nFlags;

			if(aPeerBufHdr->nFlags & OMX_BUFFERFLAG_EOS)
                {
                // TODO Logic for EOS
                if(iEosSignalledtoInput == FALSE)
                    {
                    iComp->EmptyThisBuffer(iComp, iBufferHeaders[aBufHdrOffset]);
                    iEosSignalledtoInput = TRUE;
                    }
                return;
                }
			iComp->EmptyThisBuffer(iComp, iBufferHeaders[aBufHdrOffset]);
			}
		}
	}

void CNonTunneledHandler::CPortInfo::HoldBuffers()
	{
	iHoldingBuffers = ETrue;
	}

void CNonTunneledHandler::CPortInfo::FreeBuffers()
	{
	for (TInt buf = 0; buf < iNumBufs; ++buf)
		{
		iComp->FreeBuffer(iComp, iPortNum, iBufferHeaders[buf]);
		}

	DeleteAllBuffers();
	}

void CNonTunneledHandler::CPortInfo::DeleteAllBuffers()
	{
	iBufferHeaders.Reset();

	if (iSource && iSupplier == OMX_BufferSupplyUnspecified)
		{
		iBuffers.ResetAndDestroy();
		}
	else
		{
		iBuffers.Reset();
		}
	}

TBool CNonTunneledHandler::CPortInfo::ComparePortNum(const TInt* aPortNum, const CPortInfo& aPortInfo)
	{
	return (*aPortNum == aPortInfo.iPortNum);
	}