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