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