1 /*
2 * Copyright (C) 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 #include "avcodec_xml_parser.h"
16 #include "media_errors.h"
17 #include "media_log.h"
18 #include "string_ex.h"
19
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecXmlParser"};
22 constexpr int32_t PAIR_LENGTH = 2;
23 const std::string AVCODEC_CONFIG_FILE = "/etc/codec/codec_caps.xml";
24 }
25
26 namespace OHOS {
27 namespace Media {
28 const std::unordered_map<std::string, int> VIDEO_PROFILE_MAP = {
29 // H263
30 {"H263BackwardCompatible", H263_PROFILE_BACKWARD_COMPATIBLE},
31 {"H263Baseline", H263_PROFILE_BASELINE},
32 {"H263H320Coding", H263_PROFILE_H320_CODING},
33 {"H263HighCompression", H263_PROFILE_HIGH_COMPRESSION},
34 {"H263HighLatency", H263_PROFILE_HIGH_LATENCY},
35 {"H263ISWV2", H263_PROFILE_ISW_V2},
36 {"H263ISWV3", H263_PROFILE_ISW_V3},
37 {"H263Interlace", H263_PROFILE_INTERLACE},
38 {"H263Internet", H263_PROFILE_INTERNET},
39 // H264
40 {"AVCBaseline", AVC_PROFILE_BASELINE},
41 {"AVCHighCompression", AVC_PROFILE_CONSTRAINED_BASELINE},
42 {"AVCConstrainedHigh", AVC_PROFILE_CONSTRAINED_HIGH},
43 {"AVCExtended", AVC_PROFILE_EXTENDED},
44 {"AVCHigh", AVC_PROFILE_HIGH},
45 {"AVCHigh10", AVC_PROFILE_HIGH_10},
46 {"AVCHigh422", AVC_PROFILE_HIGH_422},
47 {"AVCHigh444", AVC_PROFILE_HIGH_444},
48 {"AVCMain", AVC_PROFILE_MAIN},
49 // H265
50 {"HEVCMain", HEVC_PROFILE_MAIN},
51 {"HEVCMain10", HEVC_PROFILE_MAIN_10},
52 {"HEVCMainStill", HEVC_PROFILE_MAIN_STILL},
53 // MPEG2
54 {"MPEG2_422", MPEG2_PROFILE_422},
55 {"MPEG2High", MPEG2_PROFILE_HIGH},
56 {"MPEG2Main", MPEG2_PROFILE_MAIN},
57 {"MPEG2SNR", MPEG2_PROFILE_SNR},
58 {"MPEG2Simple", MPEG2_PROFILE_SIMPLE},
59 {"MPEG2Spatial", MPEG2_PROFILE_SPATIAL},
60 // MPEG4
61 {"MPEG4AdvancedCoding", MPEG4_PROFILE_ADVANCED_CODING},
62 {"MPEG4AdvancedCore", MPEG4_PROFILE_ADVANCED_CORE},
63 {"MPEG4AdvancedRealTime", MPEG4_PROFILE_ADVANCED_REAL_TIME},
64 {"MPEG4AdvancedScalable", MPEG4_PROFILE_ADVANCED_SCALABLE},
65 {"MPEG4AdvancedSimple", MPEG4_PROFILE_ADVANCED_SIMPLE},
66 {"MPEG4BasicAnimated", MPEG4_PROFILE_BASIC_ANIMATED},
67 {"MPEG4Core", MPEG4_PROFILE_CORE},
68 {"MPEG4CoreScalable", MPEG4_PROFILE_CORE_SCALABLE},
69 {"MPEG4Hybrid", MPEG4_PROFILE_HYBRID},
70 {"MPEG4Main", MPEG4_PROFILE_MAIN},
71 {"MPEG4Nbit", MPEG4_PROFILE_NBIT},
72 {"MPEG4ScalableTexture", MPEG4_PROFILE_SCALABLE_TEXTURE},
73 {"MPEG4Simple", MPEG4_PROFILE_SIMPLE},
74 {"MPEG4SimpleFBA", MPEG4_PROFILE_SIMPLE_FBA},
75 {"MPEG4SimpleFace", MPEG4_PROFILE_SIMPLE_FACE},
76 {"MPEG4SimpleScalable", MPEG4_PROFILE_SIMPLE_SCALABLE},
77 // VP8
78 {"VP8Main", VP8_PROFILE_MAIN},
79 };
80
81 const std::unordered_map<std::string, int> AUDIO_PROFILE_MAP = {
82 {"AAC_LC", AAC_PROFILE_LC},
83 {"AAC_ELD", AAC_PROFILE_ELD},
84 {"AAC_ERLC", AAC_PROFILE_ERLC},
85 {"AAC_HE", AAC_PROFILE_HE},
86 {"AAC_HE_V2", AAC_PROFILE_HE_V2},
87 {"AAC_LD", AAC_PROFILE_LD},
88 {"AAC_Main", AAC_PROFILE_MAIN},
89 };
90
91 const std::unordered_map<std::string, int> VIDEO_FORMAT_MAP = {
92 {"YUVI420", YUVI420},
93 {"NV12", NV12},
94 {"NV21", NV21},
95 {"RGBA", RGBA},
96 };
97
98 const std::unordered_map<std::string, int> AUDIO_FORMAT_MAP = {
99 {"U8", AudioStandard::SAMPLE_U8},
100 {"S16LE", AudioStandard::SAMPLE_S16LE},
101 {"S24LE", AudioStandard::SAMPLE_S24LE},
102 {"S32LE", AudioStandard::SAMPLE_S32LE},
103 };
104
105 const std::unordered_map<std::string, int> BITRATE_MODE_MAP = {
106 {"CBR", CBR},
107 {"VBR", VBR},
108 {"CQ", CQ},
109 };
110
111 const std::unordered_map<std::string, AVCodecType> CODEC_TYPE_MAP = {
112 {"VIDEO_ENCODER", AVCODEC_TYPE_VIDEO_ENCODER},
113 {"VIDEO_DECODER", AVCODEC_TYPE_VIDEO_DECODER},
114 {"AUDIO_ENCODER", AVCODEC_TYPE_AUDIO_ENCODER},
115 {"AUDIO_DECODER", AVCODEC_TYPE_AUDIO_DECODER},
116 };
117
AVCodecXmlParser()118 AVCodecXmlParser::AVCodecXmlParser()
119 {
120 capabilityKeys_ = {
121 "codecName",
122 "codecType",
123 "mimeType",
124 "isVendor",
125 "bitrate",
126 "channels",
127 "sampleRate",
128 "format",
129 "profiles",
130 "complexity",
131 "bitrateMode",
132 "alignment",
133 "width",
134 "height",
135 "frameRate",
136 "encodeQuality",
137 "quality",
138 "levels",
139 "blockPerFrame",
140 "blockPerSecond",
141 "blockSize",
142 "profileLevelsMap",
143 "measuredFrameRate",
144 };
145 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
146 }
147
~AVCodecXmlParser()148 AVCodecXmlParser::~AVCodecXmlParser()
149 {
150 Destroy();
151 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
152 }
153
LoadConfiguration()154 bool AVCodecXmlParser::LoadConfiguration()
155 {
156 mDoc_ = xmlReadFile(AVCODEC_CONFIG_FILE.c_str(), nullptr, 0);
157 if (mDoc_ == nullptr) {
158 MEDIA_LOGE("AVCodec xmlReadFile failed");
159 return false;
160 }
161 return true;
162 }
163
Parse()164 bool AVCodecXmlParser::Parse()
165 {
166 xmlNode *root = xmlDocGetRootElement(mDoc_);
167 if (root == nullptr) {
168 MEDIA_LOGE("AVCodec xmlDocGetRootElement failed");
169 return false;
170 }
171 return ParseInternal(root);
172 }
173
Destroy()174 void AVCodecXmlParser::Destroy()
175 {
176 if (mDoc_ != nullptr) {
177 xmlFreeDoc(mDoc_);
178 }
179 return;
180 }
181
ParseInternal(xmlNode * node)182 bool AVCodecXmlParser::ParseInternal(xmlNode *node)
183 {
184 xmlNode *currNode = node;
185 for (; currNode != nullptr; currNode = currNode->next) {
186 if (currNode->type == XML_ELEMENT_NODE) {
187 switch (GetNodeNameAsInt(currNode)) {
188 case AUDIO_DECODER:
189 case AUDIO_ENCODER:
190 case VIDEO_DECODER:
191 case VIDEO_ENCODER: {
192 ParseData(currNode);
193 break;
194 }
195 default:
196 ParseInternal(currNode->children);
197 break;
198 }
199 }
200 }
201 return true;
202 }
203
TransStrAsRange(const std::string & str,Range & range)204 bool AVCodecXmlParser::TransStrAsRange(const std::string &str, Range &range)
205 {
206 if (str == "null" || str == "") {
207 MEDIA_LOGD("str is null");
208 return false;
209 }
210 size_t pos = str.find("-");
211 if (pos != str.npos && pos + 1 < str.size()) {
212 std::string head = str.substr(0, pos);
213 std::string tail = str.substr(pos + 1);
214 if (!StrToInt(head, range.minVal)) {
215 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", head.c_str());
216 return false;
217 }
218 if (!StrToInt(tail, range.maxVal)) {
219 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", tail.c_str());
220 return false;
221 }
222 } else {
223 MEDIA_LOGD("Can not find the delimiter of \"-\" in : %{public}s", str.c_str());
224 return false;
225 }
226 return true;
227 }
228
TransStrAsSize(const std::string & str,ImgSize & size)229 bool AVCodecXmlParser::TransStrAsSize(const std::string &str, ImgSize &size)
230 {
231 if (str == "null" || str == "") {
232 MEDIA_LOGD("str is null");
233 return false;
234 }
235 size_t pos = str.find("x");
236 if (pos != str.npos && pos + 1 < str.size()) {
237 std::string head = str.substr(0, pos);
238 std::string tail = str.substr(pos + 1);
239 if (!StrToInt(head, size.width)) {
240 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", head.c_str());
241 return false;
242 }
243 if (!StrToInt(tail, size.height)) {
244 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", tail.c_str());
245 return false;
246 }
247 } else {
248 MEDIA_LOGD("Can not find the delimiter of \"x\" in : %{public}s", str.c_str());
249 return false;
250 }
251 return true;
252 }
253
TransStrAsIntegerArray(const std::vector<std::string> & spilt)254 std::vector<int32_t> AVCodecXmlParser::TransStrAsIntegerArray(const std::vector<std::string> &spilt)
255 {
256 std::vector<int32_t> array;
257 for (auto iter = spilt.begin(); iter != spilt.end(); iter++) {
258 int32_t num = -1;
259 if (!StrToInt(*iter, num)) {
260 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", iter->c_str());
261 return array;
262 }
263 array.push_back(num);
264 }
265 return array;
266 }
267
TransMapAsIntegerArray(const std::unordered_map<std::string,int> & capabilityMap,const std::vector<std::string> & spilt)268 std::vector<int32_t> AVCodecXmlParser::TransMapAsIntegerArray(
269 const std::unordered_map<std::string, int> &capabilityMap,
270 const std::vector<std::string> &spilt)
271 {
272 std::vector<int32_t> res;
273 for (auto iter = spilt.begin(); iter != spilt.end(); iter++) {
274 if (capabilityMap.find(*iter) != capabilityMap.end()) {
275 res.emplace_back(capabilityMap.at(*iter));
276 } else {
277 MEDIA_LOGD("can not find %{public}s in capabilityMap", iter->c_str());
278 }
279 }
280 return res;
281 }
282
SpiltKeyList(const std::string & str,const std::string & delim,std::vector<std::string> & spilt)283 bool AVCodecXmlParser::SpiltKeyList(const std::string &str, const std::string &delim,
284 std::vector<std::string> &spilt)
285 {
286 if (str == "") {
287 return false;
288 }
289 std::string strAddDelim = str;
290 if (str.back() != delim.back()) {
291 strAddDelim = str + delim;
292 }
293 size_t size = strAddDelim.size();
294 for (size_t i = 0; i < size; ++i) {
295 size_t pos = strAddDelim.find(delim, i);
296 if (pos != strAddDelim.npos) {
297 std::string s = strAddDelim.substr(i, pos - i);
298 spilt.push_back(s);
299 i = pos + delim.size() - 1;
300 }
301 }
302 return true;
303 }
304
SetCapabilityStringData(std::unordered_map<std::string,std::string &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)305 bool AVCodecXmlParser::SetCapabilityStringData(std::unordered_map<std::string, std::string&> dataMap,
306 const std::string &capabilityKey, const std::string &capabilityValue)
307 {
308 dataMap.at(capabilityKey) = capabilityValue;
309 return true;
310 }
311
SetCapabilityIntData(std::unordered_map<std::string,int32_t &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)312 bool AVCodecXmlParser::SetCapabilityIntData(std::unordered_map<std::string, int32_t&> dataMap,
313 const std::string &capabilityKey, const std::string &capabilityValue)
314 {
315 if (CODEC_TYPE_MAP.find(capabilityValue) != CODEC_TYPE_MAP.end()) {
316 dataMap.at(capabilityKey) = CODEC_TYPE_MAP.at(capabilityValue);
317 } else {
318 MEDIA_LOGD("The value of %{public}s in the configuration file is incorrect.", capabilityValue.c_str());
319 return false;
320 }
321 return true;
322 }
323
SetCapabilityBoolData(std::unordered_map<std::string,bool &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)324 bool AVCodecXmlParser::SetCapabilityBoolData(std::unordered_map<std::string, bool&> dataMap,
325 const std::string &capabilityKey, const std::string &capabilityValue)
326 {
327 if (capabilityValue == "true") {
328 dataMap.at(capabilityKey) = true;
329 } else if (capabilityValue == "false") {
330 dataMap.at(capabilityKey) = false;
331 } else {
332 MEDIA_LOGD("The value of %{public}s in the configuration file is incorrect.", capabilityValue.c_str());
333 return false;
334 }
335 return true;
336 }
337
SetCapabilityRangeData(std::unordered_map<std::string,Range &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)338 bool AVCodecXmlParser::SetCapabilityRangeData(std::unordered_map<std::string, Range&> dataMap,
339 const std::string &capabilityKey, const std::string &capabilityValue)
340 {
341 Range range;
342 bool ret = TransStrAsRange(capabilityValue, range);
343 CHECK_AND_RETURN_RET_LOG(ret != false, false, "failed:can not trans %{public}s", capabilityValue.c_str());
344 dataMap.at(capabilityKey) = range;
345 return true;
346 }
347
SetCapabilitySizeData(std::unordered_map<std::string,ImgSize &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)348 bool AVCodecXmlParser::SetCapabilitySizeData(std::unordered_map<std::string, ImgSize&> dataMap,
349 const std::string &capabilityKey, const std::string &capabilityValue)
350 {
351 ImgSize size;
352 bool ret = TransStrAsSize(capabilityValue, size);
353 CHECK_AND_RETURN_RET_LOG(ret != false, false, "failed:can not trans %{public}s", capabilityValue.c_str());
354 dataMap.at(capabilityKey) = size;
355 return true;
356 }
357
SetCapabilityHashRangeData(std::unordered_map<std::string,std::map<ImgSize,Range> &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)358 bool AVCodecXmlParser::SetCapabilityHashRangeData(std::unordered_map<std::string, std::map<ImgSize, Range>&> dataMap,
359 const std::string &capabilityKey, const std::string &capabilityValue)
360 {
361 std::map<ImgSize, Range> resolutionFrameRateMap;
362 std::vector<std::string> spilt;
363 bool ret = SpiltKeyList(capabilityValue, ",", spilt);
364 CHECK_AND_RETURN_RET_LOG(ret != false, false, "failed:can not split %{public}s", capabilityValue.c_str());
365 for (auto iter = spilt.begin(); iter != spilt.end(); iter++) {
366 std::vector<std::string> resolutionFrameRateVector;
367 ImgSize resolution;
368 Range frameRate;
369 ret = SpiltKeyList(*iter, "@", resolutionFrameRateVector);
370 CHECK_AND_RETURN_RET_LOG(ret != false && resolutionFrameRateVector.size() == PAIR_LENGTH, false,
371 "failed:can not trans %{public}s", iter->c_str());
372 if (!(TransStrAsSize(resolutionFrameRateVector[0], resolution) &&
373 TransStrAsRange(resolutionFrameRateVector[1], frameRate))) {
374 MEDIA_LOGD("failed:can not trans %{public}s for resolution or frame rate", iter->c_str());
375 return false;
376 }
377 resolutionFrameRateMap.insert(std::make_pair(resolution, frameRate));
378 }
379 dataMap.at(capabilityKey) = resolutionFrameRateMap;
380 return true;
381 }
382
IsNumberArray(const std::vector<std::string> & strArray)383 bool AVCodecXmlParser::IsNumberArray(const std::vector<std::string> &strArray)
384 {
385 for (auto iter = strArray.begin(); iter != strArray.end(); iter++) {
386 for (char const &c : *iter) {
387 if (std::isdigit(c) == 0) {
388 return false;
389 }
390 }
391 }
392 return true;
393 }
394
SetCapabilityVectorData(std::unordered_map<std::string,std::vector<int32_t> &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue)395 bool AVCodecXmlParser::SetCapabilityVectorData(std::unordered_map<std::string, std::vector<int32_t>&> dataMap,
396 const std::string &capabilityKey, const std::string &capabilityValue)
397 {
398 std::vector<std::string> spilt;
399 std::vector<int32_t> array;
400 bool ret = SpiltKeyList(capabilityValue, ",", spilt);
401 CHECK_AND_RETURN_RET_LOG(ret != false, false, "failed:can not split %{public}s", capabilityValue.c_str());
402 if (spilt.size() > 0) {
403 std::string probe = spilt[0];
404 if (VIDEO_PROFILE_MAP.find(probe) != VIDEO_PROFILE_MAP.end()) {
405 array = TransMapAsIntegerArray(VIDEO_PROFILE_MAP, spilt);
406 } else if (AUDIO_PROFILE_MAP.find(probe) != AUDIO_PROFILE_MAP.end()) {
407 array = TransMapAsIntegerArray(AUDIO_PROFILE_MAP, spilt);
408 } else if (VIDEO_FORMAT_MAP.find(probe) != VIDEO_FORMAT_MAP.end()) {
409 array = TransMapAsIntegerArray(VIDEO_FORMAT_MAP, spilt);
410 } else if (AUDIO_FORMAT_MAP.find(probe) != AUDIO_FORMAT_MAP.end()) {
411 array = TransMapAsIntegerArray(AUDIO_FORMAT_MAP, spilt);
412 } else if (BITRATE_MODE_MAP.find(probe) != BITRATE_MODE_MAP.end()) {
413 array = TransMapAsIntegerArray(BITRATE_MODE_MAP, spilt);
414 } else if (IsNumberArray(spilt)) {
415 array = TransStrAsIntegerArray(spilt);
416 } else {
417 MEDIA_LOGD("The value of %{public}s in the configuration file is incorrect.", capabilityValue.c_str());
418 return false;
419 }
420 dataMap.at(capabilityKey) = array;
421 }
422 return true;
423 }
424
SetCapabilityData(CapabilityData & data,const std::string & capabilityKey,const std::string & capabilityValue) const425 bool AVCodecXmlParser::SetCapabilityData(CapabilityData &data, const std::string &capabilityKey,
426 const std::string &capabilityValue) const
427 {
428 std::unordered_map<std::string, std::string&> capabilityStringMap = {
429 {"codecName", data.codecName}, {"mimeType", data.mimeType}};
430
431 std::unordered_map<std::string, int32_t&> capabilityIntMap = {{"codecType", data.codecType}};
432
433 std::unordered_map<std::string, bool&> capabilityBoolMap = {{"isVendor", data.isVendor}};
434
435 std::unordered_map<std::string, ImgSize&> capabilitySizeMap = {{"blockSize", data.blockSize}};
436
437 std::unordered_map<std::string, std::map<ImgSize, Range>&> capabilityHashRangeMap = {
438 {"measuredFrameRate", data.measuredFrameRate}};
439
440 std::unordered_map<std::string, Range&> capabilityRangeMap = {
441 {"bitrate", data.bitrate}, {"channels", data.channels}, {"complexity", data.complexity},
442 {"alignment", data.alignment}, {"width", data.width}, {"height", data.height}, {"frameRate", data.frameRate},
443 {"encodeQuality", data.encodeQuality}, {"quality", data.quality}, {"blockPerFrame", data.blockPerFrame},
444 {"blockPerSecond", data.blockPerSecond}};
445
446 std::unordered_map<std::string, std::vector<int32_t>&> capabilityVectorMap = {
447 {"sampleRate", data.sampleRate}, {"format", data.format}, {"profiles", data.profiles},
448 {"bitrateMode", data.bitrateMode}, {"levels", data.levels}};
449
450 bool ret = false;
451 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
452 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
453 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
454 } else if (capabilityIntMap.find(capabilityKey) != capabilityIntMap.end()) {
455 ret = SetCapabilityIntData(capabilityIntMap, capabilityKey, capabilityValue);
456 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityIntData failed");
457 } else if (capabilityBoolMap.find(capabilityKey) != capabilityBoolMap.end()) {
458 ret = SetCapabilityBoolData(capabilityBoolMap, capabilityKey, capabilityValue);
459 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityBoolData failed");
460 } else if (capabilitySizeMap.find(capabilityKey) != capabilitySizeMap.end()) {
461 ret = SetCapabilitySizeData(capabilitySizeMap, capabilityKey, capabilityValue);
462 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilitySizeData failed");
463 } else if (capabilityHashRangeMap.find(capabilityKey) != capabilityHashRangeMap.end()) {
464 ret = SetCapabilityHashRangeData(capabilityHashRangeMap, capabilityKey, capabilityValue);
465 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityHashRangeData failed");
466 } else if (capabilityRangeMap.find(capabilityKey) != capabilityRangeMap.end()) {
467 ret = SetCapabilityRangeData(capabilityRangeMap, capabilityKey, capabilityValue);
468 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityRangeData failed");
469 } else if (capabilityVectorMap.find(capabilityKey) != capabilityVectorMap.end()) {
470 ret = SetCapabilityVectorData(capabilityVectorMap, capabilityKey, capabilityValue);
471 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityVectorData failed");
472 } else {
473 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
474 }
475 return true;
476 }
477
ParseData(xmlNode * node)478 bool AVCodecXmlParser::ParseData(xmlNode *node)
479 {
480 xmlNode *child = node->xmlChildrenNode;
481 std::string capabilityValue;
482 CapabilityData capabilityData;
483 for (; child != nullptr; child = child->next) {
484 if (!xmlStrEqual(child->name, reinterpret_cast<const xmlChar*>("Item"))) {
485 continue;
486 }
487 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
488 std::string capabilityKey = *it;
489 if (xmlHasProp(child, reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))) {
490 xmlChar *pXmlProp = xmlGetProp(
491 child, reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())));
492 CHECK_AND_CONTINUE(pXmlProp != nullptr);
493 capabilityValue = std::string(reinterpret_cast<char*>(pXmlProp));
494 bool ret = SetCapabilityData(capabilityData, capabilityKey, capabilityValue);
495 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityData failed");
496 break;
497 }
498 }
499 }
500 capabilityDataArray_.push_back(capabilityData);
501 return true;
502 }
503
GetNodeNameAsInt(xmlNode * node)504 NodeName AVCodecXmlParser::GetNodeNameAsInt(xmlNode *node)
505 {
506 if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("Codecs"))) {
507 return CODECS;
508 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("AudioCodecs"))) {
509 return AUDIO_CODECS;
510 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("VideoCodecs"))) {
511 return VIDEO_CODECS;
512 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("AudioDecoder"))) {
513 return AUDIO_DECODER;
514 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("AudioEncoder"))) {
515 return AUDIO_ENCODER;
516 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("VideoDecoder"))) {
517 return VIDEO_DECODER;
518 } else if (xmlStrEqual(node->name, reinterpret_cast<const xmlChar*>("VideoEncoder"))) {
519 return VIDEO_ENCODER;
520 } else {
521 return UNKNOWN;
522 }
523 }
524
GetCapabilityDataArray() const525 std::vector<CapabilityData> AVCodecXmlParser::GetCapabilityDataArray() const
526 {
527 return capabilityDataArray_;
528 }
529 } // namespace Media
530 } // namespace OHOS