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