OMXNodeInstance.cpp revision 2e17686223bad35101c23083dc79f1d12f3ff429
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 != OK) 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 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 478 mHandle, 479 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"), 480 &index); 481 482 if (err != OMX_ErrorNone) { 483 LOGE("OMX_GetExtensionIndex failed"); 484 485 return StatusFromOMXError(err); 486 } 487 488 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); 489 490 OMX_BUFFERHEADERTYPE *header; 491 492 OMX_VERSIONTYPE ver; 493 ver.s.nVersionMajor = 1; 494 ver.s.nVersionMinor = 0; 495 ver.s.nRevision = 0; 496 ver.s.nStep = 0; 497 UseAndroidNativeBufferParams params = { 498 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta, 499 &header, graphicBuffer, 500 }; 501 502 err = OMX_SetParameter(mHandle, index, ¶ms); 503 504 if (err != OMX_ErrorNone) { 505 LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, 506 err); 507 508 delete bufferMeta; 509 bufferMeta = NULL; 510 511 *buffer = 0; 512 513 return UNKNOWN_ERROR; 514 } 515 516 CHECK_EQ(header->pAppPrivate, bufferMeta); 517 518 *buffer = header; 519 520 addActiveBuffer(portIndex, *buffer); 521 522 return OK; 523} 524 525status_t OMXNodeInstance::allocateBuffer( 526 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, 527 void **buffer_data) { 528 Mutex::Autolock autoLock(mLock); 529 530 BufferMeta *buffer_meta = new BufferMeta(size); 531 532 OMX_BUFFERHEADERTYPE *header; 533 534 OMX_ERRORTYPE err = OMX_AllocateBuffer( 535 mHandle, &header, portIndex, buffer_meta, size); 536 537 if (err != OMX_ErrorNone) { 538 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 539 540 delete buffer_meta; 541 buffer_meta = NULL; 542 543 *buffer = 0; 544 545 return UNKNOWN_ERROR; 546 } 547 548 CHECK_EQ(header->pAppPrivate, buffer_meta); 549 550 *buffer = header; 551 *buffer_data = header->pBuffer; 552 553 addActiveBuffer(portIndex, *buffer); 554 555 return OK; 556} 557 558status_t OMXNodeInstance::allocateBufferWithBackup( 559 OMX_U32 portIndex, const sp<IMemory> ¶ms, 560 OMX::buffer_id *buffer) { 561 Mutex::Autolock autoLock(mLock); 562 563 BufferMeta *buffer_meta = new BufferMeta(params, true); 564 565 OMX_BUFFERHEADERTYPE *header; 566 567 OMX_ERRORTYPE err = OMX_AllocateBuffer( 568 mHandle, &header, portIndex, buffer_meta, params->size()); 569 570 if (err != OMX_ErrorNone) { 571 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); 572 573 delete buffer_meta; 574 buffer_meta = NULL; 575 576 *buffer = 0; 577 578 return UNKNOWN_ERROR; 579 } 580 581 CHECK_EQ(header->pAppPrivate, buffer_meta); 582 583 *buffer = header; 584 585 addActiveBuffer(portIndex, *buffer); 586 587 return OK; 588} 589 590status_t OMXNodeInstance::freeBuffer( 591 OMX_U32 portIndex, OMX::buffer_id buffer) { 592 Mutex::Autolock autoLock(mLock); 593 594 removeActiveBuffer(portIndex, buffer); 595 596 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 597 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); 598 599 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); 600 601 delete buffer_meta; 602 buffer_meta = NULL; 603 604 return StatusFromOMXError(err); 605} 606 607status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) { 608 Mutex::Autolock autoLock(mLock); 609 610 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 611 header->nFilledLen = 0; 612 header->nOffset = 0; 613 header->nFlags = 0; 614 615 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); 616 617 return StatusFromOMXError(err); 618} 619 620status_t OMXNodeInstance::emptyBuffer( 621 OMX::buffer_id buffer, 622 OMX_U32 rangeOffset, OMX_U32 rangeLength, 623 OMX_U32 flags, OMX_TICKS timestamp) { 624 Mutex::Autolock autoLock(mLock); 625 626 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; 627 header->nFilledLen = rangeLength; 628 header->nOffset = rangeOffset; 629 header->nFlags = flags; 630 header->nTimeStamp = timestamp; 631 632 BufferMeta *buffer_meta = 633 static_cast<BufferMeta *>(header->pAppPrivate); 634 buffer_meta->CopyToOMX(header); 635 636 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); 637 638 return StatusFromOMXError(err); 639} 640 641status_t OMXNodeInstance::getExtensionIndex( 642 const char *parameterName, OMX_INDEXTYPE *index) { 643 Mutex::Autolock autoLock(mLock); 644 645 OMX_ERRORTYPE err = OMX_GetExtensionIndex( 646 mHandle, const_cast<char *>(parameterName), index); 647 648 return StatusFromOMXError(err); 649} 650 651void OMXNodeInstance::onMessage(const omx_message &msg) { 652 if (msg.type == omx_message::FILL_BUFFER_DONE) { 653 OMX_BUFFERHEADERTYPE *buffer = 654 static_cast<OMX_BUFFERHEADERTYPE *>( 655 msg.u.extended_buffer_data.buffer); 656 657 BufferMeta *buffer_meta = 658 static_cast<BufferMeta *>(buffer->pAppPrivate); 659 660 buffer_meta->CopyFromOMX(buffer); 661 } 662 663 mObserver->onMessage(msg); 664} 665 666void OMXNodeInstance::onObserverDied(OMXMaster *master) { 667 LOGE("!!! Observer died. Quickly, do something, ... anything..."); 668 669 // Try to force shutdown of the node and hope for the best. 670 freeNode(master); 671} 672 673void OMXNodeInstance::onGetHandleFailed() { 674 delete this; 675} 676 677// static 678OMX_ERRORTYPE OMXNodeInstance::OnEvent( 679 OMX_IN OMX_HANDLETYPE hComponent, 680 OMX_IN OMX_PTR pAppData, 681 OMX_IN OMX_EVENTTYPE eEvent, 682 OMX_IN OMX_U32 nData1, 683 OMX_IN OMX_U32 nData2, 684 OMX_IN OMX_PTR pEventData) { 685 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 686 if (instance->mDying) { 687 return OMX_ErrorNone; 688 } 689 return instance->owner()->OnEvent( 690 instance->nodeID(), eEvent, nData1, nData2, pEventData); 691} 692 693// static 694OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone( 695 OMX_IN OMX_HANDLETYPE hComponent, 696 OMX_IN OMX_PTR pAppData, 697 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 698 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 699 if (instance->mDying) { 700 return OMX_ErrorNone; 701 } 702 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer); 703} 704 705// static 706OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( 707 OMX_IN OMX_HANDLETYPE hComponent, 708 OMX_IN OMX_PTR pAppData, 709 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) { 710 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData); 711 if (instance->mDying) { 712 return OMX_ErrorNone; 713 } 714 return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer); 715} 716 717void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { 718 ActiveBuffer active; 719 active.mPortIndex = portIndex; 720 active.mID = id; 721 mActiveBuffers.push(active); 722} 723 724void OMXNodeInstance::removeActiveBuffer( 725 OMX_U32 portIndex, OMX::buffer_id id) { 726 bool found = false; 727 for (size_t i = 0; i < mActiveBuffers.size(); ++i) { 728 if (mActiveBuffers[i].mPortIndex == portIndex 729 && mActiveBuffers[i].mID == id) { 730 found = true; 731 mActiveBuffers.removeItemsAt(i); 732 break; 733 } 734 } 735 736 if (!found) { 737 LOGW("Attempt to remove an active buffer we know nothing about..."); 738 } 739} 740 741void OMXNodeInstance::freeActiveBuffers() { 742 // Make sure to count down here, as freeBuffer will in turn remove 743 // the active buffer from the vector... 744 for (size_t i = mActiveBuffers.size(); i--;) { 745 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); 746 } 747} 748 749} // namespace android 750