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