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 { 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 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 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 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 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 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 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 331 bool OMXNodeInstance::CallbackDispatcherThread::threadLoop() { 332 return mDispatcher->loop(); 333 } 334 335 //////////////////////////////////////////////////////////////////////////////// 336 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 370 OMXNodeInstance::~OMXNodeInstance() { 371 free(mName); 372 CHECK(mHandle == NULL); 373 } 374 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 384 sp<IOMXBufferSource> OMXNodeInstance::getBufferSource() { 385 Mutex::Autolock autoLock(mOMXBufferSourceLock); 386 return mOMXBufferSource; 387 } 388 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 395 OMX_HANDLETYPE OMXNodeInstance::handle() { 396 return mHandle; 397 } 398 399 sp<IOMXObserver> OMXNodeInstance::observer() { 400 return mObserver; 401 } 402 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1899 status_t OMXNodeInstance::dispatchMessage(const omx_message &msg) { 1900 mDispatcher->post(msg, true /*realTime*/); 1901 return OK; 1902 } 1903 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 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 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 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 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. 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 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 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 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 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 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 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 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 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 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 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