• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "V4L2ComponentStore"
7 
8 #include <v4l2_codec2/components/V4L2ComponentStore.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/V4L2ComponentCommon.h>
21 #include <v4l2_codec2/components/V4L2ComponentFactory.h>
22 
23 namespace android {
24 namespace {
25 const uint32_t kComponentRank = 0x80;
26 
getMediaTypeFromComponentName(const std::string & name)27 std::string getMediaTypeFromComponentName(const std::string& name) {
28     if (name == V4L2ComponentName::kH264Decoder || name == V4L2ComponentName::kH264SecureDecoder ||
29         name == V4L2ComponentName::kH264Encoder) {
30         return MEDIA_MIMETYPE_VIDEO_AVC;
31     }
32     if (name == V4L2ComponentName::kVP8Decoder || name == V4L2ComponentName::kVP8SecureDecoder ||
33         name == V4L2ComponentName::kVP8Encoder) {
34         return MEDIA_MIMETYPE_VIDEO_VP8;
35     }
36     if (name == V4L2ComponentName::kVP9Decoder || name == V4L2ComponentName::kVP9SecureDecoder ||
37         name == V4L2ComponentName::kVP9Encoder) {
38         return MEDIA_MIMETYPE_VIDEO_VP9;
39     }
40     if (name == V4L2ComponentName::kHEVCDecoder || name == V4L2ComponentName::kHEVCSecureDecoder) {
41         return MEDIA_MIMETYPE_VIDEO_HEVC;
42     }
43     return "";
44 }
45 
46 }  // namespace
47 
48 // static
Create()49 std::shared_ptr<C2ComponentStore> V4L2ComponentStore::Create() {
50     ALOGV("%s()", __func__);
51 
52     static std::mutex mutex;
53     static std::weak_ptr<C2ComponentStore> platformStore;
54 
55     std::lock_guard<std::mutex> lock(mutex);
56     std::shared_ptr<C2ComponentStore> store = platformStore.lock();
57     if (store != nullptr) return store;
58 
59     store = std::shared_ptr<C2ComponentStore>(new V4L2ComponentStore());
60     platformStore = store;
61     return store;
62 }
63 
V4L2ComponentStore()64 V4L2ComponentStore::V4L2ComponentStore() : mReflector(std::make_shared<C2ReflectorHelper>()) {
65     ALOGV("%s()", __func__);
66 }
67 
~V4L2ComponentStore()68 V4L2ComponentStore::~V4L2ComponentStore() {
69     ALOGV("%s()", __func__);
70 
71     std::lock_guard<std::mutex> lock(mCachedFactoriesLock);
72     mCachedFactories.clear();
73 }
74 
getName() const75 C2String V4L2ComponentStore::getName() const {
76     return "android.componentStore.v4l2";
77 }
78 
createComponent(C2String name,std::shared_ptr<C2Component> * const component)79 c2_status_t V4L2ComponentStore::createComponent(C2String name,
80                                                 std::shared_ptr<C2Component>* const component) {
81     ALOGV("%s(%s)", __func__, name.c_str());
82 
83     if (!V4L2ComponentName::isValid(name.c_str())) {
84         ALOGI("%s(): Invalid component name: %s", __func__, name.c_str());
85         return C2_NOT_FOUND;
86     }
87 
88     auto factory = GetFactory(name);
89     if (factory == nullptr) return C2_CORRUPTED;
90 
91     component->reset();
92     return factory->createComponent(0, component);
93 }
94 
createInterface(C2String name,std::shared_ptr<C2ComponentInterface> * const interface)95 c2_status_t V4L2ComponentStore::createInterface(
96         C2String name, std::shared_ptr<C2ComponentInterface>* const interface) {
97     ALOGV("%s(%s)", __func__, name.c_str());
98 
99     if (!V4L2ComponentName::isValid(name.c_str())) {
100         ALOGI("%s(): Invalid component name: %s", __func__, name.c_str());
101         return C2_NOT_FOUND;
102     }
103 
104     auto factory = GetFactory(name);
105     if (factory == nullptr) return C2_CORRUPTED;
106 
107     interface->reset();
108     return factory->createInterface(0, interface);
109 }
110 
listComponents()111 std::vector<std::shared_ptr<const C2Component::Traits>> V4L2ComponentStore::listComponents() {
112     ALOGV("%s()", __func__);
113 
114     std::vector<std::shared_ptr<const C2Component::Traits>> ret;
115     ret.push_back(GetTraits(V4L2ComponentName::kH264Encoder));
116     ret.push_back(GetTraits(V4L2ComponentName::kH264Decoder));
117     ret.push_back(GetTraits(V4L2ComponentName::kH264SecureDecoder));
118     ret.push_back(GetTraits(V4L2ComponentName::kVP8Encoder));
119     ret.push_back(GetTraits(V4L2ComponentName::kVP8Decoder));
120     ret.push_back(GetTraits(V4L2ComponentName::kVP8SecureDecoder));
121     ret.push_back(GetTraits(V4L2ComponentName::kVP9Encoder));
122     ret.push_back(GetTraits(V4L2ComponentName::kVP9Decoder));
123     ret.push_back(GetTraits(V4L2ComponentName::kVP9SecureDecoder));
124     ret.push_back(GetTraits(V4L2ComponentName::kHEVCDecoder));
125     ret.push_back(GetTraits(V4L2ComponentName::kHEVCSecureDecoder));
126     return ret;
127 }
128 
getParamReflector() const129 std::shared_ptr<C2ParamReflector> V4L2ComponentStore::getParamReflector() const {
130     return mReflector;
131 }
132 
copyBuffer(std::shared_ptr<C2GraphicBuffer>,std::shared_ptr<C2GraphicBuffer>)133 c2_status_t V4L2ComponentStore::copyBuffer(std::shared_ptr<C2GraphicBuffer> /* src */,
134                                            std::shared_ptr<C2GraphicBuffer> /* dst */) {
135     return C2_OMITTED;
136 }
137 
querySupportedParams_nb(std::vector<std::shared_ptr<C2ParamDescriptor>> * const) const138 c2_status_t V4L2ComponentStore::querySupportedParams_nb(
139         std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const {
140     return C2_OK;
141 }
142 
query_sm(const std::vector<C2Param * > & stackParams,const std::vector<C2Param::Index> & heapParamIndices,std::vector<std::unique_ptr<C2Param>> * const) const143 c2_status_t V4L2ComponentStore::query_sm(
144         const std::vector<C2Param*>& stackParams,
145         const std::vector<C2Param::Index>& heapParamIndices,
146         std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const {
147     // There are no supported config params.
148     return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX;
149 }
150 
config_sm(const std::vector<C2Param * > & params,std::vector<std::unique_ptr<C2SettingResult>> * const)151 c2_status_t V4L2ComponentStore::config_sm(
152         const std::vector<C2Param*>& params,
153         std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) {
154     // There are no supported config params.
155     return params.empty() ? C2_OK : C2_BAD_INDEX;
156 }
157 
querySupportedValues_sm(std::vector<C2FieldSupportedValuesQuery> & fields) const158 c2_status_t V4L2ComponentStore::querySupportedValues_sm(
159         std::vector<C2FieldSupportedValuesQuery>& fields) const {
160     // There are no supported config params.
161     return fields.empty() ? C2_OK : C2_BAD_INDEX;
162 }
163 
GetFactory(const C2String & name)164 ::C2ComponentFactory* V4L2ComponentStore::GetFactory(const C2String& name) {
165     ALOGV("%s(%s)", __func__, name.c_str());
166     ALOG_ASSERT(V4L2ComponentName::isValid(name.c_str()));
167 
168     std::lock_guard<std::mutex> lock(mCachedFactoriesLock);
169     const auto it = mCachedFactories.find(name);
170     if (it != mCachedFactories.end()) return it->second.get();
171 
172     std::unique_ptr<::C2ComponentFactory> factory = V4L2ComponentFactory::create(
173             name, std::static_pointer_cast<C2ReflectorHelper>(getParamReflector()));
174     if (factory == nullptr) {
175         ALOGE("Failed to create factory for %s", name.c_str());
176         return nullptr;
177     }
178 
179     auto ret = factory.get();
180     mCachedFactories.emplace(name, std::move(factory));
181     return ret;
182 }
183 
GetTraits(const C2String & name)184 std::shared_ptr<const C2Component::Traits> V4L2ComponentStore::GetTraits(const C2String& name) {
185     ALOGV("%s(%s)", __func__, name.c_str());
186 
187     if (!V4L2ComponentName::isValid(name.c_str())) {
188         ALOGE("Invalid component name: %s", name.c_str());
189         return nullptr;
190     }
191 
192     std::lock_guard<std::mutex> lock(mCachedTraitsLock);
193     auto it = mCachedTraits.find(name);
194     if (it != mCachedTraits.end()) return it->second;
195 
196     auto traits = std::make_shared<C2Component::Traits>();
197     traits->name = name;
198     traits->domain = C2Component::DOMAIN_VIDEO;
199     traits->rank = kComponentRank;
200     traits->mediaType = getMediaTypeFromComponentName(name);
201     traits->kind = V4L2ComponentName::isEncoder(name.c_str()) ? C2Component::KIND_ENCODER
202                                                               : C2Component::KIND_DECODER;
203 
204     mCachedTraits.emplace(name, traits);
205     return traits;
206 }
207 
208 }  // namespace android
209