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