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 <media/stagefright/omx/OMXNodeInstance.h>
     24 #include <media/stagefright/omx/OMXMaster.h>
     25 #include <media/stagefright/omx/OMXUtils.h>
     26 #include <android/IOMXBufferSource.h>
     27 
     28 #include <media/openmax/OMX_Component.h>
     29 #include <media/openmax/OMX_IndexExt.h>
     30 #include <media/openmax/OMX_VideoExt.h>
     31 #include <media/openmax/OMX_AsString.h>
     32 
     33 #include <binder/IMemory.h>
     34 #include <cutils/properties.h>
     35 #include <gui/BufferQueue.h>
     36 #include <media/hardware/HardwareAPI.h>
     37 #include <media/stagefright/foundation/ADebug.h>
     38 #include <media/stagefright/foundation/ABuffer.h>
     39 #include <media/stagefright/foundation/ColorUtils.h>
     40 #include <media/stagefright/MediaErrors.h>
     41 #include <utils/misc.h>
     42 #include <utils/NativeHandle.h>
     43 #include <media/OMXBuffer.h>
     44 #include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
     45 
     46 #include <hidlmemory/mapping.h>
     47 
     48 static const OMX_U32 kPortIndexInput = 0;
     49 static const OMX_U32 kPortIndexOutput = 1;
     50 
     51 #define CLOGW(fmt, ...) ALOGW("[%p:%s] " fmt, mHandle, mName, ##__VA_ARGS__)
     52 
     53 #define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \
     54     ALOGE_IF(cond, #fn "(%p:%s, " fmt ") ERROR: %s(%#x)", \
     55     mHandle, mName, ##__VA_ARGS__, asString(err), err)
     56 #define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__)
     57 #define CLOG_IF_ERROR(fn, err, fmt, ...) \
     58     CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__)
     59 
     60 #define CLOGI_(level, fn, fmt, ...) \
     61     ALOGI_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
     62 #define CLOGD_(level, fn, fmt, ...) \
     63     ALOGD_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
     64 
     65 #define CLOG_LIFE(fn, fmt, ...)     CLOGI_(ADebug::kDebugLifeCycle,     fn, fmt, ##__VA_ARGS__)
     66 #define CLOG_STATE(fn, fmt, ...)    CLOGI_(ADebug::kDebugState,         fn, fmt, ##__VA_ARGS__)
     67 #define CLOG_CONFIG(fn, fmt, ...)   CLOGI_(ADebug::kDebugConfig,        fn, fmt, ##__VA_ARGS__)
     68 #define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__)
     69 
     70 #define CLOG_DEBUG_IF(cond, fn, fmt, ...) \
     71     ALOGD_IF(cond, #fn "(%p, " fmt ")", mHandle, ##__VA_ARGS__)
     72 
     73 #define CLOG_BUFFER(fn, fmt, ...) \
     74     CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__)
     75 #define CLOG_BUMPED_BUFFER(fn, fmt, ...) \
     76     CLOG_DEBUG_IF(DEBUG_BUMP >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__)
     77 
     78 /* buffer formatting */
     79 #define BUFFER_FMT(port, fmt, ...) "%s:%u " fmt, portString(port), (port), ##__VA_ARGS__
     80 #define NEW_BUFFER_FMT(buffer_id, port, fmt, ...) \
     81     BUFFER_FMT(port, fmt ") (#%zu => %#x", ##__VA_ARGS__, mActiveBuffers.size(), (buffer_id))
     82 
     83 #define SIMPLE_BUFFER(port, size, data) BUFFER_FMT(port, "%zu@%p", (size), (data))
     84 #define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \
     85     NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data))
     86 
     87 #define EMPTY_BUFFER(addr, header, fenceFd) "%#x [%u@%p fc=%d]", \
     88     (addr), (header)->nAllocLen, (header)->pBuffer, (fenceFd)
     89 #define FULL_BUFFER(addr, header, fenceFd) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld fc=%d]", \
     90     (intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \
     91     (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp, (fenceFd)
     92 
     93 #define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \
     94     mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \
     95     mOutputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexOutput]
     96 // TRICKY: this is needed so formatting macros expand before substitution
     97 #define WITH_STATS(fmt, ...) WITH_STATS_WRAPPER(fmt, ##__VA_ARGS__)
     98 
     99 namespace android {
    100 
    101 struct BufferMeta {
    102     explicit BufferMeta(
    103             const sp<IMemory> &mem, const sp<IHidlMemory> &hidlMemory,
    104             OMX_U32 portIndex, bool copy, OMX_U8 *backup)
    105         : mMem(mem),
    106           mHidlMemory(hidlMemory),
    107           mCopyFromOmx(portIndex == kPortIndexOutput && copy),
    108           mCopyToOmx(portIndex == kPortIndexInput && copy),
    109           mPortIndex(portIndex),
    110           mBackup(backup) {
    111     }
    112 
    113     explicit BufferMeta(OMX_U32 portIndex)
    114         : mCopyFromOmx(false),
    115           mCopyToOmx(false),
    116           mPortIndex(portIndex),
    117           mBackup(NULL) {
    118     }
    119 
    120     explicit BufferMeta(const sp<GraphicBuffer> &graphicBuffer, OMX_U32 portIndex)
    121         : mGraphicBuffer(graphicBuffer),
    122           mCopyFromOmx(false),
    123           mCopyToOmx(false),
    124           mPortIndex(portIndex),
    125           mBackup(NULL) {
    126     }
    127 
    128     OMX_U8 *getPointer() {
    129         return mMem.get() ? static_cast<OMX_U8*>(mMem->pointer()) :
    130                 mHidlMemory.get() ? static_cast<OMX_U8*>(
    131                 static_cast<void*>(mHidlMemory->getPointer())) : nullptr;
    132     }
    133 
    134     void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
    135         if (!mCopyFromOmx) {
    136             return;
    137         }
    138 
    139         // check component returns proper range
    140         sp<ABuffer> codec = getBuffer(header, true /* limit */);
    141 
    142         memcpy(getPointer() + header->nOffset, codec->data(), codec->size());
    143     }
    144 
    145     void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
    146         if (!mCopyToOmx) {
    147             return;
    148         }
    149 
    150         memcpy(header->pBuffer + header->nOffset,
    151                 getPointer() + header->nOffset,
    152                 header->nFilledLen);
    153     }
    154 
    155     // return the codec buffer
    156     sp<ABuffer> getBuffer(const OMX_BUFFERHEADERTYPE *header, bool limit) {
    157         sp<ABuffer> buf = new ABuffer(header->pBuffer, header->nAllocLen);
    158         if (limit) {
    159             if (header->nOffset + header->nFilledLen > header->nOffset
    160                     && header->nOffset + header->nFilledLen <= header->nAllocLen) {
    161                 buf->setRange(header->nOffset, header->nFilledLen);
    162             } else {
    163                 buf->setRange(0, 0);
    164             }
    165         }
    166         return buf;
    167     }
    168 
    169     void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) {
    170         mGraphicBuffer = graphicBuffer;
    171     }
    172 
    173     void setNativeHandle(const sp<NativeHandle> &nativeHandle) {
    174         mNativeHandle = nativeHandle;
    175     }
    176 
    177     OMX_U32 getPortIndex() {
    178         return mPortIndex;
    179     }
    180 
    181     ~BufferMeta() {
    182         delete[] mBackup;
    183     }
    184 
    185 private:
    186     sp<GraphicBuffer> mGraphicBuffer;
    187     sp<NativeHandle> mNativeHandle;
    188     sp<IMemory> mMem;
    189     sp<IHidlMemory> mHidlMemory;
    190     bool mCopyFromOmx;
    191     bool mCopyToOmx;
    192     OMX_U32 mPortIndex;
    193     OMX_U8 *mBackup;
    194 
    195     BufferMeta(const BufferMeta &);
    196     BufferMeta &operator=(const BufferMeta &);
    197 };
    198 
    199 // static
    200 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
    201     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
    202 };
    203 
    204 static inline const char *portString(OMX_U32 portIndex) {
    205     switch (portIndex) {
    206         case kPortIndexInput:  return "Input";
    207         case kPortIndexOutput: return "Output";
    208         case ~0U:              return "All";
    209         default:               return "port";
    210     }
    211 }
    212 
    213 ////////////////////////////////////////////////////////////////////////////////
    214 
    215 // This provides the underlying Thread used by CallbackDispatcher.
    216 // Note that deriving CallbackDispatcher from Thread does not work.
    217 
    218 struct OMXNodeInstance::CallbackDispatcherThread : public Thread {
    219     explicit CallbackDispatcherThread(CallbackDispatcher *dispatcher)
    220         : mDispatcher(dispatcher) {
    221     }
    222 
    223 private:
    224     CallbackDispatcher *mDispatcher;
    225 
    226     bool threadLoop();
    227 
    228     CallbackDispatcherThread(const CallbackDispatcherThread &);
    229     CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
    230 };
    231 
    232 ////////////////////////////////////////////////////////////////////////////////
    233 
    234 struct OMXNodeInstance::CallbackDispatcher : public RefBase {
    235     explicit CallbackDispatcher(const sp<OMXNodeInstance> &owner);
    236 
    237     // Posts |msg| to the listener's queue. If |realTime| is true, the listener thread is notified
    238     // that a new message is available on the queue. Otherwise, the message stays on the queue, but
    239     // the listener is not notified of it. It will process this message when a subsequent message
    240     // is posted with |realTime| set to true.
    241     void post(const omx_message &msg, bool realTime = true);
    242 
    243     bool loop();
    244 
    245 protected:
    246     virtual ~CallbackDispatcher();
    247 
    248 private:
    249     enum {
    250         // This is used for frame_rendered message batching, which will eventually end up in a
    251         // single AMessage in MediaCodec when it is signaled to the app. AMessage can contain
    252         // up-to 64 key-value pairs, and each frame_rendered message uses 2 keys, so the max
    253         // value for this would be 32. Nonetheless, limit this to 12 to which gives at least 10
    254         // mseconds of batching at 120Hz.
    255         kMaxQueueSize = 12,
    256     };
    257 
    258     Mutex mLock;
    259 
    260     sp<OMXNodeInstance> const mOwner;
    261     bool mDone;
    262     Condition mQueueChanged;
    263     std::list<omx_message> mQueue;
    264 
    265     sp<CallbackDispatcherThread> mThread;
    266 
    267     void dispatch(std::list<omx_message> &messages);
    268 
    269     CallbackDispatcher(const CallbackDispatcher &);
    270     CallbackDispatcher &operator=(const CallbackDispatcher &);
    271 };
    272 
    273 OMXNodeInstance::CallbackDispatcher::CallbackDispatcher(const sp<OMXNodeInstance> &owner)
    274     : mOwner(owner),
    275       mDone(false) {
    276     mThread = new CallbackDispatcherThread(this);
    277     mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_FOREGROUND);
    278 }
    279 
    280 OMXNodeInstance::CallbackDispatcher::~CallbackDispatcher() {
    281     {
    282         Mutex::Autolock autoLock(mLock);
    283 
    284         mDone = true;
    285         mQueueChanged.signal();
    286     }
    287 
    288     // A join on self can happen if the last ref to CallbackDispatcher
    289     // is released within the CallbackDispatcherThread loop
    290     status_t status = mThread->join();
    291     if (status != WOULD_BLOCK) {
    292         // Other than join to self, the only other error return codes are
    293         // whatever readyToRun() returns, and we don't override that
    294         CHECK_EQ(status, (status_t)NO_ERROR);
    295     }
    296 }
    297 
    298 void OMXNodeInstance::CallbackDispatcher::post(const omx_message &msg, bool realTime) {
    299     Mutex::Autolock autoLock(mLock);
    300 
    301     mQueue.push_back(msg);
    302     if (realTime || mQueue.size() >= kMaxQueueSize) {
    303         mQueueChanged.signal();
    304     }
    305 }
    306 
    307 void OMXNodeInstance::CallbackDispatcher::dispatch(std::list<omx_message> &messages) {
    308     if (mOwner == NULL) {
    309         ALOGV("Would have dispatched a message to a node that's already gone.");
    310         return;
    311     }
    312     mOwner->onMessages(messages);
    313 }
    314 
    315 bool OMXNodeInstance::CallbackDispatcher::loop() {
    316     for (;;) {
    317         std::list<omx_message> messages;
    318 
    319         {
    320             Mutex::Autolock autoLock(mLock);
    321             while (!mDone && mQueue.empty()) {
    322                 mQueueChanged.wait(mLock);
    323             }
    324 
    325             if (mDone) {
    326                 break;
    327             }
    328 
    329             messages.swap(mQueue);
    330         }
    331 
    332         dispatch(messages);
    333     }
    334 
    335     return false;
    336 }
    337 
    338 ////////////////////////////////////////////////////////////////////////////////
    339 
    340 bool OMXNodeInstance::CallbackDispatcherThread::threadLoop() {
    341     return mDispatcher->loop();
    342 }
    343 
    344 ////////////////////////////////////////////////////////////////////////////////
    345 
    346 OMXNodeInstance::OMXNodeInstance(
    347         OmxNodeOwner *owner, const sp<IOMXObserver> &observer, const char *name)
    348     : mOwner(owner),
    349       mHandle(NULL),
    350       mObserver(observer),
    351       mDying(false),
    352       mSailed(false),
    353       mQueriedProhibitedExtensions(false),
    354       mQuirks(0),
    355       mBufferIDCount(0),
    356       mRestorePtsFailed(false),
    357       mMaxTimestampGapUs(-1ll),
    358       mPrevOriginalTimeUs(-1ll),
    359       mPrevModifiedTimeUs(-1ll)
    360 {
    361     mName = ADebug::GetDebugName(name);
    362     DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
    363     ALOGV("debug level for %s is %d", name, DEBUG);
    364     DEBUG_BUMP = DEBUG;
    365     mNumPortBuffers[0] = 0;
    366     mNumPortBuffers[1] = 0;
    367     mDebugLevelBumpPendingBuffers[0] = 0;
    368     mDebugLevelBumpPendingBuffers[1] = 0;
    369     mMetadataType[0] = kMetadataBufferTypeInvalid;
    370     mMetadataType[1] = kMetadataBufferTypeInvalid;
    371     mPortMode[0] = IOMX::kPortModePresetByteBuffer;
    372     mPortMode[1] = IOMX::kPortModePresetByteBuffer;
    373     mSecureBufferType[0] = kSecureBufferTypeUnknown;
    374     mSecureBufferType[1] = kSecureBufferTypeUnknown;
    375     mGraphicBufferEnabled[0] = false;
    376     mGraphicBufferEnabled[1] = false;
    377     mIsSecure = AString(name).endsWith(".secure");
    378     mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled("legacy-adaptive");
    379 }
    380 
    381 OMXNodeInstance::~OMXNodeInstance() {
    382     free(mName);
    383     CHECK(mHandle == NULL);
    384 }
    385 
    386 void OMXNodeInstance::setHandle(OMX_HANDLETYPE handle) {
    387     CLOG_LIFE(allocateNode, "handle=%p", handle);
    388     CHECK(mHandle == NULL);
    389     mHandle = handle;
    390     if (handle != NULL) {
    391         mDispatcher = new CallbackDispatcher(this);
    392     }
    393 }
    394 
    395 sp<IOMXBufferSource> OMXNodeInstance::getBufferSource() {
    396     Mutex::Autolock autoLock(mOMXBufferSourceLock);
    397     return mOMXBufferSource;
    398 }
    399 
    400 void OMXNodeInstance::setBufferSource(const sp<IOMXBufferSource>& bufferSource) {
    401     Mutex::Autolock autoLock(mOMXBufferSourceLock);
    402     CLOG_INTERNAL(setBufferSource, "%p", bufferSource.get());
    403     mOMXBufferSource = bufferSource;
    404 }
    405 
    406 OMX_HANDLETYPE OMXNodeInstance::handle() {
    407     return mHandle;
    408 }
    409 
    410 sp<IOMXObserver> OMXNodeInstance::observer() {
    411     return mObserver;
    412 }
    413 
    414 status_t OMXNodeInstance::freeNode() {
    415     CLOG_LIFE(freeNode, "handle=%p", mHandle);
    416     static int32_t kMaxNumIterations = 10;
    417 
    418     // Transition the node from its current state all the way down
    419     // to "Loaded".
    420     // This ensures that all active buffers are properly freed even
    421     // for components that don't do this themselves on a call to
    422     // "FreeHandle".
    423 
    424     // The code below may trigger some more events to be dispatched
    425     // by the OMX component - we want to ignore them as our client
    426     // does not expect them.
    427     bool expected = false;
    428     if (!mDying.compare_exchange_strong(expected, true)) {
    429         // exit if we have already freed the node or doing so right now.
    430         // NOTE: this ensures that the block below executes at most once.
    431         ALOGV("Already dying");
    432         return OK;
    433     }
    434 
    435     OMX_STATETYPE state;
    436     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
    437     switch (state) {
    438         case OMX_StateExecuting:
    439         {
    440             ALOGV("forcing Executing->Idle");
    441             sendCommand(OMX_CommandStateSet, OMX_StateIdle);
    442             OMX_ERRORTYPE err;
    443             int32_t iteration = 0;
    444             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    445                     && state != OMX_StateIdle
    446                     && state != OMX_StateInvalid) {
    447                 if (++iteration > kMaxNumIterations) {
    448                     CLOGW("failed to enter Idle state (now %s(%d), aborting.",
    449                             asString(state), state);
    450                     state = OMX_StateInvalid;
    451                     break;
    452                 }
    453 
    454                 usleep(100000);
    455             }
    456             CHECK_EQ(err, OMX_ErrorNone);
    457 
    458             if (state == OMX_StateInvalid) {
    459                 break;
    460             }
    461 
    462             // fall through
    463         }
    464 
    465         case OMX_StateIdle:
    466         {
    467             ALOGV("forcing Idle->Loaded");
    468             sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
    469 
    470             freeActiveBuffers();
    471 
    472             OMX_ERRORTYPE err;
    473             int32_t iteration = 0;
    474             while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
    475                     && state != OMX_StateLoaded
    476                     && state != OMX_StateInvalid) {
    477                 if (++iteration > kMaxNumIterations) {
    478                     CLOGW("failed to enter Loaded state (now %s(%d), aborting.",
    479                             asString(state), state);
    480                     state = OMX_StateInvalid;
    481                     break;
    482                 }
    483 
    484                 ALOGV("waiting for Loaded state...");
    485                 usleep(100000);
    486             }
    487             CHECK_EQ(err, OMX_ErrorNone);
    488 
    489             // fall through
    490         }
    491 
    492         case OMX_StateLoaded:
    493         case OMX_StateInvalid:
    494             break;
    495 
    496         default:
    497             LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state);
    498             break;
    499     }
    500 
    501     Mutex::Autolock _l(mLock);
    502 
    503     status_t err = mOwner->freeNode(this);
    504 
    505     mDispatcher.clear();
    506     mOMXBufferSource.clear();
    507 
    508     mHandle = NULL;
    509     CLOG_IF_ERROR(freeNode, err, "");
    510     free(mName);
    511     mName = NULL;
    512 
    513     ALOGV("OMXNodeInstance going away.");
    514 
    515     return err;
    516 }
    517 
    518 status_t OMXNodeInstance::sendCommand(
    519         OMX_COMMANDTYPE cmd, OMX_S32 param) {
    520     const sp<IOMXBufferSource> bufferSource(getBufferSource());
    521     if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
    522         if (param == OMX_StateIdle) {
    523             // Initiating transition from Executing -> Idle
    524             // ACodec is waiting for all buffers to be returned, do NOT
    525             // submit any more buffers to the codec.
    526             bufferSource->onOmxIdle();
    527         } else if (param == OMX_StateLoaded) {
    528             // Initiating transition from Idle/Executing -> Loaded
    529             // Buffers are about to be freed.
    530             bufferSource->onOmxLoaded();
    531             setBufferSource(NULL);
    532         }
    533 
    534         // fall through
    535     }
    536 
    537     Mutex::Autolock autoLock(mLock);
    538 
    539     if (cmd == OMX_CommandStateSet) {
    540         // There are no configurations past first StateSet command.
    541         mSailed = true;
    542     }
    543 
    544     // bump internal-state debug level for 2 input and output frames past a command
    545     {
    546         Mutex::Autolock _l(mDebugLock);
    547         bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */);
    548     }
    549 
    550     const char *paramString =
    551         cmd == OMX_CommandStateSet ? asString((OMX_STATETYPE)param) : portString(param);
    552     CLOG_STATE(sendCommand, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);
    553     OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
    554     CLOG_IF_ERROR(sendCommand, err, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);
    555     return StatusFromOMXError(err);
    556 }
    557 
    558 bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) {
    559     // these extensions can only be used from OMXNodeInstance, not by clients directly.
    560     static const char *restricted_extensions[] = {
    561         "OMX.google.android.index.storeMetaDataInBuffers",
    562         "OMX.google.android.index.storeANWBufferInMetadata",
    563         "OMX.google.android.index.prepareForAdaptivePlayback",
    564         "OMX.google.android.index.configureVideoTunnelMode",
    565         "OMX.google.android.index.useAndroidNativeBuffer2",
    566         "OMX.google.android.index.useAndroidNativeBuffer",
    567         "OMX.google.android.index.enableAndroidNativeBuffers",
    568         "OMX.google.android.index.allocateNativeHandle",
    569         "OMX.google.android.index.getAndroidNativeBufferUsage",
    570     };
    571 
    572     if ((index > OMX_IndexComponentStartUnused && index < OMX_IndexComponentEndUnused)
    573             || (index > OMX_IndexPortStartUnused && index < OMX_IndexPortEndUnused)
    574             || (index > OMX_IndexAudioStartUnused && index < OMX_IndexAudioEndUnused)
    575             || (index > OMX_IndexVideoStartUnused && index < OMX_IndexVideoEndUnused)
    576             || (index > OMX_IndexCommonStartUnused && index < OMX_IndexCommonEndUnused)
    577             || (index > (OMX_INDEXTYPE)OMX_IndexExtAudioStartUnused
    578                     && index < (OMX_INDEXTYPE)OMX_IndexExtAudioEndUnused)
    579             || (index > (OMX_INDEXTYPE)OMX_IndexExtVideoStartUnused
    580                     && index < (OMX_INDEXTYPE)OMX_IndexExtVideoEndUnused)
    581             || (index > (OMX_INDEXTYPE)OMX_IndexExtOtherStartUnused
    582                     && index < (OMX_INDEXTYPE)OMX_IndexExtOtherEndUnused)) {
    583         return false;
    584     }
    585 
    586     if (!mQueriedProhibitedExtensions) {
    587         for (size_t i = 0; i < NELEM(restricted_extensions); ++i) {
    588             OMX_INDEXTYPE ext;
    589             if (OMX_GetExtensionIndex(mHandle, (OMX_STRING)restricted_extensions[i], &ext) == OMX_ErrorNone) {
    590                 mProhibitedExtensions.add(ext);
    591             }
    592         }
    593         mQueriedProhibitedExtensions = true;
    594     }
    595 
    596     return mProhibitedExtensions.indexOf(index) >= 0;
    597 }
    598 
    599 status_t OMXNodeInstance::getParameter(
    600         OMX_INDEXTYPE index, void *params, size_t /* size */) {
    601     Mutex::Autolock autoLock(mLock);
    602 
    603     if (isProhibitedIndex_l(index)) {
    604         android_errorWriteLog(0x534e4554, "29422020");
    605         return BAD_INDEX;
    606     }
    607 
    608     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
    609     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    610     // some errors are expected for getParameter
    611     if (err != OMX_ErrorNoMore) {
    612         CLOG_IF_ERROR(getParameter, err, "%s(%#x)", asString(extIndex), index);
    613     }
    614     return StatusFromOMXError(err);
    615 }
    616 
    617 status_t OMXNodeInstance::setParameter(
    618         OMX_INDEXTYPE index, const void *params, size_t size) {
    619     Mutex::Autolock autoLock(mLock);
    620     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    621     CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
    622 
    623     if (extIndex == OMX_IndexParamMaxFrameDurationForBitrateControl) {
    624         return setMaxPtsGapUs(params, size);
    625     }
    626 
    627     if (isProhibitedIndex_l(index)) {
    628         android_errorWriteLog(0x534e4554, "29422020");
    629         return BAD_INDEX;
    630     }
    631 
    632     OMX_ERRORTYPE err = OMX_SetParameter(
    633             mHandle, index, const_cast<void *>(params));
    634     CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index);
    635     return StatusFromOMXError(err);
    636 }
    637 
    638 status_t OMXNodeInstance::getConfig(
    639         OMX_INDEXTYPE index, void *params, size_t /* size */) {
    640     Mutex::Autolock autoLock(mLock);
    641 
    642     if (isProhibitedIndex_l(index)) {
    643         android_errorWriteLog(0x534e4554, "29422020");
    644         return BAD_INDEX;
    645     }
    646 
    647     OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
    648     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    649     // some errors are expected for getConfig
    650     if (err != OMX_ErrorNoMore) {
    651         CLOG_IF_ERROR(getConfig, err, "%s(%#x)", asString(extIndex), index);
    652     }
    653     return StatusFromOMXError(err);
    654 }
    655 
    656 status_t OMXNodeInstance::setConfig(
    657         OMX_INDEXTYPE index, const void *params, size_t size) {
    658     Mutex::Autolock autoLock(mLock);
    659     OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
    660     CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
    661 
    662     if (isProhibitedIndex_l(index)) {
    663         android_errorWriteLog(0x534e4554, "29422020");
    664         return BAD_INDEX;
    665     }
    666 
    667     OMX_ERRORTYPE err = OMX_SetConfig(
    668             mHandle, index, const_cast<void *>(params));
    669     CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index);
    670     return StatusFromOMXError(err);
    671 }
    672 
    673 status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
    674     Mutex::Autolock autoLock(mLock);
    675 
    676     if (portIndex >= NELEM(mPortMode)) {
    677         ALOGE("b/31385713, portIndex(%u)", portIndex);
    678         android_errorWriteLog(0x534e4554, "31385713");
    679         return BAD_VALUE;
    680     }
    681 
    682     if (mSailed || mNumPortBuffers[portIndex] > 0) {
    683         android_errorWriteLog(0x534e4554, "29422020");
    684         return INVALID_OPERATION;
    685     }
    686 
    687     CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
    688 
    689     switch (mode) {
    690     case IOMX::kPortModeDynamicANWBuffer:
    691     {
    692         if (portIndex == kPortIndexOutput) {
    693             if (mLegacyAdaptiveExperiment) {
    694                 CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
    695                         "not setting port mode to %s(%d) on output",
    696                         asString(mode), mode);
    697                 return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
    698             }
    699 
    700             status_t err = enableNativeBuffers_l(
    701                     portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
    702             if (err != OK) {
    703                 return err;
    704             }
    705         }
    706         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
    707         return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
    708     }
    709 
    710     case IOMX::kPortModeDynamicNativeHandle:
    711     {
    712         if (portIndex != kPortIndexInput) {
    713             CLOG_ERROR(setPortMode, BAD_VALUE,
    714                     "%s(%d) mode is only supported on input port", asString(mode), mode);
    715             return BAD_VALUE;
    716         }
    717         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
    718         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
    719 
    720         MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
    721         return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
    722     }
    723 
    724     case IOMX::kPortModePresetSecureBuffer:
    725     {
    726         // Allow on both input and output.
    727         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
    728         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
    729         return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
    730     }
    731 
    732     case IOMX::kPortModePresetANWBuffer:
    733     {
    734         if (portIndex != kPortIndexOutput) {
    735             CLOG_ERROR(setPortMode, BAD_VALUE,
    736                     "%s(%d) mode is only supported on output port", asString(mode), mode);
    737             return BAD_VALUE;
    738         }
    739 
    740         // Check if we're simulating legacy mode with metadata mode,
    741         // if so, enable metadata mode.
    742         if (mLegacyAdaptiveExperiment) {
    743             if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
    744                 CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
    745                         "metdata mode enabled successfully");
    746                 return OK;
    747             }
    748 
    749             CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
    750                     "unable to enable metadata mode on output");
    751 
    752             mLegacyAdaptiveExperiment = false;
    753         }
    754 
    755         // Disable secure buffer and enable graphic buffer
    756         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
    757         status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
    758         if (err != OK) {
    759             return err;
    760         }
    761 
    762         // Not running experiment, or metadata is not supported.
    763         // Disable metadata mode and use legacy mode.
    764         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
    765         return OK;
    766     }
    767 
    768     case IOMX::kPortModePresetByteBuffer:
    769     {
    770         // Disable secure buffer, native buffer and metadata.
    771         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
    772         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
    773         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
    774         return OK;
    775     }
    776 
    777     default:
    778         break;
    779     }
    780 
    781     CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
    782     return BAD_VALUE;
    783 }
    784 
    785 status_t OMXNodeInstance::enableNativeBuffers_l(
    786         OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable) {
    787     if (portIndex >= NELEM(mSecureBufferType)) {
    788         ALOGE("b/31385713, portIndex(%u)", portIndex);
    789         android_errorWriteLog(0x534e4554, "31385713");
    790         return BAD_VALUE;
    791     }
    792 
    793     CLOG_CONFIG(enableNativeBuffers, "%s:%u%s, %d", portString(portIndex), portIndex,
    794                 graphic ? ", graphic" : "", enable);
    795     OMX_STRING name = const_cast<OMX_STRING>(
    796             graphic ? "OMX.google.android.index.enableAndroidNativeBuffers"
    797                     : "OMX.google.android.index.allocateNativeHandle");
    798 
    799     OMX_INDEXTYPE index;
    800     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    801 
    802     if (err == OMX_ErrorNone) {
    803         EnableAndroidNativeBuffersParams params;
    804         InitOMXParams(&params);
    805         params.nPortIndex = portIndex;
    806         params.enable = enable;
    807 
    808         err = OMX_SetParameter(mHandle, index, &params);
    809         CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
    810                       portString(portIndex), portIndex, enable);
    811         if (!graphic) {
    812             if (err == OMX_ErrorNone) {
    813                 mSecureBufferType[portIndex] =
    814                     enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;
    815             } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
    816                 mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
    817             }
    818         } else {
    819             if (err == OMX_ErrorNone) {
    820                 mGraphicBufferEnabled[portIndex] = enable;
    821             } else if (enable) {
    822                 mGraphicBufferEnabled[portIndex] = false;
    823             }
    824         }
    825     } else {
    826         CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);
    827         if (!graphic) {
    828             // Extension not supported, check for manual override with system property
    829             // This is a temporary workaround until partners support the OMX extension
    830             if (property_get_bool("media.mediadrmservice.enable", false)) {
    831                 CLOG_CONFIG(enableNativeBuffers, "system property override: using native-handles");
    832                 mSecureBufferType[portIndex] = kSecureBufferTypeNativeHandle;
    833             } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
    834                 mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
    835             }
    836             err = OMX_ErrorNone;
    837         }
    838     }
    839 
    840     return StatusFromOMXError(err);
    841 }
    842 
    843 status_t OMXNodeInstance::getGraphicBufferUsage(
    844         OMX_U32 portIndex, OMX_U32* usage) {
    845     Mutex::Autolock autoLock(mLock);
    846 
    847     OMX_INDEXTYPE index;
    848     OMX_STRING name = const_cast<OMX_STRING>(
    849             "OMX.google.android.index.getAndroidNativeBufferUsage");
    850     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    851 
    852     if (err != OMX_ErrorNone) {
    853         CLOG_ERROR(getExtensionIndex, err, "%s", name);
    854         return StatusFromOMXError(err);
    855     }
    856 
    857     GetAndroidNativeBufferUsageParams params;
    858     InitOMXParams(&params);
    859     params.nPortIndex = portIndex;
    860 
    861     err = OMX_GetParameter(mHandle, index, &params);
    862     if (err != OMX_ErrorNone) {
    863         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", name, index,
    864                 portString(portIndex), portIndex);
    865         return StatusFromOMXError(err);
    866     }
    867 
    868     *usage = params.nUsage;
    869 
    870     return OK;
    871 }
    872 
    873 status_t OMXNodeInstance::storeMetaDataInBuffers_l(
    874         OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
    875     if (mSailed) {
    876         android_errorWriteLog(0x534e4554, "29422020");
    877         return INVALID_OPERATION;
    878     }
    879     if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
    880         android_errorWriteLog(0x534e4554, "26324358");
    881         if (type != NULL) {
    882             *type = kMetadataBufferTypeInvalid;
    883         }
    884         return BAD_VALUE;
    885     }
    886 
    887     OMX_INDEXTYPE index;
    888     OMX_STRING name = const_cast<OMX_STRING>(
    889             "OMX.google.android.index.storeMetaDataInBuffers");
    890 
    891     OMX_STRING nativeBufferName = const_cast<OMX_STRING>(
    892             "OMX.google.android.index.storeANWBufferInMetadata");
    893     MetadataBufferType negotiatedType;
    894     MetadataBufferType requestedType = type != NULL ? *type : kMetadataBufferTypeANWBuffer;
    895 
    896     StoreMetaDataInBuffersParams params;
    897     InitOMXParams(&params);
    898     params.nPortIndex = portIndex;
    899     params.bStoreMetaData = enable;
    900 
    901     OMX_ERRORTYPE err =
    902         requestedType == kMetadataBufferTypeANWBuffer
    903                 ? OMX_GetExtensionIndex(mHandle, nativeBufferName, &index)
    904                 : OMX_ErrorUnsupportedIndex;
    905     OMX_ERRORTYPE xerr = err;
    906     if (err == OMX_ErrorNone) {
    907         err = OMX_SetParameter(mHandle, index, &params);
    908         if (err == OMX_ErrorNone) {
    909             name = nativeBufferName; // set name for debugging
    910             negotiatedType = requestedType;
    911         }
    912     }
    913     if (err != OMX_ErrorNone) {
    914         err = OMX_GetExtensionIndex(mHandle, name, &index);
    915         xerr = err;
    916         if (err == OMX_ErrorNone) {
    917             negotiatedType =
    918                 requestedType == kMetadataBufferTypeANWBuffer
    919                         ? kMetadataBufferTypeGrallocSource : requestedType;
    920             err = OMX_SetParameter(mHandle, index, &params);
    921         }
    922         if (err == OMX_ErrorBadParameter) {
    923             err = OMX_ErrorUnsupportedIndex;
    924         }
    925     }
    926 
    927     // don't log loud error if component does not support metadata mode on the output
    928     if (err != OMX_ErrorNone) {
    929         if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) {
    930             CLOGW("component does not support metadata mode; using fallback");
    931         } else if (xerr != OMX_ErrorNone) {
    932             CLOG_ERROR(getExtensionIndex, xerr, "%s", name);
    933         } else {
    934             CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d type=%d", name, index,
    935                     portString(portIndex), portIndex, enable, negotiatedType);
    936         }
    937         negotiatedType = mMetadataType[portIndex];
    938     } else {
    939         if (!enable) {
    940             negotiatedType = kMetadataBufferTypeInvalid;
    941         }
    942         mMetadataType[portIndex] = negotiatedType;
    943     }
    944     CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u %srequested %s:%d negotiated %s:%d",
    945             portString(portIndex), portIndex, enable ? "" : "UN",
    946             asString(requestedType), requestedType, asString(negotiatedType), negotiatedType);
    947 
    948     if (type != NULL) {
    949         *type = negotiatedType;
    950     }
    951 
    952     return StatusFromOMXError(err);
    953 }
    954 
    955 status_t OMXNodeInstance::prepareForAdaptivePlayback(
    956         OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
    957         OMX_U32 maxFrameHeight) {
    958     Mutex::Autolock autolock(mLock);
    959     if (mSailed) {
    960         android_errorWriteLog(0x534e4554, "29422020");
    961         return INVALID_OPERATION;
    962     }
    963     CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u",
    964             portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
    965 
    966     if (mLegacyAdaptiveExperiment) {
    967         CLOG_INTERNAL(prepareForAdaptivePlayback,
    968                 "Legacy adaptive experiment: reporting success");
    969         return OK;
    970     }
    971 
    972     OMX_INDEXTYPE index;
    973     OMX_STRING name = const_cast<OMX_STRING>(
    974             "OMX.google.android.index.prepareForAdaptivePlayback");
    975 
    976     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    977     if (err != OMX_ErrorNone) {
    978         CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);
    979         return StatusFromOMXError(err);
    980     }
    981 
    982     PrepareForAdaptivePlaybackParams params;
    983     InitOMXParams(&params);
    984     params.nPortIndex = portIndex;
    985     params.bEnable = enable;
    986     params.nMaxFrameWidth = maxFrameWidth;
    987     params.nMaxFrameHeight = maxFrameHeight;
    988 
    989     err = OMX_SetParameter(mHandle, index, &params);
    990     CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d max=%ux%u", name, index,
    991             portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
    992     return StatusFromOMXError(err);
    993 }
    994 
    995 status_t OMXNodeInstance::configureVideoTunnelMode(
    996         OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
    997         native_handle_t **sidebandHandle) {
    998     Mutex::Autolock autolock(mLock);
    999     if (mSailed) {
   1000         android_errorWriteLog(0x534e4554, "29422020");
   1001         return INVALID_OPERATION;
   1002     }
   1003     CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u",
   1004             portString(portIndex), portIndex, tunneled, audioHwSync);
   1005 
   1006     OMX_INDEXTYPE index;
   1007     OMX_STRING name = const_cast<OMX_STRING>(
   1008             "OMX.google.android.index.configureVideoTunnelMode");
   1009 
   1010     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
   1011     if (err != OMX_ErrorNone) {
   1012         CLOG_ERROR_IF(tunneled, getExtensionIndex, err, "%s", name);
   1013         return StatusFromOMXError(err);
   1014     }
   1015 
   1016     ConfigureVideoTunnelModeParams tunnelParams;
   1017     InitOMXParams(&tunnelParams);
   1018     tunnelParams.nPortIndex = portIndex;
   1019     tunnelParams.bTunneled = tunneled;
   1020     tunnelParams.nAudioHwSync = audioHwSync;
   1021     err = OMX_SetParameter(mHandle, index, &tunnelParams);
   1022     if (err != OMX_ErrorNone) {
   1023         CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index,
   1024                 portString(portIndex), portIndex, tunneled, audioHwSync);
   1025         return StatusFromOMXError(err);
   1026     }
   1027 
   1028     err = OMX_GetParameter(mHandle, index, &tunnelParams);
   1029     if (err != OMX_ErrorNone) {
   1030         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index,
   1031                 portString(portIndex), portIndex, tunneled, audioHwSync);
   1032         return StatusFromOMXError(err);
   1033     }
   1034     if (sidebandHandle) {
   1035         *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
   1036     }
   1037 
   1038     return OK;
   1039 }
   1040 
   1041 status_t OMXNodeInstance::useBuffer(
   1042         OMX_U32 portIndex, const OMXBuffer &omxBuffer, IOMX::buffer_id *buffer) {
   1043     if (buffer == NULL) {
   1044         ALOGE("b/25884056");
   1045         return BAD_VALUE;
   1046     }
   1047 
   1048     if (portIndex >= NELEM(mNumPortBuffers)) {
   1049         return BAD_VALUE;
   1050     }
   1051 
   1052     Mutex::Autolock autoLock(mLock);
   1053     if (!mSailed) {
   1054         ALOGE("b/35467458");
   1055         android_errorWriteLog(0x534e4554, "35467458");
   1056         return BAD_VALUE;
   1057     }
   1058 
   1059     switch (omxBuffer.mBufferType) {
   1060         case OMXBuffer::kBufferTypePreset:
   1061             return useBuffer_l(portIndex, NULL, NULL, buffer);
   1062 
   1063         case OMXBuffer::kBufferTypeSharedMem:
   1064             return useBuffer_l(portIndex, omxBuffer.mMem, NULL, buffer);
   1065 
   1066         case OMXBuffer::kBufferTypeANWBuffer:
   1067             return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
   1068 
   1069         case OMXBuffer::kBufferTypeHidlMemory: {
   1070                 sp<IHidlMemory> hidlMemory = mapMemory(omxBuffer.mHidlMemory);
   1071                 if (hidlMemory == nullptr) {
   1072                     ALOGE("OMXNodeInstance useBuffer() failed to map memory");
   1073                     return NO_MEMORY;
   1074                 }
   1075                 return useBuffer_l(portIndex, NULL, hidlMemory, buffer);
   1076             }
   1077         default:
   1078             break;
   1079     }
   1080 
   1081     return BAD_VALUE;
   1082 }
   1083 
   1084 status_t OMXNodeInstance::useBuffer_l(
   1085         OMX_U32 portIndex, const sp<IMemory> &params,
   1086         const sp<IHidlMemory> &hParams, IOMX::buffer_id *buffer) {
   1087     BufferMeta *buffer_meta;
   1088     OMX_BUFFERHEADERTYPE *header;
   1089     OMX_ERRORTYPE err = OMX_ErrorNone;
   1090     bool isMetadata = mMetadataType[portIndex] != kMetadataBufferTypeInvalid;
   1091 
   1092     if (!isMetadata && mGraphicBufferEnabled[portIndex]) {
   1093         ALOGE("b/62948670");
   1094         android_errorWriteLog(0x534e4554, "62948670");
   1095         return INVALID_OPERATION;
   1096     }
   1097 
   1098     size_t paramsSize;
   1099     void* paramsPointer;
   1100     if (params != NULL && hParams != NULL) {
   1101         return BAD_VALUE;
   1102     }
   1103     if (params != NULL) {
   1104         paramsPointer = params->pointer();
   1105         paramsSize = params->size();
   1106     } else if (hParams != NULL) {
   1107         paramsPointer = hParams->getPointer();
   1108         paramsSize = hParams->getSize();
   1109     } else {
   1110         paramsPointer = nullptr;
   1111     }
   1112 
   1113     OMX_U32 allottedSize;
   1114     if (isMetadata) {
   1115         if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource) {
   1116             allottedSize = sizeof(VideoGrallocMetadata);
   1117         } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer) {
   1118             allottedSize = sizeof(VideoNativeMetadata);
   1119         } else if (mMetadataType[portIndex] == kMetadataBufferTypeNativeHandleSource) {
   1120             allottedSize = sizeof(VideoNativeHandleMetadata);
   1121         } else {
   1122             return BAD_VALUE;
   1123         }
   1124     } else {
   1125         // NULL params is allowed only in metadata mode.
   1126         if (paramsPointer == nullptr) {
   1127             ALOGE("b/25884056");
   1128             return BAD_VALUE;
   1129         }
   1130         allottedSize = paramsSize;
   1131     }
   1132 
   1133     bool isOutputGraphicMetadata = (portIndex == kPortIndexOutput) &&
   1134             (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource ||
   1135                     mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer);
   1136 
   1137     uint32_t requiresAllocateBufferBit =
   1138         (portIndex == kPortIndexInput)
   1139             ? kRequiresAllocateBufferOnInputPorts
   1140             : kRequiresAllocateBufferOnOutputPorts;
   1141 
   1142     // we use useBuffer for output metadata regardless of quirks
   1143     if (!isOutputGraphicMetadata && (mQuirks & requiresAllocateBufferBit)) {
   1144         // metadata buffers are not connected cross process; only copy if not meta.
   1145         buffer_meta = new BufferMeta(
   1146                     params, hParams, portIndex, !isMetadata /* copy */, NULL /* data */);
   1147 
   1148         err = OMX_AllocateBuffer(
   1149                 mHandle, &header, portIndex, buffer_meta, allottedSize);
   1150 
   1151         if (err != OMX_ErrorNone) {
   1152             CLOG_ERROR(allocateBuffer, err,
   1153                     SIMPLE_BUFFER(portIndex, (size_t)allottedSize,
   1154                             paramsPointer));
   1155         }
   1156     } else {
   1157         OMX_U8 *data = NULL;
   1158 
   1159         // metadata buffers are not connected cross process
   1160         // use a backup buffer instead of the actual buffer
   1161         if (isMetadata) {
   1162             data = new (std::nothrow) OMX_U8[allottedSize];
   1163             if (data == NULL) {
   1164                 return NO_MEMORY;
   1165             }
   1166             memset(data, 0, allottedSize);
   1167 
   1168             buffer_meta = new BufferMeta(
   1169                     params, hParams, portIndex, false /* copy */, data);
   1170         } else {
   1171             data = static_cast<OMX_U8 *>(paramsPointer);
   1172 
   1173             buffer_meta = new BufferMeta(
   1174                     params, hParams, portIndex, false /* copy */, NULL);
   1175         }
   1176 
   1177         err = OMX_UseBuffer(
   1178                 mHandle, &header, portIndex, buffer_meta,
   1179                 allottedSize, data);
   1180 
   1181         if (err != OMX_ErrorNone) {
   1182             CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(
   1183                     portIndex, (size_t)allottedSize, data));
   1184         }
   1185     }
   1186 
   1187     if (err != OMX_ErrorNone) {
   1188         delete buffer_meta;
   1189         buffer_meta = NULL;
   1190 
   1191         *buffer = 0;
   1192 
   1193         return StatusFromOMXError(err);
   1194     }
   1195 
   1196     CHECK_EQ(header->pAppPrivate, buffer_meta);
   1197 
   1198     *buffer = makeBufferID(header);
   1199 
   1200     addActiveBuffer(portIndex, *buffer);
   1201 
   1202     sp<IOMXBufferSource> bufferSource(getBufferSource());
   1203     if (bufferSource != NULL && portIndex == kPortIndexInput) {
   1204         bufferSource->onInputBufferAdded(*buffer);
   1205     }
   1206 
   1207     CLOG_BUFFER(useBuffer, NEW_BUFFER_FMT(
   1208             *buffer, portIndex, "%u(%zu)@%p", allottedSize, paramsSize, paramsPointer));
   1209     return OK;
   1210 }
   1211 
   1212 status_t OMXNodeInstance::useGraphicBuffer2_l(
   1213         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
   1214         IOMX::buffer_id *buffer) {
   1215     if (graphicBuffer == NULL || buffer == NULL) {
   1216         ALOGE("b/25884056");
   1217         return BAD_VALUE;
   1218     }
   1219 
   1220     // port definition
   1221     OMX_PARAM_PORTDEFINITIONTYPE def;
   1222     InitOMXParams(&def);
   1223     def.nPortIndex = portIndex;
   1224     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
   1225     if (err != OMX_ErrorNone) {
   1226         OMX_INDEXTYPE index = OMX_IndexParamPortDefinition;
   1227         CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u",
   1228                 asString(index), index, portString(portIndex), portIndex);
   1229         return UNKNOWN_ERROR;
   1230     }
   1231 
   1232     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex);
   1233 
   1234     OMX_BUFFERHEADERTYPE *header = NULL;
   1235     OMX_U8* bufferHandle = const_cast<OMX_U8*>(
   1236             reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
   1237 
   1238     err = OMX_UseBuffer(
   1239             mHandle,
   1240             &header,
   1241             portIndex,
   1242             bufferMeta,
   1243             def.nBufferSize,
   1244             bufferHandle);
   1245 
   1246     if (err != OMX_ErrorNone) {
   1247         CLOG_ERROR(useBuffer, err, BUFFER_FMT(portIndex, "%u@%p", def.nBufferSize, bufferHandle));
   1248         delete bufferMeta;
   1249         bufferMeta = NULL;
   1250         *buffer = 0;
   1251         return StatusFromOMXError(err);
   1252     }
   1253 
   1254     CHECK_EQ(header->pBuffer, bufferHandle);
   1255     CHECK_EQ(header->pAppPrivate, bufferMeta);
   1256 
   1257     *buffer = makeBufferID(header);
   1258 
   1259     addActiveBuffer(portIndex, *buffer);
   1260     CLOG_BUFFER(useGraphicBuffer2, NEW_BUFFER_FMT(
   1261             *buffer, portIndex, "%u@%p", def.nBufferSize, bufferHandle));
   1262     return OK;
   1263 }
   1264 
   1265 // XXX: This function is here for backwards compatibility.  Once the OMX
   1266 // implementations have been updated this can be removed and useGraphicBuffer2
   1267 // can be renamed to useGraphicBuffer.
   1268 status_t OMXNodeInstance::useGraphicBuffer_l(
   1269         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
   1270         IOMX::buffer_id *buffer) {
   1271     if (graphicBuffer == NULL || buffer == NULL) {
   1272         ALOGE("b/25884056");
   1273         return BAD_VALUE;
   1274     }
   1275 
   1276     // First, see if we're in metadata mode. We could be running an experiment to simulate
   1277     // legacy behavior (preallocated buffers) on devices that supports meta.
   1278     if (mMetadataType[portIndex] != kMetadataBufferTypeInvalid) {
   1279         return useGraphicBufferWithMetadata_l(
   1280                 portIndex, graphicBuffer, buffer);
   1281     }
   1282 
   1283     if (!mGraphicBufferEnabled[portIndex]) {
   1284         // Report error if this is not in graphic buffer mode.
   1285         ALOGE("b/62948670");
   1286         android_errorWriteLog(0x534e4554, "62948670");
   1287         return INVALID_OPERATION;
   1288     }
   1289 
   1290     // See if the newer version of the extension is present.
   1291     OMX_INDEXTYPE index;
   1292     if (OMX_GetExtensionIndex(
   1293             mHandle,
   1294             const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
   1295             &index) == OMX_ErrorNone) {
   1296         return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
   1297     }
   1298 
   1299     OMX_STRING name = const_cast<OMX_STRING>(
   1300         "OMX.google.android.index.useAndroidNativeBuffer");
   1301     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
   1302     if (err != OMX_ErrorNone) {
   1303         CLOG_ERROR(getExtensionIndex, err, "%s", name);
   1304         return StatusFromOMXError(err);
   1305     }
   1306 
   1307     BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex);
   1308 
   1309     OMX_BUFFERHEADERTYPE *header;
   1310 
   1311     OMX_VERSIONTYPE ver;
   1312     ver.s.nVersionMajor = 1;
   1313     ver.s.nVersionMinor = 0;
   1314     ver.s.nRevision = 0;
   1315     ver.s.nStep = 0;
   1316     UseAndroidNativeBufferParams params = {
   1317         sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
   1318         &header, graphicBuffer,
   1319     };
   1320 
   1321     err = OMX_SetParameter(mHandle, index, &params);
   1322 
   1323     if (err != OMX_ErrorNone) {
   1324         CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index,
   1325                 portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle);
   1326 
   1327         delete bufferMeta;
   1328         bufferMeta = NULL;
   1329 
   1330         *buffer = 0;
   1331 
   1332         return StatusFromOMXError(err);
   1333     }
   1334 
   1335     CHECK_EQ(header->pAppPrivate, bufferMeta);
   1336 
   1337     *buffer = makeBufferID(header);
   1338 
   1339     addActiveBuffer(portIndex, *buffer);
   1340     CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT(
   1341             *buffer, portIndex, "GB=%p", graphicBuffer->handle));
   1342     return OK;
   1343 }
   1344 
   1345 status_t OMXNodeInstance::useGraphicBufferWithMetadata_l(
   1346         OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
   1347         IOMX::buffer_id *buffer) {
   1348     if (portIndex != kPortIndexOutput) {
   1349         return BAD_VALUE;
   1350     }
   1351 
   1352     if (mMetadataType[portIndex] != kMetadataBufferTypeGrallocSource &&
   1353             mMetadataType[portIndex] != kMetadataBufferTypeANWBuffer) {
   1354         return BAD_VALUE;
   1355     }
   1356 
   1357     status_t err = useBuffer_l(portIndex, NULL, NULL, buffer);
   1358     if (err != OK) {
   1359         return err;
   1360     }
   1361 
   1362     OMX_BUFFERHEADERTYPE *header = findBufferHeader(*buffer, portIndex);
   1363 
   1364     return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, *buffer, header);
   1365 
   1366 }
   1367 
   1368 status_t OMXNodeInstance::updateGraphicBufferInMeta_l(
   1369         OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
   1370         IOMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
   1371     // No need to check |graphicBuffer| since NULL is valid for it as below.
   1372     if (header == NULL) {
   1373         ALOGE("b/25884056");
   1374         return BAD_VALUE;
   1375     }
   1376 
   1377     if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
   1378         return BAD_VALUE;
   1379     }
   1380 
   1381     BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
   1382     sp<ABuffer> data = bufferMeta->getBuffer(header, false /* limit */);
   1383     bufferMeta->setGraphicBuffer(graphicBuffer);
   1384     MetadataBufferType metaType = mMetadataType[portIndex];
   1385     if (metaType == kMetadataBufferTypeGrallocSource
   1386             && data->capacity() >= sizeof(VideoGrallocMetadata)) {
   1387         VideoGrallocMetadata &metadata = *(VideoGrallocMetadata *)(data->data());
   1388         metadata.eType = kMetadataBufferTypeGrallocSource;
   1389         metadata.pHandle = graphicBuffer == NULL ? NULL : graphicBuffer->handle;
   1390     } else if (metaType == kMetadataBufferTypeANWBuffer
   1391             && data->capacity() >= sizeof(VideoNativeMetadata)) {
   1392         VideoNativeMetadata &metadata = *(VideoNativeMetadata *)(data->data());
   1393         metadata.eType = kMetadataBufferTypeANWBuffer;
   1394         metadata.pBuffer = graphicBuffer == NULL ? NULL : graphicBuffer->getNativeBuffer();
   1395         metadata.nFenceFd = -1;
   1396     } else {
   1397         CLOG_ERROR(updateGraphicBufferInMeta, BAD_VALUE, "%s:%u, %#x bad type (%d) or size (%u)",
   1398             portString(portIndex), portIndex, buffer, mMetadataType[portIndex], header->nAllocLen);
   1399         return BAD_VALUE;
   1400     }
   1401 
   1402     CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p",
   1403             portString(portIndex), portIndex, buffer,
   1404             graphicBuffer == NULL ? NULL : graphicBuffer->handle);
   1405     return OK;
   1406 }
   1407 
   1408 status_t OMXNodeInstance::updateNativeHandleInMeta_l(
   1409         OMX_U32 portIndex, const sp<NativeHandle>& nativeHandle,
   1410         IOMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
   1411     // No need to check |nativeHandle| since NULL is valid for it as below.
   1412     if (header == NULL) {
   1413         ALOGE("b/25884056");
   1414         return BAD_VALUE;
   1415     }
   1416 
   1417     if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
   1418         return BAD_VALUE;
   1419     }
   1420 
   1421     BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
   1422     sp<ABuffer> data = bufferMeta->getBuffer(header, false /* limit */);
   1423     bufferMeta->setNativeHandle(nativeHandle);
   1424     if (mMetadataType[portIndex] == kMetadataBufferTypeNativeHandleSource
   1425             && data->capacity() >= sizeof(VideoNativeHandleMetadata)) {
   1426         VideoNativeHandleMetadata &metadata = *(VideoNativeHandleMetadata *)(data->data());
   1427         metadata.eType = mMetadataType[portIndex];
   1428         metadata.pHandle =
   1429             nativeHandle == NULL ? NULL : const_cast<native_handle*>(nativeHandle->handle());
   1430     } else {
   1431         CLOG_ERROR(updateNativeHandleInMeta, BAD_VALUE, "%s:%u, %#x bad type (%d) or size (%zu)",
   1432             portString(portIndex), portIndex, buffer, mMetadataType[portIndex], data->capacity());
   1433         return BAD_VALUE;
   1434     }
   1435 
   1436     CLOG_BUFFER(updateNativeHandleInMeta, "%s:%u, %#x := %p",
   1437             portString(portIndex), portIndex, buffer,
   1438             nativeHandle == NULL ? NULL : nativeHandle->handle());
   1439     return OK;
   1440 }
   1441 
   1442 status_t OMXNodeInstance::setInputSurface(
   1443         const sp<IOMXBufferSource> &bufferSource) {
   1444     Mutex::Autolock autolock(mLock);
   1445 
   1446     status_t err;
   1447 
   1448     // only allow graphic source on input port, when there are no allocated buffers yet
   1449     if (mNumPortBuffers[kPortIndexInput] > 0) {
   1450         android_errorWriteLog(0x534e4554, "29422020");
   1451         return INVALID_OPERATION;
   1452     }
   1453 
   1454     if (getBufferSource() != NULL) {
   1455         return ALREADY_EXISTS;
   1456     }
   1457 
   1458     err = storeMetaDataInBuffers_l(kPortIndexInput, OMX_TRUE, NULL);
   1459     if (err != OK) {
   1460         return err;
   1461     }
   1462 
   1463     // Retrieve the width and height of the graphic buffer, set when the
   1464     // codec was configured.
   1465     OMX_PARAM_PORTDEFINITIONTYPE def;
   1466     InitOMXParams(&def);
   1467     def.nPortIndex = kPortIndexInput;
   1468     OMX_ERRORTYPE oerr = OMX_GetParameter(
   1469             mHandle, OMX_IndexParamPortDefinition, &def);
   1470     if (oerr != OMX_ErrorNone) {
   1471         OMX_INDEXTYPE index = OMX_IndexParamPortDefinition;
   1472         CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u", asString(index),
   1473                 index, portString(kPortIndexInput), kPortIndexInput);
   1474         return UNKNOWN_ERROR;
   1475     }
   1476 
   1477     if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
   1478         CLOGW("createInputSurface requires COLOR_FormatSurface "
   1479                 "(AndroidOpaque) color format instead of %s(%#x)",
   1480                 asString(def.format.video.eColorFormat), def.format.video.eColorFormat);
   1481         return INVALID_OPERATION;
   1482     }
   1483 
   1484     if (def.format.video.nFrameWidth == 0
   1485             || def.format.video.nFrameHeight == 0) {
   1486         ALOGE("Invalid video dimension %ux%u",
   1487                 def.format.video.nFrameWidth,
   1488                 def.format.video.nFrameHeight);
   1489         return BAD_VALUE;
   1490     }
   1491 
   1492     setBufferSource(bufferSource);
   1493     return OK;
   1494 }
   1495 
   1496 status_t OMXNodeInstance::allocateSecureBuffer(
   1497         OMX_U32 portIndex, size_t size, IOMX::buffer_id *buffer,
   1498         void **buffer_data, sp<NativeHandle> *native_handle) {
   1499     if (buffer == NULL || buffer_data == NULL || native_handle == NULL) {
   1500         ALOGE("b/25884056");
   1501         return BAD_VALUE;
   1502     }
   1503 
   1504     if (portIndex >= NELEM(mSecureBufferType)) {
   1505         ALOGE("b/31385713, portIndex(%u)", portIndex);
   1506         android_errorWriteLog(0x534e4554, "31385713");
   1507         return BAD_VALUE;
   1508     }
   1509 
   1510     Mutex::Autolock autoLock(mLock);
   1511 
   1512     if (!mSailed) {
   1513         ALOGE("b/35467458");
   1514         android_errorWriteLog(0x534e4554, "35467458");
   1515         return BAD_VALUE;
   1516     }
   1517     BufferMeta *buffer_meta = new BufferMeta(portIndex);
   1518 
   1519     OMX_BUFFERHEADERTYPE *header;
   1520 
   1521     OMX_ERRORTYPE err = OMX_AllocateBuffer(
   1522             mHandle, &header, portIndex, buffer_meta, size);
   1523 
   1524     if (err != OMX_ErrorNone) {
   1525         CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size));
   1526         delete buffer_meta;
   1527         buffer_meta = NULL;
   1528 
   1529         *buffer = 0;
   1530 
   1531         return StatusFromOMXError(err);
   1532     }
   1533 
   1534     CHECK_EQ(header->pAppPrivate, buffer_meta);
   1535 
   1536     *buffer = makeBufferID(header);
   1537     if (mSecureBufferType[portIndex] == kSecureBufferTypeNativeHandle) {
   1538         *buffer_data = NULL;
   1539         *native_handle = NativeHandle::create(
   1540                 (native_handle_t *)header->pBuffer, false /* ownsHandle */);
   1541     } else {
   1542         *buffer_data = header->pBuffer;
   1543         *native_handle = NULL;
   1544     }
   1545 
   1546     addActiveBuffer(portIndex, *buffer);
   1547 
   1548     sp<IOMXBufferSource> bufferSource(getBufferSource());
   1549     if (bufferSource != NULL && portIndex == kPortIndexInput) {
   1550         bufferSource->onInputBufferAdded(*buffer);
   1551     }
   1552     CLOG_BUFFER(allocateSecureBuffer, NEW_BUFFER_FMT(
   1553             *buffer, portIndex, "%zu@%p:%p", size, *buffer_data,
   1554             *native_handle == NULL ? NULL : (*native_handle)->handle()));
   1555 
   1556     return OK;
   1557 }
   1558 
   1559 status_t OMXNodeInstance::freeBuffer(
   1560         OMX_U32 portIndex, IOMX::buffer_id buffer) {
   1561     Mutex::Autolock autoLock(mLock);
   1562     CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer);
   1563 
   1564     removeActiveBuffer(portIndex, buffer);
   1565 
   1566     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
   1567     if (header == NULL) {
   1568         ALOGE("b/25884056");
   1569         return BAD_VALUE;
   1570     }
   1571     BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
   1572 
   1573     OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
   1574     CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer);
   1575 
   1576     delete buffer_meta;
   1577     buffer_meta = NULL;
   1578     invalidateBufferID(buffer);
   1579 
   1580     return StatusFromOMXError(err);
   1581 }
   1582 
   1583 status_t OMXNodeInstance::fillBuffer(
   1584         IOMX::buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) {
   1585     Mutex::Autolock autoLock(mLock);
   1586 
   1587     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput);
   1588     if (header == NULL) {
   1589         ALOGE("b/25884056");
   1590         return BAD_VALUE;
   1591     }
   1592 
   1593     if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
   1594         status_t err = updateGraphicBufferInMeta_l(
   1595                 kPortIndexOutput, omxBuffer.mGraphicBuffer, buffer, header);
   1596 
   1597         if (err != OK) {
   1598             CLOG_ERROR(fillBuffer, err, FULL_BUFFER(
   1599                     (intptr_t)header->pBuffer, header, fenceFd));
   1600             return err;
   1601         }
   1602     } else if (omxBuffer.mBufferType != OMXBuffer::kBufferTypePreset) {
   1603         return BAD_VALUE;
   1604     }
   1605 
   1606     header->nFilledLen = 0;
   1607     header->nOffset = 0;
   1608     header->nFlags = 0;
   1609 
   1610     // meta now owns fenceFd
   1611     status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexOutput);
   1612     if (res != OK) {
   1613         CLOG_ERROR(fillBuffer::storeFenceInMeta, res, EMPTY_BUFFER(buffer, header, fenceFd));
   1614         return res;
   1615     }
   1616 
   1617     {
   1618         Mutex::Autolock _l(mDebugLock);
   1619         mOutputBuffersWithCodec.add(header);
   1620         CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header, fenceFd)));
   1621     }
   1622 
   1623     OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
   1624     if (err != OMX_ErrorNone) {
   1625         CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header, fenceFd));
   1626         Mutex::Autolock _l(mDebugLock);
   1627         mOutputBuffersWithCodec.remove(header);
   1628     }
   1629     return StatusFromOMXError(err);
   1630 }
   1631 
   1632 status_t OMXNodeInstance::emptyBuffer(
   1633         buffer_id buffer, const OMXBuffer &omxBuffer,
   1634         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1635     Mutex::Autolock autoLock(mLock);
   1636 
   1637     switch (omxBuffer.mBufferType) {
   1638     case OMXBuffer::kBufferTypePreset:
   1639         return emptyBuffer_l(
   1640                 buffer, omxBuffer.mRangeOffset, omxBuffer.mRangeLength,
   1641                 flags, timestamp, fenceFd);
   1642 
   1643     case OMXBuffer::kBufferTypeANWBuffer:
   1644         return emptyGraphicBuffer_l(
   1645                 buffer, omxBuffer.mGraphicBuffer, flags, timestamp, fenceFd);
   1646 
   1647     case OMXBuffer::kBufferTypeNativeHandle:
   1648         return emptyNativeHandleBuffer_l(
   1649                 buffer, omxBuffer.mNativeHandle, flags, timestamp, fenceFd);
   1650 
   1651     default:
   1652         break;
   1653     }
   1654 
   1655     return BAD_VALUE;
   1656 }
   1657 
   1658 status_t OMXNodeInstance::emptyBuffer_l(
   1659         IOMX::buffer_id buffer,
   1660         OMX_U32 rangeOffset, OMX_U32 rangeLength,
   1661         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1662 
   1663     // no emptybuffer if using input surface
   1664     if (getBufferSource() != NULL) {
   1665         android_errorWriteLog(0x534e4554, "29422020");
   1666         return INVALID_OPERATION;
   1667     }
   1668 
   1669     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
   1670     if (header == NULL) {
   1671         ALOGE("b/25884056");
   1672         return BAD_VALUE;
   1673     }
   1674     BufferMeta *buffer_meta =
   1675         static_cast<BufferMeta *>(header->pAppPrivate);
   1676 
   1677     // set up proper filled length if component is configured for gralloc metadata mode
   1678     // ignore rangeOffset in this case (as client may be assuming ANW meta buffers).
   1679     if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource) {
   1680         header->nFilledLen = rangeLength ? sizeof(VideoGrallocMetadata) : 0;
   1681         header->nOffset = 0;
   1682     } else {
   1683         // rangeLength and rangeOffset must be a subset of the allocated data in the buffer.
   1684         // corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0.
   1685         if (rangeOffset > header->nAllocLen
   1686                 || rangeLength > header->nAllocLen - rangeOffset) {
   1687             CLOG_ERROR(emptyBuffer, OMX_ErrorBadParameter, FULL_BUFFER(NULL, header, fenceFd));
   1688             if (fenceFd >= 0) {
   1689                 ::close(fenceFd);
   1690             }
   1691             return BAD_VALUE;
   1692         }
   1693         header->nFilledLen = rangeLength;
   1694         header->nOffset = rangeOffset;
   1695 
   1696         buffer_meta->CopyToOMX(header);
   1697     }
   1698 
   1699     return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer, fenceFd);
   1700 }
   1701 
   1702 // log queued buffer activity for the next few input and/or output frames
   1703 // if logging at internal state level
   1704 void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) {
   1705     if (DEBUG == ADebug::kDebugInternalState) {
   1706         DEBUG_BUMP = ADebug::kDebugAll;
   1707         if (numInputBuffers > 0) {
   1708             mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers;
   1709         }
   1710         if (numOutputBuffers > 0) {
   1711             mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers;
   1712         }
   1713     }
   1714 }
   1715 
   1716 void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) {
   1717     if (mDebugLevelBumpPendingBuffers[portIndex]) {
   1718         --mDebugLevelBumpPendingBuffers[portIndex];
   1719     }
   1720     if (!mDebugLevelBumpPendingBuffers[0]
   1721             && !mDebugLevelBumpPendingBuffers[1]) {
   1722         DEBUG_BUMP = DEBUG;
   1723     }
   1724 }
   1725 
   1726 status_t OMXNodeInstance::storeFenceInMeta_l(
   1727         OMX_BUFFERHEADERTYPE *header, int fenceFd, OMX_U32 portIndex) {
   1728     // propagate fence if component supports it; wait for it otherwise
   1729     OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nFilledLen : header->nAllocLen;
   1730     if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
   1731             && metaSize >= sizeof(VideoNativeMetadata)) {
   1732         VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
   1733         if (nativeMeta.nFenceFd >= 0) {
   1734             ALOGE("fence (%d) already exists in meta", nativeMeta.nFenceFd);
   1735             if (fenceFd >= 0) {
   1736                 ::close(fenceFd);
   1737             }
   1738             return ALREADY_EXISTS;
   1739         }
   1740         nativeMeta.nFenceFd = fenceFd;
   1741     } else if (fenceFd >= 0) {
   1742         CLOG_BUFFER(storeFenceInMeta, "waiting for fence %d", fenceFd);
   1743         sp<Fence> fence = new Fence(fenceFd);
   1744         return fence->wait(IOMX::kFenceTimeoutMs);
   1745     }
   1746     return OK;
   1747 }
   1748 
   1749 int OMXNodeInstance::retrieveFenceFromMeta_l(
   1750         OMX_BUFFERHEADERTYPE *header, OMX_U32 portIndex) {
   1751     OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nAllocLen : header->nFilledLen;
   1752     int fenceFd = -1;
   1753     if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
   1754             && header->nAllocLen >= sizeof(VideoNativeMetadata)) {
   1755         VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
   1756         if (nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
   1757             fenceFd = nativeMeta.nFenceFd;
   1758             nativeMeta.nFenceFd = -1;
   1759         }
   1760         if (metaSize < sizeof(nativeMeta) && fenceFd >= 0) {
   1761             CLOG_ERROR(foundFenceInEmptyMeta, BAD_VALUE, FULL_BUFFER(
   1762                     NULL, header, nativeMeta.nFenceFd));
   1763             fenceFd = -1;
   1764         }
   1765     }
   1766     return fenceFd;
   1767 }
   1768 
   1769 status_t OMXNodeInstance::emptyBuffer_l(
   1770         OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp,
   1771         intptr_t debugAddr, int fenceFd) {
   1772     header->nFlags = flags;
   1773     header->nTimeStamp = timestamp;
   1774 
   1775     status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexInput);
   1776     if (res != OK) {
   1777         CLOG_ERROR(emptyBuffer::storeFenceInMeta, res, WITH_STATS(
   1778                 FULL_BUFFER(debugAddr, header, fenceFd)));
   1779         return res;
   1780     }
   1781 
   1782     {
   1783         Mutex::Autolock _l(mDebugLock);
   1784         mInputBuffersWithCodec.add(header);
   1785 
   1786         // bump internal-state debug level for 2 input frames past a buffer with CSD
   1787         if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
   1788             bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */);
   1789         }
   1790 
   1791         CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header, fenceFd)));
   1792     }
   1793 
   1794     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
   1795     CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header, fenceFd));
   1796 
   1797     {
   1798         Mutex::Autolock _l(mDebugLock);
   1799         if (err != OMX_ErrorNone) {
   1800             mInputBuffersWithCodec.remove(header);
   1801         } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
   1802             unbumpDebugLevel_l(kPortIndexInput);
   1803         }
   1804     }
   1805 
   1806     return StatusFromOMXError(err);
   1807 }
   1808 
   1809 // like emptyBuffer, but the data is already in header->pBuffer
   1810 status_t OMXNodeInstance::emptyGraphicBuffer_l(
   1811         IOMX::buffer_id buffer, const sp<GraphicBuffer> &graphicBuffer,
   1812         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1813     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
   1814     if (header == NULL) {
   1815         ALOGE("b/25884056");
   1816         return BAD_VALUE;
   1817     }
   1818 
   1819     status_t err = updateGraphicBufferInMeta_l(
   1820             kPortIndexInput, graphicBuffer, buffer, header);
   1821     if (err != OK) {
   1822         CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER(
   1823                 (intptr_t)header->pBuffer, header, fenceFd));
   1824         return err;
   1825     }
   1826 
   1827     int64_t codecTimeUs = getCodecTimestamp(timestamp);
   1828 
   1829     header->nOffset = 0;
   1830     if (graphicBuffer == NULL) {
   1831         header->nFilledLen = 0;
   1832     } else if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource) {
   1833         header->nFilledLen = sizeof(VideoGrallocMetadata);
   1834     } else {
   1835         header->nFilledLen = sizeof(VideoNativeMetadata);
   1836     }
   1837     return emptyBuffer_l(header, flags, codecTimeUs, (intptr_t)header->pBuffer, fenceFd);
   1838 }
   1839 
   1840 status_t OMXNodeInstance::setMaxPtsGapUs(const void *params, size_t size) {
   1841     if (params == NULL || size != sizeof(OMX_PARAM_U32TYPE)) {
   1842         CLOG_ERROR(setMaxPtsGapUs, BAD_VALUE, "invalid params (%p,%zu)", params, size);
   1843         return BAD_VALUE;
   1844     }
   1845 
   1846     mMaxTimestampGapUs = (int64_t)((OMX_PARAM_U32TYPE*)params)->nU32;
   1847 
   1848     return OK;
   1849 }
   1850 
   1851 int64_t OMXNodeInstance::getCodecTimestamp(OMX_TICKS timestamp) {
   1852     int64_t originalTimeUs = timestamp;
   1853 
   1854     if (mMaxTimestampGapUs > 0ll) {
   1855         /* Cap timestamp gap between adjacent frames to specified max
   1856          *
   1857          * In the scenario of cast mirroring, encoding could be suspended for
   1858          * prolonged periods. Limiting the pts gap to workaround the problem
   1859          * where encoder's rate control logic produces huge frames after a
   1860          * long period of suspension.
   1861          */
   1862         if (mPrevOriginalTimeUs >= 0ll) {
   1863             int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
   1864             timestamp = (timestampGapUs < mMaxTimestampGapUs ?
   1865                 timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
   1866         }
   1867         ALOGV("IN  timestamp: %lld -> %lld",
   1868             static_cast<long long>(originalTimeUs),
   1869             static_cast<long long>(timestamp));
   1870     }
   1871 
   1872     mPrevOriginalTimeUs = originalTimeUs;
   1873     mPrevModifiedTimeUs = timestamp;
   1874 
   1875     if (mMaxTimestampGapUs > 0ll && !mRestorePtsFailed) {
   1876         mOriginalTimeUs.add(timestamp, originalTimeUs);
   1877     }
   1878 
   1879     return timestamp;
   1880 }
   1881 
   1882 status_t OMXNodeInstance::emptyNativeHandleBuffer_l(
   1883         IOMX::buffer_id buffer, const sp<NativeHandle> &nativeHandle,
   1884         OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
   1885     OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
   1886     if (header == NULL) {
   1887         ALOGE("b/25884056");
   1888         return BAD_VALUE;
   1889     }
   1890 
   1891     status_t err = updateNativeHandleInMeta_l(
   1892             kPortIndexInput, nativeHandle, buffer, header);
   1893     if (err != OK) {
   1894         CLOG_ERROR(emptyNativeHandleBuffer_l, err, FULL_BUFFER(
   1895                 (intptr_t)header->pBuffer, header, fenceFd));
   1896         return err;
   1897     }
   1898 
   1899     header->nOffset = 0;
   1900     header->nFilledLen = (nativeHandle == NULL) ? 0 : sizeof(VideoNativeMetadata);
   1901 
   1902     return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer, fenceFd);
   1903 }
   1904 
   1905 void OMXNodeInstance::codecBufferFilled(omx_message &msg) {
   1906     Mutex::Autolock autoLock(mLock);
   1907 
   1908     if (mMaxTimestampGapUs <= 0ll || mRestorePtsFailed) {
   1909         return;
   1910     }
   1911 
   1912     OMX_U32 &flags = msg.u.extended_buffer_data.flags;
   1913     OMX_TICKS &timestamp = msg.u.extended_buffer_data.timestamp;
   1914 
   1915     if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
   1916         ssize_t index = mOriginalTimeUs.indexOfKey(timestamp);
   1917         if (index >= 0) {
   1918             ALOGV("OUT timestamp: %lld -> %lld",
   1919                     static_cast<long long>(timestamp),
   1920                     static_cast<long long>(mOriginalTimeUs[index]));
   1921             timestamp = mOriginalTimeUs[index];
   1922             mOriginalTimeUs.removeItemsAt(index);
   1923         } else {
   1924             // giving up the effort as encoder doesn't appear to preserve pts
   1925             ALOGW("giving up limiting timestamp gap (pts = %lld)", timestamp);
   1926             mRestorePtsFailed = true;
   1927         }
   1928     }
   1929 }
   1930 
   1931 status_t OMXNodeInstance::getExtensionIndex(
   1932         const char *parameterName, OMX_INDEXTYPE *index) {
   1933     Mutex::Autolock autoLock(mLock);
   1934 
   1935     OMX_ERRORTYPE err = OMX_GetExtensionIndex(
   1936             mHandle, const_cast<char *>(parameterName), index);
   1937 
   1938     return StatusFromOMXError(err);
   1939 }
   1940 
   1941 status_t OMXNodeInstance::dispatchMessage(const omx_message &msg) {
   1942     mDispatcher->post(msg, true /*realTime*/);
   1943     return OK;
   1944 }
   1945 
   1946 status_t OMXNodeInstance::setQuirks(OMX_U32 quirks) {
   1947     if (quirks & ~kQuirksMask) {
   1948         return BAD_VALUE;
   1949     }
   1950 
   1951     mQuirks = quirks;
   1952 
   1953     return OK;
   1954 }
   1955 
   1956 bool OMXNodeInstance::handleMessage(omx_message &msg) {
   1957     if (msg.type == omx_message::FILL_BUFFER_DONE) {
   1958         OMX_BUFFERHEADERTYPE *buffer =
   1959             findBufferHeader(msg.u.extended_buffer_data.buffer, kPortIndexOutput);
   1960         if (buffer == NULL) {
   1961             ALOGE("b/25884056");
   1962             return false;
   1963         }
   1964 
   1965         {
   1966             Mutex::Autolock _l(mDebugLock);
   1967             mOutputBuffersWithCodec.remove(buffer);
   1968 
   1969             CLOG_BUMPED_BUFFER(
   1970                     FBD, WITH_STATS(FULL_BUFFER(
   1971                             msg.u.extended_buffer_data.buffer, buffer, msg.fenceFd)));
   1972 
   1973             unbumpDebugLevel_l(kPortIndexOutput);
   1974         }
   1975 
   1976         BufferMeta *buffer_meta =
   1977             static_cast<BufferMeta *>(buffer->pAppPrivate);
   1978 
   1979         if (buffer->nOffset + buffer->nFilledLen < buffer->nOffset
   1980                 || buffer->nOffset + buffer->nFilledLen > buffer->nAllocLen) {
   1981             CLOG_ERROR(onFillBufferDone, OMX_ErrorBadParameter,
   1982                     FULL_BUFFER(NULL, buffer, msg.fenceFd));
   1983         }
   1984         buffer_meta->CopyFromOMX(buffer);
   1985 
   1986         // fix up the buffer info (especially timestamp) if needed
   1987         codecBufferFilled(msg);
   1988     } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
   1989         OMX_BUFFERHEADERTYPE *buffer =
   1990             findBufferHeader(msg.u.buffer_data.buffer, kPortIndexInput);
   1991         if (buffer == NULL) {
   1992             return false;
   1993         }
   1994 
   1995         {
   1996             Mutex::Autolock _l(mDebugLock);
   1997             mInputBuffersWithCodec.remove(buffer);
   1998 
   1999             CLOG_BUMPED_BUFFER(
   2000                     EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer, msg.fenceFd)));
   2001         }
   2002 
   2003         const sp<IOMXBufferSource> bufferSource(getBufferSource());
   2004 
   2005         if (bufferSource != NULL) {
   2006             // This is one of the buffers used exclusively by IOMXBufferSource.
   2007             // Don't dispatch a message back to ACodec, since it doesn't
   2008             // know that anyone asked to have the buffer emptied and will
   2009             // be very confused.
   2010             bufferSource->onInputBufferEmptied(
   2011                     msg.u.buffer_data.buffer, OMXFenceParcelable(msg.fenceFd));
   2012             return true;
   2013         }
   2014     } else if (msg.type == omx_message::EVENT &&
   2015             msg.u.event_data.event == OMX_EventDataSpaceChanged) {
   2016         handleDataSpaceChanged(msg);
   2017     }
   2018 
   2019     return false;
   2020 }
   2021 
   2022 bool OMXNodeInstance::handleDataSpaceChanged(omx_message &msg) {
   2023     android_dataspace dataSpace = (android_dataspace) msg.u.event_data.data1;
   2024     android_dataspace origDataSpace = dataSpace;
   2025 
   2026     if (!ColorUtils::convertDataSpaceToV0(dataSpace)) {
   2027         // Do not process the data space change, don't notify client either
   2028         return true;
   2029     }
   2030 
   2031     android_pixel_format pixelFormat = (android_pixel_format)msg.u.event_data.data3;
   2032 
   2033     ColorAspects requestedAspects = ColorUtils::unpackToColorAspects(msg.u.event_data.data2);
   2034     ColorAspects aspects = requestedAspects; // initially requested aspects
   2035 
   2036     // request color aspects to encode
   2037     OMX_INDEXTYPE index;
   2038     status_t err = getExtensionIndex(
   2039             "OMX.google.android.index.describeColorAspects", &index);
   2040     if (err == OK) {
   2041         // V0 dataspace
   2042         DescribeColorAspectsParams params;
   2043         InitOMXParams(&params);
   2044         params.nPortIndex = kPortIndexInput;
   2045         params.nDataSpace = origDataSpace;
   2046         params.nPixelFormat = pixelFormat;
   2047         params.bDataSpaceChanged = OMX_TRUE;
   2048         params.sAspects = requestedAspects;
   2049 
   2050         err = getConfig(index, &params, sizeof(params));
   2051         if (err == OK) {
   2052             aspects = params.sAspects;
   2053             ALOGD("Codec resolved it to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
   2054                     params.sAspects.mRange, asString(params.sAspects.mRange),
   2055                     params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
   2056                     params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
   2057                     params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
   2058                     err, asString(err));
   2059         } else {
   2060             params.sAspects = aspects;
   2061             err = OK;
   2062         }
   2063         params.bDataSpaceChanged = OMX_FALSE;
   2064         for (int triesLeft = 2; --triesLeft >= 0; ) {
   2065             status_t err = setConfig(index, &params, sizeof(params));
   2066             if (err == OK) {
   2067                 err = getConfig(index, &params, sizeof(params));
   2068             }
   2069             if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
   2070                     params.sAspects, aspects)) {
   2071                 // if we can't set or get color aspects, still communicate dataspace to client
   2072                 break;
   2073             }
   2074 
   2075             ALOGW_IF(triesLeft == 0, "Codec repeatedly changed requested ColorAspects.");
   2076         }
   2077     }
   2078 
   2079     ALOGV("Set color aspects to (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
   2080             aspects.mRange, asString(aspects.mRange),
   2081             aspects.mPrimaries, asString(aspects.mPrimaries),
   2082             aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
   2083             aspects.mTransfer, asString(aspects.mTransfer),
   2084             err, asString(err));
   2085 
   2086     // signal client that the dataspace has changed; this will update the output format
   2087     // TODO: we should tie this to an output buffer somehow, and signal the change
   2088     // just before the output buffer is returned to the client, but there are many
   2089     // ways this could fail (e.g. flushing), and we are not yet supporting this scenario.
   2090 
   2091     msg.u.event_data.data1 = (OMX_U32) dataSpace;
   2092     msg.u.event_data.data2 = (OMX_U32) ColorUtils::packToU32(aspects);
   2093 
   2094     return false;
   2095 }
   2096 
   2097 void OMXNodeInstance::onMessages(std::list<omx_message> &messages) {
   2098     for (std::list<omx_message>::iterator it = messages.begin(); it != messages.end(); ) {
   2099         if (handleMessage(*it)) {
   2100             messages.erase(it++);
   2101         } else {
   2102             ++it;
   2103         }
   2104     }
   2105 
   2106     if (!messages.empty()) {
   2107         mObserver->onMessages(messages);
   2108     }
   2109 }
   2110 
   2111 void OMXNodeInstance::onObserverDied() {
   2112     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
   2113 
   2114     // Try to force shutdown of the node and hope for the best.
   2115     freeNode();
   2116 }
   2117 
   2118 // OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
   2119 // Don't try to acquire mLock here -- in rare circumstances this will hang.
   2120 void OMXNodeInstance::onEvent(
   2121         OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
   2122     const char *arg1String = "??";
   2123     const char *arg2String = "??";
   2124     ADebug::Level level = ADebug::kDebugInternalState;
   2125 
   2126     switch (event) {
   2127         case OMX_EventCmdComplete:
   2128             arg1String = asString((OMX_COMMANDTYPE)arg1);
   2129             switch (arg1) {
   2130                 case OMX_CommandStateSet:
   2131                     arg2String = asString((OMX_STATETYPE)arg2);
   2132                     level = ADebug::kDebugState;
   2133                     break;
   2134                 case OMX_CommandFlush:
   2135                 case OMX_CommandPortEnable:
   2136                 {
   2137                     // bump internal-state debug level for 2 input and output frames
   2138                     Mutex::Autolock _l(mDebugLock);
   2139                     bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */);
   2140                 }
   2141                 // fall through
   2142                 default:
   2143                     arg2String = portString(arg2);
   2144             }
   2145             break;
   2146         case OMX_EventError:
   2147             arg1String = asString((OMX_ERRORTYPE)arg1);
   2148             level = ADebug::kDebugLifeCycle;
   2149             break;
   2150         case OMX_EventPortSettingsChanged:
   2151             arg2String = asString((OMX_INDEXEXTTYPE)arg2);
   2152             // fall through
   2153         default:
   2154             arg1String = portString(arg1);
   2155     }
   2156 
   2157     CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)",
   2158             asString(event), event, arg1String, arg1, arg2String, arg2);
   2159     const sp<IOMXBufferSource> bufferSource(getBufferSource());
   2160 
   2161     if (bufferSource != NULL
   2162             && event == OMX_EventCmdComplete
   2163             && arg1 == OMX_CommandStateSet
   2164             && arg2 == OMX_StateExecuting) {
   2165         bufferSource->onOmxExecuting();
   2166     }
   2167 
   2168     // allow configuration if we return to the loaded state
   2169     if (event == OMX_EventCmdComplete
   2170             && arg1 == OMX_CommandStateSet
   2171             && arg2 == OMX_StateLoaded) {
   2172         mSailed = false;
   2173     }
   2174 }
   2175 
   2176 // static
   2177 OMX_ERRORTYPE OMXNodeInstance::OnEvent(
   2178         OMX_IN OMX_HANDLETYPE /* hComponent */,
   2179         OMX_IN OMX_PTR pAppData,
   2180         OMX_IN OMX_EVENTTYPE eEvent,
   2181         OMX_IN OMX_U32 nData1,
   2182         OMX_IN OMX_U32 nData2,
   2183         OMX_IN OMX_PTR pEventData) {
   2184     if (pAppData == NULL) {
   2185         ALOGE("b/25884056");
   2186         return OMX_ErrorBadParameter;
   2187     }
   2188     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   2189     if (instance->mDying) {
   2190         return OMX_ErrorNone;
   2191     }
   2192 
   2193     instance->onEvent(eEvent, nData1, nData2);
   2194 
   2195     // output rendered events are not processed as regular events until they hit the observer
   2196     if (eEvent == OMX_EventOutputRendered) {
   2197         if (pEventData == NULL) {
   2198             return OMX_ErrorBadParameter;
   2199         }
   2200 
   2201         // process data from array
   2202         OMX_VIDEO_RENDEREVENTTYPE *renderData = (OMX_VIDEO_RENDEREVENTTYPE *)pEventData;
   2203         for (size_t i = 0; i < nData1; ++i) {
   2204             omx_message msg;
   2205             msg.type = omx_message::FRAME_RENDERED;
   2206             msg.fenceFd = -1;
   2207             msg.u.render_data.timestamp = renderData[i].nMediaTimeUs;
   2208             msg.u.render_data.nanoTime = renderData[i].nSystemTimeNs;
   2209             bool realTime = msg.u.render_data.timestamp == INT64_MAX;
   2210             instance->mDispatcher->post(msg, realTime);
   2211         }
   2212         return OMX_ErrorNone;
   2213     }
   2214 
   2215     omx_message msg;
   2216     msg.type = omx_message::EVENT;
   2217     msg.fenceFd = -1;
   2218     msg.u.event_data.event = eEvent;
   2219     msg.u.event_data.data1 = nData1;
   2220     msg.u.event_data.data2 = nData2;
   2221 
   2222     instance->mDispatcher->post(msg, true /* realTime */);
   2223 
   2224     return OMX_ErrorNone;
   2225 }
   2226 
   2227 // static
   2228 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
   2229         OMX_IN OMX_HANDLETYPE /* hComponent */,
   2230         OMX_IN OMX_PTR pAppData,
   2231         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
   2232     if (pAppData == NULL) {
   2233         ALOGE("b/25884056");
   2234         return OMX_ErrorBadParameter;
   2235     }
   2236     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   2237     if (instance->mDying) {
   2238         return OMX_ErrorNone;
   2239     }
   2240     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
   2241 
   2242     omx_message msg;
   2243     msg.type = omx_message::EMPTY_BUFFER_DONE;
   2244     msg.fenceFd = fenceFd;
   2245     msg.u.buffer_data.buffer = instance->findBufferID(pBuffer);
   2246     instance->mDispatcher->post(msg);
   2247 
   2248     return OMX_ErrorNone;
   2249 }
   2250 
   2251 // static
   2252 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
   2253         OMX_IN OMX_HANDLETYPE /* hComponent */,
   2254         OMX_IN OMX_PTR pAppData,
   2255         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
   2256     if (pAppData == NULL) {
   2257         ALOGE("b/25884056");
   2258         return OMX_ErrorBadParameter;
   2259     }
   2260     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
   2261     if (instance->mDying) {
   2262         return OMX_ErrorNone;
   2263     }
   2264     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
   2265 
   2266     omx_message msg;
   2267     msg.type = omx_message::FILL_BUFFER_DONE;
   2268     msg.fenceFd = fenceFd;
   2269     msg.u.extended_buffer_data.buffer = instance->findBufferID(pBuffer);
   2270     msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
   2271     msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
   2272     msg.u.extended_buffer_data.flags = pBuffer->nFlags;
   2273     msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
   2274     instance->mDispatcher->post(msg);
   2275 
   2276     return OMX_ErrorNone;
   2277 }
   2278 
   2279 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, IOMX::buffer_id id) {
   2280     ActiveBuffer active;
   2281     active.mPortIndex = portIndex;
   2282     active.mID = id;
   2283     mActiveBuffers.push(active);
   2284 
   2285     if (portIndex < NELEM(mNumPortBuffers)) {
   2286         ++mNumPortBuffers[portIndex];
   2287     }
   2288 }
   2289 
   2290 void OMXNodeInstance::removeActiveBuffer(
   2291         OMX_U32 portIndex, IOMX::buffer_id id) {
   2292     for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
   2293         if (mActiveBuffers[i].mPortIndex == portIndex
   2294                 && mActiveBuffers[i].mID == id) {
   2295             mActiveBuffers.removeItemsAt(i);
   2296 
   2297             if (portIndex < NELEM(mNumPortBuffers)) {
   2298                 --mNumPortBuffers[portIndex];
   2299             }
   2300             return;
   2301         }
   2302     }
   2303 
   2304      CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id);
   2305 }
   2306 
   2307 void OMXNodeInstance::freeActiveBuffers() {
   2308     // Make sure to count down here, as freeBuffer will in turn remove
   2309     // the active buffer from the vector...
   2310     for (size_t i = mActiveBuffers.size(); i > 0;) {
   2311         i--;
   2312         freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
   2313     }
   2314 }
   2315 
   2316 IOMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
   2317     if (bufferHeader == NULL) {
   2318         return 0;
   2319     }
   2320     Mutex::Autolock autoLock(mBufferIDLock);
   2321     IOMX::buffer_id buffer;
   2322     do { // handle the very unlikely case of ID overflow
   2323         if (++mBufferIDCount == 0) {
   2324             ++mBufferIDCount;
   2325         }
   2326         buffer = (IOMX::buffer_id)mBufferIDCount;
   2327     } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
   2328     mBufferIDToBufferHeader.add(buffer, bufferHeader);
   2329     mBufferHeaderToBufferID.add(bufferHeader, buffer);
   2330     return buffer;
   2331 }
   2332 
   2333 OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(
   2334         IOMX::buffer_id buffer, OMX_U32 portIndex) {
   2335     if (buffer == 0) {
   2336         return NULL;
   2337     }
   2338     Mutex::Autolock autoLock(mBufferIDLock);
   2339     ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
   2340     if (index < 0) {
   2341         CLOGW("findBufferHeader: buffer %u not found", buffer);
   2342         return NULL;
   2343     }
   2344     OMX_BUFFERHEADERTYPE *header = mBufferIDToBufferHeader.valueAt(index);
   2345     BufferMeta *buffer_meta =
   2346         static_cast<BufferMeta *>(header->pAppPrivate);
   2347     if (buffer_meta->getPortIndex() != portIndex) {
   2348         CLOGW("findBufferHeader: buffer %u found but with incorrect port index.", buffer);
   2349         android_errorWriteLog(0x534e4554, "28816827");
   2350         return NULL;
   2351     }
   2352     return header;
   2353 }
   2354 
   2355 IOMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
   2356     if (bufferHeader == NULL) {
   2357         return 0;
   2358     }
   2359     Mutex::Autolock autoLock(mBufferIDLock);
   2360     ssize_t index = mBufferHeaderToBufferID.indexOfKey(bufferHeader);
   2361     if (index < 0) {
   2362         CLOGW("findBufferID: bufferHeader %p not found", bufferHeader);
   2363         return 0;
   2364     }
   2365     return mBufferHeaderToBufferID.valueAt(index);
   2366 }
   2367 
   2368 void OMXNodeInstance::invalidateBufferID(IOMX::buffer_id buffer) {
   2369     if (buffer == 0) {
   2370         return;
   2371     }
   2372     Mutex::Autolock autoLock(mBufferIDLock);
   2373     ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
   2374     if (index < 0) {
   2375         CLOGW("invalidateBufferID: buffer %u not found", buffer);
   2376         return;
   2377     }
   2378     mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueAt(index));
   2379     mBufferIDToBufferHeader.removeItemsAt(index);
   2380 }
   2381 
   2382 }  // namespace android
   2383