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