OMXNodeInstance.cpp revision 10dac29441a24144029e8a194d07eb17db40b7e5
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 explicit BufferMeta(const sp<IMemory> &mem, bool is_backup = false) 97 : mMem(mem), 98 mIsBackup(is_backup) { 99 } 100 101 explicit BufferMeta(size_t size) 102 : mSize(size), 103 mIsBackup(false) { 104 } 105 106 explicit 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) { 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 bufferMeta->setGraphicBuffer(graphicBuffer); 858 if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource 859 && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 860 VideoGrallocMetadata &metadata = *(VideoGrallocMetadata *)(header->pBuffer); 861 metadata.eType = kMetadataBufferTypeGrallocSource; 862 metadata.pHandle = graphicBuffer == NULL ? NULL : graphicBuffer->handle; 863 } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer 864 && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 865 VideoNativeMetadata &metadata = *(VideoNativeMetadata *)(header->pBuffer); 866 metadata.eType = kMetadataBufferTypeANWBuffer; 867 metadata.pBuffer = graphicBuffer == NULL ? NULL : graphicBuffer->getNativeBuffer(); 868 metadata.nFenceFd = -1; 869 } else { 870 CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x bad type (%d) or size (%u)", 871 portString(portIndex), portIndex, buffer, mMetadataType[portIndex], header->nAllocLen); 872 return BAD_VALUE; 873 } 874 875 CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", 876 portString(portIndex), portIndex, buffer, 877 graphicBuffer == NULL ? NULL : graphicBuffer->handle); 878 return OK; 879} 880 881status_t OMXNodeInstance::updateGraphicBufferInMeta( 882 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 883 OMX::buffer_id buffer) { 884 Mutex::Autolock autoLock(mLock); 885 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); 886 return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header); 887} 888 889status_t OMXNodeInstance::updateNativeHandleInMeta( 890 OMX_U32 portIndex, const sp<NativeHandle>& nativeHandle, OMX::buffer_id buffer) { 891 Mutex::Autolock autoLock(mLock); 892 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); 893 // No need to check |nativeHandle| since NULL is valid for it as below. 894 if (header == NULL) { 895 ALOGE("b/25884056"); 896 return BAD_VALUE; 897 } 898 899 if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { 900 return BAD_VALUE; 901 } 902 903 BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate); 904 // update backup buffer for input, codec buffer for output 905 sp<ABuffer> data = bufferMeta->getBuffer( 906 header, portIndex == kPortIndexInput /* backup */, false /* limit */); 907 bufferMeta->setNativeHandle(nativeHandle); 908 if (mMetadataType[portIndex] == kMetadataBufferTypeNativeHandleSource 909 && data->capacity() >= sizeof(VideoNativeHandleMetadata)) { 910 VideoNativeHandleMetadata &metadata = *(VideoNativeHandleMetadata *)(data->data()); 911 metadata.eType = mMetadataType[portIndex]; 912 metadata.pHandle = 913 nativeHandle == NULL ? NULL : const_cast<native_handle*>(nativeHandle->handle()); 914 } else { 915 CLOG_ERROR(updateNativeHandleInMeta, BAD_VALUE, "%s:%u, %#x bad type (%d) or size (%zu)", 916 portString(portIndex), portIndex, buffer, mMetadataType[portIndex], data->capacity()); 917 return BAD_VALUE; 918 } 919 920 CLOG_BUFFER(updateNativeHandleInMeta, "%s:%u, %#x := %p", 921 portString(portIndex), portIndex, buffer, 922 nativeHandle == NULL ? NULL : nativeHandle->handle()); 923 return OK; 924} 925 926status_t OMXNodeInstance::createGraphicBufferSource( 927 OMX_U32 portIndex, sp<IGraphicBufferConsumer> bufferConsumer, MetadataBufferType *type) { 928 status_t err; 929 930 const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource(); 931 if (surfaceCheck != NULL) { 932 if (portIndex < NELEM(mMetadataType) && type != NULL) { 933 *type = mMetadataType[portIndex]; 934 } 935 return ALREADY_EXISTS; 936 } 937 938 // Input buffers will hold meta-data (ANativeWindowBuffer references). 939 if (type != NULL) { 940 *type = kMetadataBufferTypeANWBuffer; 941 } 942 err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, type); 943 if (err != OK) { 944 return err; 945 } 946 947 // Retrieve the width and height of the graphic buffer, set when the 948 // codec was configured. 949 OMX_PARAM_PORTDEFINITIONTYPE def; 950 InitOMXParams(&def); 951 def.nPortIndex = portIndex; 952 OMX_ERRORTYPE oerr = OMX_GetParameter( 953 mHandle, OMX_IndexParamPortDefinition, &def); 954 if (oerr != OMX_ErrorNone) { 955 OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; 956 CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u", 957 asString(index), index, portString(portIndex), portIndex); 958 return UNKNOWN_ERROR; 959 } 960 961 if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) { 962 CLOGW("createInputSurface requires COLOR_FormatSurface " 963 "(AndroidOpaque) color format instead of %s(%#x)", 964 asString(def.format.video.eColorFormat), def.format.video.eColorFormat); 965 return INVALID_OPERATION; 966 } 967 968 uint32_t usageBits; 969 oerr = OMX_GetParameter( 970 mHandle, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &usageBits); 971 if (oerr != OMX_ErrorNone) { 972 usageBits = 0; 973 } 974 975 sp<GraphicBufferSource> bufferSource = new GraphicBufferSource(this, 976 def.format.video.nFrameWidth, 977 def.format.video.nFrameHeight, 978 def.nBufferCountActual, 979 usageBits, 980 bufferConsumer); 981 982 if ((err = bufferSource->initCheck()) != OK) { 983 return err; 984 } 985 setGraphicBufferSource(bufferSource); 986 987 return OK; 988} 989 990status_t OMXNodeInstance::createInputSurface( 991 OMX_U32 portIndex, android_dataspace dataSpace, 992 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { 993 if (bufferProducer == NULL) { 994 ALOGE("b/25884056"); 995 return BAD_VALUE; 996 } 997 998 Mutex::Autolock autolock(mLock); 999 status_t err = createGraphicBufferSource(portIndex, NULL /* bufferConsumer */, type); 1000 1001 if (err != OK) { 1002 return err; 1003 } 1004 1005 mGraphicBufferSource->setDefaultDataSpace(dataSpace); 1006 1007 *bufferProducer = mGraphicBufferSource->getIGraphicBufferProducer(); 1008 return OK; 1009} 1010 1011//static 1012status_t OMXNodeInstance::createPersistentInputSurface( 1013 sp<IGraphicBufferProducer> *bufferProducer, 1014 sp<IGraphicBufferConsumer> *bufferConsumer) { 1015 if (bufferProducer == NULL || bufferConsumer == NULL) { 1016 ALOGE("b/25884056"); 1017 return BAD_VALUE; 1018 } 1019 String8 name("GraphicBufferSource"); 1020 1021 sp<IGraphicBufferProducer> producer; 1022 sp<IGraphicBufferConsumer> consumer; 1023 BufferQueue::createBufferQueue(&producer, &consumer); 1024 consumer->setConsumerName(name); 1025 consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER); 1026 1027 sp<BufferQueue::ProxyConsumerListener> proxy = 1028 new BufferQueue::ProxyConsumerListener(NULL); 1029 status_t err = consumer->consumerConnect(proxy, false); 1030 if (err != NO_ERROR) { 1031 ALOGE("Error connecting to BufferQueue: %s (%d)", 1032 strerror(-err), err); 1033 return err; 1034 } 1035 1036 *bufferProducer = producer; 1037 *bufferConsumer = consumer; 1038 1039 return OK; 1040} 1041 1042status_t OMXNodeInstance::setInputSurface( 1043 OMX_U32 portIndex, const sp<IGraphicBufferConsumer> &bufferConsumer, 1044 MetadataBufferType *type) { 1045 Mutex::Autolock autolock(mLock); 1046 return createGraphicBufferSource(portIndex, bufferConsumer, type); 1047} 1048 1049void OMXNodeInstance::signalEvent(OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { 1050 mOwner->OnEvent(mNodeID, event, arg1, arg2, NULL); 1051} 1052 1053status_t OMXNodeInstance::signalEndOfInputStream() { 1054 // For non-Surface input, the MediaCodec should convert the call to a 1055 // pair of requests (dequeue input buffer, queue input buffer with EOS 1056 // flag set). Seems easier than doing the equivalent from here. 1057 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 1058 if (bufferSource == NULL) { 1059 CLOGW("signalEndOfInputStream can only be used with Surface input"); 1060 return INVALID_OPERATION; 1061 } 1062 return bufferSource->signalEndOfInputStream(); 1063} 1064 1065status_t OMXNodeInstance::allocateSecureBuffer( 1066 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, 1067 void **buffer_data, sp<NativeHandle> *native_handle) { 1068 if (buffer == NULL || buffer_data == NULL || native_handle == NULL) { 1069 ALOGE("b/25884056"); 1070 return BAD_VALUE; 1071 } 1072 1073 Mutex::Autolock autoLock(mLock); 1074 1075 BufferMeta *buffer_meta = new BufferMeta(size); 1076 1077 OMX_BUFFERHEADERTYPE *header; 1078 1079 OMX_ERRORTYPE err = OMX_AllocateBuffer( 1080 mHandle, &header, portIndex, buffer_meta, size); 1081 1082 if (err != OMX_ErrorNone) { 1083 CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size)); 1084 delete buffer_meta; 1085 buffer_meta = NULL; 1086 1087 *buffer = 0; 1088 1089 return StatusFromOMXError(err); 1090 } 1091 1092 CHECK_EQ(header->pAppPrivate, buffer_meta); 1093 1094 *buffer = makeBufferID(header); 1095 if (mSecureBufferType[portIndex] == kSecureBufferTypeNativeHandle) { 1096 *buffer_data = NULL; 1097 *native_handle = NativeHandle::create( 1098 (native_handle_t *)header->pBuffer, false /* ownsHandle */); 1099 } else { 1100 *buffer_data = header->pBuffer; 1101 *native_handle = NULL; 1102 } 1103 1104 addActiveBuffer(portIndex, *buffer); 1105 1106 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 1107 if (bufferSource != NULL && portIndex == kPortIndexInput) { 1108 bufferSource->addCodecBuffer(header); 1109 } 1110 CLOG_BUFFER(allocateSecureBuffer, NEW_BUFFER_FMT( 1111 *buffer, portIndex, "%zu@%p:%p", size, *buffer_data, 1112 *native_handle == NULL ? NULL : (*native_handle)->handle())); 1113 1114 return OK; 1115} 1116 1117status_t OMXNodeInstance::allocateBufferWithBackup( 1118 OMX_U32 portIndex, const sp<IMemory> ¶ms, 1119 OMX::buffer_id *buffer, OMX_U32 allottedSize) { 1120 if (params == NULL || buffer == NULL) { 1121 ALOGE("b/25884056"); 1122 return BAD_VALUE; 1123 } 1124 1125 Mutex::Autolock autoLock(mLock); 1126 if (allottedSize > params->size()) { 1127 return BAD_VALUE; 1128 } 1129 1130 BufferMeta *buffer_meta = new BufferMeta(params, true); 1131 1132 OMX_BUFFERHEADERTYPE *header; 1133 1134 OMX_ERRORTYPE err = OMX_AllocateBuffer( 1135 mHandle, &header, portIndex, buffer_meta, allottedSize); 1136 if (err != OMX_ErrorNone) { 1137 CLOG_ERROR(allocateBufferWithBackup, err, 1138 SIMPLE_BUFFER(portIndex, (size_t)allottedSize, params->pointer())); 1139 delete buffer_meta; 1140 buffer_meta = NULL; 1141 1142 *buffer = 0; 1143 1144 return StatusFromOMXError(err); 1145 } 1146 1147 CHECK_EQ(header->pAppPrivate, buffer_meta); 1148 1149 *buffer = makeBufferID(header); 1150 1151 addActiveBuffer(portIndex, *buffer); 1152 1153 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 1154 if (bufferSource != NULL && portIndex == kPortIndexInput) { 1155 bufferSource->addCodecBuffer(header); 1156 } 1157 1158 CLOG_BUFFER(allocateBufferWithBackup, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p :> %u@%p", 1159 params->size(), params->pointer(), allottedSize, header->pBuffer)); 1160 1161 return OK; 1162} 1163 1164status_t OMXNodeInstance::freeBuffer( 1165 OMX_U32 portIndex, OMX::buffer_id buffer) { 1166 Mutex::Autolock autoLock(mLock); 1167 CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer); 1168 1169 removeActiveBuffer(portIndex, buffer); 1170 1171 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); 1172 if (header == NULL) { 1173 ALOGE("b/25884056"); 1174 return BAD_VALUE; 1175 } 1176 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); 1177 1178 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); 1179 CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer); 1180 1181 delete buffer_meta; 1182 buffer_meta = NULL; 1183 invalidateBufferID(buffer); 1184 1185 return StatusFromOMXError(err); 1186} 1187 1188status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) { 1189 Mutex::Autolock autoLock(mLock); 1190 1191 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); 1192 if (header == NULL) { 1193 ALOGE("b/25884056"); 1194 return BAD_VALUE; 1195 } 1196 header->nFilledLen = 0; 1197 header->nOffset = 0; 1198 header->nFlags = 0; 1199 1200 // meta now owns fenceFd 1201 status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexOutput); 1202 if (res != OK) { 1203 CLOG_ERROR(fillBuffer::storeFenceInMeta, res, EMPTY_BUFFER(buffer, header, fenceFd)); 1204 return res; 1205 } 1206 1207 { 1208 Mutex::Autolock _l(mDebugLock); 1209 mOutputBuffersWithCodec.add(header); 1210 CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header, fenceFd))); 1211 } 1212 1213 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); 1214 if (err != OMX_ErrorNone) { 1215 CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header, fenceFd)); 1216 Mutex::Autolock _l(mDebugLock); 1217 mOutputBuffersWithCodec.remove(header); 1218 } 1219 return StatusFromOMXError(err); 1220} 1221 1222status_t OMXNodeInstance::emptyBuffer( 1223 OMX::buffer_id buffer, 1224 OMX_U32 rangeOffset, OMX_U32 rangeLength, 1225 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 1226 Mutex::Autolock autoLock(mLock); 1227 1228 OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); 1229 if (header == NULL) { 1230 ALOGE("b/25884056"); 1231 return BAD_VALUE; 1232 } 1233 BufferMeta *buffer_meta = 1234 static_cast<BufferMeta *>(header->pAppPrivate); 1235 sp<ABuffer> backup = buffer_meta->getBuffer(header, true /* backup */, false /* limit */); 1236 sp<ABuffer> codec = buffer_meta->getBuffer(header, false /* backup */, false /* limit */); 1237 1238 // convert incoming ANW meta buffers if component is configured for gralloc metadata mode 1239 // ignore rangeOffset in this case 1240 if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource 1241 && backup->capacity() >= sizeof(VideoNativeMetadata) 1242 && codec->capacity() >= sizeof(VideoGrallocMetadata) 1243 && ((VideoNativeMetadata *)backup->base())->eType 1244 == kMetadataBufferTypeANWBuffer) { 1245 VideoNativeMetadata &backupMeta = *(VideoNativeMetadata *)backup->base(); 1246 VideoGrallocMetadata &codecMeta = *(VideoGrallocMetadata *)codec->base(); 1247 CLOG_BUFFER(emptyBuffer, "converting ANWB %p to handle %p", 1248 backupMeta.pBuffer, backupMeta.pBuffer->handle); 1249 codecMeta.pHandle = backupMeta.pBuffer != NULL ? backupMeta.pBuffer->handle : NULL; 1250 codecMeta.eType = kMetadataBufferTypeGrallocSource; 1251 header->nFilledLen = rangeLength ? sizeof(codecMeta) : 0; 1252 header->nOffset = 0; 1253 } else { 1254 // rangeLength and rangeOffset must be a subset of the allocated data in the buffer. 1255 // corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0. 1256 if (rangeOffset > header->nAllocLen 1257 || rangeLength > header->nAllocLen - rangeOffset) { 1258 CLOG_ERROR(emptyBuffer, OMX_ErrorBadParameter, FULL_BUFFER(NULL, header, fenceFd)); 1259 if (fenceFd >= 0) { 1260 ::close(fenceFd); 1261 } 1262 return BAD_VALUE; 1263 } 1264 header->nFilledLen = rangeLength; 1265 header->nOffset = rangeOffset; 1266 1267 buffer_meta->CopyToOMX(header); 1268 } 1269 1270 return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer, fenceFd); 1271} 1272 1273// log queued buffer activity for the next few input and/or output frames 1274// if logging at internal state level 1275void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) { 1276 if (DEBUG == ADebug::kDebugInternalState) { 1277 DEBUG_BUMP = ADebug::kDebugAll; 1278 if (numInputBuffers > 0) { 1279 mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers; 1280 } 1281 if (numOutputBuffers > 0) { 1282 mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers; 1283 } 1284 } 1285} 1286 1287void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) { 1288 if (mDebugLevelBumpPendingBuffers[portIndex]) { 1289 --mDebugLevelBumpPendingBuffers[portIndex]; 1290 } 1291 if (!mDebugLevelBumpPendingBuffers[0] 1292 && !mDebugLevelBumpPendingBuffers[1]) { 1293 DEBUG_BUMP = DEBUG; 1294 } 1295} 1296 1297status_t OMXNodeInstance::storeFenceInMeta_l( 1298 OMX_BUFFERHEADERTYPE *header, int fenceFd, OMX_U32 portIndex) { 1299 // propagate fence if component supports it; wait for it otherwise 1300 OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nFilledLen : header->nAllocLen; 1301 if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer 1302 && metaSize >= sizeof(VideoNativeMetadata)) { 1303 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer); 1304 if (nativeMeta.nFenceFd >= 0) { 1305 ALOGE("fence (%d) already exists in meta", nativeMeta.nFenceFd); 1306 if (fenceFd >= 0) { 1307 ::close(fenceFd); 1308 } 1309 return ALREADY_EXISTS; 1310 } 1311 nativeMeta.nFenceFd = fenceFd; 1312 } else if (fenceFd >= 0) { 1313 CLOG_BUFFER(storeFenceInMeta, "waiting for fence %d", fenceFd); 1314 sp<Fence> fence = new Fence(fenceFd); 1315 return fence->wait(IOMX::kFenceTimeoutMs); 1316 } 1317 return OK; 1318} 1319 1320int OMXNodeInstance::retrieveFenceFromMeta_l( 1321 OMX_BUFFERHEADERTYPE *header, OMX_U32 portIndex) { 1322 OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nAllocLen : header->nFilledLen; 1323 int fenceFd = -1; 1324 if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer 1325 && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 1326 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer); 1327 if (nativeMeta.eType == kMetadataBufferTypeANWBuffer) { 1328 fenceFd = nativeMeta.nFenceFd; 1329 nativeMeta.nFenceFd = -1; 1330 } 1331 if (metaSize < sizeof(nativeMeta) && fenceFd >= 0) { 1332 CLOG_ERROR(foundFenceInEmptyMeta, BAD_VALUE, FULL_BUFFER( 1333 NULL, header, nativeMeta.nFenceFd)); 1334 fenceFd = -1; 1335 } 1336 } 1337 return fenceFd; 1338} 1339 1340status_t OMXNodeInstance::emptyBuffer_l( 1341 OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp, 1342 intptr_t debugAddr, int fenceFd) { 1343 header->nFlags = flags; 1344 header->nTimeStamp = timestamp; 1345 1346 status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexInput); 1347 if (res != OK) { 1348 CLOG_ERROR(emptyBuffer::storeFenceInMeta, res, WITH_STATS( 1349 FULL_BUFFER(debugAddr, header, fenceFd))); 1350 return res; 1351 } 1352 1353 { 1354 Mutex::Autolock _l(mDebugLock); 1355 mInputBuffersWithCodec.add(header); 1356 1357 // bump internal-state debug level for 2 input frames past a buffer with CSD 1358 if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) { 1359 bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */); 1360 } 1361 1362 CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header, fenceFd))); 1363 } 1364 1365 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 1366 CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header, fenceFd)); 1367 1368 { 1369 Mutex::Autolock _l(mDebugLock); 1370 if (err != OMX_ErrorNone) { 1371 mInputBuffersWithCodec.remove(header); 1372 } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) { 1373 unbumpDebugLevel_l(kPortIndexInput); 1374 } 1375 } 1376 1377 return StatusFromOMXError(err); 1378} 1379 1380// like emptyBuffer, but the data is already in header->pBuffer 1381status_t OMXNodeInstance::emptyGraphicBuffer( 1382 OMX_BUFFERHEADERTYPE *header, const sp<GraphicBuffer> &graphicBuffer, 1383 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 1384 if (header == NULL) { 1385 ALOGE("b/25884056"); 1386 return BAD_VALUE; 1387 } 1388 1389 Mutex::Autolock autoLock(mLock); 1390 OMX::buffer_id buffer = findBufferID(header); 1391 status_t err = updateGraphicBufferInMeta_l(kPortIndexInput, graphicBuffer, buffer, header); 1392 if (err != OK) { 1393 CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER( 1394 (intptr_t)header->pBuffer, header, fenceFd)); 1395 return err; 1396 } 1397 1398 header->nOffset = 0; 1399 header->nFilledLen = graphicBuffer == NULL ? 0 : header->nAllocLen; 1400 return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer, fenceFd); 1401} 1402 1403status_t OMXNodeInstance::getExtensionIndex( 1404 const char *parameterName, OMX_INDEXTYPE *index) { 1405 Mutex::Autolock autoLock(mLock); 1406 1407 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 1408 mHandle, const_cast<char *>(parameterName), index); 1409 1410 return StatusFromOMXError(err); 1411} 1412 1413inline static const char *asString(IOMX::InternalOptionType i, const char *def = "??") { 1414 switch (i) { 1415 case IOMX::INTERNAL_OPTION_SUSPEND: return "SUSPEND"; 1416 case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: 1417 return "REPEAT_PREVIOUS_FRAME_DELAY"; 1418 case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: return "MAX_TIMESTAMP_GAP"; 1419 case IOMX::INTERNAL_OPTION_MAX_FPS: return "MAX_FPS"; 1420 case IOMX::INTERNAL_OPTION_START_TIME: return "START_TIME"; 1421 case IOMX::INTERNAL_OPTION_TIME_LAPSE: return "TIME_LAPSE"; 1422 default: return def; 1423 } 1424} 1425 1426template<typename T> 1427static bool getInternalOption( 1428 const void *data, size_t size, T *out) { 1429 if (size != sizeof(T)) { 1430 return false; 1431 } 1432 *out = *(T*)data; 1433 return true; 1434} 1435 1436status_t OMXNodeInstance::setInternalOption( 1437 OMX_U32 portIndex, 1438 IOMX::InternalOptionType type, 1439 const void *data, 1440 size_t size) { 1441 CLOG_CONFIG(setInternalOption, "%s(%d): %s:%u %zu@%p", 1442 asString(type), type, portString(portIndex), portIndex, size, data); 1443 switch (type) { 1444 case IOMX::INTERNAL_OPTION_SUSPEND: 1445 case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: 1446 case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: 1447 case IOMX::INTERNAL_OPTION_MAX_FPS: 1448 case IOMX::INTERNAL_OPTION_START_TIME: 1449 case IOMX::INTERNAL_OPTION_TIME_LAPSE: 1450 case IOMX::INTERNAL_OPTION_COLOR_ASPECTS: 1451 { 1452 const sp<GraphicBufferSource> &bufferSource = 1453 getGraphicBufferSource(); 1454 1455 if (bufferSource == NULL || portIndex != kPortIndexInput) { 1456 CLOGW("setInternalOption is only for Surface input"); 1457 return ERROR_UNSUPPORTED; 1458 } 1459 1460 if (type == IOMX::INTERNAL_OPTION_SUSPEND) { 1461 bool suspend; 1462 if (!getInternalOption(data, size, &suspend)) { 1463 return INVALID_OPERATION; 1464 } 1465 1466 CLOG_CONFIG(setInternalOption, "suspend=%d", suspend); 1467 bufferSource->suspend(suspend); 1468 } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY) { 1469 int64_t delayUs; 1470 if (!getInternalOption(data, size, &delayUs)) { 1471 return INVALID_OPERATION; 1472 } 1473 1474 CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs); 1475 return bufferSource->setRepeatPreviousFrameDelayUs(delayUs); 1476 } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP) { 1477 int64_t maxGapUs; 1478 if (!getInternalOption(data, size, &maxGapUs)) { 1479 return INVALID_OPERATION; 1480 } 1481 1482 CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs); 1483 return bufferSource->setMaxTimestampGapUs(maxGapUs); 1484 } else if (type == IOMX::INTERNAL_OPTION_MAX_FPS) { 1485 float maxFps; 1486 if (!getInternalOption(data, size, &maxFps)) { 1487 return INVALID_OPERATION; 1488 } 1489 1490 CLOG_CONFIG(setInternalOption, "maxFps=%f", maxFps); 1491 return bufferSource->setMaxFps(maxFps); 1492 } else if (type == IOMX::INTERNAL_OPTION_START_TIME) { 1493 int64_t skipFramesBeforeUs; 1494 if (!getInternalOption(data, size, &skipFramesBeforeUs)) { 1495 return INVALID_OPERATION; 1496 } 1497 1498 CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs); 1499 bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs); 1500 } else if (type == IOMX::INTERNAL_OPTION_TIME_LAPSE) { 1501 GraphicBufferSource::TimeLapseConfig config; 1502 if (!getInternalOption(data, size, &config)) { 1503 return INVALID_OPERATION; 1504 } 1505 1506 CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", 1507 (long long)config.mTimePerFrameUs, (long long)config.mTimePerCaptureUs); 1508 1509 return bufferSource->setTimeLapseConfig(config); 1510 } else if (type == IOMX::INTERNAL_OPTION_COLOR_ASPECTS) { 1511 ColorAspects aspects; 1512 if (!getInternalOption(data, size, &aspects)) { 1513 return INVALID_OPERATION; 1514 } 1515 1516 CLOG_CONFIG(setInternalOption, "setting color aspects"); 1517 bufferSource->setColorAspects(aspects); 1518 } 1519 1520 return OK; 1521 } 1522 1523 default: 1524 return ERROR_UNSUPPORTED; 1525 } 1526} 1527 1528bool OMXNodeInstance::handleMessage(omx_message &msg) { 1529 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 1530 1531 if (msg.type == omx_message::FILL_BUFFER_DONE) { 1532 OMX_BUFFERHEADERTYPE *buffer = 1533 findBufferHeader(msg.u.extended_buffer_data.buffer); 1534 if (buffer == NULL) { 1535 ALOGE("b/25884056"); 1536 return BAD_VALUE; 1537 } 1538 1539 { 1540 Mutex::Autolock _l(mDebugLock); 1541 mOutputBuffersWithCodec.remove(buffer); 1542 1543 CLOG_BUMPED_BUFFER( 1544 FBD, WITH_STATS(FULL_BUFFER( 1545 msg.u.extended_buffer_data.buffer, buffer, msg.fenceFd))); 1546 1547 unbumpDebugLevel_l(kPortIndexOutput); 1548 } 1549 1550 BufferMeta *buffer_meta = 1551 static_cast<BufferMeta *>(buffer->pAppPrivate); 1552 1553 if (buffer->nOffset + buffer->nFilledLen < buffer->nOffset 1554 || buffer->nOffset + buffer->nFilledLen > buffer->nAllocLen) { 1555 CLOG_ERROR(onFillBufferDone, OMX_ErrorBadParameter, 1556 FULL_BUFFER(NULL, buffer, msg.fenceFd)); 1557 } 1558 buffer_meta->CopyFromOMX(buffer); 1559 1560 if (bufferSource != NULL) { 1561 // fix up the buffer info (especially timestamp) if needed 1562 bufferSource->codecBufferFilled(buffer); 1563 1564 msg.u.extended_buffer_data.timestamp = buffer->nTimeStamp; 1565 } 1566 } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { 1567 OMX_BUFFERHEADERTYPE *buffer = 1568 findBufferHeader(msg.u.buffer_data.buffer); 1569 1570 { 1571 Mutex::Autolock _l(mDebugLock); 1572 mInputBuffersWithCodec.remove(buffer); 1573 1574 CLOG_BUMPED_BUFFER( 1575 EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer, msg.fenceFd))); 1576 } 1577 1578 if (bufferSource != NULL) { 1579 // This is one of the buffers used exclusively by 1580 // GraphicBufferSource. 1581 // Don't dispatch a message back to ACodec, since it doesn't 1582 // know that anyone asked to have the buffer emptied and will 1583 // be very confused. 1584 bufferSource->codecBufferEmptied(buffer, msg.fenceFd); 1585 return true; 1586 } 1587 } 1588 1589 return false; 1590} 1591 1592void OMXNodeInstance::onMessages(std::list<omx_message> &messages) { 1593 for (std::list<omx_message>::iterator it = messages.begin(); it != messages.end(); ) { 1594 if (handleMessage(*it)) { 1595 messages.erase(it++); 1596 } else { 1597 ++it; 1598 } 1599 } 1600 1601 if (!messages.empty()) { 1602 mObserver->onMessages(messages); 1603 } 1604} 1605 1606void OMXNodeInstance::onObserverDied(OMXMaster *master) { 1607 ALOGE("!!! Observer died. Quickly, do something, ... anything..."); 1608 1609 // Try to force shutdown of the node and hope for the best. 1610 freeNode(master); 1611} 1612 1613void OMXNodeInstance::onGetHandleFailed() { 1614 delete this; 1615} 1616 1617// OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here. 1618// Don't try to acquire mLock here -- in rare circumstances this will hang. 1619void OMXNodeInstance::onEvent( 1620 OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { 1621 const char *arg1String = "??"; 1622 const char *arg2String = "??"; 1623 ADebug::Level level = ADebug::kDebugInternalState; 1624 1625 switch (event) { 1626 case OMX_EventCmdComplete: 1627 arg1String = asString((OMX_COMMANDTYPE)arg1); 1628 switch (arg1) { 1629 case OMX_CommandStateSet: 1630 arg2String = asString((OMX_STATETYPE)arg2); 1631 level = ADebug::kDebugState; 1632 break; 1633 case OMX_CommandFlush: 1634 case OMX_CommandPortEnable: 1635 { 1636 // bump internal-state debug level for 2 input and output frames 1637 Mutex::Autolock _l(mDebugLock); 1638 bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); 1639 } 1640 // fall through 1641 default: 1642 arg2String = portString(arg2); 1643 } 1644 break; 1645 case OMX_EventError: 1646 arg1String = asString((OMX_ERRORTYPE)arg1); 1647 level = ADebug::kDebugLifeCycle; 1648 break; 1649 case OMX_EventPortSettingsChanged: 1650 arg2String = asString((OMX_INDEXEXTTYPE)arg2); 1651 // fall through 1652 default: 1653 arg1String = portString(arg1); 1654 } 1655 1656 CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)", 1657 asString(event), event, arg1String, arg1, arg2String, arg2); 1658 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 1659 1660 if (bufferSource != NULL 1661 && event == OMX_EventCmdComplete 1662 && arg1 == OMX_CommandStateSet 1663 && arg2 == OMX_StateExecuting) { 1664 bufferSource->omxExecuting(); 1665 } 1666} 1667 1668// static 1669OMX_ERRORTYPE OMXNodeInstance::OnEvent( 1670 OMX_IN OMX_HANDLETYPE /* hComponent */, 1671 OMX_IN OMX_PTR pAppData, 1672 OMX_IN OMX_EVENTTYPE eEvent, 1673 OMX_IN OMX_U32 nData1, 1674 OMX_IN OMX_U32 nData2, 1675 OMX_IN OMX_PTR pEventData) { 1676 if (pAppData == NULL) { 1677 ALOGE("b/25884056"); 1678 return OMX_ErrorBadParameter; 1679 } 1680 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 1681 if (instance->mDying) { 1682 return OMX_ErrorNone; 1683 } 1684 return instance->owner()->OnEvent( 1685 instance->nodeID(), eEvent, nData1, nData2, pEventData); 1686} 1687 1688// static 1689OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone( 1690 OMX_IN OMX_HANDLETYPE /* hComponent */, 1691 OMX_IN OMX_PTR pAppData, 1692 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 1693 if (pAppData == NULL) { 1694 ALOGE("b/25884056"); 1695 return OMX_ErrorBadParameter; 1696 } 1697 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 1698 if (instance->mDying) { 1699 return OMX_ErrorNone; 1700 } 1701 int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput); 1702 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), 1703 instance->findBufferID(pBuffer), pBuffer, fenceFd); 1704} 1705 1706// static 1707OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( 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()->OnFillBufferDone(instance->nodeID(), 1721 instance->findBufferID(pBuffer), pBuffer, fenceFd); 1722} 1723 1724void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { 1725 ActiveBuffer active; 1726 active.mPortIndex = portIndex; 1727 active.mID = id; 1728 mActiveBuffers.push(active); 1729 1730 if (portIndex < NELEM(mNumPortBuffers)) { 1731 ++mNumPortBuffers[portIndex]; 1732 } 1733} 1734 1735void OMXNodeInstance::removeActiveBuffer( 1736 OMX_U32 portIndex, OMX::buffer_id id) { 1737 for (size_t i = 0; i < mActiveBuffers.size(); ++i) { 1738 if (mActiveBuffers[i].mPortIndex == portIndex 1739 && mActiveBuffers[i].mID == id) { 1740 mActiveBuffers.removeItemsAt(i); 1741 1742 if (portIndex < NELEM(mNumPortBuffers)) { 1743 --mNumPortBuffers[portIndex]; 1744 } 1745 return; 1746 } 1747 } 1748 1749 CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id); 1750} 1751 1752void OMXNodeInstance::freeActiveBuffers() { 1753 // Make sure to count down here, as freeBuffer will in turn remove 1754 // the active buffer from the vector... 1755 for (size_t i = mActiveBuffers.size(); i > 0;) { 1756 i--; 1757 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); 1758 } 1759} 1760 1761OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { 1762 if (bufferHeader == NULL) { 1763 return 0; 1764 } 1765 Mutex::Autolock autoLock(mBufferIDLock); 1766 OMX::buffer_id buffer; 1767 do { // handle the very unlikely case of ID overflow 1768 if (++mBufferIDCount == 0) { 1769 ++mBufferIDCount; 1770 } 1771 buffer = (OMX::buffer_id)mBufferIDCount; 1772 } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0); 1773 mBufferIDToBufferHeader.add(buffer, bufferHeader); 1774 mBufferHeaderToBufferID.add(bufferHeader, buffer); 1775 return buffer; 1776} 1777 1778OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) { 1779 if (buffer == 0) { 1780 return NULL; 1781 } 1782 Mutex::Autolock autoLock(mBufferIDLock); 1783 ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer); 1784 if (index < 0) { 1785 CLOGW("findBufferHeader: buffer %u not found", buffer); 1786 return NULL; 1787 } 1788 return mBufferIDToBufferHeader.valueAt(index); 1789} 1790 1791OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { 1792 if (bufferHeader == NULL) { 1793 return 0; 1794 } 1795 Mutex::Autolock autoLock(mBufferIDLock); 1796 ssize_t index = mBufferHeaderToBufferID.indexOfKey(bufferHeader); 1797 if (index < 0) { 1798 CLOGW("findBufferID: bufferHeader %p not found", bufferHeader); 1799 return 0; 1800 } 1801 return mBufferHeaderToBufferID.valueAt(index); 1802} 1803 1804void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) { 1805 if (buffer == 0) { 1806 return; 1807 } 1808 Mutex::Autolock autoLock(mBufferIDLock); 1809 ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer); 1810 if (index < 0) { 1811 CLOGW("invalidateBufferID: buffer %u not found", buffer); 1812 return; 1813 } 1814 mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueAt(index)); 1815 mBufferIDToBufferHeader.removeItemsAt(index); 1816} 1817 1818} // namespace android 1819