aboutsummaryrefslogtreecommitdiff
path: root/plugin_store/V4L2PluginStore.cpp
blob: 2d53c5f88e10a28a33315d4ae961329981dfd859 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// 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 "V4L2PluginStore"

#include <inttypes.h>

#include <map>
#include <memory>
#include <mutex>

#include <C2AllocatorGralloc.h>
#include <C2BufferPriv.h>
#include <log/log.h>

#include <v4l2_codec2/plugin_store/C2VdaBqBlockPool.h>
#include <v4l2_codec2/plugin_store/C2VdaPooledBlockPool.h>
#include <v4l2_codec2/plugin_store/V4L2AllocatorId.h>
#include <v4l2_codec2/plugin_store/VendorAllocatorLoader.h>

namespace android {

C2Allocator* createAllocator(C2Allocator::id_t allocatorId) {
    ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
    static std::unique_ptr<VendorAllocatorLoader> sAllocatorLoader =
            VendorAllocatorLoader::Create();

    if (sAllocatorLoader != nullptr) {
        ALOGD("%s(): Create C2Allocator (id=%u) from VendorAllocatorLoader", __func__, allocatorId);
        return sAllocatorLoader->createAllocator(allocatorId);
    }

    ALOGI("%s(): Fallback to create C2AllocatorGralloc(id=%u)", __func__, allocatorId);
    return new C2AllocatorGralloc(allocatorId, true);
}

std::shared_ptr<C2Allocator> fetchAllocator(C2Allocator::id_t allocatorId) {
    ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
    static std::mutex sMutex;
    static std::map<C2Allocator::id_t, std::weak_ptr<C2Allocator>> sCacheAllocators;

    std::lock_guard<std::mutex> lock(sMutex);

    std::shared_ptr<C2Allocator> allocator;
    auto iter = sCacheAllocators.find(allocatorId);
    if (iter != sCacheAllocators.end()) {
        allocator = iter->second.lock();
        if (allocator != nullptr) {
            return allocator;
        }
    }

    allocator.reset(createAllocator(allocatorId));
    sCacheAllocators[allocatorId] = allocator;
    return allocator;
}

C2BlockPool* createBlockPool(C2Allocator::id_t allocatorId, C2BlockPool::local_id_t poolId) {
    ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);

    std::shared_ptr<C2Allocator> allocator = fetchAllocator(allocatorId);
    if (allocator == nullptr) {
        ALOGE("%s(): Failed to create allocator id=%u", __func__, allocatorId);
        return nullptr;
    }

    switch (allocatorId) {
    case V4L2AllocatorId::V4L2_BUFFERPOOL:
        return new C2VdaPooledBlockPool(allocator, poolId);

    case V4L2AllocatorId::V4L2_BUFFERQUEUE:
        return new C2VdaBqBlockPool(allocator, poolId);

    case V4L2AllocatorId::SECURE_LINEAR:
        return new C2PooledBlockPool(allocator, poolId);

    case V4L2AllocatorId::SECURE_GRAPHIC:
        return new C2VdaBqBlockPool(allocator, poolId);

    default:
        ALOGE("%s(): Unknown allocator id=%u", __func__, allocatorId);
        return nullptr;
    }
}

}  // namespace android

extern "C" ::C2BlockPool* CreateBlockPool(::C2Allocator::id_t allocatorId,
                                          ::C2BlockPool::local_id_t poolId) {
    ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);
    return ::android::createBlockPool(allocatorId, poolId);
}

extern "C" ::C2Allocator* CreateAllocator(::C2Allocator::id_t allocatorId, ::c2_status_t* status) {
    ALOGV("%s(allocatorId=%d)", __func__, allocatorId);

    ::C2Allocator* res = ::android::createAllocator(allocatorId);
    *status = (res != nullptr) ? C2_OK : C2_BAD_INDEX;
    return res;
}