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