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