aboutsummaryrefslogtreecommitdiff
path: root/plugin_store/C2VdaPooledBlockPool.cpp
blob: 2b9104bee8670a5c0f646029786075e8c2b8b2a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//#define LOG_NDEBUG 0
#define LOG_TAG "C2VdaPooledBlockPool"

#include <v4l2_codec2/plugin_store/C2VdaPooledBlockPool.h>

#include <time.h>

#include <C2BlockInternal.h>
#include <bufferpool/BufferPoolTypes.h>
#include <log/log.h>

namespace android {

using android::hardware::media::bufferpool::BufferPoolData;

// static
std::optional<uint32_t> C2VdaPooledBlockPool::getBufferIdFromGraphicBlock(const C2Block2D& block) {
    std::shared_ptr<_C2BlockPoolData> blockPoolData =
            _C2BlockFactory::GetGraphicBlockPoolData(block);
    if (blockPoolData->getType() != _C2BlockPoolData::TYPE_BUFFERPOOL) {
        ALOGE("Obtained C2GraphicBlock is not bufferpool-backed.");
        return std::nullopt;
    }
    std::shared_ptr<BufferPoolData> bpData;
    if (!_C2BlockFactory::GetBufferPoolData(blockPoolData, &bpData) || !bpData) {
        ALOGE("BufferPoolData unavailable in block.");
        return std::nullopt;
    }
    return bpData->mId;
}

// Tries to fetch a buffer from bufferpool. When the size of |mBufferIds| is smaller than
// |mBufferCount|, pass the obtained buffer to caller and record its ID in BufferPoolData to
// |mBufferIds|. When the size of |mBufferIds| is equal to |mBufferCount|, pass the obtained
// buffer only if its ID is included in |mBufferIds|. Otherwise, discard the buffer and
// return C2_TIMED_OUT.
c2_status_t C2VdaPooledBlockPool::fetchGraphicBlock(uint32_t width, uint32_t height,
                                                    uint32_t format, C2MemoryUsage usage,
                                                    std::shared_ptr<C2GraphicBlock>* block) {
    ALOG_ASSERT(block != nullptr);
    std::lock_guard<std::mutex> lock(mMutex);

    std::shared_ptr<C2GraphicBlock> fetchBlock;
    c2_status_t err =
            C2PooledBlockPool::fetchGraphicBlock(width, height, format, usage, &fetchBlock);
    if (err != C2_OK) {
        ALOGE("Failed at C2PooledBlockPool::fetchGraphicBlock: %d", err);
        return err;
    }

    std::optional<uint32_t> bufferId = getBufferIdFromGraphicBlock(*fetchBlock);
    if (!bufferId) {
        ALOGE("Failed to getBufferIdFromGraphicBlock");
        return C2_CORRUPTED;
    }

    if (mBufferIds.size() < mBufferCount) {
        mBufferIds.insert(*bufferId);
    }

    if (mBufferIds.find(*bufferId) != mBufferIds.end()) {
        ALOGV("Returned buffer id = %u", *bufferId);
        *block = std::move(fetchBlock);
        return C2_OK;
    }
    ALOGV("No buffer could be recycled now, wait for another try...");
    return C2_TIMED_OUT;
}

c2_status_t C2VdaPooledBlockPool::requestNewBufferSet(int32_t bufferCount) {
    if (bufferCount <= 0) {
        ALOGE("Invalid requested buffer count = %d", bufferCount);
        return C2_BAD_VALUE;
    }

    std::lock_guard<std::mutex> lock(mMutex);
    mBufferIds.clear();
    mBufferCount = bufferCount;
    return C2_OK;
}

}  // namespace android