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