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