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