1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define HST_LOG_TAG "Compatible_Check"
17
18 #include "pipeline/core/compatible_check.h"
19 #include <algorithm>
20 #include <functional>
21 #include <map>
22 #include "foundation/log.h"
23 #include "plugin/common/plugin_attr_desc.h"
24
25 namespace OHOS {
26 namespace Media {
27 namespace Pipeline {
28 static constexpr uint8_t ALLOW_FIXED = 1 << 0;
29 static constexpr uint8_t ALLOW_INTERVAL = 1 << 1;
30 static constexpr uint8_t ALLOW_DISCRETE = 1 << 2;
31
IsFixedAllowed(uint8_t flags)32 static inline bool IsFixedAllowed(uint8_t flags)
33 {
34 return ALLOW_FIXED & flags;
35 }
36
IsIntervalAllowed(uint8_t flags)37 static inline bool IsIntervalAllowed(uint8_t flags)
38 {
39 return ALLOW_INTERVAL & flags;
40 }
41
IsDiscreteAllowed(uint8_t flags)42 static inline bool IsDiscreteAllowed(uint8_t flags)
43 {
44 return ALLOW_DISCRETE & flags;
45 }
46
47 template<typename T>
48 bool CapabilityValueCheck(CapabilityID key, std::pair<const Plugin::ValueType&, const Plugin::ValueType&> inVals,
49 uint8_t flags, std::function<int(T,T)> cmpFunc, Plugin::ValueType& outValue);
50
51 template <typename T>
FixInvalDiscCapValCheck(CapabilityID key,const Plugin::ValueType & val1,const Plugin::ValueType & val2,Plugin::ValueType & outValue)52 bool FixInvalDiscCapValCheck(CapabilityID key, const Plugin::ValueType& val1, const Plugin::ValueType& val2,
53 Plugin::ValueType& outValue)
54 {
55 return CapabilityValueCheck<T>(key, {val1, val2}, ALLOW_FIXED | ALLOW_INTERVAL | ALLOW_DISCRETE,
56 [](T a, T b) {
57 return a - b;
58 }, outValue);
59 }
60
61 template <typename T, typename U>
FixDiscCapValCheck(CapabilityID key,const Plugin::ValueType & val1,const Plugin::ValueType & val2,Plugin::ValueType & outValue)62 bool FixDiscCapValCheck(CapabilityID key, const Plugin::ValueType& val1, const Plugin::ValueType& val2,
63 Plugin::ValueType& outValue)
64 {
65 return CapabilityValueCheck<T>(key, {val1, val2}, ALLOW_FIXED | ALLOW_DISCRETE, [](T a, T b) {
66 return static_cast<U>(a) - static_cast<U>(b);
67 }, outValue);
68 }
69
70 static std::vector<CapabilityID> g_allCapabilityId = {
71 CapabilityID::AUDIO_SAMPLE_RATE, // 0
72 CapabilityID::AUDIO_CHANNELS, // 1
73 CapabilityID::AUDIO_CHANNEL_LAYOUT, // 2
74 CapabilityID::AUDIO_SAMPLE_FORMAT, // 3
75 CapabilityID::AUDIO_MPEG_VERSION, // 4
76 CapabilityID::AUDIO_MPEG_LAYER, // 5
77 CapabilityID::AUDIO_AAC_PROFILE, // 6
78 CapabilityID::AUDIO_AAC_LEVEL, // 7
79 CapabilityID::AUDIO_AAC_STREAM_FORMAT, // 8
80 CapabilityID::VIDEO_PIXEL_FORMAT, // 9
81 CapabilityID::VIDEO_BIT_STREAM_FORMAT, // 10
82 CapabilityID::MEDIA_BITRATE, // 11
83 };
84
85 template <typename T>
86 bool ExtractFixedCap(const Plugin::ValueType& value, Plugin::ValueType& fixedValue);
87 static std::map<CapabilityID, std::function<bool(const Plugin::ValueType&, Plugin::ValueType&)>> g_capExtrMap = {
88 {g_allCapabilityId[0], ExtractFixedCap<uint32_t>}, // 0
89 {g_allCapabilityId[1], ExtractFixedCap<uint32_t>}, // 1
90 {g_allCapabilityId[2], ExtractFixedCap<Plugin::AudioChannelLayout>}, // 2
91 {g_allCapabilityId[3], ExtractFixedCap<Plugin::AudioSampleFormat>}, // 3
92 {g_allCapabilityId[4], ExtractFixedCap<uint32_t>}, // 4
93 {g_allCapabilityId[5], ExtractFixedCap<uint32_t>}, // 5
94 {g_allCapabilityId[6], ExtractFixedCap<Plugin::AudioAacProfile>}, // 6
95 {g_allCapabilityId[7], ExtractFixedCap<uint32_t>}, // 7
96 {g_allCapabilityId[8], ExtractFixedCap<Plugin::AudioAacStreamFormat>}, // 8
97 {g_allCapabilityId[9], ExtractFixedCap<Plugin::VideoPixelFormat>}, // 9
98 {g_allCapabilityId[10], ExtractFixedCap<Plugin::VideoBitStreamFormat>}, // 10
99 {g_allCapabilityId[11], ExtractFixedCap<int64_t>}, // 11
100 };
101 using CheckFunc = std::function<bool(Capability::Key key, const Plugin::ValueType& val1, const Plugin::ValueType& val2,
102 Plugin::ValueType& outValue)>;
103 static std::map<CapabilityID, CheckFunc> g_capabilityValueCheckMap = {
104 {g_allCapabilityId[0], FixInvalDiscCapValCheck<uint32_t>}, // 0
105 {g_allCapabilityId[1], FixInvalDiscCapValCheck<uint32_t>}, // 1
106 {g_allCapabilityId[2], FixDiscCapValCheck<Plugin::AudioChannelLayout, uint64_t>}, // 2
107 {g_allCapabilityId[3], FixDiscCapValCheck<Plugin::AudioSampleFormat, uint8_t>}, // 3
108 {g_allCapabilityId[4], FixInvalDiscCapValCheck<uint32_t>}, // 4
109 {g_allCapabilityId[5], FixInvalDiscCapValCheck<uint32_t>}, // 5
110 {g_allCapabilityId[6], FixDiscCapValCheck<Plugin::AudioAacProfile, uint8_t>}, // 6
111 {g_allCapabilityId[7], FixInvalDiscCapValCheck<uint32_t>}, // 7
112 {g_allCapabilityId[8], FixDiscCapValCheck<Plugin::AudioAacStreamFormat, uint8_t>}, // 8
113 {g_allCapabilityId[9], FixDiscCapValCheck<Plugin::VideoPixelFormat, uint32_t>}, // 9
114 {g_allCapabilityId[10], FixDiscCapValCheck<Plugin::VideoBitStreamFormat, uint32_t>}, // 10
115 {g_allCapabilityId[11], FixInvalDiscCapValCheck<int64_t>}, // 11
116 };
117
118
StringEqIgnoreCase(const std::string & s1,const std::string & s2)119 static bool StringEqIgnoreCase(const std::string& s1, const std::string& s2)
120 {
121 if (s1.length() == s2.length()) {
122 return std::equal(s1.begin(), s1.end(), s2.begin(), [](char a, char b) { return tolower(a) == tolower(b); });
123 }
124 return false;
125 }
126
IsSubsetMime(const std::string & subset,const std::string & universe)127 bool IsSubsetMime(const std::string& subset, const std::string& universe)
128 {
129 size_t devLinePosInMeta = subset.find_first_of('/');
130 if (devLinePosInMeta == 0 || devLinePosInMeta == std::string::npos) {
131 MEDIA_LOG_E("wrong format of subset mime, must be xx/xxx");
132 return false;
133 }
134
135 if (universe == "*") {
136 return true;
137 }
138
139 size_t devLinePosInCap = universe.find_first_of('/');
140 if (devLinePosInCap == 0 || devLinePosInCap == std::string::npos) {
141 MEDIA_LOG_E("wrong format of universe mime, must be * or xx/* or xx/xxx");
142 return false;
143 }
144
145 // if media type is not the same, return false
146 if (!StringEqIgnoreCase(subset.substr(0, devLinePosInMeta), universe.substr(0, devLinePosInCap))) {
147 return false;
148 }
149 // if media type of capability is like audio/* video/* image/* etc. always return true
150 if (universe.substr(devLinePosInCap + 1) == "*") {
151 return true;
152 }
153 // left mime string compare
154 if (!StringEqIgnoreCase(universe.substr(devLinePosInCap + 1), subset.substr(devLinePosInMeta + 1))) {
155 return false;
156 }
157 return true;
158 }
159
160 template <typename T>
Max(T val1,T val2,std::function<int (T,T)> compareFunc)161 T Max(T val1, T val2, std::function<int(T, T)> compareFunc)
162 {
163 if (compareFunc(val1, val2) >= 0) {
164 return val1;
165 }
166 return val2;
167 }
168
169 template <typename T>
Min(T val1,T val2,std::function<int (T,T)> compareFunc)170 T Min(T val1, T val2, std::function<int(T, T)> compareFunc)
171 {
172 if (compareFunc(val1, val2) <= 0) {
173 return val1;
174 }
175 return val2;
176 }
177
178 template <typename T>
FFCapabilityCheck(const Plugin::FixedCapability<T> & v1,const Plugin::FixedCapability<T> & v2,std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)179 bool FFCapabilityCheck(const Plugin::FixedCapability<T>& v1, const Plugin::FixedCapability<T>& v2,
180 std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
181 {
182 if (cmpFunc(v1, v2) == 0) {
183 outValue = v1;
184 return true;
185 }
186 return false;
187 }
188
189 template <typename T>
FICapabilityCheck(const Plugin::FixedCapability<T> & v1,const Plugin::IntervalCapability<T> & v2,const std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)190 bool FICapabilityCheck(const Plugin::FixedCapability<T>& v1, const Plugin::IntervalCapability<T>& v2,
191 const std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
192 {
193 T max = Max(v2.first, v2.second, cmpFunc);
194 T min = Min(v2.first, v2.second, cmpFunc);
195 if (cmpFunc(v1, min) >= 0 && cmpFunc(v1, max) <= 0) {
196 outValue = v1;
197 return true;
198 }
199 return false;
200 }
201
202 template <typename T>
FDCapabilityCheck(const Plugin::FixedCapability<T> & v1,const Plugin::DiscreteCapability<T> & v2,const std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)203 bool FDCapabilityCheck(const Plugin::FixedCapability<T>& v1, const Plugin::DiscreteCapability<T>& v2,
204 const std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
205 {
206 if (std::any_of(v2.begin(), v2.end(), [&v1, &cmpFunc](const T& tmp){return cmpFunc(tmp, v1) == 0;})) {
207 outValue = v1;
208 return true;
209 }
210 return false;
211 }
212
213 template <typename T>
IICapabilityCheck(const Plugin::IntervalCapability<T> & v1,const Plugin::IntervalCapability<T> & v2,const std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)214 bool IICapabilityCheck(const Plugin::IntervalCapability<T>& v1, const Plugin::IntervalCapability<T>& v2,
215 const std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
216 {
217 T max1 = Max(v1.first, v1.second, cmpFunc);
218 T min1 = Min(v1.first, v1.second, cmpFunc);
219 T max2 = Max(v2.first, v2.second, cmpFunc);
220 T min2 = Min(v2.first, v2.second, cmpFunc);
221 T tmpMin = Max(min1, min2, cmpFunc);
222 T tmpMax = Min(max1, max2, cmpFunc);
223 auto compRes = cmpFunc(tmpMin, tmpMax);
224 if (compRes > 0) {
225 return false;
226 } else if (compRes == 0) {
227 outValue = Plugin::FixedCapability<T>(tmpMin);
228 } else {
229 outValue = Plugin::IntervalCapability<T>(tmpMin, tmpMax);
230 }
231 return true;
232 }
233
234 template <typename T>
IDCapabilityCheck(const Plugin::IntervalCapability<T> & v1,const Plugin::DiscreteCapability<T> & v2,const std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)235 bool IDCapabilityCheck(const Plugin::IntervalCapability<T>& v1, const Plugin::DiscreteCapability<T>& v2,
236 const std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
237 {
238 Plugin::DiscreteCapability<T> tmpOut;
239 for (const auto& oneValue : v2) {
240 if (cmpFunc(oneValue, v1.first) >= 0 && cmpFunc(oneValue, v1.second) <= 0) {
241 tmpOut.emplace_back(oneValue);
242 }
243 }
244 if (tmpOut.empty()) {
245 return false;
246 }
247 if (tmpOut.size() == 1) {
248 outValue = Plugin::FixedCapability<T>(tmpOut[0]);
249 } else {
250 outValue = Plugin::DiscreteCapability<T>(tmpOut);
251 }
252 return true;
253 }
254
255 template <typename T>
DDCapabilityCheck(const Plugin::DiscreteCapability<T> & v1,const Plugin::DiscreteCapability<T> & v2,const std::function<int (T,T)> & cmpFunc,Plugin::ValueType & outValue)256 bool DDCapabilityCheck(const Plugin::DiscreteCapability<T>& v1, const Plugin::DiscreteCapability<T>& v2,
257 const std::function<int(T,T)>& cmpFunc, Plugin::ValueType& outValue)
258 {
259 Plugin::DiscreteCapability<T> tmpOut;
260 for (const auto& cap1 : v1) {
261 if (std::any_of(v2.begin(), v2.end(), [&cap1, &cmpFunc](const T& tmp){return cmpFunc(cap1, tmp) == 0;})) {
262 tmpOut.emplace_back(cap1);
263 }
264 }
265 if (tmpOut.empty()) {
266 return false;
267 }
268 if (tmpOut.size() == 1) {
269 outValue = Plugin::FixedCapability<T>(tmpOut[0]);
270 } else {
271 outValue = Plugin::DiscreteCapability<T>(tmpOut);
272 }
273 return true;
274 }
275
LogOutIncorrectType(CapabilityID key,uint8_t flags)276 void LogOutIncorrectType(CapabilityID key, uint8_t flags)
277 {
278 if (Plugin::HasTagInfo(static_cast<Tag>(key))) {
279 const auto& tuple = Plugin::g_tagInfoMap.at(static_cast<Tag>(key));
280 const auto& typeName = std::get<2>(tuple); // secondary
281 MEDIA_LOG_E("type of " PUBLIC_LOG_S " should be"
282 " " PUBLIC_LOG_S "(" PUBLIC_LOG_C ")"
283 " or Interval<" PUBLIC_LOG_S ">(" PUBLIC_LOG_C ")"
284 " or Discrete<" PUBLIC_LOG_S ">(" PUBLIC_LOG_C ")",
285 std::get<0>(tuple),
286 typeName, IsFixedAllowed(flags)? 'o': 'x',
287 typeName, IsFixedAllowed(flags)? 'o': 'x',
288 typeName, IsFixedAllowed(flags)? 'o': 'x');
289 } else {
290 MEDIA_LOG_E("capability " PUBLIC_LOG_D32 "is not in the map, may be update the map?", key);
291 }
292 }
293
294 template <typename T>
FixedNumericalCapabilityCheck(CapabilityID key,const T & value2,const Plugin::ValueType & value1,uint8_t flags,std::function<int (T,T)> cmpFunc,Plugin::ValueType & outValue)295 bool FixedNumericalCapabilityCheck(CapabilityID key, const T& value2, const Plugin::ValueType& value1,
296 uint8_t flags, std::function<int(T, T)> cmpFunc, Plugin::ValueType& outValue)
297 {
298 if (Plugin::Any::IsSameTypeWith<T>(value1)) {
299 return FFCapabilityCheck(value2, Plugin::AnyCast<T>(value1), cmpFunc, outValue);
300 }
301 if (IsIntervalAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(value1)) {
302 return FICapabilityCheck(value2, Plugin::AnyCast<Plugin::IntervalCapability<T>>(value1), cmpFunc, outValue);
303 }
304 if (IsDiscreteAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(value1)) {
305 return FDCapabilityCheck(value2, Plugin::AnyCast<Plugin::DiscreteCapability<T>>(value1), cmpFunc, outValue);
306 }
307 LogOutIncorrectType(key, flags);
308 return false;
309 }
310
311 template <typename T>
IntervalNumericalCapabilityCheck(CapabilityID key,const Plugin::IntervalCapability<T> & value2,const Plugin::ValueType & value1,uint8_t flags,std::function<int (T,T)> cmpFunc,Plugin::ValueType & outValue)312 bool IntervalNumericalCapabilityCheck(CapabilityID key, const Plugin::IntervalCapability<T>& value2,
313 const Plugin::ValueType& value1, uint8_t flags, std::function<int(T, T)> cmpFunc, Plugin::ValueType& outValue)
314 {
315 if (IsFixedAllowed(flags) && Plugin::Any::IsSameTypeWith<T>(value1)) {
316 return FICapabilityCheck(Plugin::AnyCast<T>(value1), value2, cmpFunc, outValue);
317 }
318 if (Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(value1)) {
319 return IICapabilityCheck(Plugin::AnyCast<Plugin::IntervalCapability<T>>(value1), value2, cmpFunc, outValue);
320 }
321 if (IsDiscreteAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(value1)) {
322 return IDCapabilityCheck(value2, Plugin::AnyCast<Plugin::DiscreteCapability<T>>(value1), cmpFunc, outValue);
323 }
324 LogOutIncorrectType(key, flags);
325 return false;
326 }
327
328 template <typename T>
DiscreteNumericalCapabilityCheck(CapabilityID key,const Plugin::DiscreteCapability<T> & value2,const Plugin::ValueType & value1,uint8_t flags,std::function<int (T,T)> cmpFunc,Plugin::ValueType & outValue)329 bool DiscreteNumericalCapabilityCheck(CapabilityID key, const Plugin::DiscreteCapability<T>& value2,
330 const Plugin::ValueType& value1, uint8_t flags, std::function<int(T, T)> cmpFunc, Plugin::ValueType& outValue)
331 {
332 if (IsFixedAllowed(flags) && Plugin::Any::IsSameTypeWith<T>(value1)) {
333 return FDCapabilityCheck(Plugin::AnyCast<T>(value1), value2, cmpFunc, outValue);
334 }
335 if (IsIntervalAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(value1)) {
336 return IDCapabilityCheck(Plugin::AnyCast<Plugin::IntervalCapability<T>>(value1), value2, cmpFunc, outValue);
337 }
338 if (Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(value1)) {
339 return DDCapabilityCheck(Plugin::AnyCast<Plugin::DiscreteCapability<T>>(value1), value2, cmpFunc, outValue);
340 }
341 LogOutIncorrectType(key, flags);
342 return false;
343 }
344
345 template<typename T>
CapabilityValueCheck(CapabilityID key,std::pair<const Plugin::ValueType &,const Plugin::ValueType &> inVals,uint8_t flags,std::function<int (T,T)> cmpFunc,Plugin::ValueType & outValue)346 bool CapabilityValueCheck(CapabilityID key, std::pair<const Plugin::ValueType&, const Plugin::ValueType&> inVals,
347 uint8_t flags, std::function<int(T,T)> cmpFunc, Plugin::ValueType& outValue)
348 {
349 if (IsFixedAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::FixedCapability<T>>(inVals.first)) {
350 return FixedNumericalCapabilityCheck<T>(key,
351 Plugin::AnyCast<Plugin::FixedCapability<T>>(inVals.first), inVals.second, flags, cmpFunc,outValue);
352 }
353 if (IsIntervalAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(inVals.first)) {
354 return IntervalNumericalCapabilityCheck(key,
355 Plugin::AnyCast<Plugin::IntervalCapability<T>>(inVals.first), inVals.second, flags, cmpFunc, outValue);
356 }
357 if (IsDiscreteAllowed(flags) && Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(inVals.first)) {
358 return DiscreteNumericalCapabilityCheck(key,
359 Plugin::AnyCast<Plugin::DiscreteCapability<T>>(inVals.first), inVals.second, flags, cmpFunc, outValue);
360 }
361 LogOutIncorrectType(key, flags);
362 return false;
363 }
364
MergeCapabilityKeys(const Capability & originCap,const Capability & otherCap,Capability & resCap)365 bool MergeCapabilityKeys(const Capability& originCap, const Capability& otherCap, Capability& resCap)
366 {
367 resCap.keys.clear();
368 for (const auto& pairKey : originCap.keys) {
369 auto oIte = otherCap.keys.find(pairKey.first);
370 if (oIte == otherCap.keys.end()) {
371 // if key is not in otherCap, then put into resCap
372 resCap.keys.insert(pairKey);
373 continue;
374 }
375 // if key is in otherCap, calculate the intersections
376 if (g_capabilityValueCheckMap.count(pairKey.first) == 0) {
377 MEDIA_LOG_W("capability " PUBLIC_LOG_S " cannot be applied, may be update the check map?",
378 Plugin::Tag2String(static_cast<Plugin::Tag>(pairKey.first)));
379 continue;
380 }
381 Plugin::ValueType tmp;
382 if (g_capabilityValueCheckMap.at(pairKey.first)(pairKey.first, pairKey.second, oIte->second, tmp)) {
383 resCap.keys[pairKey.first] = tmp;
384 } else {
385 // if no intersections return false
386 resCap.keys.clear();
387 MEDIA_LOG_W("No intersections, originCap.mime: " PUBLIC_LOG_S ", tag: " PUBLIC_LOG_S,
388 originCap.mime.c_str(), Plugin::Tag2String(static_cast<Plugin::Tag>(pairKey.first)));
389 return false;
390 }
391 }
392 // if key is otherCap but not in originCap, put into resCap
393 for (const auto& pairKey : otherCap.keys) {
394 if (resCap.keys.count(pairKey.first) == 0) {
395 resCap.keys.insert(pairKey);
396 }
397 }
398 return true;
399 }
400
MergeCapability(const Capability & originCap,const Capability & otherCap,Capability & resCap)401 bool MergeCapability(const Capability& originCap, const Capability& otherCap, Capability& resCap)
402 {
403 resCap.mime.clear();
404 resCap.keys.clear();
405 if (!IsSubsetMime(originCap.mime, otherCap.mime)) {
406 return false;
407 }
408 if (!MergeCapabilityKeys(originCap, otherCap, resCap)) {
409 return false;
410 }
411 resCap.mime = originCap.mime;
412 return true;
413 }
414
ApplyCapabilitySet(const Capability & originCap,const CapabilitySet & capabilitySet,Capability & resCap)415 bool ApplyCapabilitySet(const Capability& originCap, const CapabilitySet& capabilitySet, Capability& resCap)
416 {
417 Capability tmp;
418 for (const auto& cap : capabilitySet) {
419 if (MergeCapability(originCap, cap, resCap)) {
420 return true;
421 }
422 }
423 return false;
424 }
425
426 template <typename T>
ExtractFixedCap(const Plugin::ValueType & value,Plugin::ValueType & fixedValue)427 bool ExtractFixedCap(const Plugin::ValueType& value, Plugin::ValueType& fixedValue)
428 {
429 if (Plugin::Any::IsSameTypeWith<Plugin::FixedCapability<T>>(value)) {
430 fixedValue = Plugin::AnyCast<Plugin::FixedCapability<T>>(value);
431 return true;
432 } else if (Plugin::Any::IsSameTypeWith<Plugin::IntervalCapability<T>>(value)) {
433 auto tmp = Plugin::AnyCast<Plugin::IntervalCapability<T>>(value);
434 fixedValue = tmp.first;
435 return true;
436 } else if (Plugin::Any::IsSameTypeWith<Plugin::DiscreteCapability<T>>(value)) {
437 auto tmp = Plugin::AnyCast<Plugin::DiscreteCapability<T>>(value);
438 if (!tmp.empty()) {
439 fixedValue = tmp[0];
440 return true;
441 }
442 }
443 return false;
444 }
445
MetaToCapability(const Plugin::Meta & meta)446 std::shared_ptr<Capability> MetaToCapability(const Plugin::Meta& meta)
447 {
448 auto ret = std::make_shared<Capability>();
449 std::string mime;
450 if (meta.Get<Plugin::Tag::MIME>(mime)) {
451 ret->mime = mime;
452 }
453 for (const auto& key : g_allCapabilityId) {
454 Plugin::ValueType tmp;
455 if (meta.GetData(static_cast<Plugin::Tag>(key), tmp)) {
456 ret->keys[key] = tmp;
457 }
458 }
459 return ret;
460 }
461
MergeMetaWithCapability(const Plugin::Meta & meta,const Capability & cap,Plugin::Meta & resMeta)462 bool MergeMetaWithCapability(const Plugin::Meta& meta, const Capability& cap, Plugin::Meta& resMeta)
463 {
464 resMeta.Clear();
465 // change meta into capability firstly
466 Capability metaCap;
467 metaCap.mime = cap.mime;
468 for (const auto& key : g_allCapabilityId) {
469 Plugin::ValueType tmp;
470 if (meta.GetData(static_cast<Plugin::Tag>(key), tmp)) {
471 metaCap.keys[key] = tmp;
472 }
473 }
474 Capability resCap;
475 if (!MergeCapability(metaCap, cap, resCap)) {
476 return false;
477 }
478 // merge capability
479 resMeta = meta;
480 resMeta.Set<Plugin::Tag::MIME>(cap.mime);
481 for (const auto& oneCap : resCap.keys) {
482 if (g_capExtrMap.count(oneCap.first) == 0) {
483 continue;
484 }
485 auto func = g_capExtrMap[oneCap.first];
486 Plugin::ValueType tmp;
487 if (func(oneCap.second, tmp)) {
488 resMeta.SetData(static_cast<Plugin::Tag>(oneCap.first), tmp);
489 }
490 }
491 return true;
492 }
493 } // namespace Pipeline
494 } // namespace Media
495 } // namespace OHOS
496