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