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