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