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