1 /*
2  * Copyright (c) 2023-2023 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 "metadata_common_utils.h"
17 #include "camera_metadata_operator.h"
18 #include "camera_util.h"
19 #include <cstdint>
20 #include <memory>
21 
22 #include "camera_log.h"
23 #include "capture_session.h"
24 
25 namespace OHOS {
26 namespace CameraStandard {
27 namespace {
FillSizeListFromStreamInfo(vector<Size> & sizeList,const StreamInfo & streamInfo,const camera_format_t targetFormat)28 void FillSizeListFromStreamInfo(
29     vector<Size>& sizeList, const StreamInfo& streamInfo, const camera_format_t targetFormat)
30 {
31     for (const auto& detail : streamInfo.detailInfos) {
32         camera_format_t hdi_format = static_cast<camera_format_t>(detail.format);
33         if (hdi_format != targetFormat) {
34             continue;
35         }
36         Size size { .width = detail.width, .height = detail.height };
37         sizeList.emplace_back(size);
38     }
39 }
40 
FillSizeListFromStreamInfo(vector<Size> & sizeList,const StreamRelatedInfo & streamInfo,const camera_format_t targetFormat)41 void FillSizeListFromStreamInfo(
42     vector<Size>& sizeList, const StreamRelatedInfo& streamInfo, const camera_format_t targetFormat)
43 {
44     for (const auto &detail : streamInfo.detailInfo) {
45         camera_format_t hdi_format = static_cast<camera_format_t>(detail.format);
46         if (hdi_format != targetFormat) {
47             continue;
48         }
49         Size size{.width = detail.width, .height = detail.height};
50         sizeList.emplace_back(size);
51     }
52 }
53 
GetSupportedPreviewSizeRangeFromProfileLevel(const int32_t modeName,camera_format_t targetFormat,const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)54 std::shared_ptr<vector<Size>> GetSupportedPreviewSizeRangeFromProfileLevel(
55     const int32_t modeName, camera_format_t targetFormat, const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
56 {
57     if (metadata == nullptr) {
58         return nullptr;
59     }
60     camera_metadata_item_t item;
61     int32_t retCode = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_AVAILABLE_PROFILE_LEVEL, &item);
62     if (retCode != CAM_META_SUCCESS || item.count == 0) {
63         return nullptr;
64     }
65     std::shared_ptr<vector<Size>> sizeList = std::make_shared<vector<Size>>();
66     std::vector<SpecInfo> specInfos;
67     ProfileLevelInfo modeInfo = {};
68     CameraAbilityParseUtil::GetModeInfo(modeName, item, modeInfo);
69     specInfos.insert(specInfos.end(), modeInfo.specInfos.begin(), modeInfo.specInfos.end());
70     for (SpecInfo& specInfo : specInfos) {
71         for (StreamInfo& streamInfo : specInfo.streamInfos) {
72             if (streamInfo.streamType == 0) {
73                 FillSizeListFromStreamInfo(*sizeList.get(), streamInfo, targetFormat);
74             }
75         }
76     }
77     MEDIA_INFO_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRangeFromProfileLevel listSize: %{public}d",
78         static_cast<int>(sizeList->size()));
79     return sizeList;
80 }
81 
GetSupportedPreviewSizeRangeFromExtendConfig(const int32_t modeName,camera_format_t targetFormat,const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)82 std::shared_ptr<vector<Size>> GetSupportedPreviewSizeRangeFromExtendConfig(
83     const int32_t modeName, camera_format_t targetFormat, const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
84 {
85     auto item = MetadataCommonUtils::GetCapabilityEntry(metadata, OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS);
86     CHECK_ERROR_RETURN_RET(item == nullptr, nullptr);
87     std::shared_ptr<vector<Size>> sizeList = std::make_shared<vector<Size>>();
88 
89     ExtendInfo extendInfo = {};
90     std::shared_ptr<CameraStreamInfoParse> modeStreamParse = std::make_shared<CameraStreamInfoParse>();
91     modeStreamParse->getModeInfo(item->data.i32, item->count, extendInfo); // 解析tag中带的数据信息意义
92     for (uint32_t modeIndex = 0; modeIndex < extendInfo.modeCount; modeIndex++) {
93         auto modeInfo = std::move(extendInfo.modeInfo[modeIndex]);
94         MEDIA_DEBUG_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRangeFromExtendConfig check modeName: %{public}d",
95             modeInfo.modeName);
96         if (modeName != modeInfo.modeName) {
97             continue;
98         }
99         for (uint32_t streamIndex = 0; streamIndex < modeInfo.streamTypeCount; streamIndex++) {
100             auto streamInfo = std::move(modeInfo.streamInfo[streamIndex]);
101             int32_t streamType = streamInfo.streamType;
102             MEDIA_DEBUG_LOG(
103                 "MetadataCommonUtils::GetSupportedPreviewSizeRangeFromExtendConfig check streamType: %{public}d",
104                 streamType);
105             if (streamType != 0) { // Stremp type 0 is preview type.
106                 continue;
107             }
108             FillSizeListFromStreamInfo(*sizeList.get(), streamInfo, targetFormat);
109         }
110     }
111     MEDIA_INFO_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRangeFromExtendConfig listSize: %{public}d",
112         static_cast<int>(sizeList->size()));
113     return sizeList;
114 }
115 
GetSupportedPreviewSizeRangeFromBasicConfig(camera_format_t targetFormat,const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)116 std::shared_ptr<vector<Size>> GetSupportedPreviewSizeRangeFromBasicConfig(
117     camera_format_t targetFormat, const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
118 {
119     auto item = MetadataCommonUtils::GetCapabilityEntry(metadata, OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS);
120     CHECK_ERROR_RETURN_RET(item == nullptr, nullptr);
121     std::shared_ptr<vector<Size>> sizeList = std::make_shared<vector<Size>>();
122 
123     const uint32_t widthOffset = 1;
124     const uint32_t heightOffset = 2;
125     const uint32_t unitStep = 3;
126 
127     for (uint32_t i = 0; i < item->count; i += unitStep) {
128         camera_format_t hdi_format = static_cast<camera_format_t>(item->data.i32[i]);
129         if (hdi_format != targetFormat) {
130             continue;
131         }
132         Size size;
133         size.width = static_cast<uint32_t>(item->data.i32[i + widthOffset]);
134         size.height = static_cast<uint32_t>(item->data.i32[i + heightOffset]);
135         sizeList->emplace_back(size);
136     }
137     MEDIA_INFO_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRangeFromBasicConfig listSize: %{public}d",
138         static_cast<int>(sizeList->size()));
139     return sizeList;
140 }
141 } // namespace
142 
GetCapabilityEntry(const std::shared_ptr<Camera::CameraMetadata> metadata,uint32_t metadataTag)143 std::shared_ptr<camera_metadata_item_t> MetadataCommonUtils::GetCapabilityEntry(
144     const std::shared_ptr<Camera::CameraMetadata> metadata, uint32_t metadataTag)
145 {
146     CHECK_ERROR_RETURN_RET(metadata == nullptr, nullptr);
147     std::shared_ptr<camera_metadata_item_t> item = std::make_shared<camera_metadata_item_t>();
148     int32_t retCode = Camera::FindCameraMetadataItem(metadata->get(), metadataTag, item.get());
149     if (retCode != CAM_META_SUCCESS || item->count == 0) {
150         return nullptr;
151     }
152     return item;
153 }
154 
GetSupportedPreviewSizeRange(const int32_t modeName,camera_format_t targetFormat,const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)155 std::shared_ptr<vector<Size>> MetadataCommonUtils::GetSupportedPreviewSizeRange(
156     const int32_t modeName, camera_format_t targetFormat, const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
157 {
158     MEDIA_DEBUG_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRange modeName: %{public}d, targetFormat:%{public}d",
159         modeName, targetFormat);
160     std::shared_ptr<vector<Size>> sizeList = std::make_shared<vector<Size>>();
161     auto levelList = GetSupportedPreviewSizeRangeFromProfileLevel(modeName, targetFormat, metadata);
162     if (levelList && levelList->empty() && (modeName == SceneMode::CAPTURE || modeName == SceneMode::VIDEO)) {
163         levelList = GetSupportedPreviewSizeRangeFromProfileLevel(SceneMode::NORMAL, targetFormat, metadata);
164     }
165     if (levelList && !levelList->empty()) {
166         for (auto& size : *levelList) {
167             MEDIA_DEBUG_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRange level info:%{public}dx%{public}d",
168                 size.width, size.height);
169         }
170         sizeList->insert(sizeList->end(), levelList->begin(), levelList->end());
171         return sizeList;
172     }
173 
174     auto extendList = GetSupportedPreviewSizeRangeFromExtendConfig(modeName, targetFormat, metadata);
175     if (extendList != nullptr && extendList->empty() &&
176         (modeName == SceneMode::CAPTURE || modeName == SceneMode::VIDEO)) {
177         extendList = GetSupportedPreviewSizeRangeFromExtendConfig(SceneMode::NORMAL, targetFormat, metadata);
178     }
179     if (extendList != nullptr && !extendList->empty()) {
180         for (auto& size : *extendList) {
181             MEDIA_DEBUG_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRange extend info:%{public}dx%{public}d",
182                 size.width, size.height);
183         }
184         sizeList->insert(sizeList->end(), extendList->begin(), extendList->end());
185         return sizeList;
186     }
187     auto basicList = GetSupportedPreviewSizeRangeFromBasicConfig(targetFormat, metadata);
188     if (basicList != nullptr && !basicList->empty()) {
189         for (auto& size : *basicList) {
190             MEDIA_DEBUG_LOG("MetadataCommonUtils::GetSupportedPreviewSizeRange basic info:%{public}dx%{public}d",
191                 size.width, size.height);
192         }
193         sizeList->insert(sizeList->end(), basicList->begin(), basicList->end());
194     }
195     return sizeList;
196 }
197 
CopyMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)198 std::shared_ptr<OHOS::Camera::CameraMetadata> MetadataCommonUtils::CopyMetadata(
199     const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)
200 {
201     CHECK_ERROR_RETURN_RET_LOG(srcMetadata == nullptr, nullptr, "CopyMetadata fail,src is null");
202     auto oldMetadata = srcMetadata->get();
203     CHECK_ERROR_RETURN_RET(oldMetadata == nullptr, nullptr);
204     std::shared_ptr<OHOS::Camera::CameraMetadata> result =
205         std::make_shared<OHOS::Camera::CameraMetadata>(oldMetadata->item_capacity, oldMetadata->data_capacity);
206     auto newMetadata = result->get();
207     int32_t ret = OHOS::Camera::CopyCameraMetadataItems(newMetadata, oldMetadata);
208     CHECK_ERROR_PRINT_LOG(ret != CAM_META_SUCCESS, "CopyCameraMetadataItems failed ret:%{public}d", ret);
209     return result;
210 }
211 
ParsePhysicalApertureRangeByMode(const camera_metadata_item_t & item,const int32_t modeName)212 std::vector<float> ParsePhysicalApertureRangeByMode(const camera_metadata_item_t &item, const int32_t modeName)
213 {
214     const float factor = 20.0;
215     std::vector<float> allRange = {};
216     for (uint32_t i = 0; i < item.count; i++) {
217         allRange.push_back(item.data.f[i] * factor);
218     }
219     MEDIA_DEBUG_LOG("ParsePhysicalApertureRangeByMode allRange=%{public}s",
220                     Container2String(allRange.begin(), allRange.end()).c_str());
221     float npos = -1.0;
222     std::vector<std::vector<float>> modeRanges = {};
223     std::vector<float> modeRange = {};
224     for (uint32_t i = 0; i < item.count - 1; i++) {
225         if (item.data.f[i] == npos && item.data.f[i + 1] == npos) {
226             modeRange.emplace_back(npos);
227             MEDIA_DEBUG_LOG("ParsePhysicalApertureRangeByMode mode %{public}d, modeRange=%{public}s",
228                             modeName, Container2String(modeRange.begin(), modeRange.end()).c_str());
229             modeRanges.emplace_back(std::move(modeRange));
230             modeRange.clear();
231             i++;
232             continue;
233         }
234         modeRange.emplace_back(item.data.f[i]);
235     }
236     float currentMode = static_cast<float>(modeName);
237     auto it = std::find_if(modeRanges.begin(), modeRanges.end(),
238         [currentMode](auto value) -> bool {
239             return currentMode == value[0];
240         });
241     CHECK_ERROR_RETURN_RET_LOG(it == modeRanges.end(), {},
242         "ParsePhysicalApertureRangeByMode Failed meta not support mode:%{public}d", modeName);
243 
244     return *it;
245 }
246 
GetMetadataItem(const common_metadata_header_t * src,uint32_t tag)247 std::shared_ptr<camera_metadata_item_t> GetMetadataItem(const common_metadata_header_t* src, uint32_t tag)
248 {
249     CHECK_ERROR_RETURN_RET(src == nullptr, nullptr);
250     auto item = std::make_shared<camera_metadata_item_t>();
251     int32_t ret = OHOS::Camera::CameraMetadata::FindCameraMetadataItem(src, tag, item.get());
252     CHECK_ERROR_RETURN_RET(ret != CAM_META_SUCCESS, nullptr);
253     return item;
254 }
255 } // namespace CameraStandard
256 } // namespace OHOS
257