1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmdevicefw/mdf/src/openmax/omxcomponentbody.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,839 @@
1.4 +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32base.h>
1.20 +#include <e32msgqueue.h>
1.21 +#include <mmf/server/mmfdatabuffer.h>
1.22 +#include "omxcomponentbody.h"
1.23 +#include "omxcomponentimpl.h"
1.24 +
1.25 +const TInt KMaxMsgQueueEntries = 10;
1.26 +const TInt KMaxComponentNameLength = 256;
1.27 +
1.28 +const TInt KSymbianErrors[] =
1.29 + {
1.30 + KErrNoMemory, /*OMX_ErrorInsufficientResources*/
1.31 + KErrUnknown,
1.32 + KErrBadName,
1.33 + KErrNotFound,
1.34 + KErrGeneral, /*OMX_ErrorInvalidComponent*/
1.35 + KErrArgument, /*OMX_ErrorBadParameter*/
1.36 + KErrNotSupported, /*OMX_ErrorNotImplemented*/
1.37 + KErrUnderflow, /*OMX_ErrorUnderflow*/
1.38 + KErrOverflow, /*OMX_ErrorOverflow*/
1.39 + KErrHardwareNotAvailable, /* OMX_ErrorHardware*/
1.40 + KErrGeneral, /*OMX_ErrorInvalidState*/
1.41 + KErrCorrupt, /*OMX_ErrorStreamCorrupt*/
1.42 + KErrArgument, /*OMX_ErrorPortsNotCompatible*/
1.43 + KErrHardwareNotAvailable, /*OMX_ErrorResourcesLost*/
1.44 + KErrCompletion, /*OMX_ErrorNoMore*/
1.45 + KErrGeneral, /*OMX_ErrorVersionMismatch*/
1.46 + KErrNotReady, /*OMX_ErrorNotReady*/
1.47 + KErrTimedOut, /*OMX_ErrorTimeout*/
1.48 + KErrNone /*OMX_ErrorSameState*/
1.49 + };
1.50 +
1.51 +/**
1.52 + Converts an OpenMAX error code to a Symbian error code.
1.53 + @param aErrorType The OpenMAX error code.
1.54 + @return The Symbian error code.
1.55 + */
1.56 +TInt ConvertOmxErrorType(OMX_ERRORTYPE aErrorType)
1.57 + {
1.58 + if (aErrorType == OMX_ErrorNone)
1.59 + {
1.60 + return KErrNone;
1.61 + }
1.62 + else if (aErrorType >= OMX_ErrorInsufficientResources &&
1.63 + aErrorType <= OMX_ErrorSameState)
1.64 + {
1.65 + return KSymbianErrors[aErrorType - OMX_ErrorInsufficientResources];
1.66 + }
1.67 + else
1.68 + {
1.69 + return KErrGeneral;
1.70 + }
1.71 + }
1.72 +
1.73 +/**
1.74 + Converts a Symbian error code to an OpenMAX error code.
1.75 + @param aError The Symbian error code.
1.76 + @return The OpenMAX error code.
1.77 + */
1.78 +OMX_ERRORTYPE ConvertSymbianErrorType(TInt aError)
1.79 + {
1.80 + OMX_ERRORTYPE err = OMX_ErrorNone;
1.81 + switch (aError)
1.82 + {
1.83 + case KErrNone:
1.84 + err = OMX_ErrorNone;
1.85 + break;
1.86 + case KErrNoMemory:
1.87 + err = OMX_ErrorInsufficientResources;
1.88 + break;
1.89 + case KErrGeneral:
1.90 + break;
1.91 + default:
1.92 + err = OMX_ErrorUndefined;
1.93 + }
1.94 + return err;
1.95 + }
1.96 +
1.97 +
1.98 +COmxBufferManager::COmxBufferManager(OMX_COMPONENTTYPE* aHandle)
1.99 + : iHandle(aHandle)
1.100 + {
1.101 + }
1.102 +
1.103 +COmxBufferManager::COmxBuffer::COmxBuffer()
1.104 + {
1.105 + }
1.106 +
1.107 +
1.108 +COmxBufferManager::COmxBuffer* COmxBufferManager::COmxBuffer::NewL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
1.109 + {
1.110 + COmxBuffer* self = new (ELeave) COmxBuffer;
1.111 + CleanupStack::PushL(self);
1.112 + self->ConstructL(aBufferHeader, aBuffer);
1.113 + CleanupStack::Pop(self);
1.114 + return self;
1.115 + }
1.116 +
1.117 +COmxBufferManager::COmxBuffer::~COmxBuffer()
1.118 + {
1.119 + if (iOwnsMmfBuffer)
1.120 + {
1.121 + delete iMmfBuffer;
1.122 + }
1.123 + }
1.124 +
1.125 +
1.126 +CMMFBuffer* COmxBufferManager::COmxBuffer::MmfBuffer() const
1.127 + {
1.128 + return iMmfBuffer;
1.129 + }
1.130 +
1.131 +OMX_BUFFERHEADERTYPE* COmxBufferManager::COmxBuffer::BufferHeader() const
1.132 + {
1.133 + return iBufferHeader;
1.134 + }
1.135 +
1.136 +
1.137 +MOmxInputPortCallbacks* COmxBufferManager::COmxBuffer::InputPortCallbacks() const
1.138 + {
1.139 + return iInputPortCallbacks;
1.140 + }
1.141 +
1.142 +MOmxOutputPortCallbacks* COmxBufferManager::COmxBuffer::OutputPortCallbacks() const
1.143 + {
1.144 + return iOutputPortCallbacks;
1.145 + }
1.146 +
1.147 +void COmxBufferManager::COmxBuffer::SetInputPortCallbacks(MOmxInputPortCallbacks* aCallbacks)
1.148 + {
1.149 + iInputPortCallbacks = aCallbacks;
1.150 + }
1.151 +
1.152 +void COmxBufferManager::COmxBuffer::SetOutputPortCallbacks(MOmxOutputPortCallbacks* aCallbacks)
1.153 + {
1.154 + iOutputPortCallbacks = aCallbacks;
1.155 + }
1.156 +
1.157 +// look up the corresponding buffer
1.158 +COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(const CMMFBuffer* aBuffer) const
1.159 + {
1.160 + COmxBuffer* buffer = NULL;
1.161 + for (TInt i=0;i<iBuffers.Count() && !buffer;i++)
1.162 + {
1.163 + if (iBuffers[i]->MmfBuffer() == aBuffer)
1.164 + {
1.165 + buffer = iBuffers[i];
1.166 + }
1.167 + }
1.168 + return buffer;
1.169 + }
1.170 +
1.171 +COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(OMX_BUFFERHEADERTYPE* aBuffer) const
1.172 + {
1.173 + return reinterpret_cast<COmxBuffer*>(aBuffer->pAppPrivate);
1.174 + }
1.175 +
1.176 +
1.177 +
1.178 + TInt COmxBufferManager::UseBuffer(CMMFBuffer& aBuffer, TUint aPortIndex)
1.179 + {
1.180 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer.Type()))
1.181 + {
1.182 + OMX_BUFFERHEADERTYPE* buffer;
1.183 + CMMFDataBuffer& dataBuffer = static_cast<CMMFDataBuffer&>(aBuffer);
1.184 +
1.185 + TDes8& aBufferDes = dataBuffer.Data();
1.186 + OMX_ERRORTYPE error = iHandle->UseBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, (void*)&aBuffer, aBufferDes.MaxLength(), const_cast<TUint8*>(aBufferDes.Ptr()));
1.187 + if (error != OMX_ErrorNone)
1.188 + {
1.189 + return ConvertOmxErrorType(error);
1.190 + }
1.191 + TRAPD(err, StoreBufferL(buffer, &aBuffer));
1.192 + return err;
1.193 + }
1.194 + else
1.195 + {
1.196 + return KErrNotSupported;
1.197 + }
1.198 + }
1.199 +
1.200 +
1.201 + CMMFBuffer* COmxBufferManager::AllocateBufferL(TUint aPortIndex, TUint aSizeBytes)
1.202 + {
1.203 + OMX_BUFFERHEADERTYPE* buffer;
1.204 + OMX_ERRORTYPE error = iHandle->AllocateBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, NULL, aSizeBytes);
1.205 + User::LeaveIfError(ConvertOmxErrorType(error));
1.206 +
1.207 + StoreBufferL(buffer,NULL); // transfers ownership
1.208 +
1.209 + // return the newly created buffer
1.210 + return FindBuffer(buffer)->MmfBuffer();
1.211 + }
1.212 +
1.213 +
1.214 + TInt COmxBufferManager::FreeBuffer(CMMFBuffer* aBuffer)
1.215 + {
1.216 + COmxBuffer* buffer;
1.217 + for (TInt i=0;i<iBuffers.Count();i++)
1.218 + {
1.219 + buffer = iBuffers[i];
1.220 + if (buffer->MmfBuffer() == aBuffer)
1.221 + {
1.222 + iBuffers.Remove(i);
1.223 + OMX_ERRORTYPE err = iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, buffer->BufferHeader());
1.224 + delete buffer;
1.225 + return err;
1.226 + }
1.227 + }
1.228 + return KErrNotFound;
1.229 + }
1.230 +
1.231 +void COmxBufferManager::COmxBuffer::ConstructL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
1.232 + {
1.233 +
1.234 + // Now if CMMFBuffer is NULL, this is been called from allocate buffer, and we need to
1.235 + // Allocate a ptr buffer to correspond to the buffer created by OMX
1.236 + ASSERT(aBufferHeader);
1.237 + iBufferHeader = aBufferHeader;
1.238 + if (aBuffer == NULL)
1.239 + {
1.240 + TPtr8 ptr(iBufferHeader->pBuffer, iBufferHeader->nFilledLen, iBufferHeader->nAllocLen);
1.241 + CMMFBuffer* mmfBuffer = CMMFPtrBuffer::NewL(ptr);
1.242 + iMmfBuffer = mmfBuffer;
1.243 + iOwnsMmfBuffer = ETrue;
1.244 + }
1.245 + else
1.246 + {
1.247 + iMmfBuffer = aBuffer;
1.248 + }
1.249 +
1.250 + // store pointer to element in array
1.251 + iBufferHeader->pAppPrivate = this;
1.252 + }
1.253 +
1.254 +
1.255 +
1.256 +// Store OMX buffer pointer
1.257 +void COmxBufferManager::StoreBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, CMMFBuffer* aBuffer)
1.258 + {
1.259 + COmxBuffer* buf = COmxBuffer::NewL(aBufferHeader, aBuffer);
1.260 + CleanupStack::PushL(buf);
1.261 + iBuffers.AppendL(buf);
1.262 + CleanupStack::Pop(buf);
1.263 + }
1.264 +
1.265 +
1.266 + TInt COmxBufferManager::EmptyThisBuffer(const CMMFBuffer* aBuffer, MOmxInputPortCallbacks* aObserver)
1.267 + {
1.268 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.269 + {
1.270 + COmxBuffer* omxBuffer = FindBuffer(aBuffer);
1.271 + if (!omxBuffer)
1.272 + {
1.273 + return KErrNotFound;
1.274 + }
1.275 +
1.276 + omxBuffer->SetInputPortCallbacks(aObserver);
1.277 + OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
1.278 + const CMMFDataBuffer* buf = static_cast<const CMMFDataBuffer*>(aBuffer);
1.279 + const TDesC8& des = buf->Data();
1.280 + bufferHeader->nFilledLen = des.Length();
1.281 + bufferHeader->nFlags = 0;
1.282 + if (aBuffer->LastBuffer())
1.283 + {
1.284 + bufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
1.285 + }
1.286 + else
1.287 + {
1.288 + bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
1.289 + }
1.290 + return ConvertOmxErrorType(iHandle->EmptyThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
1.291 + }
1.292 + else
1.293 + {
1.294 + return KErrNotSupported;
1.295 + }
1.296 + }
1.297 +
1.298 +
1.299 + TInt COmxBufferManager::FillThisBuffer(CMMFBuffer* aBuffer, MOmxOutputPortCallbacks* aObserver)
1.300 + {
1.301 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.302 + {
1.303 + COmxBuffer* omxBuffer = FindBuffer(aBuffer);
1.304 + if (!omxBuffer)
1.305 + {
1.306 + return KErrNotFound;
1.307 + }
1.308 + omxBuffer->SetOutputPortCallbacks(aObserver);
1.309 + OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
1.310 +
1.311 + bufferHeader->nFilledLen = 0;
1.312 + // clear last buffer flag
1.313 + bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
1.314 + return ConvertOmxErrorType(iHandle->FillThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
1.315 + }
1.316 + else
1.317 + {
1.318 + return KErrNotSupported;
1.319 + }
1.320 + }
1.321 +
1.322 +
1.323 +
1.324 +COmxBufferManager::~COmxBufferManager()
1.325 + {
1.326 + for (TInt i=0;i<iBuffers.Count();i++)
1.327 + {
1.328 + COmxBuffer* omxBuffer = iBuffers[i];
1.329 + iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, omxBuffer->BufferHeader());
1.330 + delete omxBuffer;
1.331 + }
1.332 + iBuffers.Close();
1.333 + }
1.334 +
1.335 +// Implementation of the Class COmxComponent
1.336 +
1.337 +
1.338 +
1.339 +COmxCallbacks* COmxCallbacks::NewL(MOmxPuCallbacks& aPuCallbacks)
1.340 + {
1.341 + COmxCallbacks* self = new (ELeave) COmxCallbacks(aPuCallbacks);
1.342 + CleanupStack::PushL(self);
1.343 + self->ConstructL();
1.344 + CleanupStack::Pop(self);
1.345 + return self;
1.346 + }
1.347 +
1.348 +
1.349 +void COmxCallbacks::ConstructL()
1.350 + {
1.351 + OMX_CALLBACKTYPE h =
1.352 + {
1.353 + &::EventHandler,
1.354 + &::EmptyBufferDone,
1.355 + &::FillBufferDone
1.356 + };
1.357 +
1.358 + iHandle = h;
1.359 + CActiveScheduler::Add(this);
1.360 +
1.361 + User::LeaveIfError(iMsgQueue.CreateLocal(KMaxMsgQueueEntries));
1.362 + iMsgQueue.NotifyDataAvailable(iStatus);
1.363 + SetActive();
1.364 + }
1.365 +
1.366 +COmxCallbacks::COmxCallbacks(MOmxPuCallbacks& aPuCallbacks)
1.367 + : CActive(EPriorityNormal),
1.368 + iPuCallbacks(&aPuCallbacks)
1.369 + {
1.370 + }
1.371 +
1.372 +
1.373 +COmxCallbacks::operator OMX_CALLBACKTYPE*()
1.374 + {
1.375 + return &iHandle;
1.376 + }
1.377 +
1.378 +
1.379 +void COmxCallbacks::RunL()
1.380 + {
1.381 + TOmxMessage msg;
1.382 + while (iMsgQueue.Receive(msg)==KErrNone)
1.383 + {
1.384 + switch (msg.iType)
1.385 + {
1.386 + case EEmptyBufferCallback:
1.387 + {
1.388 + MOmxInputPortCallbacks* callback = msg.iBuffer->InputPortCallbacks();
1.389 + const CMMFBuffer* buffer = msg.iBuffer->MmfBuffer();
1.390 + callback->EmptyBufferDone(msg.iComponent, buffer);
1.391 + break;
1.392 + }
1.393 +
1.394 + case EFillBufferCallback:
1.395 + {
1.396 + CMMFBuffer* mmfBuffer = msg.iBuffer->MmfBuffer();
1.397 + OMX_BUFFERHEADERTYPE* bufferHeader = msg.iBuffer->BufferHeader();
1.398 +
1.399 + if (CMMFBuffer::IsSupportedDataBuffer(mmfBuffer->Type()))
1.400 + {
1.401 + CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(mmfBuffer);
1.402 + TDes8& aBufferDes = dataBuffer->Data();
1.403 + aBufferDes.SetLength(bufferHeader->nFilledLen);
1.404 + mmfBuffer->SetLastBuffer(bufferHeader->nFlags & OMX_BUFFERFLAG_EOS);
1.405 + }
1.406 + else
1.407 + {
1.408 + ASSERT(EFalse);
1.409 + }
1.410 + MOmxOutputPortCallbacks* callback = msg.iBuffer->OutputPortCallbacks();
1.411 + callback->FillBufferDone(msg.iComponent, mmfBuffer);
1.412 + break;
1.413 + }
1.414 + case EEventCallback:
1.415 + {
1.416 + iPuCallbacks->MopcEventHandler(msg.iComponent,
1.417 + msg.iEventParams.iEvent,
1.418 + msg.iEventParams.iData1,
1.419 + msg.iEventParams.iData2,
1.420 + msg.iEventParams.iExtra);
1.421 + break;
1.422 + }
1.423 + default:
1.424 + {
1.425 + // This is an invalid state
1.426 + ASSERT(EFalse);
1.427 + }
1.428 + };
1.429 + }
1.430 +
1.431 + // setup for next callbacks
1.432 + iStatus = KRequestPending;
1.433 + iMsgQueue.NotifyDataAvailable(iStatus);
1.434 + SetActive();
1.435 + }
1.436 +
1.437 +COmxCallbacks::~COmxCallbacks()
1.438 + {
1.439 + Cancel();
1.440 + iMsgQueue.Close();
1.441 + }
1.442 +
1.443 +
1.444 +void COmxCallbacks::DoCancel()
1.445 + {
1.446 + if (iMsgQueue.Handle()!=NULL)
1.447 + {
1.448 + iMsgQueue.CancelDataAvailable();
1.449 + }
1.450 + }
1.451 +
1.452 +TInt COmxCallbacks::FillBufferDone(OMX_HANDLETYPE aComponent, COmxBufferManager::COmxBuffer* aBuffer)
1.453 + {
1.454 + TOmxMessage message;
1.455 + message.iType = EFillBufferCallback;
1.456 + message.iComponent = aComponent;
1.457 + message.iBuffer = aBuffer;
1.458 + return iMsgQueue.Send(message);
1.459 + }
1.460 +
1.461 +TInt COmxCallbacks::EmptyBufferDone(OMX_HANDLETYPE aComponent, COmxBufferManager::COmxBuffer* aBuffer)
1.462 + {
1.463 + TOmxMessage message;
1.464 + message.iType = EEmptyBufferCallback;
1.465 + message.iComponent = aComponent;
1.466 + message.iBuffer = aBuffer;
1.467 + return iMsgQueue.Send(message);
1.468 + }
1.469 +
1.470 +TInt COmxCallbacks::EventHandler(OMX_HANDLETYPE aComponent, TEventParams aEventParams)
1.471 + {
1.472 + TOmxMessage message;
1.473 + message.iType = EEventCallback;
1.474 + message.iComponent = aComponent;
1.475 + message.iEventParams = aEventParams;
1.476 + return iMsgQueue.Send(message);
1.477 + }
1.478 +
1.479 +
1.480 + COmxProcessingUnit::CBody::CBody()
1.481 + {
1.482 + iPuState = EProcessingUnitInvalid;
1.483 + }
1.484 +
1.485 +
1.486 +COmxProcessingUnit::CBody::~CBody()
1.487 + {
1.488 + delete iBufferManager;
1.489 + delete iCallbacks;
1.490 +
1.491 + iInputPorts.Close();
1.492 + iOutputPorts.Close();
1.493 +
1.494 + ::OMX_FreeHandle((OMX_HANDLETYPE)iHandle);
1.495 + }
1.496 +
1.497 +COmxProcessingUnit::CBody* COmxProcessingUnit::CBody::NewL(const TDesC8& aComponentName,
1.498 + MOmxPuCallbacks& aPuCallbacks,
1.499 + COmxProcessingUnit* aParent,
1.500 + const MMdfProcessingUnitObserver& aObserver)
1.501 + {
1.502 + CBody* self = new (ELeave) CBody;
1.503 + CleanupStack::PushL(self);
1.504 + self->ConstructL(aComponentName, aPuCallbacks, aParent, aObserver);
1.505 + CleanupStack::Pop(self);
1.506 + return self;
1.507 + }
1.508 +
1.509 +
1.510 +void COmxProcessingUnit::CBody::ConstructL(const TDesC8& aComponentName,
1.511 + MOmxPuCallbacks& aPuCallbacks,
1.512 + COmxProcessingUnit* aParent,
1.513 + const MMdfProcessingUnitObserver& aObserver)
1.514 + {
1.515 + iCallbacks = COmxCallbacks::NewL(aPuCallbacks);
1.516 +
1.517 + iParent = aParent;
1.518 + iObserver = const_cast<MMdfProcessingUnitObserver*>(&aObserver);
1.519 +
1.520 + OMX_ERRORTYPE errorType;
1.521 + OMX_CALLBACKTYPE* omxCallbacks = *iCallbacks;
1.522 + TBuf8<KMaxComponentNameLength> buf;
1.523 + buf.Copy(aComponentName);
1.524 + const char* name = reinterpret_cast<const char*>(buf.PtrZ());
1.525 + errorType = ::OMX_GetHandle((OMX_HANDLETYPE*)&iHandle, const_cast<char*>(name), iCallbacks, omxCallbacks);
1.526 +
1.527 + User::LeaveIfError(ConvertOmxErrorType(errorType));
1.528 + // Create the BufferManager class to look after the buffering
1.529 + iBufferManager = new (ELeave) COmxBufferManager(iHandle);
1.530 + SetPuState(EProcessingUnitLoaded);
1.531 + }
1.532 +
1.533 +
1.534 +
1.535 +TInt COmxProcessingUnit::CBody::GetInputPorts(RPointerArray<MMdfInputPort>& aComponentInputPorts)
1.536 + {
1.537 + TInt err = KErrNone;
1.538 + for (TInt i=0; i < iInputPorts.Count() && err == KErrNone; i++ )
1.539 + {
1.540 + err = aComponentInputPorts.Append(iInputPorts[i]);
1.541 + }
1.542 + return err;
1.543 + }
1.544 +
1.545 +
1.546 +TInt COmxProcessingUnit::CBody::GetOutputPorts(RPointerArray<MMdfOutputPort>& aComponentOutputPorts)
1.547 + {
1.548 + TInt err = KErrNone;
1.549 + for (TInt i=0; i < iOutputPorts.Count() && err == KErrNone; i++ )
1.550 + {
1.551 + err = aComponentOutputPorts.Append(iOutputPorts[i]);
1.552 + }
1.553 + return err;
1.554 + }
1.555 +
1.556 +
1.557 +void COmxProcessingUnit::CBody::Initialize()
1.558 + {
1.559 + // if the state is not Loaded, we should not accept this call
1.560 + if (State() != EProcessingUnitLoaded)
1.561 + {
1.562 + Observer()->InitializeComplete(iParent, KErrNotReady);
1.563 + }
1.564 + else
1.565 + {
1.566 + // initialize each of the ports in turn
1.567 + for (TInt i=0; i < iInputPorts.Count(); i++ )
1.568 + {
1.569 + iInputPorts[i]->MipInitialize();
1.570 + }
1.571 +
1.572 + for (TInt i=0; i < iOutputPorts.Count(); i++ )
1.573 + {
1.574 + iOutputPorts[i]->MopInitialize();
1.575 + }
1.576 +
1.577 + // instruct the OMX component to go into the Idle state
1.578 + SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);
1.579 + SetPuState(EProcessingUnitInitializing);
1.580 + }
1.581 + }
1.582 +
1.583 +void COmxProcessingUnit::CBody::Execute()
1.584 + {
1.585 +
1.586 + SendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL);
1.587 + iPuState = EProcessingUnitExecuting;
1.588 + }
1.589 +
1.590 +TProcessingUnitState COmxProcessingUnit::CBody::State()
1.591 + {
1.592 + return iPuState;
1.593 + }
1.594 +
1.595 +TInt COmxProcessingUnit::CBody::EventHandler(OMX_HANDLETYPE /*aComponent*/, OMX_EVENTTYPE aEvent, TUint32 /*aData1*/,
1.596 + TUint32 aData2, TAny* /*aExtraInfo*/)
1.597 + {
1.598 + switch (aEvent)
1.599 + {
1.600 +
1.601 + case OMX_EventCmdComplete:
1.602 + {
1.603 +
1.604 + switch (aData2)
1.605 + {
1.606 + case OMX_StateIdle:
1.607 + if (iPuState == EProcessingUnitInitializing)
1.608 + {
1.609 + Observer()->InitializeComplete(iParent, KErrNone);
1.610 + }
1.611 + else
1.612 + {
1.613 + Observer()->ExecuteComplete(iParent, KErrNone);
1.614 + }
1.615 + SetPuState(EProcessingUnitIdle);
1.616 +
1.617 + break;
1.618 + };
1.619 + break;
1.620 + }
1.621 + case OMX_EventBufferFlag:
1.622 + {
1.623 + SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);
1.624 + }
1.625 + }
1.626 + return KErrNone;
1.627 + }
1.628 +
1.629 +// Base Versions are not supported
1.630 +TInt COmxProcessingUnit::CBody::Configure(const TPuConfig& /*aConfig*/)
1.631 + {
1.632 + return KErrNotSupported;
1.633 + }
1.634 +
1.635 +
1.636 +// Base Versions are not supported
1.637 +TInt COmxProcessingUnit::CBody::GetConfig(TPuConfig& /*aConfig*/)
1.638 + {
1.639 + return KErrNotSupported;
1.640 + }
1.641 +
1.642 +
1.643 +TInt COmxProcessingUnit::CBody::Pause ()
1.644 + {
1.645 + return KErrNone;
1.646 + }
1.647 +
1.648 +void COmxProcessingUnit::CBody::Stop()
1.649 + {
1.650 + SendCommand(OMX_CommandStateSet, OMX_StateIdle, NULL);
1.651 +
1.652 + TInt err = KErrNone;
1.653 + for (TInt i=0; i < iInputPorts.Count() && err == KErrNone; i++ )
1.654 + {
1.655 + iInputPorts[i]->MipDisconnectTunnel();
1.656 + }
1.657 +
1.658 + for (TInt i=0; i < iOutputPorts.Count() && err == KErrNone; i++ )
1.659 + {
1.660 + iOutputPorts[i]->MopDisconnectTunnel();
1.661 + }
1.662 +
1.663 + SetPuState(EProcessingUnitIdle);
1.664 + }
1.665 +
1.666 +TInt COmxProcessingUnit::CBody::CreateCustomInterface(TUid /*aUid*/)
1.667 + {
1.668 + return KErrNotSupported;
1.669 + }
1.670 +
1.671 +
1.672 +TAny* COmxProcessingUnit::CBody::CustomInterface(TUid /*aUid*/)
1.673 + {
1.674 + return NULL;
1.675 + }
1.676 +
1.677 +TInt COmxProcessingUnit::CBody::AddInputPort(MMdfInputPort* aInputPort)
1.678 + {
1.679 + if (iInputPorts.Find(aInputPort)>=0)
1.680 + return KErrAlreadyExists;
1.681 + return iInputPorts.Append(aInputPort);
1.682 + }
1.683 +
1.684 +TInt COmxProcessingUnit::CBody::AddOutputPort(MMdfOutputPort* aOutputPort)
1.685 + {
1.686 + if (iOutputPorts.Find(aOutputPort)>=0)
1.687 + return KErrAlreadyExists;
1.688 + return iOutputPorts.Append(aOutputPort);
1.689 + }
1.690 +
1.691 +MMdfProcessingUnitObserver* COmxProcessingUnit::CBody::Observer()
1.692 + {
1.693 + return iObserver;
1.694 + }
1.695 +
1.696 +void COmxProcessingUnit::CBody::SetPuState(TProcessingUnitState aPuState)
1.697 + {
1.698 + iPuState = aPuState;
1.699 + }
1.700 +
1.701 +TInt COmxProcessingUnit::CBody::GetComponentVersion(const TDesC8& /*aComponentName*/, OMX_VERSIONTYPE* /*aComponentVersion*/, OMX_VERSIONTYPE* /*aSpecVersion*/, OMX_UUIDTYPE* /*aComponentUUID*/)
1.702 + {
1.703 + return KErrNotSupported;
1.704 + }
1.705 +
1.706 +TInt COmxProcessingUnit::CBody::SendCommand(OMX_COMMANDTYPE aCmd, TUint aParam, TAny* aCmdData)
1.707 + {
1.708 + OMX_ERRORTYPE error = iHandle->SendCommand(static_cast<OMX_HANDLETYPE>(iHandle), aCmd, aParam, aCmdData);
1.709 + return ConvertOmxErrorType(error);
1.710 + }
1.711 +
1.712 +
1.713 +TInt COmxProcessingUnit::CBody::GetParameter(OMX_INDEXTYPE aParamIndex, TAny* aComponentParameterStructure)
1.714 + {
1.715 + OMX_ERRORTYPE error = iHandle->GetParameter(static_cast<OMX_HANDLETYPE>(iHandle), aParamIndex, aComponentParameterStructure);
1.716 + return ConvertOmxErrorType(error);
1.717 + }
1.718 +
1.719 +
1.720 +TInt COmxProcessingUnit::CBody::SetParameter(OMX_INDEXTYPE aIndex, TAny* aComponentParameterStructure)
1.721 + {
1.722 + OMX_ERRORTYPE error = iHandle->SetParameter(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aComponentParameterStructure);
1.723 + return ConvertOmxErrorType(error);
1.724 + }
1.725 +
1.726 +TInt COmxProcessingUnit::CBody::GetConfig(OMX_INDEXTYPE aIndex, TAny* aValue)
1.727 + {
1.728 + OMX_ERRORTYPE error = iHandle->GetConfig(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aValue);
1.729 + return ConvertOmxErrorType(error);
1.730 + }
1.731 +
1.732 +TInt COmxProcessingUnit::CBody::SetConfig(OMX_INDEXTYPE aIndex, TAny* aValue)
1.733 + {
1.734 + OMX_ERRORTYPE error = iHandle->SetConfig(static_cast<OMX_HANDLETYPE>(iHandle), aIndex, aValue);
1.735 + return ConvertOmxErrorType(error);
1.736 + }
1.737 +
1.738 +TInt COmxProcessingUnit::CBody::GetExtensionIndex(const TDesC8& aParameterName, OMX_INDEXTYPE* aIndexType)
1.739 + {
1.740 + HBufC8* buf = HBufC8::New(aParameterName.Length()+1);
1.741 + if (buf == NULL)
1.742 + {
1.743 + return KErrNoMemory;
1.744 + }
1.745 + else
1.746 + {
1.747 + // Create a zero terminated version of the paramter name
1.748 + *buf = aParameterName;
1.749 + TPtr8 ptr = buf->Des();
1.750 + TUint8* cstring = const_cast<TUint8*>(ptr.PtrZ());
1.751 + OMX_ERRORTYPE error = iHandle->GetExtensionIndex(static_cast<OMX_HANDLETYPE>(iHandle), reinterpret_cast<char*>(cstring), aIndexType);
1.752 + // delete the created memory - note no leaving functions so CleanupStack not used
1.753 + delete buf;
1.754 + return ConvertOmxErrorType(error);
1.755 + }
1.756 + }
1.757 +
1.758 +
1.759 +TInt COmxProcessingUnit::CBody::GetState(OMX_STATETYPE* aState)
1.760 + {
1.761 + OMX_ERRORTYPE error = iHandle->GetState(static_cast<OMX_HANDLETYPE>(iHandle), aState);
1.762 + return ConvertOmxErrorType(error);
1.763 + }
1.764 +
1.765 +
1.766 +TInt COmxProcessingUnit::CBody::ComponentTunnelRequest(TUint aPortInput, OMX_HANDLETYPE aOutput, TUint aPortOutput, OMX_TUNNELSETUPTYPE* aTunnelSetup)
1.767 + {
1.768 + OMX_ERRORTYPE error = iHandle->ComponentTunnelRequest(static_cast<OMX_HANDLETYPE>(iHandle), aPortInput, aOutput, aPortOutput, aTunnelSetup);
1.769 + return ConvertOmxErrorType(error);
1.770 + }
1.771 +
1.772 +TInt COmxProcessingUnit::CBody::UseBuffer(CMMFBuffer* aBuffer, TUint aPortIndex)
1.773 + {
1.774 + return iBufferManager->UseBuffer(*aBuffer, aPortIndex);
1.775 + }
1.776 +
1.777 +
1.778 +CMMFBuffer* COmxProcessingUnit::CBody::AllocateBufferL(TUint aPortIndex, TUint aSizeBytes)
1.779 + {
1.780 + return iBufferManager->AllocateBufferL(aPortIndex, aSizeBytes);
1.781 + }
1.782 +
1.783 +
1.784 +TInt COmxProcessingUnit::CBody::FreeBuffer(CMMFBuffer* aBuffer)
1.785 + {
1.786 + return iBufferManager->FreeBuffer(aBuffer);
1.787 + }
1.788 +
1.789 +TInt COmxProcessingUnit::CBody::EmptyThisBuffer(const CMMFBuffer* aBuffer, MOmxInputPortCallbacks* aObserver)
1.790 + {
1.791 + return iBufferManager->EmptyThisBuffer(aBuffer, aObserver);
1.792 + }
1.793 +
1.794 +
1.795 +TInt COmxProcessingUnit::CBody::FillThisBuffer(CMMFBuffer* aBuffer, MOmxOutputPortCallbacks* aObserver)
1.796 + {
1.797 + return iBufferManager->FillThisBuffer(aBuffer, aObserver);
1.798 + }
1.799 +
1.800 +
1.801 +TInt COmxProcessingUnit::CBody::SetCallbacks(MOmxPuCallbacks& /*aPuCallbacks*/)
1.802 + {
1.803 + return KErrNotSupported;
1.804 + }
1.805 +
1.806 +// Callbacks implementation - calls back to COMxCallbacks class, which manages a queue
1.807 +OMX_ERRORTYPE EventHandler(OMX_OUT OMX_HANDLETYPE aComponent,
1.808 + OMX_OUT TAny* aAppData,
1.809 + OMX_OUT OMX_EVENTTYPE aEvent,
1.810 + OMX_OUT TUint32 aData1,
1.811 + OMX_OUT TUint32 aData2,
1.812 + OMX_OUT TAny* aExtra)
1.813 + {
1.814 + COmxCallbacks::TEventParams eventParams;
1.815 + eventParams.iEvent = aEvent;
1.816 + eventParams.iData1 = aData1;
1.817 + eventParams.iData2 = aData2;
1.818 + eventParams.iExtra = aExtra;
1.819 + TInt error = static_cast<COmxCallbacks*>(aAppData)->EventHandler(aComponent, eventParams);
1.820 + return ConvertSymbianErrorType(error);
1.821 + }
1.822 +
1.823 +OMX_ERRORTYPE EmptyBufferDone(
1.824 + OMX_HANDLETYPE aComponent,
1.825 + TAny* aAppData,
1.826 + OMX_BUFFERHEADERTYPE* aBuffer)
1.827 + {
1.828 + COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
1.829 + TInt error = static_cast<COmxCallbacks*>(aAppData)->EmptyBufferDone(aComponent, buffer);
1.830 + return ConvertSymbianErrorType(error);
1.831 + }
1.832 +
1.833 +OMX_ERRORTYPE FillBufferDone(
1.834 + OMX_HANDLETYPE aComponent,
1.835 + TAny* aAppData,
1.836 + OMX_BUFFERHEADERTYPE* aBuffer)
1.837 + {
1.838 + COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
1.839 + TInt error = static_cast<COmxCallbacks*>(aAppData)->FillBufferDone(aComponent, buffer);
1.840 + return ConvertSymbianErrorType(error);
1.841 + }
1.842 +