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