1 /*
2 * Copyright (C) 2022 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 #include "recorder_profiles_xml_parser.h"
17 #include "media_errors.h"
18 #include "media_log.h"
19 #include "string_ex.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_RECORDER, "RecorderProfilesXmlParser"};
23 }
24
25 namespace OHOS {
26 namespace Media {
27 enum class ProfileSourceType : int32_t {
28 PORFILE_SOURCE_CAMERA_RECORDER = 0,
29 PORFILE_SOURCE_VIRTUAL_DISPLAY,
30 };
31
32 const std::vector<std::string> MP4_VIDEO_CODEC_VECTOR = {
33 "video/mp4v-es",
34 "video/avc",
35 };
36
37 const std::vector<std::string> MP4_AUDIO_CODEC_VECTOR = {
38 "audio/mp4a-latm",
39 };
40
41 const std::vector<std::string> M4A_AUDIO_CODEC_VECTOR = {
42 "audio/mp4a-latm",
43 };
44
45 const std::unordered_map<std::string, std::vector<std::string>> CONTAINER_VIDEOCAPS_VIDEO_MAP = {
46 {"mp4", MP4_VIDEO_CODEC_VECTOR},
47 };
48
49 const std::unordered_map<std::string, std::vector<std::string>> CONTAINER_VIDEOCAPS_AUDIO_MAP = {
50 {"mp4", MP4_AUDIO_CODEC_VECTOR},
51 };
52
53 const std::unordered_map<std::string, std::vector<std::string>> CONTAINER_AUDIOCAPS_AUDIO_MAP = {
54 {"m4a", M4A_AUDIO_CODEC_VECTOR},
55 };
56
57 const std::unordered_map<std::string, int> SOURCE_TYPE_MAP = {
58 {"CameraRecorder", static_cast<int>(ProfileSourceType::PORFILE_SOURCE_CAMERA_RECORDER)},
59 {"VirtualDisplay", static_cast<int>(ProfileSourceType::PORFILE_SOURCE_VIRTUAL_DISPLAY)},
60 };
61
62 const std::unordered_map<std::string, std::string> SOURCE_TYPE_ID_MAP = {
63 {"CameraRecorder", "cameraId"},
64 {"VirtualDisplay", "displayId"},
65 };
66
67 const std::unordered_map<std::string, int> PROFILE_QUALITY_MAP = {
68 {"low", RECORDER_QUALITY_LOW},
69 {"high", RECORDER_QUALITY_HIGH},
70 {"qcif", RECORDER_QUALITY_QCIF},
71 {"cif", RECORDER_QUALITY_CIF},
72 {"480p", RECORDER_QUALITY_480P},
73 {"720p", RECORDER_QUALITY_720P},
74 {"1080p", RECORDER_QUALITY_1080P},
75 {"qvga", RECORDER_QUALITY_QVGA},
76 {"2160p", RECORDER_QUALITY_2160P},
77 {"timelapse_low", RECORDER_QUALITY_TIME_LAPSE_LOW},
78 {"timelapse_high", RECORDER_QUALITY_TIME_LAPSE_HIGH},
79 {"timelapse_qcif", RECORDER_QUALITY_TIME_LAPSE_QCIF},
80 {"timelapse_cif", RECORDER_QUALITY_TIME_LAPSE_CIF},
81 {"timelapse_480p", RECORDER_QUALITY_TIME_LAPSE_480P},
82 {"timelapse_720p", RECORDER_QUALITY_TIME_LAPSE_720P},
83 {"timelapse_1080p", RECORDER_QUALITY_TIME_LAPSE_1080P},
84 {"timelapse_qvga", RECORDER_QUALITY_TIME_LAPSE_QVGA},
85 {"timelapse_2160p", RECORDER_QUALITY_TIME_LAPSE_2160P},
86 {"highspeed_low", RECORDER_QUALITY_HIGH_SPEED_LOW},
87 {"highspeed_high", RECORDER_QUALITY_HIGH_SPEED_HIGH},
88 {"highspeed_480p", RECORDER_QUALITY_HIGH_SPEED_480P},
89 {"highspeed_720p", RECORDER_QUALITY_HIGH_SPEED_720P},
90 {"highspeed_1080p", RECORDER_QUALITY_HIGH_SPEED_1080P},
91 };
92
RecorderProfilesXmlParser()93 RecorderProfilesXmlParser::RecorderProfilesXmlParser()
94 {
95 capabilityKeys_ = {"format", "codecMime", "bitrate", "width", "height", "frameRate",
96 "sampleRate", "channels", "quality", "duration", "name", "hasVideo"};
97 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
98 }
99
~RecorderProfilesXmlParser()100 RecorderProfilesXmlParser::~RecorderProfilesXmlParser()
101 {
102 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
103 }
104
ParseInternal(xmlNode * node)105 bool RecorderProfilesXmlParser::ParseInternal(xmlNode *node)
106 {
107 containerFormatArray_.clear();
108 videoEncoderCapsArray_.clear();
109 audioEncoderCapsArray_.clear();
110 capabilityDataArray_.clear();
111
112 xmlNode *currNode = node;
113 for (; currNode != nullptr; currNode = currNode->next) {
114 if (currNode->type == XML_ELEMENT_NODE) {
115 switch (GetNodeNameAsInt(currNode)) {
116 case RecorderProfilesNodeName::RECORDER_CAPS: {
117 ParseRecorderCapsData(currNode);
118 break;
119 }
120 case RecorderProfilesNodeName::RECORDER_PROFILES: {
121 ParseRecorderProfilesData(currNode);
122 break;
123 }
124 default: {
125 ParseInternal(currNode->children);
126 break;
127 }
128 }
129 }
130 }
131 return true;
132 }
133
SetCapabilityIntData(std::unordered_map<std::string,int32_t &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue) const134 bool RecorderProfilesXmlParser::SetCapabilityIntData(std::unordered_map<std::string, int32_t&> dataMap,
135 const std::string &capabilityKey, const std::string &capabilityValue) const
136 {
137 if (PROFILE_QUALITY_MAP.find(capabilityValue) != PROFILE_QUALITY_MAP.end()) {
138 dataMap.at(capabilityKey) = PROFILE_QUALITY_MAP.at(capabilityValue);
139 } else {
140 int32_t value = 0;
141 if (!StrToInt(capabilityValue, value)) {
142 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", capabilityValue.c_str());
143 return false;
144 }
145 dataMap.at(capabilityKey) = value;
146 }
147 return true;
148 }
149
SetCapabilityVectorData(std::unordered_map<std::string,std::vector<int32_t> &> dataMap,const std::string & capabilityKey,const std::string & capabilityValue) const150 bool RecorderProfilesXmlParser::SetCapabilityVectorData(std::unordered_map<std::string, std::vector<int32_t>&> dataMap,
151 const std::string &capabilityKey, const std::string &capabilityValue) const
152 {
153 std::vector<std::string> spilt;
154 std::vector<int32_t> array;
155 bool ret = SpiltKeyList(capabilityValue, ",", spilt);
156 CHECK_AND_RETURN_RET_LOG(ret != false, false, "failed:can not split %{public}s", capabilityValue.c_str());
157 if (spilt.size() > 0) {
158 if (XmlParser::IsNumberArray(spilt)) {
159 array = TransStrAsIntegerArray(spilt);
160 } else {
161 MEDIA_LOGE("The value of %{public}s in the configuration file is incorrect.", capabilityValue.c_str());
162 return false;
163 }
164 dataMap.at(capabilityKey) = array;
165 }
166 MEDIA_LOGD("RecorderProfilesXmlParser::SetCapabilityVectorData end");
167 return true;
168 }
169
ParseRecorderCapsData(xmlNode * node)170 bool RecorderProfilesXmlParser::ParseRecorderCapsData(xmlNode *node)
171 {
172 xmlNode *child = node->xmlChildrenNode;
173
174 for (; child; child = child->next) {
175 if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("ContainerFormat")) == 0) {
176 bool ret = ParseRecorderContainerFormatData(child);
177 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderContainerFormatData failed");
178 } else if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("VideoEncoderCaps")) == 0) {
179 bool ret = ParseRecorderEncodeCapsData(child, true);
180 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderEncodeCapsData failed");
181 } else if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("AudioEncoderCaps")) == 0) {
182 bool ret = ParseRecorderEncodeCapsData(child, false);
183 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderEncodeCapsData failed");
184 } else {
185 MEDIA_LOGE("not found node!");
186 }
187 }
188 PackageRecorderCaps();
189 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderCapsData end");
190 return true;
191 }
192
ParseRecorderContainerFormatData(xmlNode * node)193 bool RecorderProfilesXmlParser::ParseRecorderContainerFormatData(xmlNode *node)
194 {
195 ContainerFormatInfo containerFormatInfo;
196
197 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
198 std::string capabilityValue;
199 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>((*it).c_str())))) {
200 capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
201 reinterpret_cast<xmlChar*>(const_cast<char*>((*it).c_str())))));
202 bool ret = SetContainerFormat(containerFormatInfo, (*it), capabilityValue);
203 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetContainerFormat failed");
204 }
205 }
206 containerFormatArray_.emplace_back(containerFormatInfo);
207 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderContainerFormatData end");
208 return true;
209 }
210
ParseRecorderEncodeCapsData(xmlNode * node,bool isVideo)211 bool RecorderProfilesXmlParser::ParseRecorderEncodeCapsData(xmlNode *node, bool isVideo)
212 {
213 RecorderProfilesData capabilityData;
214
215 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
216 std::string capabilityValue;
217 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>((*it).c_str())))) {
218 capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
219 reinterpret_cast<xmlChar*>(const_cast<char*>((*it).c_str())))));
220 bool ret = false;
221 if (isVideo) {
222 ret = SetVideoRecorderCaps(capabilityData, (*it), capabilityValue);
223 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetVideoRecorderCaps failed");
224 } else {
225 ret = SetAudioRecorderCaps(capabilityData, (*it), capabilityValue);
226 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetAudioRecorderCaps failed");
227 }
228 }
229 }
230
231 if (isVideo) {
232 videoEncoderCapsArray_.emplace_back(capabilityData);
233 } else {
234 audioEncoderCapsArray_.emplace_back(capabilityData);
235 }
236 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderEncodeCapsData end");
237 return true;
238 }
239
SetContainerFormat(ContainerFormatInfo & data,const std::string & capabilityKey,const std::string & capabilityValue)240 bool RecorderProfilesXmlParser::SetContainerFormat(ContainerFormatInfo &data, const std::string &capabilityKey,
241 const std::string &capabilityValue)
242 {
243 std::unordered_map<std::string, std::string&> capabilityStringMap = {
244 {"name", data.name}, {"hasVideo", data.hasVideo}};
245
246 bool ret = false;
247 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
248 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
249 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
250 } else {
251 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
252 }
253 MEDIA_LOGD("RecorderProfilesXmlParser::SetContainerFormat end");
254 return true;
255 }
256
SetVideoRecorderCaps(RecorderProfilesData & data,const std::string & capabilityKey,const std::string & capabilityValue)257 bool RecorderProfilesXmlParser::SetVideoRecorderCaps(RecorderProfilesData &data, const std::string &capabilityKey,
258 const std::string &capabilityValue)
259 {
260 std::unordered_map<std::string, std::string&> capabilityStringMap = {
261 {"codecMime", data.videoCaps.videoEncoderMime}};
262
263 std::unordered_map<std::string, Range&> capabilityRangeMap = {
264 {"bitrate", data.videoCaps.videoBitrateRange}, {"width", data.videoCaps.videoWidthRange},
265 {"height", data.videoCaps.videoHeightRange}, {"frameRate", data.videoCaps.videoFramerateRange}};
266
267 bool ret = false;
268 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
269 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
270 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
271 } else if (capabilityRangeMap.find(capabilityKey) != capabilityRangeMap.end()) {
272 ret = SetCapabilityRangeData(capabilityRangeMap, capabilityKey, capabilityValue);
273 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityRangeData failed");
274 } else {
275 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
276 }
277 MEDIA_LOGD("RecorderProfilesXmlParser::SetVideoRecorderCaps end");
278 return true;
279 }
280
SetAudioRecorderCaps(RecorderProfilesData & data,const std::string & capabilityKey,const std::string & capabilityValue)281 bool RecorderProfilesXmlParser::SetAudioRecorderCaps(RecorderProfilesData &data, const std::string &capabilityKey,
282 const std::string &capabilityValue)
283 {
284 std::unordered_map<std::string, std::string&> capabilityStringMap = {
285 {"codecMime", data.audioCaps.mimeType}};
286
287 std::unordered_map<std::string, Range&> capabilityRangeMap = {
288 {"bitrate", data.audioCaps.bitrate}, {"channels", data.audioCaps.channels}};
289
290 std::unordered_map<std::string, std::vector<int32_t>&> capabilityVectorMap = {
291 {"sampleRate", data.audioCaps.sampleRate}};
292
293 bool ret = false;
294 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
295 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
296 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
297 } else if (capabilityRangeMap.find(capabilityKey) != capabilityRangeMap.end()) {
298 ret = SetCapabilityRangeData(capabilityRangeMap, capabilityKey, capabilityValue);
299 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityRangeData failed");
300 } else if (capabilityVectorMap.find(capabilityKey) != capabilityVectorMap.end()) {
301 ret = SetCapabilityVectorData(capabilityVectorMap, capabilityKey, capabilityValue);
302 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityVectorData failed");
303 } else {
304 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
305 }
306 MEDIA_LOGD("RecorderProfilesXmlParser::SetAudioRecorderCaps end");
307 return true;
308 }
309
PackageRecorderCaps()310 void RecorderProfilesXmlParser::PackageRecorderCaps()
311 {
312 for (auto it = containerFormatArray_.begin(); it != containerFormatArray_.end(); it++) {
313 if ((*it).hasVideo == "true") {
314 PackageVideoRecorderCaps((*it).name);
315 } else {
316 PackageAudioRecorderCaps((*it).name);
317 }
318 }
319 MEDIA_LOGD("RecorderProfilesXmlParser::PackageRecorderCaps end");
320 }
321
PackageVideoRecorderCaps(const std::string & formatType)322 void RecorderProfilesXmlParser::PackageVideoRecorderCaps(const std::string &formatType)
323 {
324 if ((CONTAINER_VIDEOCAPS_VIDEO_MAP.find(formatType) == CONTAINER_VIDEOCAPS_VIDEO_MAP.end()) ||
325 (CONTAINER_VIDEOCAPS_AUDIO_MAP.find(formatType) == CONTAINER_VIDEOCAPS_AUDIO_MAP.end())) {
326 MEDIA_LOGE("formatType not found in CONTAINER_VIDEOCAPS_VIDEO_MAP or CONTAINER_VIDEOCAPS_AUDIO_MAP");
327 return;
328 }
329 for (auto itVideo = videoEncoderCapsArray_.begin(); itVideo != videoEncoderCapsArray_.end(); itVideo++) {
330 (*itVideo).mediaProfileType = RECORDER_TYPE_VIDEO_CAPS;
331 (*itVideo).videoCaps.containerFormatType = formatType;
332 auto itVideoCodec = find(CONTAINER_VIDEOCAPS_VIDEO_MAP.at(formatType).begin(),
333 CONTAINER_VIDEOCAPS_VIDEO_MAP.at(formatType).end(), (*itVideo).videoCaps.videoEncoderMime);
334 if (itVideoCodec != CONTAINER_VIDEOCAPS_VIDEO_MAP.at(formatType).end()) {
335 PaddingVideoCapsByAudioCaps(formatType, (*itVideo));
336 }
337 }
338 MEDIA_LOGD("RecorderProfilesXmlParser::PackageVideoRecorderCaps end");
339 }
340
PaddingVideoCapsByAudioCaps(const std::string & formatType,RecorderProfilesData & videoData)341 void RecorderProfilesXmlParser::PaddingVideoCapsByAudioCaps(
342 const std::string &formatType, RecorderProfilesData &videoData)
343 {
344 for (auto itAudio = audioEncoderCapsArray_.begin(); itAudio != audioEncoderCapsArray_.end(); itAudio++) {
345 auto itAudioCodec = find(CONTAINER_VIDEOCAPS_AUDIO_MAP.at(formatType).begin(),
346 CONTAINER_VIDEOCAPS_AUDIO_MAP.at(formatType).end(), (*itAudio).audioCaps.mimeType);
347 if (itAudioCodec != CONTAINER_VIDEOCAPS_AUDIO_MAP.at(formatType).end()) {
348 videoData.videoCaps.audioEncoderMime = (*itAudio).audioCaps.mimeType;
349 videoData.videoCaps.audioBitrateRange = (*itAudio).audioCaps.bitrate;
350 videoData.videoCaps.audioSampleRates = (*itAudio).audioCaps.sampleRate;
351 videoData.videoCaps.audioChannelRange = (*itAudio).audioCaps.channels;
352 capabilityDataArray_.emplace_back(videoData);
353 }
354 }
355 MEDIA_LOGD("RecorderProfilesXmlParser::PaddingVideoCapsByAudioCaps end");
356 }
357
PackageAudioRecorderCaps(const std::string & formatType)358 void RecorderProfilesXmlParser::PackageAudioRecorderCaps(const std::string &formatType)
359 {
360 if (CONTAINER_AUDIOCAPS_AUDIO_MAP.find(formatType) == CONTAINER_AUDIOCAPS_AUDIO_MAP.end()) {
361 MEDIA_LOGE("formatType not found in CONTAINER_AUDIOCAPS_AUDIO_MAP");
362 return;
363 }
364 for (auto itAudio = audioEncoderCapsArray_.begin(); itAudio != audioEncoderCapsArray_.end(); itAudio++) {
365 (*itAudio).mediaProfileType = RECORDER_TYPE_AUDIO_CAPS;
366 (*itAudio).audioCaps.containerFormatType = formatType;
367 auto itAudioCodec = find(CONTAINER_AUDIOCAPS_AUDIO_MAP.at(formatType).begin(),
368 CONTAINER_AUDIOCAPS_AUDIO_MAP.at(formatType).end(), (*itAudio).audioCaps.mimeType);
369 if (itAudioCodec != CONTAINER_AUDIOCAPS_AUDIO_MAP.at(formatType).end()) {
370 capabilityDataArray_.emplace_back(*itAudio);
371 }
372 }
373 MEDIA_LOGD("RecorderProfilesXmlParser::PackageAudioRecorderCaps end");
374 }
375
ParseRecorderProfilesData(xmlNode * node)376 bool RecorderProfilesXmlParser::ParseRecorderProfilesData(xmlNode *node)
377 {
378 xmlNode *child = node->xmlChildrenNode;
379
380 for (; child; child = child->next) {
381 for (auto it = SOURCE_TYPE_ID_MAP.begin(); it != SOURCE_TYPE_ID_MAP.end(); it++) {
382 bool ret = ParseRecorderProfilesSourceData(it->first, child);
383 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderProfilesSourceData failed");
384 }
385 }
386 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderProfilesData end");
387 return true;
388 }
389
ParseRecorderProfilesSourceData(const std::string & sourceType,xmlNode * node)390 bool RecorderProfilesXmlParser::ParseRecorderProfilesSourceData(const std::string &sourceType, xmlNode *node)
391 {
392 if (xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>(sourceType.c_str())) == 0) {
393 std::string property = SOURCE_TYPE_ID_MAP.at(sourceType);
394 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>(property.c_str())))) {
395 std::string capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
396 reinterpret_cast<xmlChar*>(const_cast<char*>(property.c_str())))));
397 int32_t id = 0;
398 if (!StrToInt(capabilityValue, id)) {
399 MEDIA_LOGE("call StrToInt func false, input str is: %{public}s", capabilityValue.c_str());
400 return false;
401 }
402 if (SOURCE_TYPE_MAP.find(sourceType) == SOURCE_TYPE_MAP.end()) {
403 MEDIA_LOGE("not found sourceType");
404 return false;
405 }
406 uint32_t type = SOURCE_TYPE_MAP.at(sourceType);
407 RecorderProfilesData capabilityData;
408 // 8 : 8-15 bits indicates the type of source
409 capabilityData.sourceId = ((type & 0x000000ff) << 8) | (static_cast<uint32_t>(id) & 0x000000ff);
410 bool ret = ParseRecorderProfileSettingsData(node, capabilityData);
411 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderProfileSettingsData failed");
412 }
413 }
414 return true;
415 }
416
ParseRecorderProfileSettingsData(xmlNode * node,RecorderProfilesData & capabilityData)417 bool RecorderProfilesXmlParser::ParseRecorderProfileSettingsData(xmlNode *node, RecorderProfilesData &capabilityData)
418 {
419 xmlNode *child = node->xmlChildrenNode;
420 for (; child; child = child->next) {
421 if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("ProfileSettings")) == 0) {
422 bool ret = true;
423 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
424 ret = ParseVideoRecorderProfiles(child, capabilityData, *it);
425 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseVideoRecorderProfiles failed");
426 }
427
428 ret = ParseRecorderProfileVideoAudioData(child, capabilityData);
429 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseRecorderProfileVideoAudioData failed");
430 }
431 }
432 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderProfileSettingsData end");
433 return true;
434 }
435
ParseVideoRecorderProfiles(xmlNode * node,RecorderProfilesData & capabilityData,const std::string & capabilityKey)436 bool RecorderProfilesXmlParser::ParseVideoRecorderProfiles(
437 xmlNode *node, RecorderProfilesData &capabilityData, const std::string &capabilityKey)
438 {
439 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))) {
440 std::string capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
441 reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))));
442 bool ret = SetVideoRecorderProfiles(capabilityData, capabilityKey, capabilityValue);
443 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetVideoRecorderProfiles failed");
444 }
445 return true;
446 }
447
ParseRecorderProfileVideoAudioData(xmlNode * node,RecorderProfilesData & capabilityData)448 bool RecorderProfilesXmlParser::ParseRecorderProfileVideoAudioData(xmlNode *node,
449 RecorderProfilesData &capabilityData)
450 {
451 xmlNode *leafChild = node->xmlChildrenNode;
452 for (; leafChild; leafChild = leafChild->next) {
453 if (xmlStrcmp(leafChild->name, reinterpret_cast<const xmlChar*>("Video")) == 0) {
454 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
455 bool ret = ParseVideoRecorderProfilesForVideoAudioData(leafChild, capabilityData, *it);
456 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseVideoRecorderProfilesForVideoAudioData failed");
457 }
458 } else if (xmlStrcmp(leafChild->name, reinterpret_cast<const xmlChar*>("Audio")) == 0) {
459 for (auto it = capabilityKeys_.begin(); it != capabilityKeys_.end(); it++) {
460 bool ret = ParseAudioRecorderProfiles(leafChild, capabilityData, *it);
461 CHECK_AND_RETURN_RET_LOG(ret != false, false, "ParseAudioRecorderProfiles failed");
462 }
463 } else {
464 MEDIA_LOGE("not found video or audio node!");
465 }
466 }
467 MEDIA_LOGD("RecorderProfilesXmlParser::ParseRecorderProfileVideoAudioData end");
468 capabilityDataArray_.emplace_back(capabilityData);
469 return true;
470 }
471
ParseVideoRecorderProfilesForVideoAudioData(xmlNode * node,RecorderProfilesData & capabilityData,const std::string & capabilityKey)472 bool RecorderProfilesXmlParser::ParseVideoRecorderProfilesForVideoAudioData(
473 xmlNode *node, RecorderProfilesData &capabilityData, const std::string &capabilityKey)
474 {
475 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))) {
476 std::string capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
477 reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))));
478 capabilityData.mediaProfileType = RECORDER_TYPE_PROFILE;
479 bool ret = SetVideoRecorderProfiles(capabilityData, capabilityKey, capabilityValue);
480 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetVideoRecorderProfiles failed");
481 }
482 return true;
483 }
484
ParseAudioRecorderProfiles(xmlNode * node,RecorderProfilesData & capabilityData,const std::string & capabilityKey)485 bool RecorderProfilesXmlParser::ParseAudioRecorderProfiles(
486 xmlNode *node, RecorderProfilesData &capabilityData, const std::string &capabilityKey)
487 {
488 if (xmlHasProp(node, reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))) {
489 std::string capabilityValue = std::string(reinterpret_cast<char*>(xmlGetProp(node,
490 reinterpret_cast<xmlChar*>(const_cast<char*>(capabilityKey.c_str())))));
491 bool ret = SetAudioRecorderProfiles(capabilityData, capabilityKey, capabilityValue);
492 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetAudioRecorderProfiles failed");
493 }
494 return true;
495 }
496
SetVideoRecorderProfiles(RecorderProfilesData & data,const std::string & capabilityKey,const std::string & capabilityValue)497 bool RecorderProfilesXmlParser::SetVideoRecorderProfiles(RecorderProfilesData &data, const std::string &capabilityKey,
498 const std::string &capabilityValue)
499 {
500 std::unordered_map<std::string, std::string&> capabilityStringMap = {
501 {"format", data.recorderProfile.containerFormatType}, {"codecMime", data.recorderProfile.videoCodec}};
502
503 std::unordered_map<std::string, int32_t&> capabilityIntMap = {
504 {"duration", data.recorderProfile.durationTime}, {"bitrate", data.recorderProfile.videoBitrate},
505 {"width", data.recorderProfile.videoFrameWidth}, {"height", data.recorderProfile.videoFrameHeight},
506 {"frameRate", data.recorderProfile.videoFrameRate}, {"quality", data.recorderProfile.qualityLevel}};
507
508 bool ret = false;
509 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
510 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
511 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
512 } else if (capabilityIntMap.find(capabilityKey) != capabilityIntMap.end()) {
513 ret = SetCapabilityIntData(capabilityIntMap, capabilityKey, capabilityValue);
514 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityIntData failed");
515 } else {
516 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
517 }
518 MEDIA_LOGD("RecorderProfilesXmlParser::SetVideoRecorderProfiles end");
519 return true;
520 }
521
SetAudioRecorderProfiles(RecorderProfilesData & data,const std::string & capabilityKey,const std::string & capabilityValue)522 bool RecorderProfilesXmlParser::SetAudioRecorderProfiles(RecorderProfilesData &data, const std::string &capabilityKey,
523 const std::string &capabilityValue)
524 {
525 std::unordered_map<std::string, std::string&> capabilityStringMap = {
526 {"format", data.recorderProfile.containerFormatType}, {"codecMime", data.recorderProfile.audioCodec}};
527
528 std::unordered_map<std::string, int32_t&> capabilityIntMap = {
529 {"bitrate", data.recorderProfile.audioBitrate}, {"sampleRate", data.recorderProfile.audioSampleRate},
530 {"channels", data.recorderProfile.audioChannels}};
531
532 bool ret = false;
533 if (capabilityStringMap.find(capabilityKey) != capabilityStringMap.end()) {
534 ret = SetCapabilityStringData(capabilityStringMap, capabilityKey, capabilityValue);
535 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityStringData failed");
536 } else if (capabilityIntMap.find(capabilityKey) != capabilityIntMap.end()) {
537 ret = SetCapabilityIntData(capabilityIntMap, capabilityKey, capabilityValue);
538 CHECK_AND_RETURN_RET_LOG(ret != false, false, "SetCapabilityIntData failed");
539 } else {
540 CHECK_AND_RETURN_RET_LOG(ret != false, false, "can not find capabilityKey: %{public}s", capabilityKey.c_str());
541 }
542 MEDIA_LOGD("RecorderProfilesXmlParser::SetAudioRecorderProfiles end");
543 return true;
544 }
545
GetNodeNameAsInt(xmlNode * node)546 RecorderProfilesNodeName RecorderProfilesXmlParser::GetNodeNameAsInt(xmlNode *node)
547 {
548 if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("RecorderConfigurations"))) {
549 return RecorderProfilesNodeName::RECORDER_CONFIGURATIONS;
550 } else if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("RecorderCaps"))) {
551 return RecorderProfilesNodeName::RECORDER_CAPS;
552 } else if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("RecorderProfiles"))) {
553 return RecorderProfilesNodeName::RECORDER_PROFILES;
554 } else {
555 return RecorderProfilesNodeName::UNKNOWN;
556 }
557 }
558
GetRecorderProfileDataArray()559 std::vector<RecorderProfilesData> RecorderProfilesXmlParser::GetRecorderProfileDataArray()
560 {
561 return this->capabilityDataArray_;
562 }
563 } // namespace Media
564 } // namespace OHOS