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