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