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