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