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 "../include/OMXNodeInstance.h" 22 #include "OMXMaster.h" 23 #include "GraphicBufferSource.h" 24 25 #include <OMX_Component.h> 26 27 #include <binder/IMemory.h> 28 #include <gui/BufferQueue.h> 29 #include <HardwareAPI.h> 30 #include <media/stagefright/foundation/ADebug.h> 31 #include <media/stagefright/MediaErrors.h> 32 33 static const OMX_U32 kPortIndexInput = 0; 34 35 namespace android { 36 37 struct BufferMeta { 38 BufferMeta(const sp<IMemory> &mem, bool is_backup = false) 39 : mMem(mem), 40 mIsBackup(is_backup) { 41 } 42 43 BufferMeta(size_t size) 44 : mSize(size), 45 mIsBackup(false) { 46 } 47 48 BufferMeta(const sp<GraphicBuffer> &graphicBuffer) 49 : mGraphicBuffer(graphicBuffer), 50 mIsBackup(false) { 51 } 52 53 void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) { 54 if (!mIsBackup) { 55 return; 56 } 57 58 memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, 59 header->pBuffer + header->nOffset, 60 header->nFilledLen); 61 } 62 63 void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { 64 if (!mIsBackup) { 65 return; 66 } 67 68 memcpy(header->pBuffer + header->nOffset, 69 (const OMX_U8 *)mMem->pointer() + header->nOffset, 70 header->nFilledLen); 71 } 72 73 private: 74 sp<GraphicBuffer> mGraphicBuffer; 75 sp<IMemory> mMem; 76 size_t mSize; 77 bool mIsBackup; 78 79 BufferMeta(const BufferMeta &); 80 BufferMeta &operator=(const BufferMeta &); 81 }; 82 83 // static 84 OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = { 85 &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone 86 }; 87 88 OMXNodeInstance::OMXNodeInstance( 89 OMX *owner, const sp<IOMXObserver> &observer) 90 : mOwner(owner), 91 mNodeID(NULL), 92 mHandle(NULL), 93 mObserver(observer), 94 mDying(false) { 95 } 96 97 OMXNodeInstance::~OMXNodeInstance() { 98 CHECK(mHandle == NULL); 99 } 100 101 void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) { 102 CHECK(mHandle == NULL); 103 mNodeID = node_id; 104 mHandle = handle; 105 } 106 107 sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() { 108 Mutex::Autolock autoLock(mGraphicBufferSourceLock); 109 return mGraphicBufferSource; 110 } 111 112 void OMXNodeInstance::setGraphicBufferSource( 113 const sp<GraphicBufferSource>& bufferSource) { 114 Mutex::Autolock autoLock(mGraphicBufferSourceLock); 115 mGraphicBufferSource = bufferSource; 116 } 117 118 OMX *OMXNodeInstance::owner() { 119 return mOwner; 120 } 121 122 sp<IOMXObserver> OMXNodeInstance::observer() { 123 return mObserver; 124 } 125 126 OMX::node_id OMXNodeInstance::nodeID() { 127 return mNodeID; 128 } 129 130 static status_t StatusFromOMXError(OMX_ERRORTYPE err) { 131 switch (err) { 132 case OMX_ErrorNone: 133 return OK; 134 case OMX_ErrorUnsupportedSetting: 135 return ERROR_UNSUPPORTED; 136 default: 137 return UNKNOWN_ERROR; 138 } 139 } 140 141 status_t OMXNodeInstance::freeNode(OMXMaster *master) { 142 static int32_t kMaxNumIterations = 10; 143 144 // Transition the node from its current state all the way down 145 // to "Loaded". 146 // This ensures that all active buffers are properly freed even 147 // for components that don't do this themselves on a call to 148 // "FreeHandle". 149 150 // The code below may trigger some more events to be dispatched 151 // by the OMX component - we want to ignore them as our client 152 // does not expect them. 153 mDying = true; 154 155 OMX_STATETYPE state; 156 CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone); 157 switch (state) { 158 case OMX_StateExecuting: 159 { 160 ALOGV("forcing Executing->Idle"); 161 sendCommand(OMX_CommandStateSet, OMX_StateIdle); 162 OMX_ERRORTYPE err; 163 int32_t iteration = 0; 164 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone 165 && state != OMX_StateIdle 166 && state != OMX_StateInvalid) { 167 if (++iteration > kMaxNumIterations) { 168 ALOGE("component failed to enter Idle state, aborting."); 169 state = OMX_StateInvalid; 170 break; 171 } 172 173 usleep(100000); 174 } 175 CHECK_EQ(err, OMX_ErrorNone); 176 177 if (state == OMX_StateInvalid) { 178 break; 179 } 180 181 // fall through 182 } 183 184 case OMX_StateIdle: 185 { 186 ALOGV("forcing Idle->Loaded"); 187 sendCommand(OMX_CommandStateSet, OMX_StateLoaded); 188 189 freeActiveBuffers(); 190 191 OMX_ERRORTYPE err; 192 int32_t iteration = 0; 193 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone 194 && state != OMX_StateLoaded 195 && state != OMX_StateInvalid) { 196 if (++iteration > kMaxNumIterations) { 197 ALOGE("component failed to enter Loaded state, aborting."); 198 state = OMX_StateInvalid; 199 break; 200 } 201 202 ALOGV("waiting for Loaded state..."); 203 usleep(100000); 204 } 205 CHECK_EQ(err, OMX_ErrorNone); 206 207 // fall through 208 } 209 210 case OMX_StateLoaded: 211 case OMX_StateInvalid: 212 break; 213 214 default: 215 CHECK(!"should not be here, unknown state."); 216 break; 217 } 218 219 ALOGV("calling destroyComponentInstance"); 220 OMX_ERRORTYPE err = master->destroyComponentInstance( 221 static_cast<OMX_COMPONENTTYPE *>(mHandle)); 222 ALOGV("destroyComponentInstance returned err %d", err); 223 224 mHandle = NULL; 225 226 if (err != OMX_ErrorNone) { 227 ALOGE("FreeHandle FAILED with error 0x%08x.", err); 228 } 229 230 mOwner->invalidateNodeID(mNodeID); 231 mNodeID = NULL; 232 233 ALOGV("OMXNodeInstance going away."); 234 delete this; 235 236 return StatusFromOMXError(err); 237 } 238 239 status_t OMXNodeInstance::sendCommand( 240 OMX_COMMANDTYPE cmd, OMX_S32 param) { 241 Mutex::Autolock autoLock(mLock); 242 243 OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL); 244 return StatusFromOMXError(err); 245 } 246 247 status_t OMXNodeInstance::getParameter( 248 OMX_INDEXTYPE index, void *params, size_t size) { 249 Mutex::Autolock autoLock(mLock); 250 251 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); 252 253 return StatusFromOMXError(err); 254 } 255 256 status_t OMXNodeInstance::setParameter( 257 OMX_INDEXTYPE index, const void *params, size_t size) { 258 Mutex::Autolock autoLock(mLock); 259 260 OMX_ERRORTYPE err = OMX_SetParameter( 261 mHandle, index, const_cast<void *>(params)); 262 263 return StatusFromOMXError(err); 264 } 265 266 status_t OMXNodeInstance::getConfig( 267 OMX_INDEXTYPE index, void *params, size_t size) { 268 Mutex::Autolock autoLock(mLock); 269 270 OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params); 271 return StatusFromOMXError(err); 272 } 273 274 status_t OMXNodeInstance::setConfig( 275 OMX_INDEXTYPE index, const void *params, size_t size) { 276 Mutex::Autolock autoLock(mLock); 277 278 OMX_ERRORTYPE err = OMX_SetConfig( 279 mHandle, index, const_cast<void *>(params)); 280 281 return StatusFromOMXError(err); 282 } 283 284 status_t OMXNodeInstance::getState(OMX_STATETYPE* state) { 285 Mutex::Autolock autoLock(mLock); 286 287 OMX_ERRORTYPE err = OMX_GetState(mHandle, state); 288 289 return StatusFromOMXError(err); 290 } 291 292 status_t OMXNodeInstance::enableGraphicBuffers( 293 OMX_U32 portIndex, OMX_BOOL enable) { 294 Mutex::Autolock autoLock(mLock); 295 OMX_STRING name = const_cast<OMX_STRING>( 296 "OMX.google.android.index.enableAndroidNativeBuffers"); 297 298 OMX_INDEXTYPE index; 299 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 300 301 if (err != OMX_ErrorNone) { 302 if (enable) { 303 ALOGE("OMX_GetExtensionIndex %s failed", name); 304 } 305 306 return StatusFromOMXError(err); 307 } 308 309 OMX_VERSIONTYPE ver; 310 ver.s.nVersionMajor = 1; 311 ver.s.nVersionMinor = 0; 312 ver.s.nRevision = 0; 313 ver.s.nStep = 0; 314 EnableAndroidNativeBuffersParams params = { 315 sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable, 316 }; 317 318 err = OMX_SetParameter(mHandle, index, ¶ms); 319 320 if (err != OMX_ErrorNone) { 321 ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)", 322 err, err); 323 324 return UNKNOWN_ERROR; 325 } 326 327 return OK; 328 } 329 330 status_t OMXNodeInstance::getGraphicBufferUsage( 331 OMX_U32 portIndex, OMX_U32* usage) { 332 Mutex::Autolock autoLock(mLock); 333 334 OMX_INDEXTYPE index; 335 OMX_STRING name = const_cast<OMX_STRING>( 336 "OMX.google.android.index.getAndroidNativeBufferUsage"); 337 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 338 339 if (err != OMX_ErrorNone) { 340 ALOGE("OMX_GetExtensionIndex %s failed", name); 341 342 return StatusFromOMXError(err); 343 } 344 345 OMX_VERSIONTYPE ver; 346 ver.s.nVersionMajor = 1; 347 ver.s.nVersionMinor = 0; 348 ver.s.nRevision = 0; 349 ver.s.nStep = 0; 350 GetAndroidNativeBufferUsageParams params = { 351 sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0, 352 }; 353 354 err = OMX_GetParameter(mHandle, index, ¶ms); 355 356 if (err != OMX_ErrorNone) { 357 ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)", 358 err, err); 359 return UNKNOWN_ERROR; 360 } 361 362 *usage = params.nUsage; 363 364 return OK; 365 } 366 367 status_t OMXNodeInstance::storeMetaDataInBuffers( 368 OMX_U32 portIndex, 369 OMX_BOOL enable) { 370 Mutex::Autolock autolock(mLock); 371 return storeMetaDataInBuffers_l(portIndex, enable); 372 } 373 374 status_t OMXNodeInstance::storeMetaDataInBuffers_l( 375 OMX_U32 portIndex, 376 OMX_BOOL enable) { 377 OMX_INDEXTYPE index; 378 OMX_STRING name = const_cast<OMX_STRING>( 379 "OMX.google.android.index.storeMetaDataInBuffers"); 380 381 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 382 if (err != OMX_ErrorNone) { 383 ALOGE("OMX_GetExtensionIndex %s failed", name); 384 385 return StatusFromOMXError(err); 386 } 387 388 StoreMetaDataInBuffersParams params; 389 memset(¶ms, 0, sizeof(params)); 390 params.nSize = sizeof(params); 391 392 // Version: 1.0.0.0 393 params.nVersion.s.nVersionMajor = 1; 394 395 params.nPortIndex = portIndex; 396 params.bStoreMetaData = enable; 397 if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { 398 ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err); 399 return UNKNOWN_ERROR; 400 } 401 return err; 402 } 403 404 status_t OMXNodeInstance::useBuffer( 405 OMX_U32 portIndex, const sp<IMemory> ¶ms, 406 OMX::buffer_id *buffer) { 407 Mutex::Autolock autoLock(mLock); 408 409 BufferMeta *buffer_meta = new BufferMeta(params); 410 411 OMX_BUFFERHEADERTYPE *header; 412 413 OMX_ERRORTYPE err = OMX_UseBuffer( 414 mHandle, &header, portIndex, buffer_meta, 415 params->size(), static_cast<OMX_U8 *>(params->pointer())); 416 417 if (err != OMX_ErrorNone) { 418 ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); 419 420 delete buffer_meta; 421 buffer_meta = NULL; 422 423 *buffer = 0; 424 425 return UNKNOWN_ERROR; 426 } 427 428 CHECK_EQ(header->pAppPrivate, buffer_meta); 429 430 *buffer = header; 431 432 addActiveBuffer(portIndex, *buffer); 433 434 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 435 if (bufferSource != NULL && portIndex == kPortIndexInput) { 436 bufferSource->addCodecBuffer(header); 437 } 438 439 return OK; 440 } 441 442 status_t OMXNodeInstance::useGraphicBuffer2_l( 443 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 444 OMX::buffer_id *buffer) { 445 446 // port definition 447 OMX_PARAM_PORTDEFINITIONTYPE def; 448 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 449 def.nVersion.s.nVersionMajor = 1; 450 def.nVersion.s.nVersionMinor = 0; 451 def.nVersion.s.nRevision = 0; 452 def.nVersion.s.nStep = 0; 453 def.nPortIndex = portIndex; 454 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def); 455 if (err != OMX_ErrorNone) 456 { 457 ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__); 458 return err; 459 } 460 461 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); 462 463 OMX_BUFFERHEADERTYPE *header = NULL; 464 OMX_U8* bufferHandle = const_cast<OMX_U8*>( 465 reinterpret_cast<const OMX_U8*>(graphicBuffer->handle)); 466 467 err = OMX_UseBuffer( 468 mHandle, 469 &header, 470 portIndex, 471 bufferMeta, 472 def.nBufferSize, 473 bufferHandle); 474 475 if (err != OMX_ErrorNone) { 476 ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); 477 delete bufferMeta; 478 bufferMeta = NULL; 479 *buffer = 0; 480 return UNKNOWN_ERROR; 481 } 482 483 CHECK_EQ(header->pBuffer, bufferHandle); 484 CHECK_EQ(header->pAppPrivate, bufferMeta); 485 486 *buffer = header; 487 488 addActiveBuffer(portIndex, *buffer); 489 490 return OK; 491 } 492 493 // XXX: This function is here for backwards compatibility. Once the OMX 494 // implementations have been updated this can be removed and useGraphicBuffer2 495 // can be renamed to useGraphicBuffer. 496 status_t OMXNodeInstance::useGraphicBuffer( 497 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 498 OMX::buffer_id *buffer) { 499 Mutex::Autolock autoLock(mLock); 500 501 // See if the newer version of the extension is present. 502 OMX_INDEXTYPE index; 503 if (OMX_GetExtensionIndex( 504 mHandle, 505 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"), 506 &index) == OMX_ErrorNone) { 507 return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer); 508 } 509 510 OMX_STRING name = const_cast<OMX_STRING>( 511 "OMX.google.android.index.useAndroidNativeBuffer"); 512 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 513 514 if (err != OMX_ErrorNone) { 515 ALOGE("OMX_GetExtensionIndex %s failed", name); 516 517 return StatusFromOMXError(err); 518 } 519 520 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); 521 522 OMX_BUFFERHEADERTYPE *header; 523 524 OMX_VERSIONTYPE ver; 525 ver.s.nVersionMajor = 1; 526 ver.s.nVersionMinor = 0; 527 ver.s.nRevision = 0; 528 ver.s.nStep = 0; 529 UseAndroidNativeBufferParams params = { 530 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta, 531 &header, graphicBuffer, 532 }; 533 534 err = OMX_SetParameter(mHandle, index, ¶ms); 535 536 if (err != OMX_ErrorNone) { 537 ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, 538 err); 539 540 delete bufferMeta; 541 bufferMeta = NULL; 542 543 *buffer = 0; 544 545 return UNKNOWN_ERROR; 546 } 547 548 CHECK_EQ(header->pAppPrivate, bufferMeta); 549 550 *buffer = header; 551 552 addActiveBuffer(portIndex, *buffer); 553 554 return OK; 555 } 556 557 status_t OMXNodeInstance::createInputSurface( 558 OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) { 559 Mutex::Autolock autolock(mLock); 560 status_t err; 561 562 const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource(); 563 if (surfaceCheck != NULL) { 564 return ALREADY_EXISTS; 565 } 566 567 // Input buffers will hold meta-data (gralloc references). 568 err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE); 569 if (err != OK) { 570 return err; 571 } 572 573 // Retrieve the width and height of the graphic buffer, set when the 574 // codec was configured. 575 OMX_PARAM_PORTDEFINITIONTYPE def; 576 def.nSize = sizeof(def); 577 def.nVersion.s.nVersionMajor = 1; 578 def.nVersion.s.nVersionMinor = 0; 579 def.nVersion.s.nRevision = 0; 580 def.nVersion.s.nStep = 0; 581 def.nPortIndex = portIndex; 582 OMX_ERRORTYPE oerr = OMX_GetParameter( 583 mHandle, OMX_IndexParamPortDefinition, &def); 584 CHECK(oerr == OMX_ErrorNone); 585 586 if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) { 587 ALOGE("createInputSurface requires AndroidOpaque color format"); 588 return INVALID_OPERATION; 589 } 590 591 GraphicBufferSource* bufferSource = new GraphicBufferSource( 592 this, def.format.video.nFrameWidth, def.format.video.nFrameHeight, 593 def.nBufferCountActual); 594 if ((err = bufferSource->initCheck()) != OK) { 595 delete bufferSource; 596 return err; 597 } 598 setGraphicBufferSource(bufferSource); 599 600 *bufferProducer = bufferSource->getIGraphicBufferProducer(); 601 return OK; 602 } 603 604 status_t OMXNodeInstance::signalEndOfInputStream() { 605 // For non-Surface input, the MediaCodec should convert the call to a 606 // pair of requests (dequeue input buffer, queue input buffer with EOS 607 // flag set). Seems easier than doing the equivalent from here. 608 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 609 if (bufferSource == NULL) { 610 ALOGW("signalEndOfInputStream can only be used with Surface input"); 611 return INVALID_OPERATION; 612 }; 613 return bufferSource->signalEndOfInputStream(); 614 } 615 616 status_t OMXNodeInstance::allocateBuffer( 617 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, 618 void **buffer_data) { 619 Mutex::Autolock autoLock(mLock); 620 621 BufferMeta *buffer_meta = new BufferMeta(size); 622 623 OMX_BUFFERHEADERTYPE *header; 624 625 OMX_ERRORTYPE err = OMX_AllocateBuffer( 626 mHandle, &header, portIndex, buffer_meta, size); 627 628 if (err != OMX_ErrorNone) { 629 ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 630 631 delete buffer_meta; 632 buffer_meta = NULL; 633 634 *buffer = 0; 635 636 return UNKNOWN_ERROR; 637 } 638 639 CHECK_EQ(header->pAppPrivate, buffer_meta); 640 641 *buffer = header; 642 *buffer_data = header->pBuffer; 643 644 addActiveBuffer(portIndex, *buffer); 645 646 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 647 if (bufferSource != NULL && portIndex == kPortIndexInput) { 648 bufferSource->addCodecBuffer(header); 649 } 650 651 return OK; 652 } 653 654 status_t OMXNodeInstance::allocateBufferWithBackup( 655 OMX_U32 portIndex, const sp<IMemory> ¶ms, 656 OMX::buffer_id *buffer) { 657 Mutex::Autolock autoLock(mLock); 658 659 BufferMeta *buffer_meta = new BufferMeta(params, true); 660 661 OMX_BUFFERHEADERTYPE *header; 662 663 OMX_ERRORTYPE err = OMX_AllocateBuffer( 664 mHandle, &header, portIndex, buffer_meta, params->size()); 665 666 if (err != OMX_ErrorNone) { 667 ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 668 669 delete buffer_meta; 670 buffer_meta = NULL; 671 672 *buffer = 0; 673 674 return UNKNOWN_ERROR; 675 } 676 677 CHECK_EQ(header->pAppPrivate, buffer_meta); 678 679 *buffer = header; 680 681 addActiveBuffer(portIndex, *buffer); 682 683 sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); 684 if (bufferSource != NULL && portIndex == kPortIndexInput) { 685 bufferSource->addCodecBuffer(header); 686 } 687 688 return OK; 689 } 690 691 status_t OMXNodeInstance::freeBuffer( 692 OMX_U32 portIndex, OMX::buffer_id buffer) { 693 Mutex::Autolock autoLock(mLock); 694 695 removeActiveBuffer(portIndex, buffer); 696 697 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 698 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); 699 700 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); 701 702 delete buffer_meta; 703 buffer_meta = NULL; 704 705 return StatusFromOMXError(err); 706 } 707 708 status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) { 709 Mutex::Autolock autoLock(mLock); 710 711 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 712 header->nFilledLen = 0; 713 header->nOffset = 0; 714 header->nFlags = 0; 715 716 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); 717 718 return StatusFromOMXError(err); 719 } 720 721 status_t OMXNodeInstance::emptyBuffer( 722 OMX::buffer_id buffer, 723 OMX_U32 rangeOffset, OMX_U32 rangeLength, 724 OMX_U32 flags, OMX_TICKS timestamp) { 725 Mutex::Autolock autoLock(mLock); 726 727 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 728 header->nFilledLen = rangeLength; 729 header->nOffset = rangeOffset; 730 header->nFlags = flags; 731 header->nTimeStamp = timestamp; 732 733 BufferMeta *buffer_meta = 734 static_cast<BufferMeta *>(header->pAppPrivate); 735 buffer_meta->CopyToOMX(header); 736 737 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 738 739 return StatusFromOMXError(err); 740 } 741 742 // like emptyBuffer, but the data is already in header->pBuffer 743 status_t OMXNodeInstance::emptyDirectBuffer( 744 OMX_BUFFERHEADERTYPE *header, 745 OMX_U32 rangeOffset, OMX_U32 rangeLength, 746 OMX_U32 flags, OMX_TICKS timestamp) { 747 Mutex::Autolock autoLock(mLock); 748 749 header->nFilledLen = rangeLength; 750 header->nOffset = rangeOffset; 751 header->nFlags = flags; 752 header->nTimeStamp = timestamp; 753 754 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 755 if (err != OMX_ErrorNone) { 756 ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err); 757 } 758 759 return StatusFromOMXError(err); 760 } 761 762 status_t OMXNodeInstance::getExtensionIndex( 763 const char *parameterName, OMX_INDEXTYPE *index) { 764 Mutex::Autolock autoLock(mLock); 765 766 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 767 mHandle, const_cast<char *>(parameterName), index); 768 769 return StatusFromOMXError(err); 770 } 771 772 void OMXNodeInstance::onMessage(const omx_message &msg) { 773 if (msg.type == omx_message::FILL_BUFFER_DONE) { 774 OMX_BUFFERHEADERTYPE *buffer = 775 static_cast<OMX_BUFFERHEADERTYPE *>( 776 msg.u.extended_buffer_data.buffer); 777 778 BufferMeta *buffer_meta = 779 static_cast<BufferMeta *>(buffer->pAppPrivate); 780 781 buffer_meta->CopyFromOMX(buffer); 782 } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { 783 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 784 785 if (bufferSource != NULL) { 786 // This is one of the buffers used exclusively by 787 // GraphicBufferSource. 788 // Don't dispatch a message back to ACodec, since it doesn't 789 // know that anyone asked to have the buffer emptied and will 790 // be very confused. 791 792 OMX_BUFFERHEADERTYPE *buffer = 793 static_cast<OMX_BUFFERHEADERTYPE *>( 794 msg.u.buffer_data.buffer); 795 796 bufferSource->codecBufferEmptied(buffer); 797 return; 798 } 799 } 800 801 mObserver->onMessage(msg); 802 } 803 804 void OMXNodeInstance::onObserverDied(OMXMaster *master) { 805 ALOGE("!!! Observer died. Quickly, do something, ... anything..."); 806 807 // Try to force shutdown of the node and hope for the best. 808 freeNode(master); 809 } 810 811 void OMXNodeInstance::onGetHandleFailed() { 812 delete this; 813 } 814 815 // OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here. 816 // Don't try to acquire mLock here -- in rare circumstances this will hang. 817 void OMXNodeInstance::onEvent( 818 OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { 819 const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); 820 821 if (bufferSource != NULL && event == OMX_EventCmdComplete && 822 arg1 == OMX_CommandStateSet) { 823 if (arg2 == OMX_StateExecuting) { 824 bufferSource->omxExecuting(); 825 } else if (arg2 == OMX_StateLoaded) { 826 // Must be shutting down -- won't have a GraphicBufferSource 827 // on the way up. 828 bufferSource->omxLoaded(); 829 setGraphicBufferSource(NULL); 830 } 831 } 832 } 833 834 // static 835 OMX_ERRORTYPE OMXNodeInstance::OnEvent( 836 OMX_IN OMX_HANDLETYPE hComponent, 837 OMX_IN OMX_PTR pAppData, 838 OMX_IN OMX_EVENTTYPE eEvent, 839 OMX_IN OMX_U32 nData1, 840 OMX_IN OMX_U32 nData2, 841 OMX_IN OMX_PTR pEventData) { 842 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 843 if (instance->mDying) { 844 return OMX_ErrorNone; 845 } 846 return instance->owner()->OnEvent( 847 instance->nodeID(), eEvent, nData1, nData2, pEventData); 848 } 849 850 // static 851 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone( 852 OMX_IN OMX_HANDLETYPE hComponent, 853 OMX_IN OMX_PTR pAppData, 854 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 855 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 856 if (instance->mDying) { 857 return OMX_ErrorNone; 858 } 859 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer); 860 } 861 862 // static 863 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( 864 OMX_IN OMX_HANDLETYPE hComponent, 865 OMX_IN OMX_PTR pAppData, 866 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 867 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 868 if (instance->mDying) { 869 return OMX_ErrorNone; 870 } 871 return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer); 872 } 873 874 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { 875 ActiveBuffer active; 876 active.mPortIndex = portIndex; 877 active.mID = id; 878 mActiveBuffers.push(active); 879 } 880 881 void OMXNodeInstance::removeActiveBuffer( 882 OMX_U32 portIndex, OMX::buffer_id id) { 883 bool found = false; 884 for (size_t i = 0; i < mActiveBuffers.size(); ++i) { 885 if (mActiveBuffers[i].mPortIndex == portIndex 886 && mActiveBuffers[i].mID == id) { 887 found = true; 888 mActiveBuffers.removeItemsAt(i); 889 break; 890 } 891 } 892 893 if (!found) { 894 ALOGW("Attempt to remove an active buffer we know nothing about..."); 895 } 896 } 897 898 void OMXNodeInstance::freeActiveBuffers() { 899 // Make sure to count down here, as freeBuffer will in turn remove 900 // the active buffer from the vector... 901 for (size_t i = mActiveBuffers.size(); i--;) { 902 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); 903 } 904 } 905 906 } // namespace android 907