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