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