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