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