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