OMXNodeInstance.cpp revision a0dac9e24ae7520cb7d7f0505bf0936bffbcd047
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 <media/stagefright/HardwareAPI.h> 28#include <media/stagefright/MediaDebug.h> 29#include <media/stagefright/MediaErrors.h> 30 31namespace android { 32 33struct 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 69private: 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 80OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = { 81 &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone 82}; 83 84OMXNodeInstance::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 93OMXNodeInstance::~OMXNodeInstance() { 94 CHECK_EQ(mHandle, NULL); 95} 96 97void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) { 98 CHECK_EQ(mHandle, NULL); 99 mNodeID = node_id; 100 mHandle = handle; 101} 102 103OMX *OMXNodeInstance::owner() { 104 return mOwner; 105} 106 107sp<IOMXObserver> OMXNodeInstance::observer() { 108 return mObserver; 109} 110 111OMX::node_id OMXNodeInstance::nodeID() { 112 return mNodeID; 113} 114 115static 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 126status_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 LOGV("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 LOGE("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 LOGV("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 LOGE("component failed to enter Loaded state, aborting."); 183 state = OMX_StateInvalid; 184 break; 185 } 186 187 LOGV("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 LOGV("calling destroyComponentInstance"); 205 OMX_ERRORTYPE err = master->destroyComponentInstance( 206 static_cast<OMX_COMPONENTTYPE *>(mHandle)); 207 LOGV("destroyComponentInstance returned err %d", err); 208 209 mHandle = NULL; 210 211 if (err != OMX_ErrorNone) { 212 LOGE("FreeHandle FAILED with error 0x%08x.", err); 213 } 214 215 mOwner->invalidateNodeID(mNodeID); 216 mNodeID = NULL; 217 218 LOGV("OMXNodeInstance going away."); 219 delete this; 220 221 return StatusFromOMXError(err); 222} 223 224status_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 232status_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 241status_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 251status_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 259status_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 269status_t OMXNodeInstance::enableGraphicBuffers( 270 OMX_U32 portIndex, OMX_BOOL enable) { 271 Mutex::Autolock autoLock(mLock); 272 273 OMX_INDEXTYPE index; 274 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 275 mHandle, 276 const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"), 277 &index); 278 279 if (err != OMX_ErrorNone) { 280 LOGE("OMX_GetExtensionIndex failed"); 281 282 return StatusFromOMXError(err); 283 } 284 285 OMX_VERSIONTYPE ver; 286 ver.s.nVersionMajor = 1; 287 ver.s.nVersionMinor = 0; 288 ver.s.nRevision = 0; 289 ver.s.nStep = 0; 290 EnableAndroidNativeBuffersParams params = { 291 sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable, 292 }; 293 294 err = OMX_SetParameter(mHandle, index, ¶ms); 295 296 if (err != OMX_ErrorNone) { 297 LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)", 298 err, err); 299 300 return UNKNOWN_ERROR; 301 } 302 303 return OK; 304} 305 306status_t OMXNodeInstance::getGraphicBufferUsage( 307 OMX_U32 portIndex, OMX_U32* usage) { 308 Mutex::Autolock autoLock(mLock); 309 310 OMX_INDEXTYPE index; 311 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 312 mHandle, 313 const_cast<OMX_STRING>( 314 "OMX.google.android.index.getAndroidNativeBufferUsage"), 315 &index); 316 317 if (err != OMX_ErrorNone) { 318 LOGE("OMX_GetExtensionIndex failed"); 319 320 return StatusFromOMXError(err); 321 } 322 323 OMX_VERSIONTYPE ver; 324 ver.s.nVersionMajor = 1; 325 ver.s.nVersionMinor = 0; 326 ver.s.nRevision = 0; 327 ver.s.nStep = 0; 328 GetAndroidNativeBufferUsageParams params = { 329 sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0, 330 }; 331 332 err = OMX_GetParameter(mHandle, index, ¶ms); 333 334 if (err != OMX_ErrorNone) { 335 LOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)", 336 err, err); 337 return UNKNOWN_ERROR; 338 } 339 340 *usage = params.nUsage; 341 342 return OK; 343} 344 345status_t OMXNodeInstance::storeMetaDataInBuffers( 346 OMX_U32 portIndex, 347 OMX_BOOL enable) { 348 Mutex::Autolock autolock(mLock); 349 350 OMX_INDEXTYPE index; 351 OMX_STRING name = const_cast<OMX_STRING>( 352 "OMX.google.android.index.storeMetaDataInBuffers"); 353 354 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); 355 if (err != OMX_ErrorNone) { 356 LOGE("OMX_GetExtensionIndex %s failed", name); 357 return StatusFromOMXError(err); 358 } 359 360 StoreMetaDataInBuffersParams params; 361 memset(¶ms, 0, sizeof(params)); 362 params.nSize = sizeof(params); 363 364 // Version: 1.0.0.0 365 params.nVersion.s.nVersionMajor = 1; 366 367 params.nPortIndex = portIndex; 368 params.bStoreMetaData = enable; 369 if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { 370 LOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err); 371 return UNKNOWN_ERROR; 372 } 373 return err; 374} 375 376status_t OMXNodeInstance::useBuffer( 377 OMX_U32 portIndex, const sp<IMemory> ¶ms, 378 OMX::buffer_id *buffer) { 379 Mutex::Autolock autoLock(mLock); 380 381 BufferMeta *buffer_meta = new BufferMeta(params); 382 383 OMX_BUFFERHEADERTYPE *header; 384 385 OMX_ERRORTYPE err = OMX_UseBuffer( 386 mHandle, &header, portIndex, buffer_meta, 387 params->size(), static_cast<OMX_U8 *>(params->pointer())); 388 389 if (err != OMX_ErrorNone) { 390 LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); 391 392 delete buffer_meta; 393 buffer_meta = NULL; 394 395 *buffer = 0; 396 397 return UNKNOWN_ERROR; 398 } 399 400 CHECK_EQ(header->pAppPrivate, buffer_meta); 401 402 *buffer = header; 403 404 addActiveBuffer(portIndex, *buffer); 405 406 return OK; 407} 408 409status_t OMXNodeInstance::useGraphicBuffer2_l( 410 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 411 OMX::buffer_id *buffer) { 412 413 // port definition 414 OMX_PARAM_PORTDEFINITIONTYPE def; 415 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); 416 def.nVersion.s.nVersionMajor = 1; 417 def.nVersion.s.nVersionMinor = 0; 418 def.nVersion.s.nRevision = 0; 419 def.nVersion.s.nStep = 0; 420 def.nPortIndex = portIndex; 421 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def); 422 if (err != OMX_ErrorNone) 423 { 424 LOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__); 425 return err; 426 } 427 428 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); 429 430 OMX_BUFFERHEADERTYPE *header = NULL; 431 OMX_U8* bufferHandle = const_cast<OMX_U8*>( 432 reinterpret_cast<const OMX_U8*>(graphicBuffer->handle)); 433 434 err = OMX_UseBuffer( 435 mHandle, 436 &header, 437 portIndex, 438 bufferMeta, 439 def.nBufferSize, 440 bufferHandle); 441 442 if (err != OMX_ErrorNone) { 443 LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); 444 delete bufferMeta; 445 bufferMeta = NULL; 446 *buffer = 0; 447 return UNKNOWN_ERROR; 448 } 449 450 CHECK_EQ(header->pBuffer, bufferHandle); 451 CHECK_EQ(header->pAppPrivate, bufferMeta); 452 453 *buffer = header; 454 455 addActiveBuffer(portIndex, *buffer); 456 457 return OK; 458} 459 460// XXX: This function is here for backwards compatibility. Once the OMX 461// implementations have been updated this can be removed and useGraphicBuffer2 462// can be renamed to useGraphicBuffer. 463status_t OMXNodeInstance::useGraphicBuffer( 464 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, 465 OMX::buffer_id *buffer) { 466 Mutex::Autolock autoLock(mLock); 467 468 // See if the newer version of the extension is present. 469 OMX_INDEXTYPE index; 470 if (OMX_GetExtensionIndex( 471 mHandle, 472 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"), 473 &index) == OMX_ErrorNone) { 474 return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer); 475 } 476 477 LOGW("Falling back to the deprecated useAndroidNativeBuffer support. You " 478 "should switch to the useAndroidNativeBuffer2 extension."); 479 480 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 481 mHandle, 482 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"), 483 &index); 484 485 if (err != OMX_ErrorNone) { 486 LOGE("OMX_GetExtensionIndex failed"); 487 488 return StatusFromOMXError(err); 489 } 490 491 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); 492 493 OMX_BUFFERHEADERTYPE *header; 494 495 OMX_VERSIONTYPE ver; 496 ver.s.nVersionMajor = 1; 497 ver.s.nVersionMinor = 0; 498 ver.s.nRevision = 0; 499 ver.s.nStep = 0; 500 UseAndroidNativeBufferParams params = { 501 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta, 502 &header, graphicBuffer, 503 }; 504 505 err = OMX_SetParameter(mHandle, index, ¶ms); 506 507 if (err != OMX_ErrorNone) { 508 LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, 509 err); 510 511 delete bufferMeta; 512 bufferMeta = NULL; 513 514 *buffer = 0; 515 516 return UNKNOWN_ERROR; 517 } 518 519 CHECK_EQ(header->pAppPrivate, bufferMeta); 520 521 *buffer = header; 522 523 addActiveBuffer(portIndex, *buffer); 524 525 return OK; 526} 527 528status_t OMXNodeInstance::allocateBuffer( 529 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, 530 void **buffer_data) { 531 Mutex::Autolock autoLock(mLock); 532 533 BufferMeta *buffer_meta = new BufferMeta(size); 534 535 OMX_BUFFERHEADERTYPE *header; 536 537 OMX_ERRORTYPE err = OMX_AllocateBuffer( 538 mHandle, &header, portIndex, buffer_meta, size); 539 540 if (err != OMX_ErrorNone) { 541 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 542 543 delete buffer_meta; 544 buffer_meta = NULL; 545 546 *buffer = 0; 547 548 return UNKNOWN_ERROR; 549 } 550 551 CHECK_EQ(header->pAppPrivate, buffer_meta); 552 553 *buffer = header; 554 *buffer_data = header->pBuffer; 555 556 addActiveBuffer(portIndex, *buffer); 557 558 return OK; 559} 560 561status_t OMXNodeInstance::allocateBufferWithBackup( 562 OMX_U32 portIndex, const sp<IMemory> ¶ms, 563 OMX::buffer_id *buffer) { 564 Mutex::Autolock autoLock(mLock); 565 566 BufferMeta *buffer_meta = new BufferMeta(params, true); 567 568 OMX_BUFFERHEADERTYPE *header; 569 570 OMX_ERRORTYPE err = OMX_AllocateBuffer( 571 mHandle, &header, portIndex, buffer_meta, params->size()); 572 573 if (err != OMX_ErrorNone) { 574 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 575 576 delete buffer_meta; 577 buffer_meta = NULL; 578 579 *buffer = 0; 580 581 return UNKNOWN_ERROR; 582 } 583 584 CHECK_EQ(header->pAppPrivate, buffer_meta); 585 586 *buffer = header; 587 588 addActiveBuffer(portIndex, *buffer); 589 590 return OK; 591} 592 593status_t OMXNodeInstance::freeBuffer( 594 OMX_U32 portIndex, OMX::buffer_id buffer) { 595 Mutex::Autolock autoLock(mLock); 596 597 removeActiveBuffer(portIndex, buffer); 598 599 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 600 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); 601 602 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); 603 604 delete buffer_meta; 605 buffer_meta = NULL; 606 607 return StatusFromOMXError(err); 608} 609 610status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) { 611 Mutex::Autolock autoLock(mLock); 612 613 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 614 header->nFilledLen = 0; 615 header->nOffset = 0; 616 header->nFlags = 0; 617 618 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); 619 620 return StatusFromOMXError(err); 621} 622 623status_t OMXNodeInstance::emptyBuffer( 624 OMX::buffer_id buffer, 625 OMX_U32 rangeOffset, OMX_U32 rangeLength, 626 OMX_U32 flags, OMX_TICKS timestamp) { 627 Mutex::Autolock autoLock(mLock); 628 629 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 630 header->nFilledLen = rangeLength; 631 header->nOffset = rangeOffset; 632 header->nFlags = flags; 633 header->nTimeStamp = timestamp; 634 635 BufferMeta *buffer_meta = 636 static_cast<BufferMeta *>(header->pAppPrivate); 637 buffer_meta->CopyToOMX(header); 638 639 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 640 641 return StatusFromOMXError(err); 642} 643 644status_t OMXNodeInstance::getExtensionIndex( 645 const char *parameterName, OMX_INDEXTYPE *index) { 646 Mutex::Autolock autoLock(mLock); 647 648 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 649 mHandle, const_cast<char *>(parameterName), index); 650 651 return StatusFromOMXError(err); 652} 653 654void OMXNodeInstance::onMessage(const omx_message &msg) { 655 if (msg.type == omx_message::FILL_BUFFER_DONE) { 656 OMX_BUFFERHEADERTYPE *buffer = 657 static_cast<OMX_BUFFERHEADERTYPE *>( 658 msg.u.extended_buffer_data.buffer); 659 660 BufferMeta *buffer_meta = 661 static_cast<BufferMeta *>(buffer->pAppPrivate); 662 663 buffer_meta->CopyFromOMX(buffer); 664 } 665 666 mObserver->onMessage(msg); 667} 668 669void OMXNodeInstance::onObserverDied(OMXMaster *master) { 670 LOGE("!!! Observer died. Quickly, do something, ... anything..."); 671 672 // Try to force shutdown of the node and hope for the best. 673 freeNode(master); 674} 675 676void OMXNodeInstance::onGetHandleFailed() { 677 delete this; 678} 679 680// static 681OMX_ERRORTYPE OMXNodeInstance::OnEvent( 682 OMX_IN OMX_HANDLETYPE hComponent, 683 OMX_IN OMX_PTR pAppData, 684 OMX_IN OMX_EVENTTYPE eEvent, 685 OMX_IN OMX_U32 nData1, 686 OMX_IN OMX_U32 nData2, 687 OMX_IN OMX_PTR pEventData) { 688 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 689 if (instance->mDying) { 690 return OMX_ErrorNone; 691 } 692 return instance->owner()->OnEvent( 693 instance->nodeID(), eEvent, nData1, nData2, pEventData); 694} 695 696// static 697OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone( 698 OMX_IN OMX_HANDLETYPE hComponent, 699 OMX_IN OMX_PTR pAppData, 700 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 701 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 702 if (instance->mDying) { 703 return OMX_ErrorNone; 704 } 705 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer); 706} 707 708// static 709OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( 710 OMX_IN OMX_HANDLETYPE hComponent, 711 OMX_IN OMX_PTR pAppData, 712 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 713 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 714 if (instance->mDying) { 715 return OMX_ErrorNone; 716 } 717 return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer); 718} 719 720void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { 721 ActiveBuffer active; 722 active.mPortIndex = portIndex; 723 active.mID = id; 724 mActiveBuffers.push(active); 725} 726 727void OMXNodeInstance::removeActiveBuffer( 728 OMX_U32 portIndex, OMX::buffer_id id) { 729 bool found = false; 730 for (size_t i = 0; i < mActiveBuffers.size(); ++i) { 731 if (mActiveBuffers[i].mPortIndex == portIndex 732 && mActiveBuffers[i].mID == id) { 733 found = true; 734 mActiveBuffers.removeItemsAt(i); 735 break; 736 } 737 } 738 739 if (!found) { 740 LOGW("Attempt to remove an active buffer we know nothing about..."); 741 } 742} 743 744void OMXNodeInstance::freeActiveBuffers() { 745 // Make sure to count down here, as freeBuffer will in turn remove 746 // the active buffer from the vector... 747 for (size_t i = mActiveBuffers.size(); i--;) { 748 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); 749 } 750} 751 752} // namespace android 753