1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "C2VdaPooledBlockPool"
7
8 #include <v4l2_codec2/plugin_store/C2VdaPooledBlockPool.h>
9
10 #include <time.h>
11
12 #include <C2BlockInternal.h>
13 #include <bufferpool/BufferPoolTypes.h>
14 #include <log/log.h>
15
16 namespace android {
17
18 using android::hardware::media::bufferpool::BufferPoolData;
19
20 // static
getBufferIdFromGraphicBlock(const C2Block2D & block)21 std::optional<uint32_t> C2VdaPooledBlockPool::getBufferIdFromGraphicBlock(const C2Block2D& block) {
22 std::shared_ptr<_C2BlockPoolData> blockPoolData =
23 _C2BlockFactory::GetGraphicBlockPoolData(block);
24 if (blockPoolData->getType() != _C2BlockPoolData::TYPE_BUFFERPOOL) {
25 ALOGE("Obtained C2GraphicBlock is not bufferpool-backed.");
26 return std::nullopt;
27 }
28 std::shared_ptr<BufferPoolData> bpData;
29 if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData) || !bpData) {
30 ALOGE("BufferPoolData unavailable in block.");
31 return std::nullopt;
32 }
33 return bpData->mId;
34 }
35
36 // Tries to fetch a buffer from bufferpool. When the size of |mBufferIds| is smaller than
37 // |mBufferCount|, pass the obtained buffer to caller and record its ID in BufferPoolData to
38 // |mBufferIds|. When the size of |mBufferIds| is equal to |mBufferCount|, pass the obtained
39 // buffer only if its ID is included in |mBufferIds|. Otherwise, discard the buffer and
40 // return C2_TIMED_OUT.
fetchGraphicBlock(uint32_t width,uint32_t height,uint32_t format,C2MemoryUsage usage,std::shared_ptr<C2GraphicBlock> * block)41 c2_status_t C2VdaPooledBlockPool::fetchGraphicBlock(uint32_t width, uint32_t height,
42 uint32_t format, C2MemoryUsage usage,
43 std::shared_ptr<C2GraphicBlock>* block) {
44 ALOG_ASSERT(block != nullptr);
45 std::lock_guard<std::mutex> lock(mMutex);
46
47 std::shared_ptr<C2GraphicBlock> fetchBlock;
48 c2_status_t err =
49 C2PooledBlockPool::fetchGraphicBlock(width, height, format, usage, &fetchBlock);
50 if (err != C2_OK) {
51 ALOGE("Failed at C2PooledBlockPool::fetchGraphicBlock: %d", err);
52 return err;
53 }
54
55 std::optional<uint32_t> bufferId = getBufferIdFromGraphicBlock(*fetchBlock);
56 if (!bufferId) {
57 ALOGE("Failed to getBufferIdFromGraphicBlock");
58 return C2_CORRUPTED;
59 }
60
61 if (mBufferIds.size() < mBufferCount) {
62 mBufferIds.insert(*bufferId);
63 }
64
65 if (mBufferIds.find(*bufferId) != mBufferIds.end()) {
66 ALOGV("Returned buffer id = %u", *bufferId);
67 *block = std::move(fetchBlock);
68 return C2_OK;
69 }
70 ALOGV("No buffer could be recycled now, wait for another try...");
71 return C2_TIMED_OUT;
72 }
73
requestNewBufferSet(int32_t bufferCount)74 c2_status_t C2VdaPooledBlockPool::requestNewBufferSet(int32_t bufferCount) {
75 if (bufferCount <= 0) {
76 ALOGE("Invalid requested buffer count = %d", bufferCount);
77 return C2_BAD_VALUE;
78 }
79
80 std::lock_guard<std::mutex> lock(mMutex);
81 mBufferIds.clear();
82 mBufferCount = bufferCount;
83 return C2_OK;
84 }
85
86 } // namespace android
87