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 <inttypes.h>
     22 
     23 #include "../include/OMXNodeInstance.h"
     24 #include "OMXMaster.h"
     25 #include "GraphicBufferSource.h"
     26 
     27 #include <OMX_Component.h>
     28 #include <OMX_IndexExt.h>
     29 #include <OMX_AsString.h>
     30 
     31 #include <binder/IMemory.h>
     32 #include <gui/BufferQueue.h>
     33 #include <HardwareAPI.h>
     34 #include <media/stagefright/foundation/ADebug.h>
     35 #include <media/stagefright/foundation/ABuffer.h>
     36 #include <media/stagefright/MediaErrors.h>
     37 
     38 #include <utils/misc.h>
     39 
     40 static const OMX_U32 kPortIndexInput = 0;
     41 static const OMX_U32 kPortIndexOutput = 1;
     42 
     43 #define CLOGW(fmt, ...) ALOGW("[%x:%s] " fmt, mNodeID, mName, ##__VA_ARGS__)
     44 
     45 #define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \
     46     ALOGE_IF(cond, #fn "(%x:%s, " fmt ") ERROR: %s(%#x)", \
     47     mNodeID, mName, ##__VA_ARGS__, asString(err), err)
     48 #define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__)
     49 #define CLOG_IF_ERROR(fn, err, fmt, ...) \
     50     CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__)
     51 
     52 #define CLOGI_(level, fn, fmt, ...) \
     53     ALOGI_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__)
     54 #define CLOGD_(level, fn, fmt, ...) \
     55     ALOGD_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__)
     56 
     57 #define CLOG_LIFE(fn, fmt, ...)     CLOGI_(ADebug::kDebugLifeCycle,     fn, fmt, ##__VA_ARGS__)
     58 #define CLOG_STATE(fn, fmt, ...)    CLOGI_(ADebug::kDebugState,         fn, fmt, ##__VA_ARGS__)
     59 #define CLOG_CONFIG(fn, fmt, ...)   CLOGI_(ADebug::kDebugConfig,        fn, fmt, ##__VA_ARGS__)
     60 #define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__)
     61 
     62 #define CLOG_DEBUG_IF(cond, fn, fmt, ...) \
     63     ALOGD_IF(cond, #fn "(%x, " fmt ")", mNodeID, ##__VA_ARGS__)
     64 
     65 #define CLOG_BUFFER(fn, fmt, ...) \
     66     CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__)
     67 #define CLOG_BUMPED_BUFFER(fn, fmt, ...) \
     68     CLOG_DEBUG_IF(DEBUG_BUMP >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__)
     69 
     70 /* buffer formatting */
     71 #define BUFFER_FMT(port, fmt, ...) "%s:%u " fmt, portString(port), (port), ##__VA_ARGS__
     72 #define NEW_BUFFER_FMT(buffer_id, port, fmt, ...) \
     73     BUFFER_FMT(port, fmt ") (#%zu => %#x", ##__VA_ARGS__, mActiveBuffers.size(), (buffer_id))
     74 
     75 #define SIMPLE_BUFFER(port, size, data) BUFFER_FMT(port, "%zu@%p", (size), (data))
     76 #define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \
     77     NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data))
     78 
     79 #define EMPTY_BUFFER(addr, header, fenceFd) "%#x [%u@%p fc=%d]", \
     80     (addr), (header)->nAllocLen, (header)->pBuffer, (fenceFd)
     81 #define FULL_BUFFER(addr, header, fenceFd) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld fc=%d]", \
     82     (intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \
     83     (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp, (fenceFd)
     84 
     85 #define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \
     86     mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \
     87     mOutputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexOutput]
     88 // TRICKY: this is needed so formatting macros expand before substitution
     89 #define WITH_STATS(fmt, ...) WITH_STATS_WRAPPER(fmt, ##__VA_ARGS__)
     90 
     91 template<class T>
     92 static void InitOMXParams(T *params) {
     93     memset(params, 0, sizeof(T));
     94     params->nSize = sizeof(T);
     95     params->nVersion.s.nVersionMajor = 1;
     96     params->nVersion.s.nVersionMinor = 0;
     97     params->nVersion.s.nRevision = 0;
     98     params->nVersion.s.nStep = 0;
     99 }
    100 
    101 namespace android {
    102 
    103 struct BufferMeta {
    104     BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
    105         : mMem(mem),
    106           mIsBackup(is_backup) {
    107     }
    108 
    109     BufferMeta(size_t size)
    110         : mSize(size),
    111           mIsBackup(false) {
    112     }
    113 
    114     BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
    115         : mGraphicBuffer(graphicBuffer),
    116           mIsBackup(false) {
    117     }
    118 
    119     void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
    120         if (!mIsBackup) {
    121             return;
    122         }
    123 
    124         // check component returns proper range
    125         sp<ABuffer> codec = getBuffer(header, false /* backup */, true /* limit */);
    126 
    127         memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, codec->data(), codec->size());
    128     }
    129 
    130     void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
    131         if (!mIsBackup) {
    132             return;
    133         }
    134 
    135         memcpy(header->pBuffer + header->nOffset,
    136                 (const OMX_U8 *)mMem->pointer() + header->nOffset,
    137                 header->nFilledLen);
    138     }
    139 
    140     // return either the codec or the backup buffer
    141     sp<ABuffer> getBuffer(const OMX_BUFFERHEADERTYPE *header, bool backup, bool limit) {
    142         sp<ABuffer> buf;
    143         if (backup && mMem != NULL) {
    144             buf = new ABuffer(mMem->pointer(), mMem->size());
    145         } else {
    146             buf = new ABuffer(header->pBuffer, header->nAllocLen);
    147         }
    148         if (limit) {
    149             if (header->nOffset + header->nFilledLen > header->nOffset
    150                     && header->nOffset + header->nFilledLen <= header->nAllocLen) {
    151                 buf->setRange(header->nOffset, header->nFilledLen);
    152             } else {
    153                 buf->setRange(0, 0);
    154             }
    155         }
    156         return buf;
    157     }
    158 
    159     void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) {
    160         mGraphicBuffer = graphicBuffer;
    161     }
    162 
    163 private:
    164     sp<GraphicBuffer> mGraphicBuffer;
    165     sp<IMemory> mMem;
    166     size_t mSize;
    167     bool mIsBackup;
    168 
    169     BufferMeta(const BufferMeta &);
    170     BufferMeta &operator=(const BufferMeta &);
    171 };
    172 
    173 // static
    174 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
    175     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
    176 };
    177 
    178 static inline const char *portString(OMX_U32 portIndex) {
    179     switch (portIndex) {
    180         case kPortIndexInput:  return "Input";
    181         case kPortIndexOutput: return "Output";
    182         case ~0U:              return "All";
    183         default:               return "port";
    184     }
    185 }
    186 
    187 OMXNodeInstance::OMXNodeInstance(
    188         OMX *owner, const sp<IOMXObserver> &observer, const char *name)
    189     : mOwner(owner),
    190       mNodeID(0),
    191       mHandle(NULL),
    192       mObserver(observer),
    193       mDying(false),
    194       mBufferIDCount(0)
    195 {
    196     mName = ADebug::GetDebugName(name);
    197     DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
    198     ALOGV("debug level for %s is %d", name, DEBUG);
    199     DEBUG_BUMP = DEBUG;
    200     mNumPortBuffers[0] = 0;
    201     mNumPortBuffers[1] = 0;
    202     mDebugLevelBumpPendingBuffers[0] = 0;
    203     mDebugLevelBumpPendingBuffers[1] = 0;
    204     mMetadataType[0] = kMetadataBufferTypeInvalid;
    205     mMetadataType[1] = kMetadataBufferTypeInvalid;
    206 }
    207 
    208 OMXNodeInstance::~OMXNodeInstance() {
    209     free(mName);
    210     CHECK(mHandle == NULL);
    211 }
    212 
    213 void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
    214     mNodeID = node_id;
    215     CLOG_LIFE(allocateNode, "handle=%p", handle);
    216     CHECK(mHandle == NULL);
    217     mHandle = handle;
    218 }
    219 
    220 sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() {
    221     Mutex::Autolock autoLock(mGraphicBufferSourceLock);
    222     return mGraphicBufferSource;
    223 }
    224 
    225 void OMXNodeInstance::setGraphicBufferSource(
    226         const sp<GraphicBufferSource>& bufferSource) {
    227     Mutex::Autolock autoLock(mGraphicBufferSourceLock);
    228     CLOG_INTERNAL(setGraphicBufferSource, "%p", bufferSource.get());
    229     mGraphicBufferSource = bufferSource;
    230 }
    231 
    232 OMX *OMXNodeInstance::owner() {
    233     return mOwner;
    234 }
    235 
    236 sp<IOMXObserver> OMXNodeInstance::observer() {
    237     return mObserver;
    238 }
    239 
    240 OMX::node_id OMXNodeInstance::nodeID() {
    241     return mNodeID;
    242 }
    243 
    244 status_t StatusFromOMXError(OMX_ERRORTYPE err) {
    245     switch (err) {
    246         case OMX_ErrorNone:
    247             return OK;
    248         case OMX_ErrorUnsupportedSetting:
    249         case OMX_ErrorUnsupportedIndex:
    250             return ERROR_UNSUPPORTED;
    251         case OMX_ErrorInsufficientResources:
    252             return NO_MEMORY;
    253         default:
    254             return UNKNOWN_ERROR;
    255     }
    256 }
    257 
    258 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
    259     CLOG_LIFE(freeNode, "handle=%p", mHandle);
    260     static int32_t kMaxNumIterations = 10;
    261 
    262     // exit if we have already freed the node
    263     if (mHandle == NULL) {
    264         return OK;
    265     }
    266 
    267     // Transition the node from its current state all the way down
    268     // to "Loaded".
    269     // This ensures that all active buffers are properly freed even
    270     // for components that don't do this themselves on a call to
    271     // "FreeHandle".
    272 
    273     // The code below may trigger some more events to be dispatched
    274     // by the OMX component - we want to ignore them as our client
    275     // does not expect them.
    276     mDying = true;
    277 
    278     OMX_STATETYPE state;
    279     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
    280     switch (state) {
    281         case OMX_StateExecuting:
    282         {
    283             ALOGV("forcing Executing->Idle");
    284             sendCommand(OMX_CommandStateSet, OMX_StateIdle);
    285             OMX_ERRORTYPE err;
    286             int32_t iteration = 0;
    287             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    288                     && state != OMX_StateIdle
    289                     && state != OMX_StateInvalid) {
    290                 if (++iteration > kMaxNumIterations) {
    291                     CLOGW("failed to enter Idle state (now %s(%d), aborting.",
    292                             asString(state), state);
    293                     state = OMX_StateInvalid;
    294                     break;
    295                 }
    296 
    297                 usleep(100000);
    298             }
    299             CHECK_EQ(err, OMX_ErrorNone);
    300 
    301             if (state == OMX_StateInvalid) {
    302                 break;
    303             }
    304 
    305             // fall through
    306         }
    307 
    308         case OMX_StateIdle:
    309         {
    310             ALOGV("forcing Idle->Loaded");
    311             sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
    312 
    313             freeActiveBuffers();
    314 
    315             OMX_ERRORTYPE err;
    316             int32_t iteration = 0;
    317             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    318                     && state != OMX_StateLoaded
    319                     && state != OMX_StateInvalid) {
    320                 if (++iteration > kMaxNumIterations) {
    321                     CLOGW("failed to enter Loaded state (now %s(%d), aborting.",
    322                             asString(state), state);
    323                     state = OMX_StateInvalid;
    324                     break;
    325                 }
    326 
    327                 ALOGV("waiting for Loaded state...");
    328                 usleep(100000);
    329             }
    330             CHECK_EQ(err, OMX_ErrorNone);
    331 
    332             // fall through
    333         }
    334 
    335         case OMX_StateLoaded:
    336         case OMX_StateInvalid:
    337             break;
    338 
    339         default:
    340             LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state);
    341             break;
    342     }
    343 
    344     ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);
    345     OMX_ERRORTYPE err = master->destroyComponentInstance(
    346             static_cast<OMX_COMPONENTTYPE *>(mHandle));
    347 
    348     mHandle = NULL;
    349     CLOG_IF_ERROR(freeNode, err, "");
    350     free(mName);
    351     mName = NULL;
    352 
    353     mOwner->invalidateNodeID(mNodeID);
    354     mNodeID = 0;
    355 
    356     ALOGV("OMXNodeInstance going away.");
    357     delete this;
    358 
    359     return StatusFromOMXError(err);
    360 }
    361 
    362 status_t OMXNodeInstance::sendCommand(
    363         OMX_COMMANDTYPE cmd, OMX_S32 param) {
    364     const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
    365     if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
    366         if (param == OMX_StateIdle) {
    367             // Initiating transition from Executing -> Idle
    368             // ACodec is waiting for all buffers to be returned, do NOT
    369             // submit any more buffers to the codec.
    370             bufferSource->omxIdle();
    371         } else if (param == OMX_StateLoaded) {
    372             // Initiating transition from Idle/Executing -> Loaded
    373             // Buffers are about to be freed.
    374             bufferSource->omxLoaded();
    375             setGraphicBufferSource(NULL);
    376         }
    377 
    378         // fall through
    379     }
    380 
    381     Mutex::Autolock autoLock(mLock);
    382 
    383     // bump internal-state debug level for 2 input and output frames past a command
    384     {
    385         Mutex::Autolock _l(mDebugLock);
    386         bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */);
    387     }
    388 
    389     const char *paramString =
    390         cmd == OMX_CommandStateSet ? asString((OMX_STATETYPE)param) : portString(param);
    391     CLOG_STATE(sendCommand, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);
    392     OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
    393     CLOG_IF_ERROR(sendCommand, err, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);
    394     return StatusFromOMXError(err);
    395 }
    396 
    397 status_t OMXNodeInstance::getParameter(
    398         OMX_INDEXTYPE index, void *params, size_t /* size */) {
    399     Mutex::Autolock autoLock(mLock);
    400 
    401     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
    402     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    403     // some errors are expected for getParameter
    404     if (err != OMX_ErrorNoMore) {
    405         CLOG_IF_ERROR(getParameter, err, "%s(%#x)", asString(extIndex), index);
    406     }
    407     return StatusFromOMXError(err);
    408 }
    409 
    410 status_t OMXNodeInstance::setParameter(
    411         OMX_INDEXTYPE index, const void *params, size_t size) {
    412     Mutex::Autolock autoLock(mLock);
    413     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    414     CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
    415 
    416     OMX_ERRORTYPE err = OMX_SetParameter(
    417             mHandle, index, const_cast<void *>(params));
    418     CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index);
    419     return StatusFromOMXError(err);
    420 }
    421 
    422 status_t OMXNodeInstance::getConfig(
    423         OMX_INDEXTYPE index, void *params, size_t /* size */) {
    424     Mutex::Autolock autoLock(mLock);
    425 
    426     OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
    427     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    428     // some errors are expected for getConfig
    429     if (err != OMX_ErrorNoMore) {
    430         CLOG_IF_ERROR(getConfig, err, "%s(%#x)", asString(extIndex), index);
    431     }
    432     return StatusFromOMXError(err);
    433 }
    434 
    435 status_t OMXNodeInstance::setConfig(
    436         OMX_INDEXTYPE index, const void *params, size_t size) {
    437     Mutex::Autolock autoLock(mLock);
    438     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    439     CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
    440 
    441     OMX_ERRORTYPE err = OMX_SetConfig(
    442             mHandle, index, const_cast<void *>(params));
    443     CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index);
    444     return StatusFromOMXError(err);
    445 }
    446 
    447 status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
    448     Mutex::Autolock autoLock(mLock);
    449 
    450     OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
    451     CLOG_IF_ERROR(getState, err, "");
    452     return StatusFromOMXError(err);
    453 }
    454 
    455 status_t OMXNodeInstance::enableGraphicBuffers(
    456         OMX_U32 portIndex, OMX_BOOL enable) {
    457     Mutex::Autolock autoLock(mLock);
    458     CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable);
    459     OMX_STRING name = const_cast<OMX_STRING>(
    460             "OMX.google.android.index.enableAndroidNativeBuffers");
    461 
    462     OMX_INDEXTYPE index;
    463     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    464 
    465     if (err != OMX_ErrorNone) {
    466         CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);
    467         return StatusFromOMXError(err);
    468     }
    469 
    470     EnableAndroidNativeBuffersParams params;
    471     InitOMXParams(&params);
    472     params.nPortIndex = portIndex;
    473     params.enable = enable;
    474 
    475     err = OMX_SetParameter(mHandle, index, &params);
    476     CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
    477             portString(portIndex), portIndex, enable);
    478     return StatusFromOMXError(err);
    479 }
    480 
    481 status_t OMXNodeInstance::getGraphicBufferUsage(
    482         OMX_U32 portIndex, OMX_U32* usage) {
    483     Mutex::Autolock autoLock(mLock);
    484 
    485     OMX_INDEXTYPE index;
    486     OMX_STRING name = const_cast<OMX_STRING>(
    487             "OMX.google.android.index.getAndroidNativeBufferUsage");
    488     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    489 
    490     if (err != OMX_ErrorNone) {
    491         CLOG_ERROR(getExtensionIndex, err, "%s", name);
    492         return StatusFromOMXError(err);
    493     }
    494 
    495     GetAndroidNativeBufferUsageParams params;
    496     InitOMXParams(&params);
    497     params.nPortIndex = portIndex;
    498 
    499     err = OMX_GetParameter(mHandle, index, &params);
    500     if (err != OMX_ErrorNone) {
    501         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", name, index,
    502                 portString(portIndex), portIndex);
    503         return StatusFromOMXError(err);
    504     }
    505 
    506     *usage = params.nUsage;
    507 
    508     return OK;
    509 }
    510 
    511 status_t OMXNodeInstance::storeMetaDataInBuffers(
    512         OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
    513     Mutex::Autolock autolock(mLock);
    514     CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u en:%d", portString(portIndex), portIndex, enable);
    515     return storeMetaDataInBuffers_l(portIndex, enable, type);
    516 }
    517 
    518 status_t OMXNodeInstance::storeMetaDataInBuffers_l(
    519         OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
    520     if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
    521         return BAD_VALUE;
    522     }
    523 
    524     OMX_INDEXTYPE index;
    525     OMX_STRING name = const_cast<OMX_STRING>(
    526             "OMX.google.android.index.storeMetaDataInBuffers");
    527 
    528     OMX_STRING nativeBufferName = const_cast<OMX_STRING>(
    529             "OMX.google.android.index.storeANWBufferInMetadata");
    530     MetadataBufferType negotiatedType;
    531 
    532     StoreMetaDataInBuffersParams params;
    533     InitOMXParams(&params);
    534     params.nPortIndex = portIndex;
    535     params.bStoreMetaData = enable;
    536 
    537     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, nativeBufferName, &index);
    538     OMX_ERRORTYPE xerr = err;
    539     if (err == OMX_ErrorNone) {
    540         err = OMX_SetParameter(mHandle, index, &params);
    541         if (err == OMX_ErrorNone) {
    542             name = nativeBufferName; // set name for debugging
    543             negotiatedType = kMetadataBufferTypeANWBuffer;
    544         }
    545     }
    546     if (err != OMX_ErrorNone) {
    547         err = OMX_GetExtensionIndex(mHandle, name, &index);
    548         xerr = err;
    549         if (err == OMX_ErrorNone) {
    550             negotiatedType = kMetadataBufferTypeGrallocSource;
    551             err = OMX_SetParameter(mHandle, index, &params);
    552         }
    553     }
    554 
    555     // don't log loud error if component does not support metadata mode on the output
    556     if (err != OMX_ErrorNone) {
    557         if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) {
    558             CLOGW("component does not support metadata mode; using fallback");
    559         } else if (xerr != OMX_ErrorNone) {
    560             CLOG_ERROR(getExtensionIndex, xerr, "%s", name);
    561         } else {
    562             CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d type=%d", name, index,
    563                     portString(portIndex), portIndex, enable, negotiatedType);
    564         }
    565         negotiatedType = mMetadataType[portIndex];
    566     } else {
    567         if (!enable) {
    568             negotiatedType = kMetadataBufferTypeInvalid;
    569         }
    570         mMetadataType[portIndex] = negotiatedType;
    571     }
    572     CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u negotiated %s:%d",
    573             portString(portIndex), portIndex, asString(negotiatedType), negotiatedType);
    574 
    575     if (type != NULL) {
    576         *type = negotiatedType;
    577     }
    578 
    579     return StatusFromOMXError(err);
    580 }
    581 
    582 status_t OMXNodeInstance::prepareForAdaptivePlayback(
    583         OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
    584         OMX_U32 maxFrameHeight) {
    585     Mutex::Autolock autolock(mLock);
    586     CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u",
    587             portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
    588 
    589     OMX_INDEXTYPE index;
    590     OMX_STRING name = const_cast<OMX_STRING>(
    591             "OMX.google.android.index.prepareForAdaptivePlayback");
    592 
    593     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    594     if (err != OMX_ErrorNone) {
    595         CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);
    596         return StatusFromOMXError(err);
    597     }
    598 
    599     PrepareForAdaptivePlaybackParams params;
    600     InitOMXParams(&params);
    601     params.nPortIndex = portIndex;
    602     params.bEnable = enable;
    603     params.nMaxFrameWidth = maxFrameWidth;
    604     params.nMaxFrameHeight = maxFrameHeight;
    605 
    606     err = OMX_SetParameter(mHandle, index, &params);
    607     CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d max=%ux%u", name, index,
    608             portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
    609     return StatusFromOMXError(err);
    610 }
    611 
    612 status_t OMXNodeInstance::configureVideoTunnelMode(
    613         OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
    614         native_handle_t **sidebandHandle) {
    615     Mutex::Autolock autolock(mLock);
    616     CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u",
    617             portString(portIndex), portIndex, tunneled, audioHwSync);
    618 
    619     OMX_INDEXTYPE index;
    620     OMX_STRING name = const_cast<OMX_STRING>(
    621             "OMX.google.android.index.configureVideoTunnelMode");
    622 
    623     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    624     if (err != OMX_ErrorNone) {
    625         CLOG_ERROR_IF(tunneled, getExtensionIndex, err, "%s", name);
    626         return StatusFromOMXError(err);
    627     }
    628 
    629     ConfigureVideoTunnelModeParams tunnelParams;
    630     InitOMXParams(&tunnelParams);
    631     tunnelParams.nPortIndex = portIndex;
    632     tunnelParams.bTunneled = tunneled;
    633     tunnelParams.nAudioHwSync = audioHwSync;
    634     err = OMX_SetParameter(mHandle, index, &tunnelParams);
    635     if (err != OMX_ErrorNone) {
    636         CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index,
    637                 portString(portIndex), portIndex, tunneled, audioHwSync);
    638         return StatusFromOMXError(err);
    639     }
    640 
    641     err = OMX_GetParameter(mHandle, index, &tunnelParams);
    642     if (err != OMX_ErrorNone) {
    643         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index,
    644                 portString(portIndex), portIndex, tunneled, audioHwSync);
    645         return StatusFromOMXError(err);
    646     }
    647     if (sidebandHandle) {
    648         *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
    649     }
    650 
    651     return OK;
    652 }
    653 
    654 status_t OMXNodeInstance::useBuffer(
    655         OMX_U32 portIndex, const sp<IMemory> &params,
    656         OMX::buffer_id *buffer, OMX_U32 allottedSize) {
    657     Mutex::Autolock autoLock(mLock);
    658     if (allottedSize > params->size()) {
    659         return BAD_VALUE;
    660     }
    661 
    662     BufferMeta *buffer_meta = new BufferMeta(params);
    663 
    664     OMX_BUFFERHEADERTYPE *header;
    665 
    666     OMX_ERRORTYPE err = OMX_UseBuffer(
    667             mHandle, &header, portIndex, buffer_meta,
    668             allottedSize, static_cast<OMX_U8 *>(params->pointer()));
    669 
    670     if (err != OMX_ErrorNone) {
    671         CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(
    672                 portIndex, (size_t)allottedSize, params->pointer()));
    673 
    674         delete buffer_meta;
    675         buffer_meta = NULL;
    676 
    677         *buffer = 0;
    678 
    679         return StatusFromOMXError(err);
    680     }
    681 
    682     CHECK_EQ(header->pAppPrivate, buffer_meta);
    683 
    684     *buffer = makeBufferID(header);
    685 
    686     addActiveBuffer(portIndex, *buffer);
    687 
    688     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    689     if (bufferSource != NULL && portIndex == kPortIndexInput) {
    690         bufferSource->addCodecBuffer(header);
    691     }
    692 
    693     CLOG_BUFFER(useBuffer, NEW_BUFFER_FMT(
    694             *buffer, portIndex, "%u(%zu)@%p", allottedSize, params->size(), params->pointer()));
    695     return OK;
    696 }
    697 
    698 status_t OMXNodeInstance::useGraphicBuffer2_l(
    699         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    700         OMX::buffer_id *buffer) {
    701 
    702     // port definition
    703     OMX_PARAM_PORTDEFINITIONTYPE def;
    704     InitOMXParams(&def);
    705     def.nPortIndex = portIndex;
    706     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
    707     if (err != OMX_ErrorNone) {
    708         OMX_INDEXTYPE index = OMX_IndexParamPortDefinition;
    709         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u",
    710                 asString(index), index, portString(portIndex), portIndex);
    711         return UNKNOWN_ERROR;
    712     }
    713 
    714     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    715 
    716     OMX_BUFFERHEADERTYPE *header = NULL;
    717     OMX_U8* bufferHandle = const_cast<OMX_U8*>(
    718             reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
    719 
    720     err = OMX_UseBuffer(
    721             mHandle,
    722             &header,
    723             portIndex,
    724             bufferMeta,
    725             def.nBufferSize,
    726             bufferHandle);
    727 
    728     if (err != OMX_ErrorNone) {
    729         CLOG_ERROR(useBuffer, err, BUFFER_FMT(portIndex, "%u@%p", def.nBufferSize, bufferHandle));
    730         delete bufferMeta;
    731         bufferMeta = NULL;
    732         *buffer = 0;
    733         return StatusFromOMXError(err);
    734     }
    735 
    736     CHECK_EQ(header->pBuffer, bufferHandle);
    737     CHECK_EQ(header->pAppPrivate, bufferMeta);
    738 
    739     *buffer = makeBufferID(header);
    740 
    741     addActiveBuffer(portIndex, *buffer);
    742     CLOG_BUFFER(useGraphicBuffer2, NEW_BUFFER_FMT(
    743             *buffer, portIndex, "%u@%p", def.nBufferSize, bufferHandle));
    744     return OK;
    745 }
    746 
    747 // XXX: This function is here for backwards compatibility.  Once the OMX
    748 // implementations have been updated this can be removed and useGraphicBuffer2
    749 // can be renamed to useGraphicBuffer.
    750 status_t OMXNodeInstance::useGraphicBuffer(
    751         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    752         OMX::buffer_id *buffer) {
    753     Mutex::Autolock autoLock(mLock);
    754 
    755     // See if the newer version of the extension is present.
    756     OMX_INDEXTYPE index;
    757     if (OMX_GetExtensionIndex(
    758             mHandle,
    759             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
    760             &index) == OMX_ErrorNone) {
    761         return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
    762     }
    763 
    764     OMX_STRING name = const_cast<OMX_STRING>(
    765         "OMX.google.android.index.useAndroidNativeBuffer");
    766     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    767     if (err != OMX_ErrorNone) {
    768         CLOG_ERROR(getExtensionIndex, err, "%s", name);
    769         return StatusFromOMXError(err);
    770     }
    771 
    772     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
    773 
    774     OMX_BUFFERHEADERTYPE *header;
    775 
    776     OMX_VERSIONTYPE ver;
    777     ver.s.nVersionMajor = 1;
    778     ver.s.nVersionMinor = 0;
    779     ver.s.nRevision = 0;
    780     ver.s.nStep = 0;
    781     UseAndroidNativeBufferParams params = {
    782         sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
    783         &header, graphicBuffer,
    784     };
    785 
    786     err = OMX_SetParameter(mHandle, index, &params);
    787 
    788     if (err != OMX_ErrorNone) {
    789         CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index,
    790                 portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle);
    791 
    792         delete bufferMeta;
    793         bufferMeta = NULL;
    794 
    795         *buffer = 0;
    796 
    797         return StatusFromOMXError(err);
    798     }
    799 
    800     CHECK_EQ(header->pAppPrivate, bufferMeta);
    801 
    802     *buffer = makeBufferID(header);
    803 
    804     addActiveBuffer(portIndex, *buffer);
    805     CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT(
    806             *buffer, portIndex, "GB=%p", graphicBuffer->handle));
    807     return OK;
    808 }
    809 
    810 status_t OMXNodeInstance::updateGraphicBufferInMeta_l(
    811         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    812         OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
    813     if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
    814         return BAD_VALUE;
    815     }
    816 
    817     BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
    818     bufferMeta->setGraphicBuffer(graphicBuffer);
    819     if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource
    820             && header->nAllocLen >= sizeof(VideoGrallocMetadata)) {
    821         VideoGrallocMetadata &metadata = *(VideoGrallocMetadata *)(header->pBuffer);
    822         metadata.eType = kMetadataBufferTypeGrallocSource;
    823         metadata.pHandle = graphicBuffer == NULL ? NULL : graphicBuffer->handle;
    824     } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
    825             && header->nAllocLen >= sizeof(VideoNativeMetadata)) {
    826         VideoNativeMetadata &metadata = *(VideoNativeMetadata *)(header->pBuffer);
    827         metadata.eType = kMetadataBufferTypeANWBuffer;
    828         metadata.pBuffer = graphicBuffer == NULL ? NULL : graphicBuffer->getNativeBuffer();
    829         metadata.nFenceFd = -1;
    830     } else {
    831         CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x bad type (%d) or size (%u)",
    832             portString(portIndex), portIndex, buffer, mMetadataType[portIndex], header->nAllocLen);
    833         return BAD_VALUE;
    834     }
    835 
    836     CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p",
    837             portString(portIndex), portIndex, buffer,
    838             graphicBuffer == NULL ? NULL : graphicBuffer->handle);
    839     return OK;
    840 }
    841 
    842 status_t OMXNodeInstance::updateGraphicBufferInMeta(
    843         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
    844         OMX::buffer_id buffer) {
    845     Mutex::Autolock autoLock(mLock);
    846     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
    847     return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header);
    848 }
    849 
    850 status_t OMXNodeInstance::createGraphicBufferSource(
    851         OMX_U32 portIndex, sp<IGraphicBufferConsumer> bufferConsumer, MetadataBufferType *type) {
    852     status_t err;
    853 
    854     const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
    855     if (surfaceCheck != NULL) {
    856         if (portIndex < NELEM(mMetadataType) && type != NULL) {
    857             *type = mMetadataType[portIndex];
    858         }
    859         return ALREADY_EXISTS;
    860     }
    861 
    862     // Input buffers will hold meta-data (ANativeWindowBuffer references).
    863     err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, type);
    864     if (err != OK) {
    865         return err;
    866     }
    867 
    868     // Retrieve the width and height of the graphic buffer, set when the
    869     // codec was configured.
    870     OMX_PARAM_PORTDEFINITIONTYPE def;
    871     InitOMXParams(&def);
    872     def.nPortIndex = portIndex;
    873     OMX_ERRORTYPE oerr = OMX_GetParameter(
    874             mHandle, OMX_IndexParamPortDefinition, &def);
    875     if (oerr != OMX_ErrorNone) {
    876         OMX_INDEXTYPE index = OMX_IndexParamPortDefinition;
    877         CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u",
    878                 asString(index), index, portString(portIndex), portIndex);
    879         return UNKNOWN_ERROR;
    880     }
    881 
    882     if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
    883         CLOGW("createInputSurface requires COLOR_FormatSurface "
    884                 "(AndroidOpaque) color format instead of %s(%#x)",
    885                 asString(def.format.video.eColorFormat), def.format.video.eColorFormat);
    886         return INVALID_OPERATION;
    887     }
    888 
    889     uint32_t usageBits;
    890     oerr = OMX_GetParameter(
    891             mHandle, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &usageBits);
    892     if (oerr != OMX_ErrorNone) {
    893         usageBits = 0;
    894     }
    895 
    896     sp<GraphicBufferSource> bufferSource = new GraphicBufferSource(this,
    897             def.format.video.nFrameWidth,
    898             def.format.video.nFrameHeight,
    899             def.nBufferCountActual,
    900             usageBits,
    901             bufferConsumer);
    902 
    903     if ((err = bufferSource->initCheck()) != OK) {
    904         return err;
    905     }
    906     setGraphicBufferSource(bufferSource);
    907 
    908     return OK;
    909 }
    910 
    911 status_t OMXNodeInstance::createInputSurface(
    912         OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
    913     Mutex::Autolock autolock(mLock);
    914     status_t err = createGraphicBufferSource(portIndex, NULL /* bufferConsumer */, type);
    915 
    916     if (err != OK) {
    917         return err;
    918     }
    919 
    920     *bufferProducer = mGraphicBufferSource->getIGraphicBufferProducer();
    921     return OK;
    922 }
    923 
    924 //static
    925 status_t OMXNodeInstance::createPersistentInputSurface(
    926         sp<IGraphicBufferProducer> *bufferProducer,
    927         sp<IGraphicBufferConsumer> *bufferConsumer) {
    928     String8 name("GraphicBufferSource");
    929 
    930     sp<IGraphicBufferProducer> producer;
    931     sp<IGraphicBufferConsumer> consumer;
    932     BufferQueue::createBufferQueue(&producer, &consumer);
    933     consumer->setConsumerName(name);
    934     consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER);
    935 
    936     sp<BufferQueue::ProxyConsumerListener> proxy =
    937         new BufferQueue::ProxyConsumerListener(NULL);
    938     status_t err = consumer->consumerConnect(proxy, false);
    939     if (err != NO_ERROR) {
    940         ALOGE("Error connecting to BufferQueue: %s (%d)",
    941                 strerror(-err), err);
    942         return err;
    943     }
    944 
    945     *bufferProducer = producer;
    946     *bufferConsumer = consumer;
    947 
    948     return OK;
    949 }
    950 
    951 status_t OMXNodeInstance::setInputSurface(
    952         OMX_U32 portIndex, const sp<IGraphicBufferConsumer> &bufferConsumer,
    953         MetadataBufferType *type) {
    954     Mutex::Autolock autolock(mLock);
    955     return createGraphicBufferSource(portIndex, bufferConsumer, type);
    956 }
    957 
    958 status_t OMXNodeInstance::signalEndOfInputStream() {
    959     // For non-Surface input, the MediaCodec should convert the call to a
    960     // pair of requests (dequeue input buffer, queue input buffer with EOS
    961     // flag set).  Seems easier than doing the equivalent from here.
    962     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
    963     if (bufferSource == NULL) {
    964         CLOGW("signalEndOfInputStream can only be used with Surface input");
    965         return INVALID_OPERATION;
    966     }
    967     return bufferSource->signalEndOfInputStream();
    968 }
    969 
    970 status_t OMXNodeInstance::allocateBuffer(
    971         OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
    972         void **buffer_data) {
    973     Mutex::Autolock autoLock(mLock);
    974 
    975     BufferMeta *buffer_meta = new BufferMeta(size);
    976 
    977     OMX_BUFFERHEADERTYPE *header;
    978 
    979     OMX_ERRORTYPE err = OMX_AllocateBuffer(
    980             mHandle, &header, portIndex, buffer_meta, size);
    981 
    982     if (err != OMX_ErrorNone) {
    983         CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size));
    984         delete buffer_meta;
    985         buffer_meta = NULL;
    986 
    987         *buffer = 0;
    988 
    989         return StatusFromOMXError(err);
    990     }
    991 
    992     CHECK_EQ(header->pAppPrivate, buffer_meta);
    993 
    994     *buffer = makeBufferID(header);
    995     *buffer_data = header->pBuffer;
    996 
    997     addActiveBuffer(portIndex, *buffer);
    998 
    999     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
   1000     if (bufferSource != NULL && portIndex == kPortIndexInput) {
   1001         bufferSource->addCodecBuffer(header);
   1002     }
   1003     CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data));
   1004 
   1005     return OK;
   1006 }
   1007 
   1008 status_t OMXNodeInstance::allocateBufferWithBackup(
   1009         OMX_U32 portIndex, const sp<IMemory> &params,
   1010         OMX::buffer_id *buffer, OMX_U32 allottedSize) {
   1011     Mutex::Autolock autoLock(mLock);
   1012     if (allottedSize > params->size()) {
   1013         return BAD_VALUE;
   1014     }
   1015 
   1016     BufferMeta *buffer_meta = new BufferMeta(params, true);
   1017 
   1018     OMX_BUFFERHEADERTYPE *header;
   1019 
   1020     OMX_ERRORTYPE err = OMX_AllocateBuffer(
   1021             mHandle, &header, portIndex, buffer_meta, allottedSize);
   1022     if (err != OMX_ErrorNone) {
   1023         CLOG_ERROR(allocateBufferWithBackup, err,
   1024                 SIMPLE_BUFFER(portIndex, (size_t)allottedSize, params->pointer()));
   1025         delete buffer_meta;
   1026         buffer_meta = NULL;
   1027 
   1028         *buffer = 0;
   1029 
   1030         return StatusFromOMXError(err);
   1031     }
   1032 
   1033     CHECK_EQ(header->pAppPrivate, buffer_meta);
   1034 
   1035     *buffer = makeBufferID(header);
   1036 
   1037     addActiveBuffer(portIndex, *buffer);
   1038 
   1039     sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
   1040     if (bufferSource != NULL && portIndex == kPortIndexInput) {
   1041         bufferSource->addCodecBuffer(header);
   1042     }
   1043 
   1044     CLOG_BUFFER(allocateBufferWithBackup, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p :> %u@%p",
   1045             params->size(), params->pointer(), allottedSize, header->pBuffer));
   1046 
   1047     return OK;
   1048 }
   1049 
   1050 status_t OMXNodeInstance::freeBuffer(
   1051         OMX_U32 portIndex, OMX::buffer_id buffer) {
   1052     Mutex::Autolock autoLock(mLock);
   1053     CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer);
   1054 
   1055     removeActiveBuffer(portIndex, buffer);
   1056 
   1057     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
   1058     BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
   1059 
   1060     OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
   1061     CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer);
   1062 
   1063     delete buffer_meta;
   1064     buffer_meta = NULL;
   1065     invalidateBufferID(buffer);
   1066 
   1067     return StatusFromOMXError(err);
   1068 }
   1069 
   1070 status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) {
   1071     Mutex::Autolock autoLock(mLock);
   1072 
   1073     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
   1074     header->nFilledLen = 0;
   1075     header->nOffset = 0;
   1076     header->nFlags = 0;
   1077 
   1078     // meta now owns fenceFd
   1079     status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexOutput);
   1080     if (res != OK) {
   1081         CLOG_ERROR(fillBuffer::storeFenceInMeta, res, EMPTY_BUFFER(buffer, header, fenceFd));
   1082         return res;
   1083     }
   1084 
   1085     {
   1086         Mutex::Autolock _l(mDebugLock);
   1087         mOutputBuffersWithCodec.add(header);
   1088         CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header, fenceFd)));
   1089     }
   1090 
   1091     OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
   1092     if (err != OMX_ErrorNone) {
   1093         CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header, fenceFd));
   1094         Mutex::Autolock _l(mDebugLock);
   1095         mOutputBuffersWithCodec.remove(header);
   1096     }
   1097     return StatusFromOMXError(err);
   1098 }
   1099 
   1100 status_t OMXNodeInstance::emptyBuffer(
   1101         OMX::buffer_id buffer,
   1102         OMX_U32 rangeOffset, OMX_U32 rangeLength,
   1103         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1104     Mutex::Autolock autoLock(mLock);
   1105 
   1106     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
   1107     BufferMeta *buffer_meta =
   1108         static_cast<BufferMeta *>(header->pAppPrivate);
   1109     sp<ABuffer> backup = buffer_meta->getBuffer(header, true /* backup */, false /* limit */);
   1110     sp<ABuffer> codec = buffer_meta->getBuffer(header, false /* backup */, false /* limit */);
   1111 
   1112     // convert incoming ANW meta buffers if component is configured for gralloc metadata mode
   1113     // ignore rangeOffset in this case
   1114     if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource
   1115             && backup->capacity() >= sizeof(VideoNativeMetadata)
   1116             && codec->capacity() >= sizeof(VideoGrallocMetadata)
   1117             && ((VideoNativeMetadata *)backup->base())->eType
   1118                     == kMetadataBufferTypeANWBuffer) {
   1119         VideoNativeMetadata &backupMeta = *(VideoNativeMetadata *)backup->base();
   1120         VideoGrallocMetadata &codecMeta = *(VideoGrallocMetadata *)codec->base();
   1121         CLOG_BUFFER(emptyBuffer, "converting ANWB %p to handle %p",
   1122                 backupMeta.pBuffer, backupMeta.pBuffer->handle);
   1123         codecMeta.pHandle = backupMeta.pBuffer != NULL ? backupMeta.pBuffer->handle : NULL;
   1124         codecMeta.eType = kMetadataBufferTypeGrallocSource;
   1125         header->nFilledLen = rangeLength ? sizeof(codecMeta) : 0;
   1126         header->nOffset = 0;
   1127     } else {
   1128         // rangeLength and rangeOffset must be a subset of the allocated data in the buffer.
   1129         // corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0.
   1130         if (rangeOffset > header->nAllocLen
   1131                 || rangeLength > header->nAllocLen - rangeOffset) {
   1132             CLOG_ERROR(emptyBuffer, OMX_ErrorBadParameter, FULL_BUFFER(NULL, header, fenceFd));
   1133             if (fenceFd >= 0) {
   1134                 ::close(fenceFd);
   1135             }
   1136             return BAD_VALUE;
   1137         }
   1138         header->nFilledLen = rangeLength;
   1139         header->nOffset = rangeOffset;
   1140 
   1141         buffer_meta->CopyToOMX(header);
   1142     }
   1143 
   1144     return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer, fenceFd);
   1145 }
   1146 
   1147 // log queued buffer activity for the next few input and/or output frames
   1148 // if logging at internal state level
   1149 void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) {
   1150     if (DEBUG == ADebug::kDebugInternalState) {
   1151         DEBUG_BUMP = ADebug::kDebugAll;
   1152         if (numInputBuffers > 0) {
   1153             mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers;
   1154         }
   1155         if (numOutputBuffers > 0) {
   1156             mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers;
   1157         }
   1158     }
   1159 }
   1160 
   1161 void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) {
   1162     if (mDebugLevelBumpPendingBuffers[portIndex]) {
   1163         --mDebugLevelBumpPendingBuffers[portIndex];
   1164     }
   1165     if (!mDebugLevelBumpPendingBuffers[0]
   1166             && !mDebugLevelBumpPendingBuffers[1]) {
   1167         DEBUG_BUMP = DEBUG;
   1168     }
   1169 }
   1170 
   1171 status_t OMXNodeInstance::storeFenceInMeta_l(
   1172         OMX_BUFFERHEADERTYPE *header, int fenceFd, OMX_U32 portIndex) {
   1173     // propagate fence if component supports it; wait for it otherwise
   1174     OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nFilledLen : header->nAllocLen;
   1175     if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
   1176             && metaSize >= sizeof(VideoNativeMetadata)) {
   1177         VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
   1178         if (nativeMeta.nFenceFd >= 0) {
   1179             ALOGE("fence (%d) already exists in meta", nativeMeta.nFenceFd);
   1180             if (fenceFd >= 0) {
   1181                 ::close(fenceFd);
   1182             }
   1183             return ALREADY_EXISTS;
   1184         }
   1185         nativeMeta.nFenceFd = fenceFd;
   1186     } else if (fenceFd >= 0) {
   1187         CLOG_BUFFER(storeFenceInMeta, "waiting for fence %d", fenceFd);
   1188         sp<Fence> fence = new Fence(fenceFd);
   1189         return fence->wait(IOMX::kFenceTimeoutMs);
   1190     }
   1191     return OK;
   1192 }
   1193 
   1194 int OMXNodeInstance::retrieveFenceFromMeta_l(
   1195         OMX_BUFFERHEADERTYPE *header, OMX_U32 portIndex) {
   1196     OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nAllocLen : header->nFilledLen;
   1197     int fenceFd = -1;
   1198     if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
   1199             && header->nAllocLen >= sizeof(VideoNativeMetadata)) {
   1200         VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
   1201         if (nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
   1202             fenceFd = nativeMeta.nFenceFd;
   1203             nativeMeta.nFenceFd = -1;
   1204         }
   1205         if (metaSize < sizeof(nativeMeta) && fenceFd >= 0) {
   1206             CLOG_ERROR(foundFenceInEmptyMeta, BAD_VALUE, FULL_BUFFER(
   1207                     NULL, header, nativeMeta.nFenceFd));
   1208             fenceFd = -1;
   1209         }
   1210     }
   1211     return fenceFd;
   1212 }
   1213 
   1214 status_t OMXNodeInstance::emptyBuffer_l(
   1215         OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp,
   1216         intptr_t debugAddr, int fenceFd) {
   1217     header->nFlags = flags;
   1218     header->nTimeStamp = timestamp;
   1219 
   1220     status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexInput);
   1221     if (res != OK) {
   1222         CLOG_ERROR(emptyBuffer::storeFenceInMeta, res, WITH_STATS(
   1223                 FULL_BUFFER(debugAddr, header, fenceFd)));
   1224         return res;
   1225     }
   1226 
   1227     {
   1228         Mutex::Autolock _l(mDebugLock);
   1229         mInputBuffersWithCodec.add(header);
   1230 
   1231         // bump internal-state debug level for 2 input frames past a buffer with CSD
   1232         if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
   1233             bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */);
   1234         }
   1235 
   1236         CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header, fenceFd)));
   1237     }
   1238 
   1239     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
   1240     CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header, fenceFd));
   1241 
   1242     {
   1243         Mutex::Autolock _l(mDebugLock);
   1244         if (err != OMX_ErrorNone) {
   1245             mInputBuffersWithCodec.remove(header);
   1246         } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
   1247             unbumpDebugLevel_l(kPortIndexInput);
   1248         }
   1249     }
   1250 
   1251     return StatusFromOMXError(err);
   1252 }
   1253 
   1254 // like emptyBuffer, but the data is already in header->pBuffer
   1255 status_t OMXNodeInstance::emptyGraphicBuffer(
   1256         OMX_BUFFERHEADERTYPE *header, const sp<GraphicBuffer> &graphicBuffer,
   1257         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1258     Mutex::Autolock autoLock(mLock);
   1259     OMX::buffer_id buffer = findBufferID(header);
   1260     status_t err = updateGraphicBufferInMeta_l(kPortIndexInput, graphicBuffer, buffer, header);
   1261     if (err != OK) {
   1262         CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER(
   1263                 (intptr_t)header->pBuffer, header, fenceFd));
   1264         return err;
   1265     }
   1266 
   1267     header->nOffset = 0;
   1268     header->nFilledLen = graphicBuffer == NULL ? 0 : header->nAllocLen;
   1269     return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer, fenceFd);
   1270 }
   1271 
   1272 status_t OMXNodeInstance::getExtensionIndex(
   1273         const char *parameterName, OMX_INDEXTYPE *index) {
   1274     Mutex::Autolock autoLock(mLock);
   1275 
   1276     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
   1277             mHandle, const_cast<char *>(parameterName), index);
   1278 
   1279     return StatusFromOMXError(err);
   1280 }
   1281 
   1282 inline static const char *asString(IOMX::InternalOptionType i, const char *def = "??") {
   1283     switch (i) {
   1284         case IOMX::INTERNAL_OPTION_SUSPEND:           return "SUSPEND";
   1285         case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
   1286             return "REPEAT_PREVIOUS_FRAME_DELAY";
   1287         case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: return "MAX_TIMESTAMP_GAP";
   1288         case IOMX::INTERNAL_OPTION_MAX_FPS:           return "MAX_FPS";
   1289         case IOMX::INTERNAL_OPTION_START_TIME:        return "START_TIME";
   1290         case IOMX::INTERNAL_OPTION_TIME_LAPSE:        return "TIME_LAPSE";
   1291         default:                                      return def;
   1292     }
   1293 }
   1294 
   1295 status_t OMXNodeInstance::setInternalOption(
   1296         OMX_U32 portIndex,
   1297         IOMX::InternalOptionType type,
   1298         const void *data,
   1299         size_t size) {
   1300     CLOG_CONFIG(setInternalOption, "%s(%d): %s:%u %zu@%p",
   1301             asString(type), type, portString(portIndex), portIndex, size, data);
   1302     switch (type) {
   1303         case IOMX::INTERNAL_OPTION_SUSPEND:
   1304         case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
   1305         case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
   1306         case IOMX::INTERNAL_OPTION_MAX_FPS:
   1307         case IOMX::INTERNAL_OPTION_START_TIME:
   1308         case IOMX::INTERNAL_OPTION_TIME_LAPSE:
   1309         {
   1310             const sp<GraphicBufferSource> &bufferSource =
   1311                 getGraphicBufferSource();
   1312 
   1313             if (bufferSource == NULL || portIndex != kPortIndexInput) {
   1314                 CLOGW("setInternalOption is only for Surface input");
   1315                 return ERROR_UNSUPPORTED;
   1316             }
   1317 
   1318             if (type == IOMX::INTERNAL_OPTION_SUSPEND) {
   1319                 if (size != sizeof(bool)) {
   1320                     return INVALID_OPERATION;
   1321                 }
   1322 
   1323                 bool suspend = *(bool *)data;
   1324                 CLOG_CONFIG(setInternalOption, "suspend=%d", suspend);
   1325                 bufferSource->suspend(suspend);
   1326             } else if (type ==
   1327                     IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
   1328                 if (size != sizeof(int64_t)) {
   1329                     return INVALID_OPERATION;
   1330                 }
   1331 
   1332                 int64_t delayUs = *(int64_t *)data;
   1333                 CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs);
   1334                 return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
   1335             } else if (type ==
   1336                     IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){
   1337                 if (size != sizeof(int64_t)) {
   1338                     return INVALID_OPERATION;
   1339                 }
   1340 
   1341                 int64_t maxGapUs = *(int64_t *)data;
   1342                 CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs);
   1343                 return bufferSource->setMaxTimestampGapUs(maxGapUs);
   1344             } else if (type == IOMX::INTERNAL_OPTION_MAX_FPS) {
   1345                 if (size != sizeof(float)) {
   1346                     return INVALID_OPERATION;
   1347                 }
   1348 
   1349                 float maxFps = *(float *)data;
   1350                 CLOG_CONFIG(setInternalOption, "maxFps=%f", maxFps);
   1351                 return bufferSource->setMaxFps(maxFps);
   1352             } else if (type == IOMX::INTERNAL_OPTION_START_TIME) {
   1353                 if (size != sizeof(int64_t)) {
   1354                     return INVALID_OPERATION;
   1355                 }
   1356 
   1357                 int64_t skipFramesBeforeUs = *(int64_t *)data;
   1358                 CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs);
   1359                 bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);
   1360             } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE
   1361                 if (size != sizeof(int64_t) * 2) {
   1362                     return INVALID_OPERATION;
   1363                 }
   1364 
   1365                 int64_t timePerFrameUs = ((int64_t *)data)[0];
   1366                 int64_t timePerCaptureUs = ((int64_t *)data)[1];
   1367                 CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld",
   1368                         (long long)timePerFrameUs, (long long)timePerCaptureUs);
   1369 
   1370                 bufferSource->setTimeLapseUs((int64_t *)data);
   1371             }
   1372 
   1373             return OK;
   1374         }
   1375 
   1376         default:
   1377             return ERROR_UNSUPPORTED;
   1378     }
   1379 }
   1380 
   1381 bool OMXNodeInstance::handleMessage(omx_message &msg) {
   1382     const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
   1383 
   1384     if (msg.type == omx_message::FILL_BUFFER_DONE) {
   1385         OMX_BUFFERHEADERTYPE *buffer =
   1386             findBufferHeader(msg.u.extended_buffer_data.buffer);
   1387 
   1388         {
   1389             Mutex::Autolock _l(mDebugLock);
   1390             mOutputBuffersWithCodec.remove(buffer);
   1391 
   1392             CLOG_BUMPED_BUFFER(
   1393                     FBD, WITH_STATS(FULL_BUFFER(
   1394                             msg.u.extended_buffer_data.buffer, buffer, msg.fenceFd)));
   1395 
   1396             unbumpDebugLevel_l(kPortIndexOutput);
   1397         }
   1398 
   1399         BufferMeta *buffer_meta =
   1400             static_cast<BufferMeta *>(buffer->pAppPrivate);
   1401 
   1402         if (buffer->nOffset + buffer->nFilledLen < buffer->nOffset
   1403                 || buffer->nOffset + buffer->nFilledLen > buffer->nAllocLen) {
   1404             CLOG_ERROR(onFillBufferDone, OMX_ErrorBadParameter,
   1405                     FULL_BUFFER(NULL, buffer, msg.fenceFd));
   1406         }
   1407         buffer_meta->CopyFromOMX(buffer);
   1408 
   1409         if (bufferSource != NULL) {
   1410             // fix up the buffer info (especially timestamp) if needed
   1411             bufferSource->codecBufferFilled(buffer);
   1412 
   1413             msg.u.extended_buffer_data.timestamp = buffer->nTimeStamp;
   1414         }
   1415     } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
   1416         OMX_BUFFERHEADERTYPE *buffer =
   1417             findBufferHeader(msg.u.buffer_data.buffer);
   1418 
   1419         {
   1420             Mutex::Autolock _l(mDebugLock);
   1421             mInputBuffersWithCodec.remove(buffer);
   1422 
   1423             CLOG_BUMPED_BUFFER(
   1424                     EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer, msg.fenceFd)));
   1425         }
   1426 
   1427         if (bufferSource != NULL) {
   1428             // This is one of the buffers used exclusively by
   1429             // GraphicBufferSource.
   1430             // Don't dispatch a message back to ACodec, since it doesn't
   1431             // know that anyone asked to have the buffer emptied and will
   1432             // be very confused.
   1433             bufferSource->codecBufferEmptied(buffer, msg.fenceFd);
   1434             return true;
   1435         }
   1436     }
   1437 
   1438     return false;
   1439 }
   1440 
   1441 void OMXNodeInstance::onMessages(std::list<omx_message> &messages) {
   1442     for (std::list<omx_message>::iterator it = messages.begin(); it != messages.end(); ) {
   1443         if (handleMessage(*it)) {
   1444             messages.erase(it++);
   1445         } else {
   1446             ++it;
   1447         }
   1448     }
   1449 
   1450     if (!messages.empty()) {
   1451         mObserver->onMessages(messages);
   1452     }
   1453 }
   1454 
   1455 void OMXNodeInstance::onObserverDied(OMXMaster *master) {
   1456     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
   1457 
   1458     // Try to force shutdown of the node and hope for the best.
   1459     freeNode(master);
   1460 }
   1461 
   1462 void OMXNodeInstance::onGetHandleFailed() {
   1463     delete this;
   1464 }
   1465 
   1466 // OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
   1467 // Don't try to acquire mLock here -- in rare circumstances this will hang.
   1468 void OMXNodeInstance::onEvent(
   1469         OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
   1470     const char *arg1String = "??";
   1471     const char *arg2String = "??";
   1472     ADebug::Level level = ADebug::kDebugInternalState;
   1473 
   1474     switch (event) {
   1475         case OMX_EventCmdComplete:
   1476             arg1String = asString((OMX_COMMANDTYPE)arg1);
   1477             switch (arg1) {
   1478                 case OMX_CommandStateSet:
   1479                     arg2String = asString((OMX_STATETYPE)arg2);
   1480                     level = ADebug::kDebugState;
   1481                     break;
   1482                 case OMX_CommandFlush:
   1483                 case OMX_CommandPortEnable:
   1484                 {
   1485                     // bump internal-state debug level for 2 input and output frames
   1486                     Mutex::Autolock _l(mDebugLock);
   1487                     bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */);
   1488                 }
   1489                 // fall through
   1490                 default:
   1491                     arg2String = portString(arg2);
   1492             }
   1493             break;
   1494         case OMX_EventError:
   1495             arg1String = asString((OMX_ERRORTYPE)arg1);
   1496             level = ADebug::kDebugLifeCycle;
   1497             break;
   1498         case OMX_EventPortSettingsChanged:
   1499             arg2String = asString((OMX_INDEXEXTTYPE)arg2);
   1500             // fall through
   1501         default:
   1502             arg1String = portString(arg1);
   1503     }
   1504 
   1505     CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)",
   1506             asString(event), event, arg1String, arg1, arg2String, arg2);
   1507     const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
   1508 
   1509     if (bufferSource != NULL
   1510             && event == OMX_EventCmdComplete
   1511             && arg1 == OMX_CommandStateSet
   1512             && arg2 == OMX_StateExecuting) {
   1513         bufferSource->omxExecuting();
   1514     }
   1515 }
   1516 
   1517 // static
   1518 OMX_ERRORTYPE OMXNodeInstance::OnEvent(
   1519         OMX_IN OMX_HANDLETYPE /* hComponent */,
   1520         OMX_IN OMX_PTR pAppData,
   1521         OMX_IN OMX_EVENTTYPE eEvent,
   1522         OMX_IN OMX_U32 nData1,
   1523         OMX_IN OMX_U32 nData2,
   1524         OMX_IN OMX_PTR pEventData) {
   1525     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   1526     if (instance->mDying) {
   1527         return OMX_ErrorNone;
   1528     }
   1529     return instance->owner()->OnEvent(
   1530             instance->nodeID(), eEvent, nData1, nData2, pEventData);
   1531 }
   1532 
   1533 // static
   1534 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
   1535         OMX_IN OMX_HANDLETYPE /* hComponent */,
   1536         OMX_IN OMX_PTR pAppData,
   1537         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
   1538     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   1539     if (instance->mDying) {
   1540         return OMX_ErrorNone;
   1541     }
   1542     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
   1543     return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
   1544             instance->findBufferID(pBuffer), pBuffer, fenceFd);
   1545 }
   1546 
   1547 // static
   1548 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
   1549         OMX_IN OMX_HANDLETYPE /* hComponent */,
   1550         OMX_IN OMX_PTR pAppData,
   1551         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
   1552     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   1553     if (instance->mDying) {
   1554         return OMX_ErrorNone;
   1555     }
   1556     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
   1557     return instance->owner()->OnFillBufferDone(instance->nodeID(),
   1558             instance->findBufferID(pBuffer), pBuffer, fenceFd);
   1559 }
   1560 
   1561 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
   1562     ActiveBuffer active;
   1563     active.mPortIndex = portIndex;
   1564     active.mID = id;
   1565     mActiveBuffers.push(active);
   1566 
   1567     if (portIndex < NELEM(mNumPortBuffers)) {
   1568         ++mNumPortBuffers[portIndex];
   1569     }
   1570 }
   1571 
   1572 void OMXNodeInstance::removeActiveBuffer(
   1573         OMX_U32 portIndex, OMX::buffer_id id) {
   1574     for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
   1575         if (mActiveBuffers[i].mPortIndex == portIndex
   1576                 && mActiveBuffers[i].mID == id) {
   1577             mActiveBuffers.removeItemsAt(i);
   1578 
   1579             if (portIndex < NELEM(mNumPortBuffers)) {
   1580                 --mNumPortBuffers[portIndex];
   1581             }
   1582             return;
   1583         }
   1584     }
   1585 
   1586      CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id);
   1587 }
   1588 
   1589 void OMXNodeInstance::freeActiveBuffers() {
   1590     // Make sure to count down here, as freeBuffer will in turn remove
   1591     // the active buffer from the vector...
   1592     for (size_t i = mActiveBuffers.size(); i--;) {
   1593         freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
   1594     }
   1595 }
   1596 
   1597 OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
   1598     if (bufferHeader == NULL) {
   1599         return 0;
   1600     }
   1601     Mutex::Autolock autoLock(mBufferIDLock);
   1602     OMX::buffer_id buffer;
   1603     do { // handle the very unlikely case of ID overflow
   1604         if (++mBufferIDCount == 0) {
   1605             ++mBufferIDCount;
   1606         }
   1607         buffer = (OMX::buffer_id)mBufferIDCount;
   1608     } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
   1609     mBufferIDToBufferHeader.add(buffer, bufferHeader);
   1610     mBufferHeaderToBufferID.add(bufferHeader, buffer);
   1611     return buffer;
   1612 }
   1613 
   1614 OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
   1615     if (buffer == 0) {
   1616         return NULL;
   1617     }
   1618     Mutex::Autolock autoLock(mBufferIDLock);
   1619     ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
   1620     if (index < 0) {
   1621         CLOGW("findBufferHeader: buffer %u not found", buffer);
   1622         return NULL;
   1623     }
   1624     return mBufferIDToBufferHeader.valueAt(index);
   1625 }
   1626 
   1627 OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
   1628     if (bufferHeader == NULL) {
   1629         return 0;
   1630     }
   1631     Mutex::Autolock autoLock(mBufferIDLock);
   1632     ssize_t index = mBufferHeaderToBufferID.indexOfKey(bufferHeader);
   1633     if (index < 0) {
   1634         CLOGW("findBufferID: bufferHeader %p not found", bufferHeader);
   1635         return 0;
   1636     }
   1637     return mBufferHeaderToBufferID.valueAt(index);
   1638 }
   1639 
   1640 void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
   1641     if (buffer == 0) {
   1642         return;
   1643     }
   1644     Mutex::Autolock autoLock(mBufferIDLock);
   1645     ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
   1646     if (index < 0) {
   1647         CLOGW("invalidateBufferID: buffer %u not found", buffer);
   1648         return;
   1649     }
   1650     mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueAt(index));
   1651     mBufferIDToBufferHeader.removeItemsAt(index);
   1652 }
   1653 
   1654 }  // namespace android
   1655