Home | History | Annotate | Download | only in omx
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "OMXNodeInstance"
     19 #include <utils/Log.h>
     20 
     21 #include "../include/OMXNodeInstance.h"
     22 #include "OMXMaster.h"
     23 #include "GraphicBufferSource.h"
     24 
     25 #include <OMX_Component.h>
     26 
     27 #include <binder/IMemory.h>
     28 #include <gui/BufferQueue.h>
     29 #include <HardwareAPI.h>
     30 #include <media/stagefright/foundation/ADebug.h>
     31 #include <media/stagefright/MediaErrors.h>
     32 
     33 static const OMX_U32 kPortIndexInput = 0;
     34 
     35 namespace android {
     36 
     37 struct BufferMeta {
     38     BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
     39         : mMem(mem),
     40           mIsBackup(is_backup) {
     41     }
     42 
     43     BufferMeta(size_t size)
     44         : mSize(size),
     45           mIsBackup(false) {
     46     }
     47 
     48     BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
     49         : mGraphicBuffer(graphicBuffer),
     50           mIsBackup(false) {
     51     }
     52 
     53     void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
     54         if (!mIsBackup) {
     55             return;
     56         }
     57 
     58         memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
     59                header->pBuffer + header->nOffset,
     60                header->nFilledLen);
     61     }
     62 
     63     void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
     64         if (!mIsBackup) {
     65             return;
     66         }
     67 
     68         memcpy(header->pBuffer + header->nOffset,
     69                (const OMX_U8 *)mMem->pointer() + header->nOffset,
     70                header->nFilledLen);
     71     }
     72 
     73 private:
     74     sp<GraphicBuffer> mGraphicBuffer;
     75     sp<IMemory> mMem;
     76     size_t mSize;
     77     bool mIsBackup;
     78 
     79     BufferMeta(const BufferMeta &);
     80     BufferMeta &operator=(const BufferMeta &);
     81 };
     82 
     83 // static
     84 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
     85     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
     86 };
     87 
     88 OMXNodeInstance::OMXNodeInstance(
     89         OMX *owner, const sp<IOMXObserver> &observer)
     90     : mOwner(owner),
     91       mNodeID(NULL),
     92       mHandle(NULL),
     93       mObserver(observer),
     94       mDying(false) {
     95 }
     96 
     97 OMXNodeInstance::~OMXNodeInstance() {
     98     CHECK(mHandle == NULL);
     99 }
    100 
    101 void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
    102     CHECK(mHandle == NULL);
    103     mNodeID = node_id;
    104     mHandle = handle;
    105 }
    106 
    107 sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() {
    108     Mutex::Autolock autoLock(mGraphicBufferSourceLock);
    109     return mGraphicBufferSource;
    110 }
    111 
    112 void OMXNodeInstance::setGraphicBufferSource(
    113         const sp<GraphicBufferSource>& bufferSource) {
    114     Mutex::Autolock autoLock(mGraphicBufferSourceLock);
    115     mGraphicBufferSource = bufferSource;
    116 }
    117 
    118 OMX *OMXNodeInstance::owner() {
    119     return mOwner;
    120 }
    121 
    122 sp<IOMXObserver> OMXNodeInstance::observer() {
    123     return mObserver;
    124 }
    125 
    126 OMX::node_id OMXNodeInstance::nodeID() {
    127     return mNodeID;
    128 }
    129 
    130 static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
    131     switch (err) {
    132         case OMX_ErrorNone:
    133             return OK;
    134         case OMX_ErrorUnsupportedSetting:
    135             return ERROR_UNSUPPORTED;
    136         default:
    137             return UNKNOWN_ERROR;
    138     }
    139 }
    140 
    141 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
    142     static int32_t kMaxNumIterations = 10;
    143 
    144     // Transition the node from its current state all the way down
    145     // to "Loaded".
    146     // This ensures that all active buffers are properly freed even
    147     // for components that don't do this themselves on a call to
    148     // "FreeHandle".
    149 
    150     // The code below may trigger some more events to be dispatched
    151     // by the OMX component - we want to ignore them as our client
    152     // does not expect them.
    153     mDying = true;
    154 
    155     OMX_STATETYPE state;
    156     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
    157     switch (state) {
    158         case OMX_StateExecuting:
    159         {
    160             ALOGV("forcing Executing->Idle");
    161             sendCommand(OMX_CommandStateSet, OMX_StateIdle);
    162             OMX_ERRORTYPE err;
    163             int32_t iteration = 0;
    164             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    165                    && state != OMX_StateIdle
    166                    && state != OMX_StateInvalid) {
    167                 if (++iteration > kMaxNumIterations) {
    168                     ALOGE("component failed to enter Idle state, aborting.");
    169                     state = OMX_StateInvalid;
    170                     break;
    171                 }
    172 
    173                 usleep(100000);
    174             }
    175             CHECK_EQ(err, OMX_ErrorNone);
    176 
    177             if (state == OMX_StateInvalid) {
    178                 break;
    179             }
    180 
    181             // fall through
    182         }
    183 
    184         case OMX_StateIdle:
    185         {
    186             ALOGV("forcing Idle->Loaded");
    187             sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
    188 
    189             freeActiveBuffers();
    190 
    191             OMX_ERRORTYPE err;
    192             int32_t iteration = 0;
    193             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    194                    && state != OMX_StateLoaded
    195                    && state != OMX_StateInvalid) {
    196                 if (++iteration > kMaxNumIterations) {
    197                     ALOGE("component failed to enter Loaded state, aborting.");
    198                     state = OMX_StateInvalid;
    199                     break;
    200                 }
    201 
    202                 ALOGV("waiting for Loaded state...");
    203                 usleep(100000);
    204             }
    205             CHECK_EQ(err, OMX_ErrorNone);
    206 
    207             // fall through
    208         }
    209 
    210         case OMX_StateLoaded:
    211         case OMX_StateInvalid:
    212             break;
    213 
    214         default:
    215             CHECK(!"should not be here, unknown state.");
    216             break;
    217     }
    218 
    219     ALOGV("calling destroyComponentInstance");
    220     OMX_ERRORTYPE err = master->destroyComponentInstance(
    221             static_cast<OMX_COMPONENTTYPE *>(mHandle));
    222     ALOGV("destroyComponentInstance returned err %d", err);
    223 
    224     mHandle = NULL;
    225 
    226     if (err != OMX_ErrorNone) {
    227         ALOGE("FreeHandle FAILED with error 0x%08x.", err);
    228     }
    229 
    230     mOwner->invalidateNodeID(mNodeID);
    231     mNodeID = NULL;
    232 
    233     ALOGV("OMXNodeInstance going away.");
    234     delete this;
    235 
    236     return StatusFromOMXError(err);
    237 }
    238 
    239 status_t OMXNodeInstance::sendCommand(
    240         OMX_COMMANDTYPE cmd, OMX_S32 param) {
    241     Mutex::Autolock autoLock(mLock);
    242 
    243     OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
    244     return StatusFromOMXError(err);
    245 }
    246 
    247 status_t OMXNodeInstance::getParameter(
    248         OMX_INDEXTYPE index, void *params, size_t size) {
    249     Mutex::Autolock autoLock(mLock);
    250 
    251     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
    252 
    253     return StatusFromOMXError(err);
    254 }
    255 
    256 status_t OMXNodeInstance::setParameter(
    257         OMX_INDEXTYPE index, const void *params, size_t size) {
    258     Mutex::Autolock autoLock(mLock);
    259 
    260     OMX_ERRORTYPE err = OMX_SetParameter(
    261             mHandle, index, const_cast<void *>(params));
    262 
    263     return StatusFromOMXError(err);
    264 }
    265 
    266 status_t OMXNodeInstance::getConfig(
    267         OMX_INDEXTYPE index, void *params, size_t size) {
    268     Mutex::Autolock autoLock(mLock);
    269 
    270     OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
    271     return StatusFromOMXError(err);
    272 }
    273 
    274 status_t OMXNodeInstance::setConfig(
    275         OMX_INDEXTYPE index, const void *params, size_t size) {
    276     Mutex::Autolock autoLock(mLock);
    277 
    278     OMX_ERRORTYPE err = OMX_SetConfig(
    279             mHandle, index, const_cast<void *>(params));
    280 
    281     return StatusFromOMXError(err);
    282 }
    283 
    284 status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
    285     Mutex::Autolock autoLock(mLock);
    286 
    287     OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
    288 
    289     return StatusFromOMXError(err);
    290 }
    291 
    292 status_t OMXNodeInstance::enableGraphicBuffers(
    293         OMX_U32 portIndex, OMX_BOOL enable) {
    294     Mutex::Autolock autoLock(mLock);
    295     OMX_STRING name = const_cast<OMX_STRING>(
    296             "OMX.google.android.index.enableAndroidNativeBuffers");
    297 
    298     OMX_INDEXTYPE index;
    299     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    300 
    301     if (err != OMX_ErrorNone) {
    302         if (enable) {
    303             ALOGE("OMX_GetExtensionIndex %s failed", name);
    304         }
    305 
    306         return StatusFromOMXError(err);
    307     }
    308 
    309     OMX_VERSIONTYPE ver;
    310     ver.s.nVersionMajor = 1;
    311     ver.s.nVersionMinor = 0;
    312     ver.s.nRevision = 0;
    313     ver.s.nStep = 0;
    314     EnableAndroidNativeBuffersParams params = {
    315         sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
    316     };
    317 
    318     err = OMX_SetParameter(mHandle, index, &params);
    319 
    320     if (err != OMX_ErrorNone) {
    321         ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
    322                 err, err);
    323 
    324         return UNKNOWN_ERROR;
    325     }
    326 
    327     return OK;
    328 }
    329 
    330 status_t OMXNodeInstance::getGraphicBufferUsage(
    331         OMX_U32 portIndex, OMX_U32* usage) {
    332     Mutex::Autolock autoLock(mLock);
    333 
    334     OMX_INDEXTYPE index;
    335     OMX_STRING name = const_cast<OMX_STRING>(
    336             "OMX.google.android.index.getAndroidNativeBufferUsage");
    337     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    338 
    339     if (err != OMX_ErrorNone) {
    340         ALOGE("OMX_GetExtensionIndex %s failed", name);
    341 
    342         return StatusFromOMXError(err);
    343     }
    344 
    345     OMX_VERSIONTYPE ver;
    346     ver.s.nVersionMajor = 1;
    347     ver.s.nVersionMinor = 0;
    348     ver.s.nRevision = 0;
    349     ver.s.nStep = 0;
    350     GetAndroidNativeBufferUsageParams params = {
    351         sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
    352     };
    353 
    354     err = OMX_GetParameter(mHandle, index, &params);
    355 
    356     if (err != OMX_ErrorNone) {
    357         ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
    358                 err, err);
    359         return UNKNOWN_ERROR;
    360     }
    361 
    362     *usage = params.nUsage;
    363 
    364     return OK;
    365 }
    366 
    367 status_t OMXNodeInstance::storeMetaDataInBuffers(
    368         OMX_U32 portIndex,
    369         OMX_BOOL enable) {
    370     Mutex::Autolock autolock(mLock);
    371     return storeMetaDataInBuffers_l(portIndex, enable);
    372 }
    373 
    374 status_t OMXNodeInstance::storeMetaDataInBuffers_l(
    375         OMX_U32 portIndex,
    376         OMX_BOOL enable) {
    377     OMX_INDEXTYPE index;
    378     OMX_STRING name = const_cast<OMX_STRING>(
    379             "OMX.google.android.index.storeMetaDataInBuffers");
    380 
    381     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    382     if (err != OMX_ErrorNone) {
    383         ALOGE("OMX_GetExtensionIndex %s failed", name);
    384 
    385         return StatusFromOMXError(err);
    386     }
    387 
    388     StoreMetaDataInBuffersParams params;
    389     memset(&params, 0, sizeof(params));
    390     params.nSize = sizeof(params);
    391 
    392     // Version: 1.0.0.0
    393     params.nVersion.s.nVersionMajor = 1;
    394 
    395     params.nPortIndex = portIndex;
    396     params.bStoreMetaData = enable;
    397     if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
    398         ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
    399         return UNKNOWN_ERROR;
    400     }
    401     return err;
    402 }
    403 
    404 status_t OMXNodeInstance::useBuffer(
    405         OMX_U32 portIndex, const sp<IMemory> &params,
    406         OMX::buffer_id *buffer) {
    407     Mutex::Autolock autoLock(mLock);
    408 
    409     BufferMeta *buffer_meta = new BufferMeta(params);
    410 
    411     OMX_BUFFERHEADERTYPE *header;
    412 
    413     OMX_ERRORTYPE err = OMX_UseBuffer(
    414             mHandle, &header, portIndex, buffer_meta,
    415             params->size(), static_cast<OMX_U8 *>(params->pointer()));
    416 
    417     if (err != OMX_ErrorNone) {
    418         ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
    419 
    420         delete buffer_meta;
    421         buffer_meta = NULL;
    422 
    423         *buffer = 0;
    424 
    425         return UNKNOWN_ERROR;
    426     }
    427 
    428     CHECK_EQ(header->pAppPrivate, buffer_meta);
    429 
    430     *buffer = header;
    431 
    432     addActiveBuffer(portIndex, *buffer);
    433 
    434     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    435     if (bufferSource != NULL && portIndex == kPortIndexInput) {
    436         bufferSource->addCodecBuffer(header);
    437     }
    438 
    439     return OK;
    440 }
    441 
    442 status_t OMXNodeInstance::useGraphicBuffer2_l(
    443         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    444         OMX::buffer_id *buffer) {
    445 
    446     // port definition
    447     OMX_PARAM_PORTDEFINITIONTYPE def;
    448     def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    449     def.nVersion.s.nVersionMajor = 1;
    450     def.nVersion.s.nVersionMinor = 0;
    451     def.nVersion.s.nRevision = 0;
    452     def.nVersion.s.nStep = 0;
    453     def.nPortIndex = portIndex;
    454     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
    455     if (err != OMX_ErrorNone)
    456     {
    457         ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
    458         return err;
    459     }
    460 
    461     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    462 
    463     OMX_BUFFERHEADERTYPE *header = NULL;
    464     OMX_U8* bufferHandle = const_cast<OMX_U8*>(
    465             reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
    466 
    467     err = OMX_UseBuffer(
    468             mHandle,
    469             &header,
    470             portIndex,
    471             bufferMeta,
    472             def.nBufferSize,
    473             bufferHandle);
    474 
    475     if (err != OMX_ErrorNone) {
    476         ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
    477         delete bufferMeta;
    478         bufferMeta = NULL;
    479         *buffer = 0;
    480         return UNKNOWN_ERROR;
    481     }
    482 
    483     CHECK_EQ(header->pBuffer, bufferHandle);
    484     CHECK_EQ(header->pAppPrivate, bufferMeta);
    485 
    486     *buffer = header;
    487 
    488     addActiveBuffer(portIndex, *buffer);
    489 
    490     return OK;
    491 }
    492 
    493 // XXX: This function is here for backwards compatibility.  Once the OMX
    494 // implementations have been updated this can be removed and useGraphicBuffer2
    495 // can be renamed to useGraphicBuffer.
    496 status_t OMXNodeInstance::useGraphicBuffer(
    497         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    498         OMX::buffer_id *buffer) {
    499     Mutex::Autolock autoLock(mLock);
    500 
    501     // See if the newer version of the extension is present.
    502     OMX_INDEXTYPE index;
    503     if (OMX_GetExtensionIndex(
    504             mHandle,
    505             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
    506             &index) == OMX_ErrorNone) {
    507         return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
    508     }
    509 
    510     OMX_STRING name = const_cast<OMX_STRING>(
    511         "OMX.google.android.index.useAndroidNativeBuffer");
    512     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    513 
    514     if (err != OMX_ErrorNone) {
    515         ALOGE("OMX_GetExtensionIndex %s failed", name);
    516 
    517         return StatusFromOMXError(err);
    518     }
    519 
    520     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    521 
    522     OMX_BUFFERHEADERTYPE *header;
    523 
    524     OMX_VERSIONTYPE ver;
    525     ver.s.nVersionMajor = 1;
    526     ver.s.nVersionMinor = 0;
    527     ver.s.nRevision = 0;
    528     ver.s.nStep = 0;
    529     UseAndroidNativeBufferParams params = {
    530         sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
    531         &header, graphicBuffer,
    532     };
    533 
    534     err = OMX_SetParameter(mHandle, index, &params);
    535 
    536     if (err != OMX_ErrorNone) {
    537         ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
    538                 err);
    539 
    540         delete bufferMeta;
    541         bufferMeta = NULL;
    542 
    543         *buffer = 0;
    544 
    545         return UNKNOWN_ERROR;
    546     }
    547 
    548     CHECK_EQ(header->pAppPrivate, bufferMeta);
    549 
    550     *buffer = header;
    551 
    552     addActiveBuffer(portIndex, *buffer);
    553 
    554     return OK;
    555 }
    556 
    557 status_t OMXNodeInstance::createInputSurface(
    558         OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) {
    559     Mutex::Autolock autolock(mLock);
    560     status_t err;
    561 
    562     const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
    563     if (surfaceCheck != NULL) {
    564         return ALREADY_EXISTS;
    565     }
    566 
    567     // Input buffers will hold meta-data (gralloc references).
    568     err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE);
    569     if (err != OK) {
    570         return err;
    571     }
    572 
    573     // Retrieve the width and height of the graphic buffer, set when the
    574     // codec was configured.
    575     OMX_PARAM_PORTDEFINITIONTYPE def;
    576     def.nSize = sizeof(def);
    577     def.nVersion.s.nVersionMajor = 1;
    578     def.nVersion.s.nVersionMinor = 0;
    579     def.nVersion.s.nRevision = 0;
    580     def.nVersion.s.nStep = 0;
    581     def.nPortIndex = portIndex;
    582     OMX_ERRORTYPE oerr = OMX_GetParameter(
    583             mHandle, OMX_IndexParamPortDefinition, &def);
    584     CHECK(oerr == OMX_ErrorNone);
    585 
    586     if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
    587         ALOGE("createInputSurface requires AndroidOpaque color format");
    588         return INVALID_OPERATION;
    589     }
    590 
    591     GraphicBufferSource* bufferSource = new GraphicBufferSource(
    592             this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
    593             def.nBufferCountActual);
    594     if ((err = bufferSource->initCheck()) != OK) {
    595         delete bufferSource;
    596         return err;
    597     }
    598     setGraphicBufferSource(bufferSource);
    599 
    600     *bufferProducer = bufferSource->getIGraphicBufferProducer();
    601     return OK;
    602 }
    603 
    604 status_t OMXNodeInstance::signalEndOfInputStream() {
    605     // For non-Surface input, the MediaCodec should convert the call to a
    606     // pair of requests (dequeue input buffer, queue input buffer with EOS
    607     // flag set).  Seems easier than doing the equivalent from here.
    608     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    609     if (bufferSource == NULL) {
    610         ALOGW("signalEndOfInputStream can only be used with Surface input");
    611         return INVALID_OPERATION;
    612     };
    613     return bufferSource->signalEndOfInputStream();
    614 }
    615 
    616 status_t OMXNodeInstance::allocateBuffer(
    617         OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
    618         void **buffer_data) {
    619     Mutex::Autolock autoLock(mLock);
    620 
    621     BufferMeta *buffer_meta = new BufferMeta(size);
    622 
    623     OMX_BUFFERHEADERTYPE *header;
    624 
    625     OMX_ERRORTYPE err = OMX_AllocateBuffer(
    626             mHandle, &header, portIndex, buffer_meta, size);
    627 
    628     if (err != OMX_ErrorNone) {
    629         ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
    630 
    631         delete buffer_meta;
    632         buffer_meta = NULL;
    633 
    634         *buffer = 0;
    635 
    636         return UNKNOWN_ERROR;
    637     }
    638 
    639     CHECK_EQ(header->pAppPrivate, buffer_meta);
    640 
    641     *buffer = header;
    642     *buffer_data = header->pBuffer;
    643 
    644     addActiveBuffer(portIndex, *buffer);
    645 
    646     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    647     if (bufferSource != NULL && portIndex == kPortIndexInput) {
    648         bufferSource->addCodecBuffer(header);
    649     }
    650 
    651     return OK;
    652 }
    653 
    654 status_t OMXNodeInstance::allocateBufferWithBackup(
    655         OMX_U32 portIndex, const sp<IMemory> &params,
    656         OMX::buffer_id *buffer) {
    657     Mutex::Autolock autoLock(mLock);
    658 
    659     BufferMeta *buffer_meta = new BufferMeta(params, true);
    660 
    661     OMX_BUFFERHEADERTYPE *header;
    662 
    663     OMX_ERRORTYPE err = OMX_AllocateBuffer(
    664             mHandle, &header, portIndex, buffer_meta, params->size());
    665 
    666     if (err != OMX_ErrorNone) {
    667         ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
    668 
    669         delete buffer_meta;
    670         buffer_meta = NULL;
    671 
    672         *buffer = 0;
    673 
    674         return UNKNOWN_ERROR;
    675     }
    676 
    677     CHECK_EQ(header->pAppPrivate, buffer_meta);
    678 
    679     *buffer = header;
    680 
    681     addActiveBuffer(portIndex, *buffer);
    682 
    683     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    684     if (bufferSource != NULL && portIndex == kPortIndexInput) {
    685         bufferSource->addCodecBuffer(header);
    686     }
    687 
    688     return OK;
    689 }
    690 
    691 status_t OMXNodeInstance::freeBuffer(
    692         OMX_U32 portIndex, OMX::buffer_id buffer) {
    693     Mutex::Autolock autoLock(mLock);
    694 
    695     removeActiveBuffer(portIndex, buffer);
    696 
    697     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    698     BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
    699 
    700     OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
    701 
    702     delete buffer_meta;
    703     buffer_meta = NULL;
    704 
    705     return StatusFromOMXError(err);
    706 }
    707 
    708 status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
    709     Mutex::Autolock autoLock(mLock);
    710 
    711     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    712     header->nFilledLen = 0;
    713     header->nOffset = 0;
    714     header->nFlags = 0;
    715 
    716     OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
    717 
    718     return StatusFromOMXError(err);
    719 }
    720 
    721 status_t OMXNodeInstance::emptyBuffer(
    722         OMX::buffer_id buffer,
    723         OMX_U32 rangeOffset, OMX_U32 rangeLength,
    724         OMX_U32 flags, OMX_TICKS timestamp) {
    725     Mutex::Autolock autoLock(mLock);
    726 
    727     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    728     header->nFilledLen = rangeLength;
    729     header->nOffset = rangeOffset;
    730     header->nFlags = flags;
    731     header->nTimeStamp = timestamp;
    732 
    733     BufferMeta *buffer_meta =
    734         static_cast<BufferMeta *>(header->pAppPrivate);
    735     buffer_meta->CopyToOMX(header);
    736 
    737     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
    738 
    739     return StatusFromOMXError(err);
    740 }
    741 
    742 // like emptyBuffer, but the data is already in header->pBuffer
    743 status_t OMXNodeInstance::emptyDirectBuffer(
    744         OMX_BUFFERHEADERTYPE *header,
    745         OMX_U32 rangeOffset, OMX_U32 rangeLength,
    746         OMX_U32 flags, OMX_TICKS timestamp) {
    747     Mutex::Autolock autoLock(mLock);
    748 
    749     header->nFilledLen = rangeLength;
    750     header->nOffset = rangeOffset;
    751     header->nFlags = flags;
    752     header->nTimeStamp = timestamp;
    753 
    754     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
    755     if (err != OMX_ErrorNone) {
    756         ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err);
    757     }
    758 
    759     return StatusFromOMXError(err);
    760 }
    761 
    762 status_t OMXNodeInstance::getExtensionIndex(
    763         const char *parameterName, OMX_INDEXTYPE *index) {
    764     Mutex::Autolock autoLock(mLock);
    765 
    766     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
    767             mHandle, const_cast<char *>(parameterName), index);
    768 
    769     return StatusFromOMXError(err);
    770 }
    771 
    772 void OMXNodeInstance::onMessage(const omx_message &msg) {
    773     if (msg.type == omx_message::FILL_BUFFER_DONE) {
    774         OMX_BUFFERHEADERTYPE *buffer =
    775             static_cast<OMX_BUFFERHEADERTYPE *>(
    776                     msg.u.extended_buffer_data.buffer);
    777 
    778         BufferMeta *buffer_meta =
    779             static_cast<BufferMeta *>(buffer->pAppPrivate);
    780 
    781         buffer_meta->CopyFromOMX(buffer);
    782     } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
    783         const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
    784 
    785         if (bufferSource != NULL) {
    786             // This is one of the buffers used exclusively by
    787             // GraphicBufferSource.
    788             // Don't dispatch a message back to ACodec, since it doesn't
    789             // know that anyone asked to have the buffer emptied and will
    790             // be very confused.
    791 
    792             OMX_BUFFERHEADERTYPE *buffer =
    793                 static_cast<OMX_BUFFERHEADERTYPE *>(
    794                         msg.u.buffer_data.buffer);
    795 
    796             bufferSource->codecBufferEmptied(buffer);
    797             return;
    798         }
    799     }
    800 
    801     mObserver->onMessage(msg);
    802 }
    803 
    804 void OMXNodeInstance::onObserverDied(OMXMaster *master) {
    805     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
    806 
    807     // Try to force shutdown of the node and hope for the best.
    808     freeNode(master);
    809 }
    810 
    811 void OMXNodeInstance::onGetHandleFailed() {
    812     delete this;
    813 }
    814 
    815 // OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
    816 // Don't try to acquire mLock here -- in rare circumstances this will hang.
    817 void OMXNodeInstance::onEvent(
    818         OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
    819     const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
    820 
    821     if (bufferSource != NULL && event == OMX_EventCmdComplete &&
    822             arg1 == OMX_CommandStateSet) {
    823         if (arg2 == OMX_StateExecuting) {
    824             bufferSource->omxExecuting();
    825         } else if (arg2 == OMX_StateLoaded) {
    826             // Must be shutting down -- won't have a GraphicBufferSource
    827             // on the way up.
    828             bufferSource->omxLoaded();
    829             setGraphicBufferSource(NULL);
    830         }
    831     }
    832 }
    833 
    834 // static
    835 OMX_ERRORTYPE OMXNodeInstance::OnEvent(
    836         OMX_IN OMX_HANDLETYPE hComponent,
    837         OMX_IN OMX_PTR pAppData,
    838         OMX_IN OMX_EVENTTYPE eEvent,
    839         OMX_IN OMX_U32 nData1,
    840         OMX_IN OMX_U32 nData2,
    841         OMX_IN OMX_PTR pEventData) {
    842     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    843     if (instance->mDying) {
    844         return OMX_ErrorNone;
    845     }
    846     return instance->owner()->OnEvent(
    847             instance->nodeID(), eEvent, nData1, nData2, pEventData);
    848 }
    849 
    850 // static
    851 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
    852         OMX_IN OMX_HANDLETYPE hComponent,
    853         OMX_IN OMX_PTR pAppData,
    854         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
    855     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    856     if (instance->mDying) {
    857         return OMX_ErrorNone;
    858     }
    859     return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
    860 }
    861 
    862 // static
    863 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
    864         OMX_IN OMX_HANDLETYPE hComponent,
    865         OMX_IN OMX_PTR pAppData,
    866         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
    867     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    868     if (instance->mDying) {
    869         return OMX_ErrorNone;
    870     }
    871     return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
    872 }
    873 
    874 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
    875     ActiveBuffer active;
    876     active.mPortIndex = portIndex;
    877     active.mID = id;
    878     mActiveBuffers.push(active);
    879 }
    880 
    881 void OMXNodeInstance::removeActiveBuffer(
    882         OMX_U32 portIndex, OMX::buffer_id id) {
    883     bool found = false;
    884     for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
    885         if (mActiveBuffers[i].mPortIndex == portIndex
    886             && mActiveBuffers[i].mID == id) {
    887             found = true;
    888             mActiveBuffers.removeItemsAt(i);
    889             break;
    890         }
    891     }
    892 
    893     if (!found) {
    894         ALOGW("Attempt to remove an active buffer we know nothing about...");
    895     }
    896 }
    897 
    898 void OMXNodeInstance::freeActiveBuffers() {
    899     // Make sure to count down here, as freeBuffer will in turn remove
    900     // the active buffer from the vector...
    901     for (size_t i = mActiveBuffers.size(); i--;) {
    902         freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
    903     }
    904 }
    905 
    906 }  // namespace android
    907