14b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber/*
24b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Copyright (C) 2011 The Android Open Source Project
34b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
44b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
54b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * you may not use this file except in compliance with the License.
64b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * You may obtain a copy of the License at
74b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
84b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
94b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Unless required by applicable law or agreed to in writing, software
114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * See the License for the specific language governing permissions and
144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * limitations under the License.
154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber */
164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber//#define LOG_NDEBUG 0
184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#define LOG_TAG "SimpleSoftOMXComponent"
194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <utils/Log.h>
204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include "include/SimpleSoftOMXComponent.h"
224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <media/stagefright/foundation/ADebug.h>
244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <media/stagefright/foundation/ALooper.h>
254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <media/stagefright/foundation/AMessage.h>
264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubernamespace android {
284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
294b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberSimpleSoftOMXComponent::SimpleSoftOMXComponent(
304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        const char *name,
314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        const OMX_CALLBACKTYPE *callbacks,
324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_PTR appData,
334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_COMPONENTTYPE **component)
344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    : SoftOMXComponent(name, callbacks, appData, component),
354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mLooper(new ALooper),
364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)),
374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mState(OMX_StateLoaded),
384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mTargetState(OMX_StateLoaded) {
394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mLooper->setName(name);
404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mLooper->registerHandler(mHandler);
414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mLooper->start(
434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            false, // runOnCallingThread
444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            false, // canCallJava
45115cac8131e9b2a599ac5f10f9e973487c8fd25cAndreas Huber            ANDROID_PRIORITY_FOREGROUND);
464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4854802de06cfd336c9232a5647b3310fef33d4d81Andreas Hubervoid SimpleSoftOMXComponent::prepareForDestruction() {
4954802de06cfd336c9232a5647b3310fef33d4d81Andreas Huber    // The looper's queue may still contain messages referencing this
5054802de06cfd336c9232a5647b3310fef33d4d81Andreas Huber    // object. Make sure those are flushed before returning so that
5154802de06cfd336c9232a5647b3310fef33d4d81Andreas Huber    // a subsequent dlunload() does not pull out the rug from under us.
5254802de06cfd336c9232a5647b3310fef33d4d81Andreas Huber
534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mLooper->unregisterHandler(mHandler->id());
544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mLooper->stop();
554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
574b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::sendCommand(
584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(data == NULL);
604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler->id());
624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->setInt32("cmd", cmd);
634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->setInt32("param", param);
644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->post();
654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huberbool SimpleSoftOMXComponent::isSetParameterAllowed(
704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) const {
714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (mState == OMX_StateLoaded) {
724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return true;
734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    OMX_U32 portIndex;
764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (index) {
784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamPortDefinition:
794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            portIndex = ((OMX_PARAM_PORTDEFINITIONTYPE *)params)->nPortIndex;
814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamAudioPcm:
854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            portIndex = ((OMX_AUDIO_PARAM_PCMMODETYPE *)params)->nPortIndex;
874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamAudioAac:
914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            portIndex = ((OMX_AUDIO_PARAM_AACPROFILETYPE *)params)->nPortIndex;
934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return false;
984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(portIndex < mPorts.size());
1014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return !mPorts.itemAt(portIndex).mDef.bEnabled;
1034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1054b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::getParameter(
1064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
1074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
1084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return internalGetParameter(index, params);
1094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1114b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::setParameter(
1124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
1134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
1144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(isSetParameterAllowed(index, params));
1164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return internalSetParameter(index, params);
1184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1204b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::internalGetParameter(
1214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
1224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (index) {
1234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamPortDefinition:
1244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
1254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            OMX_PARAM_PORTDEFINITIONTYPE *defParams =
1264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (OMX_PARAM_PORTDEFINITIONTYPE *)params;
1274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (defParams->nPortIndex >= mPorts.size()
1294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    || defParams->nSize
1304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                            != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
1314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
1324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            const PortInfo *port =
1354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                &mPorts.itemAt(defParams->nPortIndex);
1364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            memcpy(defParams, &port->mDef, sizeof(port->mDef));
1384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
1404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
1414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
1434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorUnsupportedIndex;
1444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
1454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1474b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::internalSetParameter(
1484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
1494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (index) {
1504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamPortDefinition:
1514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
1524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            OMX_PARAM_PORTDEFINITIONTYPE *defParams =
1534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (OMX_PARAM_PORTDEFINITIONTYPE *)params;
1544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (defParams->nPortIndex >= mPorts.size()
1564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    || defParams->nSize
1574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                            != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
1584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
1594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            PortInfo *port =
1624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                &mPorts.editItemAt(defParams->nPortIndex);
1634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (defParams->nBufferSize != port->mDef.nBufferSize) {
1654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                CHECK_GE(defParams->nBufferSize, port->mDef.nBufferSize);
1664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                port->mDef.nBufferSize = defParams->nBufferSize;
1674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (defParams->nBufferCountActual
1704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    != port->mDef.nBufferCountActual) {
1714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                CHECK_GE(defParams->nBufferCountActual,
1724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                         port->mDef.nBufferCountMin);
1734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                port->mDef.nBufferCountActual = defParams->nBufferCountActual;
1754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
1784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
1794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
1814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorUnsupportedIndex;
1824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
1834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1854b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::useBuffer(
1864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE **header,
1874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex,
1884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_PTR appPrivate,
1894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 size,
1904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U8 *ptr) {
1914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
1924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
1934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    *header = new OMX_BUFFERHEADERTYPE;
1954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
1964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nVersion.s.nVersionMajor = 1;
1974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nVersion.s.nVersionMinor = 0;
1984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nVersion.s.nRevision = 0;
1994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nVersion.s.nStep = 0;
2004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pBuffer = ptr;
2014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nAllocLen = size;
2024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nFilledLen = 0;
2034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nOffset = 0;
2044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pAppPrivate = appPrivate;
2054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pPlatformPrivate = NULL;
2064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pInputPortPrivate = NULL;
2074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pOutputPortPrivate = NULL;
2084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->hMarkTargetComponent = NULL;
2094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pMarkData = NULL;
2104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nTickCount = 0;
2114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nTimeStamp = 0;
2124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nFlags = 0;
2134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nOutputPortIndex = portIndex;
2144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->nInputPortIndex = portIndex;
2154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    PortInfo *port = &mPorts.editItemAt(portIndex);
2174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(mState == OMX_StateLoaded || port->mDef.bEnabled == OMX_FALSE);
2194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(port->mBuffers.size(), port->mDef.nBufferCountActual);
2214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    port->mBuffers.push();
2234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    BufferInfo *buffer =
2254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        &port->mBuffers.editItemAt(port->mBuffers.size() - 1);
2264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    buffer->mHeader = *header;
2284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    buffer->mOwnedByUs = false;
2294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (port->mBuffers.size() == port->mDef.nBufferCountActual) {
2314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        port->mDef.bPopulated = OMX_TRUE;
2324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        checkTransitions();
2334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
2344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
2364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
2374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2384b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::allocateBuffer(
2394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE **header,
2404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex,
2414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_PTR appPrivate,
2424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 size) {
2434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    OMX_U8 *ptr = new OMX_U8[size];
2444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    OMX_ERRORTYPE err =
2464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        useBuffer(header, portIndex, appPrivate, size, ptr);
2474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (err != OMX_ErrorNone) {
2494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        delete[] ptr;
2504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        ptr = NULL;
2514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return err;
2534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
2544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK((*header)->pPlatformPrivate == NULL);
2564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    (*header)->pPlatformPrivate = ptr;
2574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
2594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
2604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2614b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::freeBuffer(
2624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex,
2634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *header) {
2644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
2654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
2674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    PortInfo *port = &mPorts.editItemAt(portIndex);
2694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#if 0 // XXX
2714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK((mState == OMX_StateIdle && mTargetState == OMX_StateLoaded)
2724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            || port->mDef.bEnabled == OMX_FALSE);
2734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#endif
2744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    bool found = false;
2764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    for (size_t i = 0; i < port->mBuffers.size(); ++i) {
2774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        BufferInfo *buffer = &port->mBuffers.editItemAt(i);
2784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (buffer->mHeader == header) {
2804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(!buffer->mOwnedByUs);
2814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (header->pPlatformPrivate != NULL) {
2834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                // This buffer's data was allocated by us.
2844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                CHECK(header->pPlatformPrivate == header->pBuffer);
2854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                delete[] header->pBuffer;
2874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                header->pBuffer = NULL;
2884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
2894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            delete header;
2914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            header = NULL;
2924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            port->mBuffers.removeAt(i);
2944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            port->mDef.bPopulated = OMX_FALSE;
2954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            checkTransitions();
2974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            found = true;
2994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
3004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
3024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(found);
3044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
3064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
3074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3084b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::emptyThisBuffer(
3094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *buffer) {
3104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler->id());
3114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->setPointer("header", buffer);
3124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->post();
3134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
3154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
3164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3174b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::fillThisBuffer(
3184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *buffer) {
3194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler->id());
3204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->setPointer("header", buffer);
3214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    msg->post();
3224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
3244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
3254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3264b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SimpleSoftOMXComponent::getState(OMX_STATETYPE *state) {
3274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
3284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    *state = mState;
3304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OMX_ErrorNone;
3324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
3334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onMessageReceived(const sp<AMessage> &msg) {
3354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Mutex::Autolock autoLock(mLock);
3364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (msg->what()) {
3384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case kWhatSendCommand:
3394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
3404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            int32_t cmd, param;
3414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(msg->findInt32("cmd", &cmd));
3424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(msg->findInt32("param", &param));
3434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            onSendCommand((OMX_COMMANDTYPE)cmd, (OMX_U32)param);
3454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
3464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case kWhatEmptyThisBuffer:
3494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case kWhatFillThisBuffer:
3504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
3514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            OMX_BUFFERHEADERTYPE *header;
3524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(msg->findPointer("header", (void **)&header));
3534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(mState == OMX_StateExecuting && mTargetState == mState);
3554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            bool found = false;
3574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            for (size_t i = 0; i < mPorts.size(); ++i) {
3584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                PortInfo *port = &mPorts.editItemAt(i);
3594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                for (size_t j = 0; j < port->mBuffers.size(); ++j) {
3614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    BufferInfo *buffer = &port->mBuffers.editItemAt(j);
3624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    if (buffer->mHeader == header) {
3644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        CHECK(!buffer->mOwnedByUs);
3654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        buffer->mOwnedByUs = true;
3674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        CHECK((msg->what() == kWhatEmptyThisBuffer
3694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                                    && port->mDef.eDir == OMX_DirInput)
3704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                                || (port->mDef.eDir == OMX_DirOutput));
3714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        port->mQueue.push_back(buffer);
3734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        onQueueFilled(i);
3744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        found = true;
3764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        break;
3774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    }
3784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
3794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
3804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(found);
3824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
3834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
3864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            TRESPASS();
3874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
3884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
3894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
3904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onSendCommand(
3924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_COMMANDTYPE cmd, OMX_U32 param) {
3934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (cmd) {
3944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_CommandStateSet:
3954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
3964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            onChangeState((OMX_STATETYPE)param);
3974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
3984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_CommandPortEnable:
4014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_CommandPortDisable:
4024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
4034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            onPortEnable(param, cmd == OMX_CommandPortEnable);
4044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_CommandFlush:
4084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
4094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            onPortFlush(param, true /* sendFlushComplete */);
4104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
4144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            TRESPASS();
4154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) {
4204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    // We shouldn't be in a state transition already.
4214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_EQ((int)mState, (int)mTargetState);
4224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (mState) {
4244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_StateLoaded:
4254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ((int)state, (int)OMX_StateIdle);
4264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_StateIdle:
4284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
4294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_StateExecuting:
4314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
4324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ((int)state, (int)OMX_StateIdle);
4334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            for (size_t i = 0; i < mPorts.size(); ++i) {
4354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                onPortFlush(i, false /* sendFlushComplete */);
4364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
4374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mState = OMX_StateIdle;
4394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL);
4404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
4444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            TRESPASS();
4454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mTargetState = state;
4484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    checkTransitions();
4504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) {
4534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
4544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    PortInfo *port = &mPorts.editItemAt(portIndex);
4564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE);
4574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK(port->mDef.bEnabled == !enable);
4584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (!enable) {
4604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        port->mDef.bEnabled = OMX_FALSE;
4614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        port->mTransition = PortInfo::DISABLING;
4624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        for (size_t i = 0; i < port->mBuffers.size(); ++i) {
4644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            BufferInfo *buffer = &port->mBuffers.editItemAt(i);
4654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (buffer->mOwnedByUs) {
4674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                buffer->mOwnedByUs = false;
4684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (port->mDef.eDir == OMX_DirInput) {
4704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    notifyEmptyBufferDone(buffer->mHeader);
4714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                } else {
4724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
4734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    notifyFillBufferDone(buffer->mHeader);
4744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
4754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
4764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        port->mQueue.clear();
4794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    } else {
4804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        port->mTransition = PortInfo::ENABLING;
4814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    checkTransitions();
4844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onPortFlush(
4874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex, bool sendFlushComplete) {
4884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (portIndex == OMX_ALL) {
4894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        for (size_t i = 0; i < mPorts.size(); ++i) {
4904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            onPortFlush(i, sendFlushComplete);
4914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (sendFlushComplete) {
4944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notify(OMX_EventCmdComplete, OMX_CommandFlush, OMX_ALL, NULL);
4954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return;
4984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
5014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    PortInfo *port = &mPorts.editItemAt(portIndex);
5034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE);
5044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    for (size_t i = 0; i < port->mBuffers.size(); ++i) {
5064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        BufferInfo *buffer = &port->mBuffers.editItemAt(i);
5074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (!buffer->mOwnedByUs) {
5094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            continue;
5104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
5114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        buffer->mHeader->nFilledLen = 0;
5134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        buffer->mHeader->nOffset = 0;
5144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        buffer->mHeader->nFlags = 0;
5154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        buffer->mOwnedByUs = false;
5174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (port->mDef.eDir == OMX_DirInput) {
5194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notifyEmptyBufferDone(buffer->mHeader);
5204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        } else {
5214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
5224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notifyFillBufferDone(buffer->mHeader);
5244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
5254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
5264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    port->mQueue.clear();
5284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (sendFlushComplete) {
5304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        notify(OMX_EventCmdComplete, OMX_CommandFlush, portIndex, NULL);
5314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        onPortFlushCompleted(portIndex);
5334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
5344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
5354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::checkTransitions() {
5374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (mState != mTargetState) {
5384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        bool transitionComplete = true;
5394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (mState == OMX_StateLoaded) {
5414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ((int)mTargetState, (int)OMX_StateIdle);
5424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            for (size_t i = 0; i < mPorts.size(); ++i) {
5444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                const PortInfo &port = mPorts.itemAt(i);
5454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (port.mDef.bEnabled == OMX_FALSE) {
5464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    continue;
5474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
5484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (port.mDef.bPopulated == OMX_FALSE) {
5504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    transitionComplete = false;
5514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    break;
5524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
5534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
5544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        } else if (mTargetState == OMX_StateLoaded) {
5554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ((int)mState, (int)OMX_StateIdle);
5564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            for (size_t i = 0; i < mPorts.size(); ++i) {
5584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                const PortInfo &port = mPorts.itemAt(i);
5594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (port.mDef.bEnabled == OMX_FALSE) {
5604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    continue;
5614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
5624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                size_t n = port.mBuffers.size();
5644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (n > 0) {
5664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    CHECK_LE(n, port.mDef.nBufferCountActual);
5674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    if (n == port.mDef.nBufferCountActual) {
5694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_TRUE);
5704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    } else {
5714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_FALSE);
5724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    }
5734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    transitionComplete = false;
5754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    break;
5764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
5774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
5784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
5794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (transitionComplete) {
5814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mState = mTargetState;
5824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notify(OMX_EventCmdComplete, OMX_CommandStateSet, mState, NULL);
5844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
5854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
5864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    for (size_t i = 0; i < mPorts.size(); ++i) {
5884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        PortInfo *port = &mPorts.editItemAt(i);
5894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (port->mTransition == PortInfo::DISABLING) {
5914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (port->mBuffers.empty()) {
5924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                LOGV("Port %d now disabled.", i);
5934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                port->mTransition = PortInfo::NONE;
5954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                notify(OMX_EventCmdComplete, OMX_CommandPortDisable, i, NULL);
5964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
5974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                onPortEnableCompleted(i, false /* enabled */);
5984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
5994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        } else if (port->mTransition == PortInfo::ENABLING) {
6004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (port->mDef.bPopulated == OMX_TRUE) {
6014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                LOGV("Port %d now enabled.", i);
6024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                port->mTransition = PortInfo::NONE;
6044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                port->mDef.bEnabled = OMX_TRUE;
6054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                notify(OMX_EventCmdComplete, OMX_CommandPortEnable, i, NULL);
6064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                onPortEnableCompleted(i, true /* enabled */);
6084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
6094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
6104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
6114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def) {
6144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_EQ(def.nPortIndex, mPorts.size());
6154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mPorts.push();
6174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    PortInfo *info = &mPorts.editItemAt(mPorts.size() - 1);
6184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    info->mDef = def;
6194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    info->mTransition = PortInfo::NONE;
6204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onQueueFilled(OMX_U32 portIndex) {
6234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onPortFlushCompleted(OMX_U32 portIndex) {
6264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SimpleSoftOMXComponent::onPortEnableCompleted(
6294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex, bool enabled) {
6304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6324b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberList<SimpleSoftOMXComponent::BufferInfo *> &
6334b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberSimpleSoftOMXComponent::getPortQueue(OMX_U32 portIndex) {
6344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
6354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return mPorts.editItemAt(portIndex).mQueue;
6364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6384b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberSimpleSoftOMXComponent::PortInfo *SimpleSoftOMXComponent::editPortInfo(
6394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_U32 portIndex) {
6404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_LT(portIndex, mPorts.size());
6414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return &mPorts.editItemAt(portIndex);
6424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
6434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
6444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}  // namespace android
645