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