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