1e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia/*
2e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * Copyright (C) 2009 The Android Open Source Project
3e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia *
4e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * Licensed under the Apache License, Version 2.0 (the "License");
5e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * you may not use this file except in compliance with the License.
6e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * You may obtain a copy of the License at
7e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia *
8e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia *      http://www.apache.org/licenses/LICENSE-2.0
9e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia *
10e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * Unless required by applicable law or agreed to in writing, software
11e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * distributed under the License is distributed on an "AS IS" BASIS,
12e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * See the License for the specific language governing permissions and
14e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia * limitations under the License.
15e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia */
16e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
17e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#define LOG_TAG "MediaBufferGroup"
18e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#include <utils/Log.h>
19e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
204d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang#include <list>
214d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang
224d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang#include <binder/MemoryDealer.h>
23e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#include <media/stagefright/foundation/ADebug.h>
24e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#include <media/stagefright/MediaBuffer.h>
25e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#include <media/stagefright/MediaBufferGroup.h>
264d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang#include <utils/threads.h>
27e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
28e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jianamespace android {
29e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
30cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung// std::min is not constexpr in C++11
31cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hungtemplate<typename T>
32cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hungconstexpr T MIN(const T &a, const T &b) { return a <= b ? a : b; }
33cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
34cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung// MediaBufferGroup may create shared memory buffers at a
35cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung// smaller threshold than an isolated new MediaBuffer.
36cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hungstatic const size_t kSharedMemoryThreshold = MIN(
37cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        (size_t)MediaBuffer::kSharedMemThreshold, (size_t)(4 * 1024));
38cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
394d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kangstruct MediaBufferGroup::InternalData {
404d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    Mutex mLock;
414d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    Condition mCondition;
424d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    size_t mGrowthLimit;  // Do not automatically grow group larger than this.
431889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang    std::list<MediaBufferBase *> mBuffers;
444d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang};
454d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang
464d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon KangMediaBufferGroup::MediaBufferGroup(size_t growthLimit)
474d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    : mInternal(new InternalData()) {
484d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    mInternal->mGrowthLimit = growthLimit;
49e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
50e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
51cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy HungMediaBufferGroup::MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit)
524d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    : mInternal(new InternalData()) {
534d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    mInternal->mGrowthLimit = growthLimit;
54cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
554d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    if (mInternal->mGrowthLimit > 0 && buffers > mInternal->mGrowthLimit) {
567f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung        ALOGW("Preallocated buffers %zu > growthLimit %zu, increasing growthLimit",
574d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang                buffers, mInternal->mGrowthLimit);
584d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang        mInternal->mGrowthLimit = buffers;
597f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung    }
607f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung
61cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    if (buffer_size >= kSharedMemoryThreshold) {
62cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        ALOGD("creating MemoryDealer");
63cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        // Using a single MemoryDealer is efficient for a group of shared memory objects.
64cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        // This loop guarantees that we use shared memory (no fallback to malloc).
65cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
66cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        size_t alignment = MemoryDealer::getAllocationAlignment();
67cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        size_t augmented_size = buffer_size + sizeof(MediaBuffer::SharedControl);
68cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        size_t total = (augmented_size + alignment - 1) / alignment * alignment * buffers;
69cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        sp<MemoryDealer> memoryDealer = new MemoryDealer(total, "MediaBufferGroup");
70cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
71cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        for (size_t i = 0; i < buffers; ++i) {
72cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            sp<IMemory> mem = memoryDealer->allocate(augmented_size);
739bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            if (mem.get() == nullptr || mem->pointer() == nullptr) {
74cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung                ALOGW("Only allocated %zu shared buffers of size %zu", i, buffer_size);
75cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung                break;
76cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            }
77cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            MediaBuffer *buffer = new MediaBuffer(mem);
78cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            buffer->getSharedControl()->clear();
79cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            add_buffer(buffer);
80cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        }
81cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return;
82cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
83cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
84cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    // Non-shared memory allocation.
85cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    for (size_t i = 0; i < buffers; ++i) {
86cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        MediaBuffer *buffer = new MediaBuffer(buffer_size);
87cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        if (buffer->data() == nullptr) {
88cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            delete buffer; // don't call release, it's not properly formed
89cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            ALOGW("Only allocated %zu malloc buffers of size %zu", i, buffer_size);
90cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            break;
91cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        }
92cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        add_buffer(buffer);
93cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
94cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung}
95cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
96e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei JiaMediaBufferGroup::~MediaBufferGroup() {
971889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang    for (MediaBufferBase *buffer : mInternal->mBuffers) {
989bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung        if (buffer->refcount() != 0) {
999bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            const int localRefcount = buffer->localRefcount();
1009bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            const int remoteRefcount = buffer->remoteRefcount();
1019bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung
1029bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // Fatal if we have a local refcount.
1039bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            LOG_ALWAYS_FATAL_IF(localRefcount != 0,
1049bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung                    "buffer(%p) localRefcount %d != 0, remoteRefcount %d",
1059bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung                    buffer, localRefcount, remoteRefcount);
1069bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung
1079bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // Log an error if we have a remaining remote refcount,
1089bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // as the remote process may have died or may have inappropriate behavior.
1099bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // The shared memory associated with the MediaBuffer will
1109bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // automatically be reclaimed when there are no remaining fds
1119bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            // associated with it.
1129bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung            ALOGE("buffer(%p) has residual remoteRefcount %d",
1139bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung                    buffer, remoteRefcount);
1149bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung        }
1159bd3c9b0e894c9f6c48a2cfa7c5f21d384b1c596Andy Hung        // gracefully delete.
116f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung        buffer->setObserver(nullptr);
117e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        buffer->release();
118e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    }
1194d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    delete mInternal;
120e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
121e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
1221889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kangvoid MediaBufferGroup::add_buffer(MediaBufferBase *buffer) {
1234d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    Mutex::Autolock autoLock(mInternal->mLock);
124e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
1257f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung    // if we're above our growth limit, release buffers if we can
1264d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    for (auto it = mInternal->mBuffers.begin();
1274d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang            mInternal->mGrowthLimit > 0
1284d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang            && mInternal->mBuffers.size() >= mInternal->mGrowthLimit
1294d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang            && it != mInternal->mBuffers.end();) {
1307f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung        if ((*it)->refcount() == 0) {
1317f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung            (*it)->setObserver(nullptr);
1327f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung            (*it)->release();
1334d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang            it = mInternal->mBuffers.erase(it);
1347f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung        } else {
1357f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung            ++it;
1367f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung        }
1377f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung    }
1387f7dea6a92e12d395d470d51c8157d6ef230200bAndy Hung
139e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    buffer->setObserver(this);
1404d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    mInternal->mBuffers.emplace_back(buffer);
141f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung}
142e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
143cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hungbool MediaBufferGroup::has_buffers() {
1444d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    if (mInternal->mBuffers.size() < mInternal->mGrowthLimit) {
145cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        return true; // We can add more buffers internally.
146cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
1471889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang    for (MediaBufferBase *buffer : mInternal->mBuffers) {
148cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        if (buffer->refcount() == 0) {
149cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung            return true;
150cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung        }
151cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    }
152cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung    return false;
153cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung}
154cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung
155e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jiastatus_t MediaBufferGroup::acquire_buffer(
1561889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang        MediaBufferBase **out, bool nonBlocking, size_t requestedSize) {
1574d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    Mutex::Autolock autoLock(mInternal->mLock);
158e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    for (;;) {
159e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        size_t smallest = requestedSize;
1601889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang        MediaBufferBase *buffer = nullptr;
1614d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang        auto free = mInternal->mBuffers.end();
1624d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang        for (auto it = mInternal->mBuffers.begin(); it != mInternal->mBuffers.end(); ++it) {
163f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            if ((*it)->refcount() == 0) {
164f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                const size_t size = (*it)->size();
165f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                if (size >= requestedSize) {
166f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    buffer = *it;
167f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    break;
168f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                }
169f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                if (size < smallest) {
170f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    smallest = size; // always free the smallest buf
171f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    free = it;
172f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                }
173e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            }
174e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        }
175f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung        if (buffer == nullptr
1764d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang                && (free != mInternal->mBuffers.end()
1774d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang                    || mInternal->mBuffers.size() < mInternal->mGrowthLimit)) {
178f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            // We alloc before we free so failure leaves group unchanged.
179f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            const size_t allocateSize = requestedSize < SIZE_MAX / 3 * 2 /* NB: ordering */ ?
180f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    requestedSize * 3 / 2 : requestedSize;
181f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            buffer = new MediaBuffer(allocateSize);
182f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            if (buffer->data() == nullptr) {
183f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                ALOGE("Allocation failure for size %zu", allocateSize);
184f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                delete buffer; // Invalid alloc, prefer not to call release.
185f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                buffer = nullptr;
186f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            } else {
187f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                buffer->setObserver(this);
1884d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang                if (free != mInternal->mBuffers.end()) {
189f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    ALOGV("reallocate buffer, requested size %zu vs available %zu",
190f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                            requestedSize, (*free)->size());
191f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    (*free)->setObserver(nullptr);
192f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    (*free)->release();
193f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    *free = buffer; // in-place replace
194f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                } else {
195f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                    ALOGV("allocate buffer, requested size %zu", requestedSize);
1964d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang                    mInternal->mBuffers.emplace_back(buffer);
197f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung                }
198e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            }
199e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        }
200f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung        if (buffer != nullptr) {
201e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            buffer->add_ref();
202e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            buffer->reset();
203e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            *out = buffer;
204f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            return OK;
205e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        }
206e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        if (nonBlocking) {
207f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung            *out = nullptr;
208e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia            return WOULD_BLOCK;
209e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        }
210f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung        // All buffers are in use, block until one of them is returned.
2114d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang        mInternal->mCondition.wait(mInternal->mLock);
212e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    }
213f59c0bafebcd795b20141bf928a5cab8ac46e882Andy Hung    // Never gets here.
214e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
215e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
2164d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kangsize_t MediaBufferGroup::buffers() const {
2174d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    return mInternal->mBuffers.size();
2184d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang}
2194d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang
2201889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kangvoid MediaBufferGroup::signalBufferReturned(MediaBufferBase *) {
2214d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    Mutex::Autolock autoLock(mInternal->mLock);
2224d0c0a8942de184f07fdd6c918c6355e5771bdffDongwon Kang    mInternal->mCondition.signal();
223e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
224e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
225e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}  // namespace android
226