OMXNodeInstance.cpp revision 0520fa2f690f26d392c716af5863b657e4faadc7
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 "GraphicBufferSource.h" 26 27#include <OMX_Component.h> 28#include <OMX_IndexExt.h> 29#include <OMX_AsString.h> 30 31#include <binder/IMemory.h> 32#include <gui/BufferQueue.h> 33#include <HardwareAPI.h> 34#include <media/stagefright/foundation/ADebug.h> 35#include <media/stagefright/MediaErrors.h> 36 37#include <utils/misc.h> 38 39static const OMX_U32 kPortIndexInput = 0; 40static const OMX_U32 kPortIndexOutput = 1; 41 42#define CLOGW(fmt, ...) ALOGW("[%x:%s] " fmt, mNodeID, mName, ##__VA_ARGS__) 43 44#define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \ 45 ALOGE_IF(cond, #fn "(%x:%s, " fmt ") ERROR: %s(%#x)", \ 46 mNodeID, mName, ##__VA_ARGS__, asString(err), err) 47#define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__) 48#define CLOG_IF_ERROR(fn, err, fmt, ...) \ 49 CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__) 50 51#define CLOGI_(level, fn, fmt, ...) \ 52 ALOGI_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) 53#define CLOGD_(level, fn, fmt, ...) \ 54 ALOGD_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) 55 56#define CLOG_LIFE(fn, fmt, ...) CLOGI_(ADebug::kDebugLifeCycle, fn, fmt, ##__VA_ARGS__) 57#define CLOG_STATE(fn, fmt, ...) CLOGI_(ADebug::kDebugState, fn, fmt, ##__VA_ARGS__) 58#define CLOG_CONFIG(fn, fmt, ...) CLOGI_(ADebug::kDebugConfig, fn, fmt, ##__VA_ARGS__) 59#define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__) 60 61#define CLOG_DEBUG_IF(cond, fn, fmt, ...) \ 62 ALOGD_IF(cond, #fn "(%x, " fmt ")", mNodeID, ##__VA_ARGS__) 63 64#define CLOG_BUFFER(fn, fmt, ...) \ 65 CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) 66#define CLOG_BUMPED_BUFFER(fn, fmt, ...) \ 67 CLOG_DEBUG_IF(DEBUG_BUMP >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) 68 69/* buffer formatting */ 70#define BUFFER_FMT(port, fmt, ...) "%s:%u " fmt, portString(port), (port), ##__VA_ARGS__ 71#define NEW_BUFFER_FMT(buffer_id, port, fmt, ...) \ 72 BUFFER_FMT(port, fmt ") (#%zu => %#x", ##__VA_ARGS__, mActiveBuffers.size(), (buffer_id)) 73 74#define SIMPLE_BUFFER(port, size, data) BUFFER_FMT(port, "%zu@%p", (size), (data)) 75#define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \ 76 NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data)) 77 78#define EMPTY_BUFFER(addr, header) "%#x [%u@%p]", \ 79 (addr), (header)->nAllocLen, (header)->pBuffer 80#define FULL_BUFFER(addr, header) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld]", \ 81 (intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \ 82 (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp 83 84#define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \ 85 mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \ 86 mOutputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexOutput] 87// TRICKY: this is needed so formatting macros expand before substitution 88#define WITH_STATS(fmt, ...) WITH_STATS_WRAPPER(fmt, ##__VA_ARGS__) 89 90template<class T> 91static void InitOMXParams(T *params) { 92 memset(params, 0, sizeof(T)); 93 params->nSize = sizeof(T); 94 params->nVersion.s.nVersionMajor = 1; 95 params->nVersion.s.nVersionMinor = 0; 96 params->nVersion.s.nRevision = 0; 97 params->nVersion.s.nStep = 0; 98} 99 100namespace android { 101 102struct BufferMeta { 103 BufferMeta( 104 const sp<IMemory> &mem, OMX_U32 portIndex, bool copyToOmx, 105 bool copyFromOmx, OMX_U8 *backup) 106 : mMem(mem), 107 mCopyFromOmx(copyFromOmx), 108 mCopyToOmx(copyToOmx), 109 mPortIndex(portIndex), 110 mBackup(backup) { 111 } 112 113 BufferMeta(size_t size, OMX_U32 portIndex) 114 : mSize(size), 115 mCopyFromOmx(false), 116 mCopyToOmx(false), 117 mPortIndex(portIndex), 118 mBackup(NULL) { 119 } 120 121 BufferMeta(const sp<GraphicBuffer> &graphicBuffer, OMX_U32 portIndex) 122 : mGraphicBuffer(graphicBuffer), 123 mCopyFromOmx(false), 124 mCopyToOmx(false), 125 mPortIndex(portIndex), 126 mBackup(NULL) { 127 } 128 129 void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) { 130 if (!mCopyFromOmx) { 131 return; 132 } 133 134 memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, 135 header->pBuffer + header->nOffset, 136 header->nFilledLen); 137 } 138 139 void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { 140 if (!mCopyToOmx) { 141 return; 142 } 143 144 memcpy(header->pBuffer + header->nOffset, 145 (const OMX_U8 *)mMem->pointer() + header->nOffset, 146 header->nFilledLen); 147 } 148 149 void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) { 150 mGraphicBuffer = graphicBuffer; 151 } 152 153 OMX_U32 getPortIndex() { 154 return mPortIndex; 155 } 156 157 ~BufferMeta() { 158 delete[] mBackup; 159 } 160 161private: 162 sp<GraphicBuffer> mGraphicBuffer; 163 sp<IMemory> mMem; 164 size_t mSize; 165 bool mCopyFromOmx; 166 bool mCopyToOmx; 167 OMX_U32 mPortIndex; 168 OMX_U8 *mBackup; 169 170 BufferMeta(const BufferMeta &); 171 BufferMeta &operator=(const BufferMeta &); 172}; 173 174// static 175OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = { 176 &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone 177}; 178 179static inline const char *portString(OMX_U32 portIndex) { 180 switch (portIndex) { 181 case kPortIndexInput: return "Input"; 182 case kPortIndexOutput: return "Output"; 183 case ~0U: return "All"; 184 default: return "port"; 185 } 186} 187 188OMXNodeInstance::OMXNodeInstance( 189 OMX *owner, const sp<IOMXObserver> &observer, const char *name) 190 : mOwner(owner), 191 mNodeID(0), 192 mHandle(NULL), 193 mObserver(observer), 194 mDying(false), 195 mSailed(false), 196 mQueriedProhibitedExtensions(false), 197 mBufferIDCount(0) 198{ 199 mName = ADebug::GetDebugName(name); 200 DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug"); 201 ALOGV("debug level for %s is %d", name, DEBUG); 202 DEBUG_BUMP = DEBUG; 203 mNumPortBuffers[0] = 0; 204 mNumPortBuffers[1] = 0; 205 mDebugLevelBumpPendingBuffers[0] = 0; 206 mDebugLevelBumpPendingBuffers[1] = 0; 207 mUsingMetadata[0] = false; 208 mUsingMetadata[1] = false; 209 mIsSecure = AString(name).endsWith(".secure"); 210} 211 212OMXNodeInstance::~OMXNodeInstance() { 213 free(mName); 214 CHECK(mHandle == NULL); 215} 216 217void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) { 218 mNodeID = node_id; 219 CLOG_LIFE(allocateNode, "handle=%p", handle); 220 CHECK(mHandle == NULL); 221 mHandle = handle; 222} 223 224sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() { 225 Mutex::Autolock autoLock(mGraphicBufferSourceLock); 226 return mGraphicBufferSource; 227} 228 229void OMXNodeInstance::setGraphicBufferSource( 230 const sp<GraphicBufferSource>& bufferSource) { 231 Mutex::Autolock autoLock(mGraphicBufferSourceLock); 232 CLOG_INTERNAL(setGraphicBufferSource, "%p", bufferSource.get()); 233 mGraphicBufferSource = bufferSource; 234} 235 236OMX *OMXNodeInstance::owner() { 237 return mOwner; 238} 239 240sp<IOMXObserver> OMXNodeInstance::observer() { 241 return mObserver; 242} 243 244OMX::node_id OMXNodeInstance::nodeID() { 245 return mNodeID; 246} 247 248static status_t StatusFromOMXError(OMX_ERRORTYPE err) { 249 switch (err) { 250 case OMX_ErrorNone: 251 return OK; 252 case OMX_ErrorUnsupportedSetting: 253 case OMX_ErrorUnsupportedIndex: 254 return ERROR_UNSUPPORTED; 255 default: 256 return UNKNOWN_ERROR; 257 } 258} 259 260status_t OMXNodeInstance::freeNode(OMXMaster *master) { 261 CLOG_LIFE(freeNode, "handle=%p", mHandle); 262 static int32_t kMaxNumIterations = 10; 263 264 // exit if we have already freed the node 265 if (mHandle == NULL) { 266 return OK; 267 } 268 269 // Transition the node from its current state all the way down 270 // to "Loaded". 271 // This ensures that all active buffers are properly freed even 272 // for components that don't do this themselves on a call to 273 // "FreeHandle". 274 275 // The code below may trigger some more events to be dispatched 276 // by the OMX component - we want to ignore them as our client 277 // does not expect them. 278 mDying = true; 279 280 OMX_STATETYPE state; 281 CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone); 282 switch (state) { 283 case OMX_StateExecuting: 284 { 285 ALOGV("forcing Executing->Idle"); 286 sendCommand(OMX_CommandStateSet, OMX_StateIdle); 287 OMX_ERRORTYPE err; 288 int32_t iteration = 0; 289 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone 290 && state != OMX_StateIdle 291 && state != OMX_StateInvalid) { 292 if (++iteration > kMaxNumIterations) { 293 CLOGW("failed to enter Idle state (now %s(%d), aborting.", 294 asString(state), state); 295 state = OMX_StateInvalid; 296 break; 297 } 298 299 usleep(100000); 300 } 301 CHECK_EQ(err, OMX_ErrorNone); 302 303 if (state == OMX_StateInvalid) { 304 break; 305 } 306 307 // fall through 308 } 309 310 case OMX_StateIdle: 311 { 312 ALOGV("forcing Idle->Loaded"); 313 sendCommand(OMX_CommandStateSet, OMX_StateLoaded); 314 315 freeActiveBuffers(); 316 317 OMX_ERRORTYPE err; 318 int32_t iteration = 0; 319 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone 320 && state != OMX_StateLoaded 321 && state != OMX_StateInvalid) { 322 if (++iteration > kMaxNumIterations) { 323 CLOGW("failed to enter Loaded state (now %s(%d), aborting.", 324 asString(state), state); 325 state = OMX_StateInvalid; 326 break; 327 } 328 329 ALOGV("waiting for Loaded state..."); 330 usleep(100000); 331 } 332 CHECK_EQ(err, OMX_ErrorNone); 333 334 // fall through 335 } 336 337 case OMX_StateLoaded: 338 case OMX_StateInvalid: 339 break; 340 341 default: 342 LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state); 343 break; 344 } 345 346 ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName); 347 OMX_ERRORTYPE err = master->destroyComponentInstance( 348 static_cast<OMX_COMPONENTTYPE *>(mHandle)); 349 350 mHandle = NULL; 351 CLOG_IF_ERROR(freeNode, err, ""); 352 free(mName); 353 mName = NULL; 354 355 mOwner->invalidateNodeID(mNodeID); 356 mNodeID = 0; 357 358 ALOGV("OMXNodeInstance going away."); 359 delete this; 360 361 return StatusFromOMXError(err); 362} 363 364status_t OMXNodeInstance::sendCommand( 365 OMX_COMMANDTYPE cmd, OMX_S32 param) { 366 if (cmd == OMX_CommandStateSet && param != OMX_StateIdle) { 367 // Normally there are no configurations past first StateSet; however, OMXCodec supports 368 // meta configuration past Stateset:Idle. 369 mSailed = true; 370 } 371 const sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 372 if (bufferSource != NULL && cmd == OMX_CommandStateSet) { 373 if (param == OMX_StateIdle) { 374 // Initiating transition from Executing -> Idle 375 // ACodec is waiting for all buffers to be returned, do NOT 376 // submit any more buffers to the codec. 377 bufferSource->omxIdle(); 378 } else if (param == OMX_StateLoaded) { 379 // Initiating transition from Idle/Executing -> Loaded 380 // Buffers are about to be freed. 381 bufferSource->omxLoaded(); 382 setGraphicBufferSource(NULL); 383 } 384 385 // fall through 386 } 387 388 Mutex::Autolock autoLock(mLock); 389 390 // bump internal-state debug level for 2 input and output frames past a command 391 { 392 Mutex::Autolock _l(mDebugLock); 393 bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); 394 } 395 396 const char *paramString = 397 cmd == OMX_CommandStateSet ? asString((OMX_STATETYPE)param) : portString(param); 398 CLOG_STATE(sendCommand, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param); 399 OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL); 400 CLOG_IF_ERROR(sendCommand, err, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param); 401 return StatusFromOMXError(err); 402} 403 404bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) { 405 // these extensions can only be used from OMXNodeInstance, not by clients directly. 406 static const char *restricted_extensions[] = { 407 "OMX.google.android.index.storeMetaDataInBuffers", 408 "OMX.google.android.index.prepareForAdaptivePlayback", 409 "OMX.google.android.index.configureVideoTunnelMode", 410 "OMX.google.android.index.useAndroidNativeBuffer2", 411 "OMX.google.android.index.useAndroidNativeBuffer", 412 "OMX.google.android.index.enableAndroidNativeBuffers", 413 "OMX.google.android.index.getAndroidNativeBufferUsage", 414 }; 415 416 if ((index > OMX_IndexComponentStartUnused && index <= OMX_IndexParamStandardComponentRole) 417 || (index > OMX_IndexPortStartUnused && index <= OMX_IndexParamCompBufferSupplier) 418 || (index > OMX_IndexAudioStartUnused && index <= OMX_IndexConfigAudioChannelVolume) 419 || (index > OMX_IndexVideoStartUnused && index <= OMX_IndexConfigVideoNalSize) 420 || (index > OMX_IndexCommonStartUnused 421 && index <= OMX_IndexConfigCommonTransitionEffect) 422 || (index > (OMX_INDEXTYPE)OMX_IndexExtAudioStartUnused 423 && index <= (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3) 424 || (index > (OMX_INDEXTYPE)OMX_IndexExtVideoStartUnused 425 && index <= (OMX_INDEXTYPE)OMX_IndexParamSliceSegments) 426 || (index > (OMX_INDEXTYPE)OMX_IndexExtOtherStartUnused 427 && index <= (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion)) { 428 return false; 429 } 430 431 if (!mQueriedProhibitedExtensions) { 432 for (size_t i = 0; i < NELEM(restricted_extensions); ++i) { 433 OMX_INDEXTYPE ext; 434 if (OMX_GetExtensionIndex(mHandle, (OMX_STRING)restricted_extensions[i], &ext) == OMX_ErrorNone) { 435 mProhibitedExtensions.add(ext); 436 } 437 } 438 mQueriedProhibitedExtensions = true; 439 } 440 441 return mProhibitedExtensions.indexOf(index) >= 0; 442} 443 444status_t OMXNodeInstance::getParameter( 445 OMX_INDEXTYPE index, void *params, size_t /* size */) { 446 Mutex::Autolock autoLock(mLock); 447 448 if (isProhibitedIndex_l(index)) { 449 android_errorWriteLog(0x534e4554, "29422020"); 450 return BAD_INDEX; 451 } 452 453 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); 454 OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; 455 // some errors are expected for getParameter 456 if (err != OMX_ErrorNoMore) { 457 CLOG_IF_ERROR(getParameter, err, "%s(%#x)", asString(extIndex), index); 458 } 459 return StatusFromOMXError(err); 460} 461 462status_t OMXNodeInstance::setParameter( 463 OMX_INDEXTYPE index, const void *params, size_t size) { 464 Mutex::Autolock autoLock(mLock); 465 OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; 466 CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); 467 468 if (isProhibitedIndex_l(index)) { 469 android_errorWriteLog(0x534e4554, "29422020"); 470 return BAD_INDEX; 471 } 472 473 OMX_ERRORTYPE err = OMX_SetParameter( 474 mHandle, index, const_cast<void *>(params)); 475 CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index); 476 return StatusFromOMXError(err); 477} 478 479status_t OMXNodeInstance::getConfig( 480 OMX_INDEXTYPE index, void *params, size_t /* size */) { 481 Mutex::Autolock autoLock(mLock); 482 483 if (isProhibitedIndex_l(index)) { 484 android_errorWriteLog(0x534e4554, "29422020"); 485 return BAD_INDEX; 486 } 487 488 OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params); 489 OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; 490 // some errors are expected for getConfig 491 if (err != OMX_ErrorNoMore) { 492 CLOG_IF_ERROR(getConfig, err, "%s(%#x)", asString(extIndex), index); 493 } 494 return StatusFromOMXError(err); 495} 496 497status_t OMXNodeInstance::setConfig( 498 OMX_INDEXTYPE index, const void *params, size_t size) { 499 Mutex::Autolock autoLock(mLock); 500 OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; 501 CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); 502 503 if (isProhibitedIndex_l(index)) { 504 android_errorWriteLog(0x534e4554, "29422020"); 505 return BAD_INDEX; 506 } 507 508 OMX_ERRORTYPE err = OMX_SetConfig( 509 mHandle, index, const_cast<void *>(params)); 510 CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index); 511 return StatusFromOMXError(err); 512} 513 514status_t OMXNodeInstance::getState(OMX_STATETYPE* state) { 515 Mutex::Autolock autoLock(mLock); 516 517 OMX_ERRORTYPE err = OMX_GetState(mHandle, state); 518 CLOG_IF_ERROR(getState, err, ""); 519 return StatusFromOMXError(err); 520} 521 522status_t OMXNodeInstance::enableGraphicBuffers( 523 OMX_U32 portIndex, OMX_BOOL enable) { 524 Mutex::Autolock autoLock(mLock); 525 CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable); 526 OMX_STRING name = const_cast<OMX_STRING>( 527 "OMX.google.android.index.enableAndroidNativeBuffers"); 528 529 OMX_INDEXTYPE index; 530 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 531 532 if (err != OMX_ErrorNone) { 533 CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name); 534 return StatusFromOMXError(err); 535 } 536 537 EnableAndroidNativeBuffersParams params; 538 InitOMXParams(¶ms); 539 params.nPortIndex = portIndex; 540 params.enable = enable; 541 542 err = OMX_SetParameter(mHandle, index, ¶ms); 543 CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index, 544 portString(portIndex), portIndex, enable); 545 return StatusFromOMXError(err); 546} 547 548status_t OMXNodeInstance::getGraphicBufferUsage( 549 OMX_U32 portIndex, OMX_U32* usage) { 550 Mutex::Autolock autoLock(mLock); 551 552 OMX_INDEXTYPE index; 553 OMX_STRING name = const_cast<OMX_STRING>( 554 "OMX.google.android.index.getAndroidNativeBufferUsage"); 555 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 556 557 if (err != OMX_ErrorNone) { 558 CLOG_ERROR(getExtensionIndex, err, "%s", name); 559 return StatusFromOMXError(err); 560 } 561 562 GetAndroidNativeBufferUsageParams params; 563 InitOMXParams(¶ms); 564 params.nPortIndex = portIndex; 565 566 err = OMX_GetParameter(mHandle, index, ¶ms); 567 if (err != OMX_ErrorNone) { 568 CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", name, index, 569 portString(portIndex), portIndex); 570 return StatusFromOMXError(err); 571 } 572 573 *usage = params.nUsage; 574 575 return OK; 576} 577 578status_t OMXNodeInstance::storeMetaDataInBuffers( 579 OMX_U32 portIndex, 580 OMX_BOOL enable) { 581 Mutex::Autolock autolock(mLock); 582 CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u en:%d", portString(portIndex), portIndex, enable); 583 return storeMetaDataInBuffers_l( 584 portIndex, enable, 585 OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */); 586} 587 588status_t OMXNodeInstance::storeMetaDataInBuffers_l( 589 OMX_U32 portIndex, 590 OMX_BOOL enable, 591 OMX_BOOL useGraphicBuffer, 592 OMX_BOOL *usingGraphicBufferInMetadata) { 593 if (mSailed) { 594 android_errorWriteLog(0x534e4554, "29422020"); 595 return INVALID_OPERATION; 596 } 597 if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { 598 android_errorWriteLog(0x534e4554, "26324358"); 599 return BAD_VALUE; 600 } 601 602 OMX_INDEXTYPE index; 603 OMX_STRING name = const_cast<OMX_STRING>( 604 "OMX.google.android.index.storeMetaDataInBuffers"); 605 606 OMX_STRING graphicBufferName = const_cast<OMX_STRING>( 607 "OMX.google.android.index.storeGraphicBufferInMetaData"); 608 if (usingGraphicBufferInMetadata == NULL) { 609 usingGraphicBufferInMetadata = &useGraphicBuffer; 610 } 611 612 OMX_ERRORTYPE err = 613 (useGraphicBuffer && portIndex == kPortIndexInput) 614 ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index) 615 : OMX_ErrorBadParameter; 616 if (err == OMX_ErrorNone) { 617 *usingGraphicBufferInMetadata = OMX_TRUE; 618 name = graphicBufferName; 619 } else { 620 err = OMX_GetExtensionIndex(mHandle, name, &index); 621 } 622 623 OMX_ERRORTYPE xerr = err; 624 if (err == OMX_ErrorNone) { 625 StoreMetaDataInBuffersParams params; 626 InitOMXParams(¶ms); 627 params.nPortIndex = portIndex; 628 params.bStoreMetaData = enable; 629 630 err = OMX_SetParameter(mHandle, index, ¶ms); 631 } 632 633 // don't log loud error if component does not support metadata mode on the output 634 if (err != OMX_ErrorNone) { 635 *usingGraphicBufferInMetadata = OMX_FALSE; 636 if (enable) { 637 mUsingMetadata[portIndex] = false; 638 } 639 if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) { 640 CLOGW("component does not support metadata mode; using fallback"); 641 } else if (xerr != OMX_ErrorNone) { 642 CLOG_ERROR(getExtensionIndex, xerr, "%s", name); 643 } else { 644 CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d GB=%d", name, index, 645 portString(portIndex), portIndex, enable, useGraphicBuffer); 646 } 647 } else { 648 mUsingMetadata[portIndex] = enable; 649 } 650 return StatusFromOMXError(err); 651} 652 653status_t OMXNodeInstance::prepareForAdaptivePlayback( 654 OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, 655 OMX_U32 maxFrameHeight) { 656 Mutex::Autolock autolock(mLock); 657 if (mSailed) { 658 android_errorWriteLog(0x534e4554, "29422020"); 659 return INVALID_OPERATION; 660 } 661 CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u", 662 portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); 663 664 OMX_INDEXTYPE index; 665 OMX_STRING name = const_cast<OMX_STRING>( 666 "OMX.google.android.index.prepareForAdaptivePlayback"); 667 668 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 669 if (err != OMX_ErrorNone) { 670 CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name); 671 return StatusFromOMXError(err); 672 } 673 674 PrepareForAdaptivePlaybackParams params; 675 InitOMXParams(¶ms); 676 params.nPortIndex = portIndex; 677 params.bEnable = enable; 678 params.nMaxFrameWidth = maxFrameWidth; 679 params.nMaxFrameHeight = maxFrameHeight; 680 681 err = OMX_SetParameter(mHandle, index, ¶ms); 682 CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d max=%ux%u", name, index, 683 portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); 684 return StatusFromOMXError(err); 685} 686 687status_t OMXNodeInstance::configureVideoTunnelMode( 688 OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync, 689 native_handle_t **sidebandHandle) { 690 Mutex::Autolock autolock(mLock); 691 if (mSailed) { 692 android_errorWriteLog(0x534e4554, "29422020"); 693 return INVALID_OPERATION; 694 } 695 CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u", 696 portString(portIndex), portIndex, tunneled, audioHwSync); 697 698 OMX_INDEXTYPE index; 699 OMX_STRING name = const_cast<OMX_STRING>( 700 "OMX.google.android.index.configureVideoTunnelMode"); 701 702 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 703 if (err != OMX_ErrorNone) { 704 CLOG_ERROR_IF(tunneled, getExtensionIndex, err, "%s", name); 705 return StatusFromOMXError(err); 706 } 707 708 ConfigureVideoTunnelModeParams tunnelParams; 709 InitOMXParams(&tunnelParams); 710 tunnelParams.nPortIndex = portIndex; 711 tunnelParams.bTunneled = tunneled; 712 tunnelParams.nAudioHwSync = audioHwSync; 713 err = OMX_SetParameter(mHandle, index, &tunnelParams); 714 if (err != OMX_ErrorNone) { 715 CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, 716 portString(portIndex), portIndex, tunneled, audioHwSync); 717 return StatusFromOMXError(err); 718 } 719 720 err = OMX_GetParameter(mHandle, index, &tunnelParams); 721 if (err != OMX_ErrorNone) { 722 CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, 723 portString(portIndex), portIndex, tunneled, audioHwSync); 724 return StatusFromOMXError(err); 725 } 726 if (sidebandHandle) { 727 *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow; 728 } 729 730 return OK; 731} 732 733status_t OMXNodeInstance::useBuffer( 734 OMX_U32 portIndex, const sp<IMemory> ¶ms, 735 OMX::buffer_id *buffer, OMX_BOOL crossProcess) { 736 Mutex::Autolock autoLock(mLock); 737 if (portIndex >= NELEM(mUsingMetadata)) { 738 return BAD_VALUE; 739 } 740 // We do not support metadata mode changes past buffer allocation 741 mSailed = true; 742 743 // metadata buffers are not connected cross process 744 BufferMeta *buffer_meta; 745 bool isMeta = mUsingMetadata[portIndex]; 746 bool useBackup = crossProcess && isMeta; // use a backup buffer instead of the actual buffer 747 OMX_U8 *data = static_cast<OMX_U8 *>(params->pointer()); 748 // allocate backup buffer 749 if (useBackup) { 750 data = new (std::nothrow) OMX_U8[params->size()]; 751 if (data == NULL) { 752 return NO_MEMORY; 753 } 754 memset(data, 0, params->size()); 755 756 buffer_meta = new BufferMeta( 757 params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, data); 758 } else { 759 buffer_meta = new BufferMeta( 760 params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, NULL); 761 } 762 763 OMX_BUFFERHEADERTYPE *header; 764 765 OMX_ERRORTYPE err = OMX_UseBuffer( 766 mHandle, &header, portIndex, buffer_meta, 767 params->size(), data); 768 769 if (err != OMX_ErrorNone) { 770 CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(portIndex, params->size(), params->pointer())); 771 772 delete buffer_meta; 773 buffer_meta = NULL; 774 775 *buffer = 0; 776 777 return StatusFromOMXError(err); 778 } 779 780 CHECK_EQ(header->pAppPrivate, buffer_meta); 781 782 *buffer = makeBufferID(header); 783 784 addActiveBuffer(portIndex, *buffer); 785 786 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 787 if (bufferSource != NULL && portIndex == kPortIndexInput) { 788 bufferSource->addCodecBuffer(header); 789 } 790 791 CLOG_BUFFER(useBuffer, NEW_BUFFER_FMT( 792 *buffer, portIndex, "%zu@%p", params->size(), params->pointer())); 793 return OK; 794} 795 796status_t OMXNodeInstance::useGraphicBuffer2_l( 797 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 798 OMX::buffer_id *buffer) { 799 800 // port definition 801 OMX_PARAM_PORTDEFINITIONTYPE def; 802 InitOMXParams(&def); 803 def.nPortIndex = portIndex; 804 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def); 805 if (err != OMX_ErrorNone) { 806 OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; 807 CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", 808 asString(index), index, portString(portIndex), portIndex); 809 return UNKNOWN_ERROR; 810 } 811 812 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex); 813 814 OMX_BUFFERHEADERTYPE *header = NULL; 815 OMX_U8* bufferHandle = const_cast<OMX_U8*>( 816 reinterpret_cast<const OMX_U8*>(graphicBuffer->handle)); 817 818 err = OMX_UseBuffer( 819 mHandle, 820 &header, 821 portIndex, 822 bufferMeta, 823 def.nBufferSize, 824 bufferHandle); 825 826 if (err != OMX_ErrorNone) { 827 CLOG_ERROR(useBuffer, err, BUFFER_FMT(portIndex, "%u@%p", def.nBufferSize, bufferHandle)); 828 delete bufferMeta; 829 bufferMeta = NULL; 830 *buffer = 0; 831 return StatusFromOMXError(err); 832 } 833 834 CHECK_EQ(header->pBuffer, bufferHandle); 835 CHECK_EQ(header->pAppPrivate, bufferMeta); 836 837 *buffer = makeBufferID(header); 838 839 addActiveBuffer(portIndex, *buffer); 840 CLOG_BUFFER(useGraphicBuffer2, NEW_BUFFER_FMT( 841 *buffer, portIndex, "%u@%p", def.nBufferSize, bufferHandle)); 842 return OK; 843} 844 845// XXX: This function is here for backwards compatibility. Once the OMX 846// implementations have been updated this can be removed and useGraphicBuffer2 847// can be renamed to useGraphicBuffer. 848status_t OMXNodeInstance::useGraphicBuffer( 849 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 850 OMX::buffer_id *buffer) { 851 Mutex::Autolock autoLock(mLock); 852 853 // See if the newer version of the extension is present. 854 OMX_INDEXTYPE index; 855 if (OMX_GetExtensionIndex( 856 mHandle, 857 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"), 858 &index) == OMX_ErrorNone) { 859 return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer); 860 } 861 862 OMX_STRING name = const_cast<OMX_STRING>( 863 "OMX.google.android.index.useAndroidNativeBuffer"); 864 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 865 if (err != OMX_ErrorNone) { 866 CLOG_ERROR(getExtensionIndex, err, "%s", name); 867 return StatusFromOMXError(err); 868 } 869 870 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex); 871 872 OMX_BUFFERHEADERTYPE *header; 873 874 OMX_VERSIONTYPE ver; 875 ver.s.nVersionMajor = 1; 876 ver.s.nVersionMinor = 0; 877 ver.s.nRevision = 0; 878 ver.s.nStep = 0; 879 UseAndroidNativeBufferParams params = { 880 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta, 881 &header, graphicBuffer, 882 }; 883 884 err = OMX_SetParameter(mHandle, index, ¶ms); 885 886 if (err != OMX_ErrorNone) { 887 CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index, 888 portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle); 889 890 delete bufferMeta; 891 bufferMeta = NULL; 892 893 *buffer = 0; 894 895 return StatusFromOMXError(err); 896 } 897 898 CHECK_EQ(header->pAppPrivate, bufferMeta); 899 900 *buffer = makeBufferID(header); 901 902 addActiveBuffer(portIndex, *buffer); 903 CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT( 904 *buffer, portIndex, "GB=%p", graphicBuffer->handle)); 905 return OK; 906} 907 908status_t OMXNodeInstance::updateGraphicBufferInMeta( 909 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 910 OMX::buffer_id buffer) { 911 Mutex::Autolock autoLock(mLock); 912 913 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex); 914 if (header == NULL) { 915 return BAD_VALUE; 916 } 917 VideoDecoderOutputMetaData *metadata = 918 (VideoDecoderOutputMetaData *)(header->pBuffer); 919 BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate); 920 bufferMeta->setGraphicBuffer(graphicBuffer); 921 metadata->eType = kMetadataBufferTypeGrallocSource; 922 metadata->pHandle = graphicBuffer->handle; 923 CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", 924 portString(portIndex), portIndex, buffer, graphicBuffer->handle); 925 return OK; 926} 927 928status_t OMXNodeInstance::createInputSurface( 929 OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) { 930 Mutex::Autolock autolock(mLock); 931 status_t err; 932 933 // only allow graphic source on input port, when there are no allocated buffers yet 934 if (portIndex != kPortIndexInput) { 935 android_errorWriteLog(0x534e4554, "29422020"); 936 return BAD_VALUE; 937 } else if (mNumPortBuffers[portIndex] > 0) { 938 android_errorWriteLog(0x534e4554, "29422020"); 939 return INVALID_OPERATION; 940 } 941 942 const sp<GraphicBufferSource> surfaceCheck = getGraphicBufferSource(); 943 if (surfaceCheck != NULL) { 944 return ALREADY_EXISTS; 945 } 946 947 // Input buffers will hold meta-data (gralloc references). 948 OMX_BOOL usingGraphicBuffer = OMX_FALSE; 949 err = storeMetaDataInBuffers_l( 950 portIndex, OMX_TRUE, 951 OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer); 952 if (err != OK) { 953 return err; 954 } 955 956 // Retrieve the width and height of the graphic buffer, set when the 957 // codec was configured. 958 OMX_PARAM_PORTDEFINITIONTYPE def; 959 InitOMXParams(&def); 960 def.nPortIndex = portIndex; 961 OMX_ERRORTYPE oerr = OMX_GetParameter( 962 mHandle, OMX_IndexParamPortDefinition, &def); 963 if (oerr != OMX_ErrorNone) { 964 OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; 965 CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u", 966 asString(index), index, portString(portIndex), portIndex); 967 return UNKNOWN_ERROR; 968 } 969 970 if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) { 971 CLOGW("createInputSurface requires COLOR_FormatSurface " 972 "(AndroidOpaque) color format instead of %s(%#x)", 973 asString(def.format.video.eColorFormat), def.format.video.eColorFormat); 974 return INVALID_OPERATION; 975 } 976 977 GraphicBufferSource* bufferSource = new GraphicBufferSource( 978 this, def.format.video.nFrameWidth, def.format.video.nFrameHeight, 979 def.nBufferCountActual, usingGraphicBuffer); 980 if ((err = bufferSource->initCheck()) != OK) { 981 delete bufferSource; 982 return err; 983 } 984 setGraphicBufferSource(bufferSource); 985 986 *bufferProducer = bufferSource->getIGraphicBufferProducer(); 987 return OK; 988} 989 990status_t OMXNodeInstance::signalEndOfInputStream() { 991 // For non-Surface input, the MediaCodec should convert the call to a 992 // pair of requests (dequeue input buffer, queue input buffer with EOS 993 // flag set). Seems easier than doing the equivalent from here. 994 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 995 if (bufferSource == NULL) { 996 CLOGW("signalEndOfInputStream can only be used with Surface input"); 997 return INVALID_OPERATION; 998 } 999 return bufferSource->signalEndOfInputStream(); 1000} 1001 1002status_t OMXNodeInstance::allocateBuffer( 1003 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, 1004 void **buffer_data) { 1005 Mutex::Autolock autoLock(mLock); 1006 // We do not support metadata mode changes past buffer allocation 1007 mSailed = true; 1008 1009 BufferMeta *buffer_meta = new BufferMeta(size, portIndex); 1010 1011 OMX_BUFFERHEADERTYPE *header; 1012 1013 OMX_ERRORTYPE err = OMX_AllocateBuffer( 1014 mHandle, &header, portIndex, buffer_meta, size); 1015 1016 if (err != OMX_ErrorNone) { 1017 CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size)); 1018 delete buffer_meta; 1019 buffer_meta = NULL; 1020 1021 *buffer = 0; 1022 1023 return StatusFromOMXError(err); 1024 } 1025 1026 CHECK_EQ(header->pAppPrivate, buffer_meta); 1027 1028 *buffer = makeBufferID(header); 1029 *buffer_data = header->pBuffer; 1030 1031 addActiveBuffer(portIndex, *buffer); 1032 1033 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 1034 if (bufferSource != NULL && portIndex == kPortIndexInput) { 1035 bufferSource->addCodecBuffer(header); 1036 } 1037 CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data)); 1038 1039 return OK; 1040} 1041 1042status_t OMXNodeInstance::allocateBufferWithBackup( 1043 OMX_U32 portIndex, const sp<IMemory> ¶ms, 1044 OMX::buffer_id *buffer, OMX_BOOL crossProcess) { 1045 Mutex::Autolock autoLock(mLock); 1046 if (portIndex >= NELEM(mUsingMetadata)) { 1047 return BAD_VALUE; 1048 } 1049 // We do not support metadata mode changes past buffer allocation 1050 mSailed = true; 1051 1052 // metadata buffers are not connected cross process 1053 bool isMeta = mUsingMetadata[portIndex]; 1054 bool copy = !(crossProcess && isMeta); 1055 1056 BufferMeta *buffer_meta = new BufferMeta( 1057 params, portIndex, 1058 (portIndex == kPortIndexInput) && copy /* copyToOmx */, 1059 (portIndex == kPortIndexOutput) && copy /* copyFromOmx */, 1060 NULL /* data */); 1061 1062 OMX_BUFFERHEADERTYPE *header; 1063 1064 OMX_ERRORTYPE err = OMX_AllocateBuffer( 1065 mHandle, &header, portIndex, buffer_meta, params->size()); 1066 1067 if (err != OMX_ErrorNone) { 1068 CLOG_ERROR(allocateBufferWithBackup, err, 1069 SIMPLE_BUFFER(portIndex, params->size(), params->pointer())); 1070 delete buffer_meta; 1071 buffer_meta = NULL; 1072 1073 *buffer = 0; 1074 1075 return StatusFromOMXError(err); 1076 } 1077 1078 CHECK_EQ(header->pAppPrivate, buffer_meta); 1079 memset(header->pBuffer, 0, header->nAllocLen); 1080 1081 *buffer = makeBufferID(header); 1082 1083 addActiveBuffer(portIndex, *buffer); 1084 1085 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 1086 if (bufferSource != NULL && portIndex == kPortIndexInput) { 1087 bufferSource->addCodecBuffer(header); 1088 } 1089 1090 CLOG_BUFFER(allocateBufferWithBackup, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p :> %p", 1091 params->size(), params->pointer(), header->pBuffer)); 1092 1093 return OK; 1094} 1095 1096status_t OMXNodeInstance::freeBuffer( 1097 OMX_U32 portIndex, OMX::buffer_id buffer) { 1098 Mutex::Autolock autoLock(mLock); 1099 CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer); 1100 1101 removeActiveBuffer(portIndex, buffer); 1102 1103 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex); 1104 if (header == NULL) { 1105 return BAD_VALUE; 1106 } 1107 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); 1108 1109 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); 1110 CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer); 1111 1112 delete buffer_meta; 1113 buffer_meta = NULL; 1114 invalidateBufferID(buffer); 1115 1116 return StatusFromOMXError(err); 1117} 1118 1119status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) { 1120 Mutex::Autolock autoLock(mLock); 1121 1122 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput); 1123 if (header == NULL) { 1124 return BAD_VALUE; 1125 } 1126 header->nFilledLen = 0; 1127 header->nOffset = 0; 1128 header->nFlags = 0; 1129 1130 { 1131 Mutex::Autolock _l(mDebugLock); 1132 mOutputBuffersWithCodec.add(header); 1133 CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header))); 1134 } 1135 1136 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); 1137 if (err != OMX_ErrorNone) { 1138 CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header)); 1139 Mutex::Autolock _l(mDebugLock); 1140 mOutputBuffersWithCodec.remove(header); 1141 } 1142 return StatusFromOMXError(err); 1143} 1144 1145status_t OMXNodeInstance::emptyBuffer( 1146 OMX::buffer_id buffer, 1147 OMX_U32 rangeOffset, OMX_U32 rangeLength, 1148 OMX_U32 flags, OMX_TICKS timestamp) { 1149 Mutex::Autolock autoLock(mLock); 1150 1151 // no emptybuffer if using input surface 1152 if (getGraphicBufferSource() != NULL) { 1153 android_errorWriteLog(0x534e4554, "29422020"); 1154 return INVALID_OPERATION; 1155 } 1156 1157 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput); 1158 // rangeLength and rangeOffset must be a subset of the allocated data in the buffer. 1159 // corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0. 1160 if (header == NULL 1161 || rangeOffset > header->nAllocLen 1162 || rangeLength > header->nAllocLen - rangeOffset) { 1163 return BAD_VALUE; 1164 } 1165 header->nFilledLen = rangeLength; 1166 header->nOffset = rangeOffset; 1167 1168 BufferMeta *buffer_meta = 1169 static_cast<BufferMeta *>(header->pAppPrivate); 1170 buffer_meta->CopyToOMX(header); 1171 1172 return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer); 1173} 1174 1175// log queued buffer activity for the next few input and/or output frames 1176// if logging at internal state level 1177void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) { 1178 if (DEBUG == ADebug::kDebugInternalState) { 1179 DEBUG_BUMP = ADebug::kDebugAll; 1180 if (numInputBuffers > 0) { 1181 mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers; 1182 } 1183 if (numOutputBuffers > 0) { 1184 mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers; 1185 } 1186 } 1187} 1188 1189void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) { 1190 if (mDebugLevelBumpPendingBuffers[portIndex]) { 1191 --mDebugLevelBumpPendingBuffers[portIndex]; 1192 } 1193 if (!mDebugLevelBumpPendingBuffers[0] 1194 && !mDebugLevelBumpPendingBuffers[1]) { 1195 DEBUG_BUMP = DEBUG; 1196 } 1197} 1198 1199status_t OMXNodeInstance::emptyBuffer_l( 1200 OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr) { 1201 header->nFlags = flags; 1202 header->nTimeStamp = timestamp; 1203 1204 { 1205 Mutex::Autolock _l(mDebugLock); 1206 mInputBuffersWithCodec.add(header); 1207 1208 // bump internal-state debug level for 2 input frames past a buffer with CSD 1209 if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) { 1210 bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */); 1211 } 1212 1213 CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header))); 1214 } 1215 1216 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 1217 CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header)); 1218 1219 { 1220 Mutex::Autolock _l(mDebugLock); 1221 if (err != OMX_ErrorNone) { 1222 mInputBuffersWithCodec.remove(header); 1223 } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) { 1224 unbumpDebugLevel_l(kPortIndexInput); 1225 } 1226 } 1227 1228 return StatusFromOMXError(err); 1229} 1230 1231// like emptyBuffer, but the data is already in header->pBuffer 1232status_t OMXNodeInstance::emptyDirectBuffer( 1233 OMX_BUFFERHEADERTYPE *header, 1234 OMX_U32 rangeOffset, OMX_U32 rangeLength, 1235 OMX_U32 flags, OMX_TICKS timestamp) { 1236 Mutex::Autolock autoLock(mLock); 1237 1238 header->nFilledLen = rangeLength; 1239 header->nOffset = rangeOffset; 1240 1241 return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer); 1242} 1243 1244status_t OMXNodeInstance::getExtensionIndex( 1245 const char *parameterName, OMX_INDEXTYPE *index) { 1246 Mutex::Autolock autoLock(mLock); 1247 1248 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 1249 mHandle, const_cast<char *>(parameterName), index); 1250 1251 return StatusFromOMXError(err); 1252} 1253 1254inline static const char *asString(IOMX::InternalOptionType i, const char *def = "??") { 1255 switch (i) { 1256 case IOMX::INTERNAL_OPTION_SUSPEND: return "SUSPEND"; 1257 case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: 1258 return "REPEAT_PREVIOUS_FRAME_DELAY"; 1259 case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: return "MAX_TIMESTAMP_GAP"; 1260 case IOMX::INTERNAL_OPTION_START_TIME: return "START_TIME"; 1261 case IOMX::INTERNAL_OPTION_TIME_LAPSE: return "TIME_LAPSE"; 1262 default: return def; 1263 } 1264} 1265 1266status_t OMXNodeInstance::setInternalOption( 1267 OMX_U32 portIndex, 1268 IOMX::InternalOptionType type, 1269 const void *data, 1270 size_t size) { 1271 CLOG_CONFIG(setInternalOption, "%s(%d): %s:%u %zu@%p", 1272 asString(type), type, portString(portIndex), portIndex, size, data); 1273 switch (type) { 1274 case IOMX::INTERNAL_OPTION_SUSPEND: 1275 case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: 1276 case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: 1277 case IOMX::INTERNAL_OPTION_START_TIME: 1278 case IOMX::INTERNAL_OPTION_TIME_LAPSE: 1279 { 1280 const sp<GraphicBufferSource> &bufferSource = 1281 getGraphicBufferSource(); 1282 1283 if (bufferSource == NULL || portIndex != kPortIndexInput) { 1284 CLOGW("setInternalOption is only for Surface input"); 1285 return ERROR_UNSUPPORTED; 1286 } 1287 1288 if (type == IOMX::INTERNAL_OPTION_SUSPEND) { 1289 if (size != sizeof(bool)) { 1290 return INVALID_OPERATION; 1291 } 1292 1293 bool suspend = *(bool *)data; 1294 CLOG_CONFIG(setInternalOption, "suspend=%d", suspend); 1295 bufferSource->suspend(suspend); 1296 } else if (type == 1297 IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){ 1298 if (size != sizeof(int64_t)) { 1299 return INVALID_OPERATION; 1300 } 1301 1302 int64_t delayUs = *(int64_t *)data; 1303 CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs); 1304 return bufferSource->setRepeatPreviousFrameDelayUs(delayUs); 1305 } else if (type == 1306 IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){ 1307 if (size != sizeof(int64_t)) { 1308 return INVALID_OPERATION; 1309 } 1310 1311 int64_t maxGapUs = *(int64_t *)data; 1312 CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs); 1313 return bufferSource->setMaxTimestampGapUs(maxGapUs); 1314 } else if (type == IOMX::INTERNAL_OPTION_START_TIME) { 1315 if (size != sizeof(int64_t)) { 1316 return INVALID_OPERATION; 1317 } 1318 1319 int64_t skipFramesBeforeUs = *(int64_t *)data; 1320 CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs); 1321 bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs); 1322 } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE 1323 if (size != sizeof(int64_t) * 2) { 1324 return INVALID_OPERATION; 1325 } 1326 1327 int64_t timePerFrameUs = ((int64_t *)data)[0]; 1328 int64_t timePerCaptureUs = ((int64_t *)data)[1]; 1329 CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", 1330 (long long)timePerFrameUs, (long long)timePerCaptureUs); 1331 1332 bufferSource->setTimeLapseUs((int64_t *)data); 1333 } 1334 1335 return OK; 1336 } 1337 1338 default: 1339 return ERROR_UNSUPPORTED; 1340 } 1341} 1342 1343void OMXNodeInstance::onMessage(const omx_message &msg) { 1344 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 1345 1346 if (msg.type == omx_message::FILL_BUFFER_DONE) { 1347 OMX_BUFFERHEADERTYPE *buffer = 1348 findBufferHeader(msg.u.extended_buffer_data.buffer, kPortIndexOutput); 1349 if (buffer == NULL) { 1350 return; 1351 } 1352 1353 { 1354 Mutex::Autolock _l(mDebugLock); 1355 mOutputBuffersWithCodec.remove(buffer); 1356 1357 CLOG_BUMPED_BUFFER( 1358 FBD, WITH_STATS(FULL_BUFFER(msg.u.extended_buffer_data.buffer, buffer))); 1359 1360 unbumpDebugLevel_l(kPortIndexOutput); 1361 } 1362 1363 BufferMeta *buffer_meta = 1364 static_cast<BufferMeta *>(buffer->pAppPrivate); 1365 1366 buffer_meta->CopyFromOMX(buffer); 1367 1368 if (bufferSource != NULL) { 1369 // fix up the buffer info (especially timestamp) if needed 1370 bufferSource->codecBufferFilled(buffer); 1371 1372 omx_message newMsg = msg; 1373 newMsg.u.extended_buffer_data.timestamp = buffer->nTimeStamp; 1374 mObserver->onMessage(newMsg); 1375 return; 1376 } 1377 } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { 1378 OMX_BUFFERHEADERTYPE *buffer = 1379 findBufferHeader(msg.u.buffer_data.buffer, kPortIndexInput); 1380 if (buffer == NULL) { 1381 return; 1382 } 1383 1384 { 1385 Mutex::Autolock _l(mDebugLock); 1386 mInputBuffersWithCodec.remove(buffer); 1387 1388 CLOG_BUMPED_BUFFER( 1389 EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer))); 1390 } 1391 1392 if (bufferSource != NULL) { 1393 // This is one of the buffers used exclusively by 1394 // GraphicBufferSource. 1395 // Don't dispatch a message back to ACodec, since it doesn't 1396 // know that anyone asked to have the buffer emptied and will 1397 // be very confused. 1398 bufferSource->codecBufferEmptied(buffer); 1399 return; 1400 } 1401 } 1402 1403 mObserver->onMessage(msg); 1404} 1405 1406void OMXNodeInstance::onObserverDied(OMXMaster *master) { 1407 ALOGE("!!! Observer died. Quickly, do something, ... anything..."); 1408 1409 // Try to force shutdown of the node and hope for the best. 1410 freeNode(master); 1411} 1412 1413void OMXNodeInstance::onGetHandleFailed() { 1414 delete this; 1415} 1416 1417// OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here. 1418// Don't try to acquire mLock here -- in rare circumstances this will hang. 1419void OMXNodeInstance::onEvent( 1420 OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { 1421 const char *arg1String = "??"; 1422 const char *arg2String = "??"; 1423 ADebug::Level level = ADebug::kDebugInternalState; 1424 1425 switch (event) { 1426 case OMX_EventCmdComplete: 1427 arg1String = asString((OMX_COMMANDTYPE)arg1); 1428 switch (arg1) { 1429 case OMX_CommandStateSet: 1430 arg2String = asString((OMX_STATETYPE)arg2); 1431 level = ADebug::kDebugState; 1432 break; 1433 case OMX_CommandFlush: 1434 case OMX_CommandPortEnable: 1435 { 1436 // bump internal-state debug level for 2 input and output frames 1437 Mutex::Autolock _l(mDebugLock); 1438 bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); 1439 } 1440 // fall through 1441 default: 1442 arg2String = portString(arg2); 1443 } 1444 break; 1445 case OMX_EventError: 1446 arg1String = asString((OMX_ERRORTYPE)arg1); 1447 level = ADebug::kDebugLifeCycle; 1448 break; 1449 case OMX_EventPortSettingsChanged: 1450 arg2String = asString((OMX_INDEXEXTTYPE)arg2); 1451 // fall through 1452 default: 1453 arg1String = portString(arg1); 1454 } 1455 1456 CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)", 1457 asString(event), event, arg1String, arg1, arg2String, arg2); 1458 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 1459 1460 if (bufferSource != NULL 1461 && event == OMX_EventCmdComplete 1462 && arg1 == OMX_CommandStateSet 1463 && arg2 == OMX_StateExecuting) { 1464 bufferSource->omxExecuting(); 1465 } 1466 1467 // allow configuration if we return to the loaded state 1468 if (event == OMX_EventCmdComplete 1469 && arg1 == OMX_CommandStateSet 1470 && arg2 == OMX_StateLoaded) { 1471 mSailed = false; 1472 } 1473} 1474 1475// static 1476OMX_ERRORTYPE OMXNodeInstance::OnEvent( 1477 OMX_IN OMX_HANDLETYPE /* hComponent */, 1478 OMX_IN OMX_PTR pAppData, 1479 OMX_IN OMX_EVENTTYPE eEvent, 1480 OMX_IN OMX_U32 nData1, 1481 OMX_IN OMX_U32 nData2, 1482 OMX_IN OMX_PTR pEventData) { 1483 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 1484 if (instance->mDying) { 1485 return OMX_ErrorNone; 1486 } 1487 return instance->owner()->OnEvent( 1488 instance->nodeID(), eEvent, nData1, nData2, pEventData); 1489} 1490 1491// static 1492OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone( 1493 OMX_IN OMX_HANDLETYPE /* hComponent */, 1494 OMX_IN OMX_PTR pAppData, 1495 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 1496 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 1497 if (instance->mDying) { 1498 return OMX_ErrorNone; 1499 } 1500 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), 1501 instance->findBufferID(pBuffer), pBuffer); 1502} 1503 1504// static 1505OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( 1506 OMX_IN OMX_HANDLETYPE /* hComponent */, 1507 OMX_IN OMX_PTR pAppData, 1508 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 1509 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 1510 if (instance->mDying) { 1511 return OMX_ErrorNone; 1512 } 1513 return instance->owner()->OnFillBufferDone(instance->nodeID(), 1514 instance->findBufferID(pBuffer), pBuffer); 1515} 1516 1517void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { 1518 ActiveBuffer active; 1519 active.mPortIndex = portIndex; 1520 active.mID = id; 1521 mActiveBuffers.push(active); 1522 1523 if (portIndex < NELEM(mNumPortBuffers)) { 1524 ++mNumPortBuffers[portIndex]; 1525 } 1526} 1527 1528void OMXNodeInstance::removeActiveBuffer( 1529 OMX_U32 portIndex, OMX::buffer_id id) { 1530 for (size_t i = 0; i < mActiveBuffers.size(); ++i) { 1531 if (mActiveBuffers[i].mPortIndex == portIndex 1532 && mActiveBuffers[i].mID == id) { 1533 mActiveBuffers.removeItemsAt(i); 1534 1535 if (portIndex < NELEM(mNumPortBuffers)) { 1536 --mNumPortBuffers[portIndex]; 1537 } 1538 return; 1539 } 1540 } 1541 1542 CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id); 1543} 1544 1545void OMXNodeInstance::freeActiveBuffers() { 1546 // Make sure to count down here, as freeBuffer will in turn remove 1547 // the active buffer from the vector... 1548 for (size_t i = mActiveBuffers.size(); i--;) { 1549 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); 1550 } 1551} 1552 1553OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { 1554 if (bufferHeader == NULL) { 1555 return 0; 1556 } 1557 Mutex::Autolock autoLock(mBufferIDLock); 1558 OMX::buffer_id buffer; 1559 do { // handle the very unlikely case of ID overflow 1560 if (++mBufferIDCount == 0) { 1561 ++mBufferIDCount; 1562 } 1563 buffer = (OMX::buffer_id)mBufferIDCount; 1564 } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0); 1565 mBufferIDToBufferHeader.add(buffer, bufferHeader); 1566 mBufferHeaderToBufferID.add(bufferHeader, buffer); 1567 return buffer; 1568} 1569 1570OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader( 1571 OMX::buffer_id buffer, OMX_U32 portIndex) { 1572 if (buffer == 0) { 1573 return NULL; 1574 } 1575 Mutex::Autolock autoLock(mBufferIDLock); 1576 ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer); 1577 if (index < 0) { 1578 ALOGW("findBufferHeader: buffer %u not found", buffer); 1579 return NULL; 1580 } 1581 OMX_BUFFERHEADERTYPE *header = mBufferIDToBufferHeader.valueAt(index); 1582 BufferMeta *buffer_meta = 1583 static_cast<BufferMeta *>(header->pAppPrivate); 1584 if (buffer_meta->getPortIndex() != portIndex) { 1585 ALOGW("findBufferHeader: buffer %u found but with incorrect port index.", buffer); 1586 android_errorWriteLog(0x534e4554, "28816827"); 1587 return NULL; 1588 } 1589 return header; 1590} 1591 1592OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { 1593 if (bufferHeader == NULL) { 1594 return 0; 1595 } 1596 Mutex::Autolock autoLock(mBufferIDLock); 1597 return mBufferHeaderToBufferID.valueFor(bufferHeader); 1598} 1599 1600void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) { 1601 if (buffer == 0) { 1602 return; 1603 } 1604 Mutex::Autolock autoLock(mBufferIDLock); 1605 mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer)); 1606 mBufferIDToBufferHeader.removeItem(buffer); 1607} 1608 1609} // namespace android 1610