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