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