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