1 /*
2 * Copyright (c) 2024-2024 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 "ability/camera_ability_parse_util.h"
16 #include "camera_log.h"
17
18 namespace OHOS {
19 namespace CameraStandard {
20
GetModeInfo(const int32_t modeName,const camera_metadata_item_t & item,ProfileLevelInfo & modeInfo)21 void CameraAbilityParseUtil::GetModeInfo(
22 const int32_t modeName, const camera_metadata_item_t &item, ProfileLevelInfo &modeInfo)
23 {
24 int32_t* originInfo = item.data.i32;
25 uint32_t count = item.count;
26 if (count == 0 || originInfo == nullptr) {
27 return;
28 }
29 uint32_t i = 0;
30 uint32_t j = i + STEP_THREE;
31 auto isModeEnd = [](int32_t *originInfo, uint32_t j) {
32 return originInfo[j] == MODE_END && originInfo[j - 1] == SPEC_END &&
33 originInfo[j - 2] == STREAM_END && originInfo[j - 3] == DETAIL_END;
34 };
35 while (j < count) {
36 if (originInfo[j] != MODE_END) {
37 j = j + STEP_FOUR;
38 continue;
39 }
40 if (isModeEnd(originInfo, j)) {
41 if (originInfo[i] == modeName) {
42 GetSpecInfo(originInfo, i + 1, j - 1, modeInfo);
43 break;
44 } else {
45 i = j + STEP_ONE;
46 j = i + STEP_THREE;
47 }
48 } else {
49 j++;
50 }
51 }
52 }
53
GetAvailableConfiguration(const int32_t modeName,common_metadata_header_t * metadata,AvailableConfig & availableConfig)54 void CameraAbilityParseUtil::GetAvailableConfiguration(
55 const int32_t modeName, common_metadata_header_t *metadata, AvailableConfig &availableConfig)
56 {
57 camera_metadata_item_t item;
58 int ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_AVAILABLE_CONFIGURATIONS, &item);
59 if (ret != CAM_META_SUCCESS) {
60 MEDIA_ERR_LOG("GetAvailableConfiguration failed due to can't find related tag");
61 return;
62 }
63 int32_t* originInfo = item.data.i32;
64 uint32_t count = item.count;
65 if (count == 0 || originInfo == nullptr) {
66 return;
67 }
68 uint32_t i = 0;
69 uint32_t j = i + STEP_ONE;
70 while (j < count) {
71 if (originInfo[j] != MODE_END) {
72 j = j + STEP_TWO;
73 continue;
74 }
75 if (originInfo[j-1] == TAG_END) {
76 if (originInfo[i] == modeName) {
77 GetAvailableConfigInfo(originInfo, i + 1, j - 1, availableConfig);
78 break;
79 } else {
80 i = j + STEP_ONE;
81 j = i + STEP_ONE;
82 }
83 } else {
84 j++;
85 }
86 }
87 }
88
GetConflictConfiguration(const int32_t modeName,common_metadata_header_t * metadata,ConflictConfig & conflictConfig)89 void CameraAbilityParseUtil::GetConflictConfiguration(
90 const int32_t modeName, common_metadata_header_t *metadata, ConflictConfig &conflictConfig)
91 {
92 camera_metadata_item_t item;
93 int ret = Camera::FindCameraMetadataItem(metadata, OHOS_ABILITY_CONFLICT_CONFIGURATIONS, &item);
94 if (ret != CAM_META_SUCCESS) {
95 MEDIA_ERR_LOG("GetConflictConfiguration failed due to can't find related tag");
96 return;
97 }
98 int32_t* originInfo = item.data.i32;
99 uint32_t count = item.count;
100 if (count == 0 || originInfo == nullptr) {
101 return;
102 }
103 uint32_t i = 0;
104 uint32_t j = i + STEP_ONE;
105 while (j < count) {
106 if (originInfo[j] != MODE_END) {
107 j = j + STEP_TWO;
108 continue;
109 }
110 if (originInfo[j-1] == TAG_END) {
111 if (originInfo[i] == modeName) {
112 GetConflictConfigInfo(originInfo, i + 1, j - 1, conflictConfig);
113 break;
114 } else {
115 i = j + STEP_ONE;
116 j = i + STEP_ONE;
117 }
118 } else {
119 j++;
120 }
121 }
122 }
123
GetAbilityInfo(const int32_t modeName,common_metadata_header_t * metadata,uint32_t tagId,std::map<int32_t,std::vector<int32_t>> & infoMap)124 void CameraAbilityParseUtil::GetAbilityInfo(const int32_t modeName, common_metadata_header_t *metadata, uint32_t tagId,
125 std::map<int32_t, std::vector<int32_t>> &infoMap)
126 {
127 infoMap = {};
128 camera_metadata_item_t item;
129 int ret = Camera::FindCameraMetadataItem(metadata, tagId, &item);
130 if (ret != CAM_META_SUCCESS) {
131 MEDIA_ERR_LOG("GetAbilityInfo failed due to can't find related tag %{public}u", tagId);
132 return;
133 }
134 int32_t* originInfo = item.data.i32;
135 uint32_t count = item.count;
136 if (count == 0 || originInfo == nullptr) {
137 return;
138 }
139 uint32_t i = 0;
140 uint32_t j = i + STEP_ONE;
141 while (j < count) {
142 if (originInfo[j] != MODE_END) {
143 j = j + STEP_TWO;
144 continue;
145 }
146 if (originInfo[j - 1] == INFO_END) {
147 if (originInfo[i] == modeName) {
148 GetInfo(originInfo, i + 1, j - 1, infoMap);
149 break;
150 } else {
151 i = j + STEP_ONE;
152 j = i + STEP_ONE;
153 }
154 } else {
155 j++;
156 }
157 }
158 }
159
GetInfo(int32_t * originInfo,uint32_t start,uint32_t end,std::map<int32_t,std::vector<int32_t>> & infoMap)160 void CameraAbilityParseUtil::GetInfo(
161 int32_t *originInfo, uint32_t start, uint32_t end, std::map<int32_t, std::vector<int32_t>> &infoMap)
162 {
163 uint32_t i = start;
164 uint32_t j = i;
165 std::vector<std::pair<uint32_t, uint32_t>> infoIndexRange;
166 while (j <= end) {
167 if (originInfo[j] == INFO_END) {
168 std::pair<uint32_t, uint32_t> indexPair(i, j);
169 infoIndexRange.push_back(indexPair);
170 i = j + STEP_ONE;
171 j = i;
172 } else {
173 j++;
174 }
175 }
176
177 for (const auto& indexPair : infoIndexRange) {
178 i = indexPair.first;
179 j = indexPair.second;
180 int32_t specId = originInfo[i];
181 std::vector<int32_t> infoValues(originInfo + i + 1, originInfo + j);
182 infoMap[specId] = std::move(infoValues);
183 }
184 }
185
GetSpecInfo(int32_t * originInfo,uint32_t start,uint32_t end,ProfileLevelInfo & modeInfo)186 void CameraAbilityParseUtil::GetSpecInfo(int32_t *originInfo, uint32_t start, uint32_t end, ProfileLevelInfo &modeInfo)
187 {
188 uint32_t i = start;
189 uint32_t j = i + STEP_TWO;
190 std::vector<std::pair<uint32_t, uint32_t>> specIndexRange;
191 while (j <= end) {
192 if (originInfo[j] != SPEC_END) {
193 j = j + STEP_THREE;
194 continue;
195 }
196 if (originInfo[j - STEP_ONE] == STREAM_END && originInfo[j - STEP_TWO] == DETAIL_END) {
197 std::pair<uint32_t, uint32_t> indexPair(i, j);
198 specIndexRange.push_back(indexPair);
199 i = j + STEP_ONE;
200 j = i + STEP_TWO;
201 } else {
202 j++;
203 }
204 }
205 uint32_t specCount = specIndexRange.size();
206 modeInfo.specInfos.resize(specCount);
207
208 for (uint32_t k = 0; k < specCount; ++k) {
209 SpecInfo& specInfo = modeInfo.specInfos[k];
210 i = specIndexRange[k].first;
211 j = specIndexRange[k].second;
212 specInfo.specId = originInfo[i];
213 GetStreamInfo(originInfo, i + 1, j - 1, specInfo);
214 }
215 }
216
GetStreamInfo(int32_t * originInfo,uint32_t start,uint32_t end,SpecInfo & specInfo)217 void CameraAbilityParseUtil::GetStreamInfo(int32_t *originInfo, uint32_t start, uint32_t end, SpecInfo &specInfo)
218 {
219 uint32_t i = start;
220 uint32_t j = i + STEP_ONE;
221
222 std::vector<std::pair<uint32_t, uint32_t>> streamIndexRange;
223 while (j <= end) {
224 if (originInfo[j] == STREAM_END) {
225 if (originInfo[j - 1] == DETAIL_END) {
226 std::pair<uint32_t, uint32_t> indexPair(i, j);
227 streamIndexRange.push_back(indexPair);
228 i = j + STEP_ONE;
229 j = i + STEP_ONE;
230 } else {
231 j++;
232 }
233 } else {
234 j = j + STEP_TWO;
235 }
236 }
237 uint32_t streamTypeCount = streamIndexRange.size();
238 specInfo.streamInfos.resize(streamTypeCount);
239
240 for (uint32_t k = 0; k < streamTypeCount; ++k) {
241 StreamInfo& streamInfo = specInfo.streamInfos[k];
242 i = streamIndexRange[k].first;
243 j = streamIndexRange[k].second;
244 streamInfo.streamType = originInfo[i];
245 GetDetailInfo(originInfo, i + 1, j - 1, streamInfo);
246 }
247 }
248
GetDetailInfo(int32_t * originInfo,uint32_t start,uint32_t end,StreamInfo & streamInfo)249 void CameraAbilityParseUtil::GetDetailInfo(int32_t *originInfo, uint32_t start, uint32_t end, StreamInfo &streamInfo)
250 {
251 uint32_t i = start;
252 uint32_t j = i;
253 std::vector<std::pair<uint32_t, uint32_t>> detailIndexRange;
254 while (j <= end) {
255 if (originInfo[j] == DETAIL_END) {
256 std::pair<uint32_t, uint32_t> indexPair(i, j);
257 detailIndexRange.push_back(indexPair);
258 i = j + STEP_ONE;
259 j = i;
260 } else {
261 j++;
262 }
263 }
264
265 uint32_t detailCount = detailIndexRange.size();
266 streamInfo.detailInfos.resize(detailCount);
267
268 for (uint32_t k = 0; k < detailCount; ++k) {
269 auto &detailInfo = streamInfo.detailInfos[k];
270 i = detailIndexRange[k].first;
271 j = detailIndexRange[k].second;
272 detailInfo.format = static_cast<uint32_t>(originInfo[i++]);
273 detailInfo.width = static_cast<uint32_t>(originInfo[i++]);
274 detailInfo.height = static_cast<uint32_t>(originInfo[i++]);
275 detailInfo.fixedFps = static_cast<uint32_t>(originInfo[i++]);
276 detailInfo.minFps = static_cast<uint32_t>(originInfo[i++]);
277 detailInfo.maxFps = static_cast<uint32_t>(originInfo[i++]);
278 detailInfo.abilityIds.resize(j - i);
279 std::transform(originInfo + i, originInfo + j, detailInfo.abilityIds.begin(),
280 [](auto val) { return static_cast<uint32_t>(val); });
281 }
282 }
283
GetAvailableConfigInfo(int32_t * originInfo,uint32_t start,uint32_t end,AvailableConfig & availableConfig)284 void CameraAbilityParseUtil::GetAvailableConfigInfo(
285 int32_t *originInfo, uint32_t start, uint32_t end, AvailableConfig &availableConfig)
286 {
287 uint32_t i = start;
288 uint32_t j = i;
289 std::vector<std::pair<uint32_t, uint32_t>> infoIndexRange;
290 while (j <= end) {
291 if (originInfo[j] == TAG_END) {
292 std::pair<uint32_t, uint32_t> indexPair(i, j-1);
293 infoIndexRange.push_back(indexPair);
294 i = j + STEP_ONE;
295 j = i;
296 } else {
297 j++;
298 }
299 }
300
301 uint32_t configInfoCount = infoIndexRange.size();
302 availableConfig.configInfos.resize(configInfoCount);
303 for (uint32_t k = 0; k < configInfoCount; ++k) {
304 i = infoIndexRange[k].first;
305 j = infoIndexRange[k].second;
306 auto &configInfo = availableConfig.configInfos[k];
307 configInfo.specId = originInfo[i++];
308 configInfo.tagIds.resize(j - i + 1);
309 std::transform(originInfo + i, originInfo + j + 1, configInfo.tagIds.begin(),
310 [](auto val) { return static_cast<uint32_t>(val); });
311 }
312 }
313
GetConflictConfigInfo(int32_t * originInfo,uint32_t start,uint32_t end,ConflictConfig & conflictConfig)314 void CameraAbilityParseUtil::GetConflictConfigInfo(
315 int32_t *originInfo, uint32_t start, uint32_t end, ConflictConfig &conflictConfig)
316 {
317 uint32_t i = start;
318 uint32_t j = i;
319 std::vector<std::pair<uint32_t, uint32_t>> infoIndexRange;
320 while (j <= end) {
321 if (originInfo[j] == TAG_END) {
322 std::pair<uint32_t, uint32_t> indexPair(i, j-1);
323 infoIndexRange.push_back(indexPair);
324 i = j + STEP_ONE;
325 j = i;
326 } else {
327 j++;
328 }
329 }
330
331 uint32_t configInfoCount = infoIndexRange.size();
332 conflictConfig.configInfos.resize(configInfoCount);
333 for (uint32_t k = 0; k < configInfoCount; ++k) {
334 i = infoIndexRange[k].first;
335 j = infoIndexRange[k].second;
336 auto &configInfo = conflictConfig.configInfos[k];
337 configInfo.cid = originInfo[i++];
338 uint32_t tagInfoCount = (j - i + 1) / 2;
339 configInfo.tagInfos.resize(tagInfoCount);
340 for (uint32_t m = 0; m < tagInfoCount; ++m) {
341 auto &tagInfo = configInfo.tagInfos[m];
342 tagInfo.first = static_cast<uint32_t>(originInfo[i++]);
343 tagInfo.second = static_cast<uint32_t>(originInfo[i++]);
344 }
345 }
346 }
347 } // namespace CameraStandard
348 } // namespace OHOS