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