OMXNodeInstance.cpp revision ee5201b4d9115cc7ac282155573e6354cc9c6819
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
48static const OMX_U32 kPortIndexInput = 0;
49static 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
99namespace android {
100
101struct 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
185private:
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
200OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
201    &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
202};
203
204static 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
218struct OMXNodeInstance::CallbackDispatcherThread : public Thread {
219    explicit CallbackDispatcherThread(CallbackDispatcher *dispatcher)
220        : mDispatcher(dispatcher) {
221    }
222
223private:
224    CallbackDispatcher *mDispatcher;
225
226    bool threadLoop();
227
228    CallbackDispatcherThread(const CallbackDispatcherThread &);
229    CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
230};
231
232////////////////////////////////////////////////////////////////////////////////
233
234struct 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
245protected:
246    virtual ~CallbackDispatcher();
247
248private:
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
273OMXNodeInstance::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
280OMXNodeInstance::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
298void 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
307void 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
315bool 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
340bool OMXNodeInstance::CallbackDispatcherThread::threadLoop() {
341    return mDispatcher->loop();
342}
343
344////////////////////////////////////////////////////////////////////////////////
345
346OMXNodeInstance::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
381OMXNodeInstance::~OMXNodeInstance() {
382    free(mName);
383    CHECK(mHandle == NULL);
384}
385
386void 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
395sp<IOMXBufferSource> OMXNodeInstance::getBufferSource() {
396    Mutex::Autolock autoLock(mOMXBufferSourceLock);
397    return mOMXBufferSource;
398}
399
400void OMXNodeInstance::setBufferSource(const sp<IOMXBufferSource>& bufferSource) {
401    Mutex::Autolock autoLock(mOMXBufferSourceLock);
402    CLOG_INTERNAL(setBufferSource, "%p", bufferSource.get());
403    mOMXBufferSource = bufferSource;
404}
405
406OMX_HANDLETYPE OMXNodeInstance::handle() {
407    return mHandle;
408}
409
410sp<IOMXObserver> OMXNodeInstance::observer() {
411    return mObserver;
412}
413
414status_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
518status_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
558bool 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
599status_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
617status_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
638status_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
656status_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
673status_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
785status_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
843status_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
873status_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
955status_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
995status_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
1041status_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
1084status_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
1212status_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.
1268status_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
1345status_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
1368status_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
1408status_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
1442status_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
1496status_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
1559status_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
1583status_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
1632status_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
1658status_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
1704void 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
1716void 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
1726status_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
1749int 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
1769status_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
1810status_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
1840status_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
1851int64_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
1882status_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
1905void 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
1931status_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
1941status_t OMXNodeInstance::dispatchMessage(const omx_message &msg) {
1942    mDispatcher->post(msg, true /*realTime*/);
1943    return OK;
1944}
1945
1946status_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
1956bool 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
2022bool 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
2097void 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
2111void 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.
2120void 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
2177OMX_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
2228OMX_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
2252OMX_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
2279void 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
2290void 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
2307void 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
2316IOMX::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
2333OMX_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
2355IOMX::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
2368void 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