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