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 
     24 #include <OMX_Component.h>
     25 
     26 #include <binder/IMemory.h>
     27 #include <HardwareAPI.h>
     28 #include <media/stagefright/foundation/ADebug.h>
     29 #include <media/stagefright/MediaErrors.h>
     30 
     31 namespace android {
     32 
     33 struct BufferMeta {
     34     BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
     35         : mMem(mem),
     36           mIsBackup(is_backup) {
     37     }
     38 
     39     BufferMeta(size_t size)
     40         : mSize(size),
     41           mIsBackup(false) {
     42     }
     43 
     44     BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
     45         : mGraphicBuffer(graphicBuffer),
     46           mIsBackup(false) {
     47     }
     48 
     49     void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
     50         if (!mIsBackup) {
     51             return;
     52         }
     53 
     54         memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
     55                header->pBuffer + header->nOffset,
     56                header->nFilledLen);
     57     }
     58 
     59     void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
     60         if (!mIsBackup) {
     61             return;
     62         }
     63 
     64         memcpy(header->pBuffer + header->nOffset,
     65                (const OMX_U8 *)mMem->pointer() + header->nOffset,
     66                header->nFilledLen);
     67     }
     68 
     69 private:
     70     sp<GraphicBuffer> mGraphicBuffer;
     71     sp<IMemory> mMem;
     72     size_t mSize;
     73     bool mIsBackup;
     74 
     75     BufferMeta(const BufferMeta &);
     76     BufferMeta &operator=(const BufferMeta &);
     77 };
     78 
     79 // static
     80 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
     81     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
     82 };
     83 
     84 OMXNodeInstance::OMXNodeInstance(
     85         OMX *owner, const sp<IOMXObserver> &observer)
     86     : mOwner(owner),
     87       mNodeID(NULL),
     88       mHandle(NULL),
     89       mObserver(observer),
     90       mDying(false) {
     91 }
     92 
     93 OMXNodeInstance::~OMXNodeInstance() {
     94     CHECK(mHandle == NULL);
     95 }
     96 
     97 void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
     98     CHECK(mHandle == NULL);
     99     mNodeID = node_id;
    100     mHandle = handle;
    101 }
    102 
    103 OMX *OMXNodeInstance::owner() {
    104     return mOwner;
    105 }
    106 
    107 sp<IOMXObserver> OMXNodeInstance::observer() {
    108     return mObserver;
    109 }
    110 
    111 OMX::node_id OMXNodeInstance::nodeID() {
    112     return mNodeID;
    113 }
    114 
    115 static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
    116     switch (err) {
    117         case OMX_ErrorNone:
    118             return OK;
    119         case OMX_ErrorUnsupportedSetting:
    120             return ERROR_UNSUPPORTED;
    121         default:
    122             return UNKNOWN_ERROR;
    123     }
    124 }
    125 
    126 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
    127     static int32_t kMaxNumIterations = 10;
    128 
    129     // Transition the node from its current state all the way down
    130     // to "Loaded".
    131     // This ensures that all active buffers are properly freed even
    132     // for components that don't do this themselves on a call to
    133     // "FreeHandle".
    134 
    135     // The code below may trigger some more events to be dispatched
    136     // by the OMX component - we want to ignore them as our client
    137     // does not expect them.
    138     mDying = true;
    139 
    140     OMX_STATETYPE state;
    141     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
    142     switch (state) {
    143         case OMX_StateExecuting:
    144         {
    145             ALOGV("forcing Executing->Idle");
    146             sendCommand(OMX_CommandStateSet, OMX_StateIdle);
    147             OMX_ERRORTYPE err;
    148             int32_t iteration = 0;
    149             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    150                    && state != OMX_StateIdle
    151                    && state != OMX_StateInvalid) {
    152                 if (++iteration > kMaxNumIterations) {
    153                     ALOGE("component failed to enter Idle state, aborting.");
    154                     state = OMX_StateInvalid;
    155                     break;
    156                 }
    157 
    158                 usleep(100000);
    159             }
    160             CHECK_EQ(err, OMX_ErrorNone);
    161 
    162             if (state == OMX_StateInvalid) {
    163                 break;
    164             }
    165 
    166             // fall through
    167         }
    168 
    169         case OMX_StateIdle:
    170         {
    171             ALOGV("forcing Idle->Loaded");
    172             sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
    173 
    174             freeActiveBuffers();
    175 
    176             OMX_ERRORTYPE err;
    177             int32_t iteration = 0;
    178             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    179                    && state != OMX_StateLoaded
    180                    && state != OMX_StateInvalid) {
    181                 if (++iteration > kMaxNumIterations) {
    182                     ALOGE("component failed to enter Loaded state, aborting.");
    183                     state = OMX_StateInvalid;
    184                     break;
    185                 }
    186 
    187                 ALOGV("waiting for Loaded state...");
    188                 usleep(100000);
    189             }
    190             CHECK_EQ(err, OMX_ErrorNone);
    191 
    192             // fall through
    193         }
    194 
    195         case OMX_StateLoaded:
    196         case OMX_StateInvalid:
    197             break;
    198 
    199         default:
    200             CHECK(!"should not be here, unknown state.");
    201             break;
    202     }
    203 
    204     ALOGV("calling destroyComponentInstance");
    205     OMX_ERRORTYPE err = master->destroyComponentInstance(
    206             static_cast<OMX_COMPONENTTYPE *>(mHandle));
    207     ALOGV("destroyComponentInstance returned err %d", err);
    208 
    209     mHandle = NULL;
    210 
    211     if (err != OMX_ErrorNone) {
    212         ALOGE("FreeHandle FAILED with error 0x%08x.", err);
    213     }
    214 
    215     mOwner->invalidateNodeID(mNodeID);
    216     mNodeID = NULL;
    217 
    218     ALOGV("OMXNodeInstance going away.");
    219     delete this;
    220 
    221     return StatusFromOMXError(err);
    222 }
    223 
    224 status_t OMXNodeInstance::sendCommand(
    225         OMX_COMMANDTYPE cmd, OMX_S32 param) {
    226     Mutex::Autolock autoLock(mLock);
    227 
    228     OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
    229     return StatusFromOMXError(err);
    230 }
    231 
    232 status_t OMXNodeInstance::getParameter(
    233         OMX_INDEXTYPE index, void *params, size_t size) {
    234     Mutex::Autolock autoLock(mLock);
    235 
    236     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
    237 
    238     return StatusFromOMXError(err);
    239 }
    240 
    241 status_t OMXNodeInstance::setParameter(
    242         OMX_INDEXTYPE index, const void *params, size_t size) {
    243     Mutex::Autolock autoLock(mLock);
    244 
    245     OMX_ERRORTYPE err = OMX_SetParameter(
    246             mHandle, index, const_cast<void *>(params));
    247 
    248     return StatusFromOMXError(err);
    249 }
    250 
    251 status_t OMXNodeInstance::getConfig(
    252         OMX_INDEXTYPE index, void *params, size_t size) {
    253     Mutex::Autolock autoLock(mLock);
    254 
    255     OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
    256     return StatusFromOMXError(err);
    257 }
    258 
    259 status_t OMXNodeInstance::setConfig(
    260         OMX_INDEXTYPE index, const void *params, size_t size) {
    261     Mutex::Autolock autoLock(mLock);
    262 
    263     OMX_ERRORTYPE err = OMX_SetConfig(
    264             mHandle, index, const_cast<void *>(params));
    265 
    266     return StatusFromOMXError(err);
    267 }
    268 
    269 status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
    270     Mutex::Autolock autoLock(mLock);
    271 
    272     OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
    273 
    274     return StatusFromOMXError(err);
    275 }
    276 
    277 status_t OMXNodeInstance::enableGraphicBuffers(
    278         OMX_U32 portIndex, OMX_BOOL enable) {
    279     Mutex::Autolock autoLock(mLock);
    280 
    281     OMX_INDEXTYPE index;
    282     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
    283             mHandle,
    284             const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
    285             &index);
    286 
    287     if (err != OMX_ErrorNone) {
    288         ALOGE("OMX_GetExtensionIndex failed");
    289 
    290         return StatusFromOMXError(err);
    291     }
    292 
    293     OMX_VERSIONTYPE ver;
    294     ver.s.nVersionMajor = 1;
    295     ver.s.nVersionMinor = 0;
    296     ver.s.nRevision = 0;
    297     ver.s.nStep = 0;
    298     EnableAndroidNativeBuffersParams params = {
    299         sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
    300     };
    301 
    302     err = OMX_SetParameter(mHandle, index, &params);
    303 
    304     if (err != OMX_ErrorNone) {
    305         ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
    306                 err, err);
    307 
    308         return UNKNOWN_ERROR;
    309     }
    310 
    311     return OK;
    312 }
    313 
    314 status_t OMXNodeInstance::getGraphicBufferUsage(
    315         OMX_U32 portIndex, OMX_U32* usage) {
    316     Mutex::Autolock autoLock(mLock);
    317 
    318     OMX_INDEXTYPE index;
    319     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
    320             mHandle,
    321             const_cast<OMX_STRING>(
    322                     "OMX.google.android.index.getAndroidNativeBufferUsage"),
    323             &index);
    324 
    325     if (err != OMX_ErrorNone) {
    326         ALOGE("OMX_GetExtensionIndex failed");
    327 
    328         return StatusFromOMXError(err);
    329     }
    330 
    331     OMX_VERSIONTYPE ver;
    332     ver.s.nVersionMajor = 1;
    333     ver.s.nVersionMinor = 0;
    334     ver.s.nRevision = 0;
    335     ver.s.nStep = 0;
    336     GetAndroidNativeBufferUsageParams params = {
    337         sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
    338     };
    339 
    340     err = OMX_GetParameter(mHandle, index, &params);
    341 
    342     if (err != OMX_ErrorNone) {
    343         ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
    344                 err, err);
    345         return UNKNOWN_ERROR;
    346     }
    347 
    348     *usage = params.nUsage;
    349 
    350     return OK;
    351 }
    352 
    353 status_t OMXNodeInstance::storeMetaDataInBuffers(
    354         OMX_U32 portIndex,
    355         OMX_BOOL enable) {
    356     Mutex::Autolock autolock(mLock);
    357 
    358     OMX_INDEXTYPE index;
    359     OMX_STRING name = const_cast<OMX_STRING>(
    360             "OMX.google.android.index.storeMetaDataInBuffers");
    361 
    362     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    363     if (err != OMX_ErrorNone) {
    364         ALOGE("OMX_GetExtensionIndex %s failed", name);
    365         return StatusFromOMXError(err);
    366     }
    367 
    368     StoreMetaDataInBuffersParams params;
    369     memset(&params, 0, sizeof(params));
    370     params.nSize = sizeof(params);
    371 
    372     // Version: 1.0.0.0
    373     params.nVersion.s.nVersionMajor = 1;
    374 
    375     params.nPortIndex = portIndex;
    376     params.bStoreMetaData = enable;
    377     if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
    378         ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
    379         return UNKNOWN_ERROR;
    380     }
    381     return err;
    382 }
    383 
    384 status_t OMXNodeInstance::useBuffer(
    385         OMX_U32 portIndex, const sp<IMemory> &params,
    386         OMX::buffer_id *buffer) {
    387     Mutex::Autolock autoLock(mLock);
    388 
    389     BufferMeta *buffer_meta = new BufferMeta(params);
    390 
    391     OMX_BUFFERHEADERTYPE *header;
    392 
    393     OMX_ERRORTYPE err = OMX_UseBuffer(
    394             mHandle, &header, portIndex, buffer_meta,
    395             params->size(), static_cast<OMX_U8 *>(params->pointer()));
    396 
    397     if (err != OMX_ErrorNone) {
    398         ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
    399 
    400         delete buffer_meta;
    401         buffer_meta = NULL;
    402 
    403         *buffer = 0;
    404 
    405         return UNKNOWN_ERROR;
    406     }
    407 
    408     CHECK_EQ(header->pAppPrivate, buffer_meta);
    409 
    410     *buffer = header;
    411 
    412     addActiveBuffer(portIndex, *buffer);
    413 
    414     return OK;
    415 }
    416 
    417 status_t OMXNodeInstance::useGraphicBuffer2_l(
    418         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    419         OMX::buffer_id *buffer) {
    420 
    421     // port definition
    422     OMX_PARAM_PORTDEFINITIONTYPE def;
    423     def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    424     def.nVersion.s.nVersionMajor = 1;
    425     def.nVersion.s.nVersionMinor = 0;
    426     def.nVersion.s.nRevision = 0;
    427     def.nVersion.s.nStep = 0;
    428     def.nPortIndex = portIndex;
    429     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
    430     if (err != OMX_ErrorNone)
    431     {
    432         ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
    433         return err;
    434     }
    435 
    436     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    437 
    438     OMX_BUFFERHEADERTYPE *header = NULL;
    439     OMX_U8* bufferHandle = const_cast<OMX_U8*>(
    440             reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
    441 
    442     err = OMX_UseBuffer(
    443             mHandle,
    444             &header,
    445             portIndex,
    446             bufferMeta,
    447             def.nBufferSize,
    448             bufferHandle);
    449 
    450     if (err != OMX_ErrorNone) {
    451         ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
    452         delete bufferMeta;
    453         bufferMeta = NULL;
    454         *buffer = 0;
    455         return UNKNOWN_ERROR;
    456     }
    457 
    458     CHECK_EQ(header->pBuffer, bufferHandle);
    459     CHECK_EQ(header->pAppPrivate, bufferMeta);
    460 
    461     *buffer = header;
    462 
    463     addActiveBuffer(portIndex, *buffer);
    464 
    465     return OK;
    466 }
    467 
    468 // XXX: This function is here for backwards compatibility.  Once the OMX
    469 // implementations have been updated this can be removed and useGraphicBuffer2
    470 // can be renamed to useGraphicBuffer.
    471 status_t OMXNodeInstance::useGraphicBuffer(
    472         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    473         OMX::buffer_id *buffer) {
    474     Mutex::Autolock autoLock(mLock);
    475 
    476     // See if the newer version of the extension is present.
    477     OMX_INDEXTYPE index;
    478     if (OMX_GetExtensionIndex(
    479             mHandle,
    480             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
    481             &index) == OMX_ErrorNone) {
    482         return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
    483     }
    484 
    485     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
    486             mHandle,
    487             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
    488             &index);
    489 
    490     if (err != OMX_ErrorNone) {
    491         ALOGE("OMX_GetExtensionIndex failed");
    492 
    493         return StatusFromOMXError(err);
    494     }
    495 
    496     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    497 
    498     OMX_BUFFERHEADERTYPE *header;
    499 
    500     OMX_VERSIONTYPE ver;
    501     ver.s.nVersionMajor = 1;
    502     ver.s.nVersionMinor = 0;
    503     ver.s.nRevision = 0;
    504     ver.s.nStep = 0;
    505     UseAndroidNativeBufferParams params = {
    506         sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
    507         &header, graphicBuffer,
    508     };
    509 
    510     err = OMX_SetParameter(mHandle, index, &params);
    511 
    512     if (err != OMX_ErrorNone) {
    513         ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
    514                 err);
    515 
    516         delete bufferMeta;
    517         bufferMeta = NULL;
    518 
    519         *buffer = 0;
    520 
    521         return UNKNOWN_ERROR;
    522     }
    523 
    524     CHECK_EQ(header->pAppPrivate, bufferMeta);
    525 
    526     *buffer = header;
    527 
    528     addActiveBuffer(portIndex, *buffer);
    529 
    530     return OK;
    531 }
    532 
    533 status_t OMXNodeInstance::allocateBuffer(
    534         OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
    535         void **buffer_data) {
    536     Mutex::Autolock autoLock(mLock);
    537 
    538     BufferMeta *buffer_meta = new BufferMeta(size);
    539 
    540     OMX_BUFFERHEADERTYPE *header;
    541 
    542     OMX_ERRORTYPE err = OMX_AllocateBuffer(
    543             mHandle, &header, portIndex, buffer_meta, size);
    544 
    545     if (err != OMX_ErrorNone) {
    546         ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
    547 
    548         delete buffer_meta;
    549         buffer_meta = NULL;
    550 
    551         *buffer = 0;
    552 
    553         return UNKNOWN_ERROR;
    554     }
    555 
    556     CHECK_EQ(header->pAppPrivate, buffer_meta);
    557 
    558     *buffer = header;
    559     *buffer_data = header->pBuffer;
    560 
    561     addActiveBuffer(portIndex, *buffer);
    562 
    563     return OK;
    564 }
    565 
    566 status_t OMXNodeInstance::allocateBufferWithBackup(
    567         OMX_U32 portIndex, const sp<IMemory> &params,
    568         OMX::buffer_id *buffer) {
    569     Mutex::Autolock autoLock(mLock);
    570 
    571     BufferMeta *buffer_meta = new BufferMeta(params, true);
    572 
    573     OMX_BUFFERHEADERTYPE *header;
    574 
    575     OMX_ERRORTYPE err = OMX_AllocateBuffer(
    576             mHandle, &header, portIndex, buffer_meta, params->size());
    577 
    578     if (err != OMX_ErrorNone) {
    579         ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
    580 
    581         delete buffer_meta;
    582         buffer_meta = NULL;
    583 
    584         *buffer = 0;
    585 
    586         return UNKNOWN_ERROR;
    587     }
    588 
    589     CHECK_EQ(header->pAppPrivate, buffer_meta);
    590 
    591     *buffer = header;
    592 
    593     addActiveBuffer(portIndex, *buffer);
    594 
    595     return OK;
    596 }
    597 
    598 status_t OMXNodeInstance::freeBuffer(
    599         OMX_U32 portIndex, OMX::buffer_id buffer) {
    600     Mutex::Autolock autoLock(mLock);
    601 
    602     removeActiveBuffer(portIndex, buffer);
    603 
    604     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    605     BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
    606 
    607     OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
    608 
    609     delete buffer_meta;
    610     buffer_meta = NULL;
    611 
    612     return StatusFromOMXError(err);
    613 }
    614 
    615 status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
    616     Mutex::Autolock autoLock(mLock);
    617 
    618     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    619     header->nFilledLen = 0;
    620     header->nOffset = 0;
    621     header->nFlags = 0;
    622 
    623     OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
    624 
    625     return StatusFromOMXError(err);
    626 }
    627 
    628 status_t OMXNodeInstance::emptyBuffer(
    629         OMX::buffer_id buffer,
    630         OMX_U32 rangeOffset, OMX_U32 rangeLength,
    631         OMX_U32 flags, OMX_TICKS timestamp) {
    632     Mutex::Autolock autoLock(mLock);
    633 
    634     OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
    635     header->nFilledLen = rangeLength;
    636     header->nOffset = rangeOffset;
    637     header->nFlags = flags;
    638     header->nTimeStamp = timestamp;
    639 
    640     BufferMeta *buffer_meta =
    641         static_cast<BufferMeta *>(header->pAppPrivate);
    642     buffer_meta->CopyToOMX(header);
    643 
    644     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
    645 
    646     return StatusFromOMXError(err);
    647 }
    648 
    649 status_t OMXNodeInstance::getExtensionIndex(
    650         const char *parameterName, OMX_INDEXTYPE *index) {
    651     Mutex::Autolock autoLock(mLock);
    652 
    653     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
    654             mHandle, const_cast<char *>(parameterName), index);
    655 
    656     return StatusFromOMXError(err);
    657 }
    658 
    659 void OMXNodeInstance::onMessage(const omx_message &msg) {
    660     if (msg.type == omx_message::FILL_BUFFER_DONE) {
    661         OMX_BUFFERHEADERTYPE *buffer =
    662             static_cast<OMX_BUFFERHEADERTYPE *>(
    663                     msg.u.extended_buffer_data.buffer);
    664 
    665         BufferMeta *buffer_meta =
    666             static_cast<BufferMeta *>(buffer->pAppPrivate);
    667 
    668         buffer_meta->CopyFromOMX(buffer);
    669     }
    670 
    671     mObserver->onMessage(msg);
    672 }
    673 
    674 void OMXNodeInstance::onObserverDied(OMXMaster *master) {
    675     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
    676 
    677     // Try to force shutdown of the node and hope for the best.
    678     freeNode(master);
    679 }
    680 
    681 void OMXNodeInstance::onGetHandleFailed() {
    682     delete this;
    683 }
    684 
    685 // static
    686 OMX_ERRORTYPE OMXNodeInstance::OnEvent(
    687         OMX_IN OMX_HANDLETYPE hComponent,
    688         OMX_IN OMX_PTR pAppData,
    689         OMX_IN OMX_EVENTTYPE eEvent,
    690         OMX_IN OMX_U32 nData1,
    691         OMX_IN OMX_U32 nData2,
    692         OMX_IN OMX_PTR pEventData) {
    693     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    694     if (instance->mDying) {
    695         return OMX_ErrorNone;
    696     }
    697     return instance->owner()->OnEvent(
    698             instance->nodeID(), eEvent, nData1, nData2, pEventData);
    699 }
    700 
    701 // static
    702 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
    703         OMX_IN OMX_HANDLETYPE hComponent,
    704         OMX_IN OMX_PTR pAppData,
    705         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
    706     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    707     if (instance->mDying) {
    708         return OMX_ErrorNone;
    709     }
    710     return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
    711 }
    712 
    713 // static
    714 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
    715         OMX_IN OMX_HANDLETYPE hComponent,
    716         OMX_IN OMX_PTR pAppData,
    717         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
    718     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
    719     if (instance->mDying) {
    720         return OMX_ErrorNone;
    721     }
    722     return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
    723 }
    724 
    725 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
    726     ActiveBuffer active;
    727     active.mPortIndex = portIndex;
    728     active.mID = id;
    729     mActiveBuffers.push(active);
    730 }
    731 
    732 void OMXNodeInstance::removeActiveBuffer(
    733         OMX_U32 portIndex, OMX::buffer_id id) {
    734     bool found = false;
    735     for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
    736         if (mActiveBuffers[i].mPortIndex == portIndex
    737             && mActiveBuffers[i].mID == id) {
    738             found = true;
    739             mActiveBuffers.removeItemsAt(i);
    740             break;
    741         }
    742     }
    743 
    744     if (!found) {
    745         ALOGW("Attempt to remove an active buffer we know nothing about...");
    746     }
    747 }
    748 
    749 void OMXNodeInstance::freeActiveBuffers() {
    750     // Make sure to count down here, as freeBuffer will in turn remove
    751     // the active buffer from the vector...
    752     for (size_t i = mActiveBuffers.size(); i--;) {
    753         freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
    754     }
    755 }
    756 
    757 }  // namespace android
    758