status_t MediaBufferGroup::acquire_buffer( MediaBuffer **out, bool nonBlocking) { Mutex::Autolock autoLock(mLock); for (;;) { for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL; buffer = buffer->nextBuffer()) { if (buffer->refcount() == 0) { buffer->add_ref(); buffer->reset(); *out = buffer; goto exit; } } if (nonBlocking) { *out = NULL; return WOULD_BLOCK; } // All buffers are in use. Block until one of them is returned to us. mCondition.wait(mLock); } exit: return OK; }
MediaBufferPool::~MediaBufferPool() { MediaBuffer *next; for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL; buffer = next) { next = buffer->nextBuffer(); CHECK_EQ(buffer->refcount(), 0); buffer->setObserver(NULL); buffer->release(); } }
void OmxDecoder::ReleaseAllPendingVideoBuffersLocked() { Vector<BufferItem> releasingVideoBuffers; { Mutex::Autolock autoLock(mPendingVideoBuffersLock); int size = mPendingVideoBuffers.size(); for (int i = 0; i < size; i++) { releasingVideoBuffers.push(mPendingVideoBuffers[i]); } mPendingVideoBuffers.clear(); } // Free all pending video buffers without holding mPendingVideoBuffersLock. int size = releasingVideoBuffers.size(); for (int i = 0; i < size; i++) { MediaBuffer *buffer; buffer = releasingVideoBuffers[i].mMediaBuffer; #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 android::sp<Fence> fence; int fenceFd = -1; fence = releasingVideoBuffers[i].mReleaseFenceHandle.mFence; if (fence.get() && fence->isValid()) { fenceFd = fence->dup(); } MOZ_ASSERT(buffer->refcount() == 1); // This code expect MediaBuffer's ref count is 1. // Return gralloc buffer to ANativeWindow ANativeWindow* window = static_cast<ANativeWindow*>(mNativeWindowClient.get()); window->cancelBuffer(window, buffer->graphicBuffer().get(), fenceFd); // Mark MediaBuffer as rendered. // When gralloc buffer is directly returned to ANativeWindow, // this mark is necesary. sp<MetaData> metaData = buffer->meta_data(); metaData->setInt32(kKeyRendered, 1); #endif // Return MediaBuffer to OMXCodec. buffer->release(); } releasingVideoBuffers.clear(); }