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