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