xref: /aosp_15_r20/external/v4l2_codec2/components/ComponentStore.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2023 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 "ComponentStore"
7 
8 #include <v4l2_codec2/components/ComponentStore.h>
9 
10 #include <stdint.h>
11 
12 #include <memory>
13 #include <mutex>
14 
15 #include <C2.h>
16 #include <C2Config.h>
17 #include <log/log.h>
18 #include <media/stagefright/foundation/MediaDefs.h>
19 
20 #include <v4l2_codec2/common/VideoTypes.h>
21 
22 namespace android {
23 namespace {
24 const uint32_t kComponentRank = 0x80;
25 
26 }  // namespace
27 
ComponentStore(C2String storeName)28 ComponentStore::ComponentStore(C2String storeName)
29       : mStoreName(std::move(storeName)), mReflector(std::make_shared<C2ReflectorHelper>()) {
30     ALOGV("%s()", __func__);
31 }
32 
~ComponentStore()33 ComponentStore::~ComponentStore() {
34     ALOGV("%s()", __func__);
35 
36     std::lock_guard<std::mutex> lock(mCachedFactoriesLock);
37     mCachedFactories.clear();
38 }
39 
getName() const40 C2String ComponentStore::getName() const {
41     return mStoreName;
42 }
43 
createComponent(C2String name,std::shared_ptr<C2Component> * const component)44 c2_status_t ComponentStore::createComponent(C2String name,
45                                             std::shared_ptr<C2Component>* const component) {
46     ALOGV("%s(%s)", __func__, name.c_str());
47 
48     const auto& decl = mDeclarations.find(name);
49     if (decl == mDeclarations.end()) {
50         ALOGI("%s(): Invalid component name: %s", __func__, name.c_str());
51         return C2_NOT_FOUND;
52     }
53 
54     auto factory = getFactory(name);
55     if (factory == nullptr) return C2_CORRUPTED;
56 
57     component->reset();
58     return factory->createComponent(0, component);
59 }
60 
createInterface(C2String name,std::shared_ptr<C2ComponentInterface> * const interface)61 c2_status_t ComponentStore::createInterface(
62         C2String name, std::shared_ptr<C2ComponentInterface>* const interface) {
63     ALOGV("%s(%s)", __func__, name.c_str());
64 
65     const auto& decl = mDeclarations.find(name);
66     if (decl == mDeclarations.end()) {
67         ALOGI("%s(): Invalid component name: %s", __func__, name.c_str());
68         return C2_NOT_FOUND;
69     }
70 
71     auto factory = getFactory(name);
72     if (factory == nullptr) return C2_CORRUPTED;
73 
74     interface->reset();
75     return factory->createInterface(0, interface);
76 }
77 
listComponents()78 std::vector<std::shared_ptr<const C2Component::Traits>> ComponentStore::listComponents() {
79     ALOGV("%s()", __func__);
80 
81     std::vector<std::shared_ptr<const C2Component::Traits>> ret;
82     for (const auto& decl : mDeclarations) {
83         ret.push_back(getTraits(decl.first));
84     }
85 
86     return ret;
87 }
88 
getParamReflector() const89 std::shared_ptr<C2ParamReflector> ComponentStore::getParamReflector() const {
90     return mReflector;
91 }
92 
copyBuffer(std::shared_ptr<C2GraphicBuffer>,std::shared_ptr<C2GraphicBuffer>)93 c2_status_t ComponentStore::copyBuffer(std::shared_ptr<C2GraphicBuffer> /* src */,
94                                        std::shared_ptr<C2GraphicBuffer> /* dst */) {
95     return C2_OMITTED;
96 }
97 
querySupportedParams_nb(std::vector<std::shared_ptr<C2ParamDescriptor>> * const) const98 c2_status_t ComponentStore::querySupportedParams_nb(
99         std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const {
100     return C2_OK;
101 }
102 
query_sm(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const) const103 c2_status_t ComponentStore::query_sm(
104         const std::vector<C2Param*>& stackParams,
105         const std::vector<C2Param::Index>& heapParamIndices,
106         std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const {
107     // There are no supported config params.
108     return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX;
109 }
110 
config_sm(const std::vector<C2Param * > & params,std::vector<std::unique_ptr<C2SettingResult>> * const)111 c2_status_t ComponentStore::config_sm(
112         const std::vector<C2Param*>& params,
113         std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) {
114     // There are no supported config params.
115     return params.empty() ? C2_OK : C2_BAD_INDEX;
116 }
117 
querySupportedValues_sm(std::vector<C2FieldSupportedValuesQuery> & fields) const118 c2_status_t ComponentStore::querySupportedValues_sm(
119         std::vector<C2FieldSupportedValuesQuery>& fields) const {
120     // There are no supported config params.
121     return fields.empty() ? C2_OK : C2_BAD_INDEX;
122 }
123 
getFactory(const C2String & name)124 ::C2ComponentFactory* ComponentStore::getFactory(const C2String& name) {
125     ALOGV("%s(%s)", __func__, name.c_str());
126     ALOG_ASSERT(V4L2ComponentName::isValid(name.c_str()));
127 
128     std::lock_guard<std::mutex> lock(mCachedFactoriesLock);
129     const auto it = mCachedFactories.find(name);
130     if (it != mCachedFactories.end()) return it->second.get();
131 
132     const auto& decl = mDeclarations.find(name);
133     if (decl == mDeclarations.end()) {
134         ALOGI("%s(): Invalid component name: %s", __func__, name.c_str());
135         return nullptr;
136     }
137 
138     std::unique_ptr<::C2ComponentFactory> factory = decl->second.factory(name, mReflector);
139     if (factory == nullptr) {
140         ALOGE("Failed to create factory for %s", name.c_str());
141         return nullptr;
142     }
143 
144     auto ret = factory.get();
145     mCachedFactories.emplace(name, std::move(factory));
146     return ret;
147 }
148 
getTraits(const C2String & name)149 std::shared_ptr<const C2Component::Traits> ComponentStore::getTraits(const C2String& name) {
150     ALOGV("%s(%s)", __func__, name.c_str());
151 
152     const auto& iter = mDeclarations.find(name);
153     if (iter == mDeclarations.end()) {
154         ALOGE("Invalid component name: %s", name.c_str());
155         return nullptr;
156     }
157 
158     const Declaration& decl = iter->second;
159 
160     std::lock_guard<std::mutex> lock(mCachedTraitsLock);
161     auto it = mCachedTraits.find(name);
162     if (it != mCachedTraits.end()) return it->second;
163 
164     auto traits = std::make_shared<C2Component::Traits>();
165     traits->name = name;
166     traits->domain = C2Component::DOMAIN_VIDEO;
167     traits->rank = kComponentRank;
168     traits->kind = decl.kind;
169 
170     switch (decl.codec) {
171     case VideoCodec::H264:
172         traits->mediaType = MEDIA_MIMETYPE_VIDEO_AVC;
173         break;
174     case VideoCodec::VP8:
175         traits->mediaType = MEDIA_MIMETYPE_VIDEO_VP8;
176         break;
177     case VideoCodec::VP9:
178         traits->mediaType = MEDIA_MIMETYPE_VIDEO_VP9;
179         break;
180     case VideoCodec::HEVC:
181         traits->mediaType = MEDIA_MIMETYPE_VIDEO_HEVC;
182         break;
183     }
184 
185     mCachedTraits.emplace(name, traits);
186     return traits;
187 }
188 
Builder(C2String storeName)189 ComponentStore::Builder::Builder(C2String storeName)
190       : mStore(new ComponentStore(std::move(storeName))) {}
191 
decoder(std::string name,VideoCodec codec,GetFactory factory)192 ComponentStore::Builder& ComponentStore::Builder::decoder(std::string name, VideoCodec codec,
193                                                           GetFactory factory) {
194     mStore->mDeclarations[name] = Declaration{codec, C2Component::KIND_DECODER, std::move(factory)};
195     return *this;
196 }
197 
encoder(std::string name,VideoCodec codec,GetFactory factory)198 ComponentStore::Builder& ComponentStore::Builder::encoder(std::string name, VideoCodec codec,
199                                                           GetFactory factory) {
200     mStore->mDeclarations[name] = Declaration{codec, C2Component::KIND_ENCODER, std::move(factory)};
201     return *this;
202 }
203 
build()204 std::shared_ptr<ComponentStore> ComponentStore::Builder::build() && {
205     return std::shared_ptr<ComponentStore>(std::move(mStore));
206 }
207 }  // namespace android
208