1 /*
2  * Copyright (c) 2023-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 
16 #include "camera_fwk_metadata_utils.h"
17 
18 #include <cstdint>
19 
20 #include "camera_log.h"
21 #include "camera_metadata_operator.h"
22 
23 namespace OHOS {
24 namespace CameraStandard {
25 namespace CameraFwkMetadataUtils {
26 namespace {
27 
28 constexpr uint32_t ITEM_CAPACITY = 20;
29 constexpr uint32_t DATA_CAPACITY = 200;
30 
31 std::vector<uint32_t> reportMetadataTag {
32     OHOS_CONTROL_FLASH_MODE,
33     OHOS_CONTROL_FLASH_STATE,
34     OHOS_CONTROL_FOCUS_MODE,
35     OHOS_CONTROL_QUALITY_PRIORITIZATION,
36     OHOS_CONTROL_FOCUS_STATE,
37     OHOS_STATISTICS_FACE_RECTANGLES,
38     OHOS_CAMERA_MACRO_STATUS
39 };
40 
ForEach(uint32_t iteratorCount,std::function<void (uint32_t)> fun)41 void ForEach(uint32_t iteratorCount, std::function<void(uint32_t)> fun)
42 {
43     for (uint32_t index = 0; index < iteratorCount; index++) {
44         fun(index);
45     }
46 }
47 } // namespace
MergeMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata,std::shared_ptr<OHOS::Camera::CameraMetadata> dstMetadata)48 bool MergeMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata,
49     std::shared_ptr<OHOS::Camera::CameraMetadata> dstMetadata)
50 {
51     CHECK_ERROR_RETURN_RET(srcMetadata == nullptr || dstMetadata == nullptr, false);
52     auto srcHeader = srcMetadata->get();
53     CHECK_ERROR_RETURN_RET(srcHeader == nullptr, false);
54     auto dstHeader = dstMetadata->get();
55     CHECK_ERROR_RETURN_RET(dstHeader == nullptr, false);
56     auto srcItemCount = srcHeader->item_count;
57     camera_metadata_item_t srcItem;
58     for (uint32_t index = 0; index < srcItemCount; index++) {
59         int ret = OHOS::Camera::GetCameraMetadataItem(srcHeader, index, &srcItem);
60         CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS, false,
61             "Failed to get metadata item at index: %{public}d", index);
62         bool status = false;
63         uint32_t currentIndex;
64         ret = OHOS::Camera::FindCameraMetadataItemIndex(dstHeader, srcItem.item, &currentIndex);
65         if (ret == CAM_META_ITEM_NOT_FOUND) {
66             status = dstMetadata->addEntry(srcItem.item, srcItem.data.u8, srcItem.count);
67         } else if (ret == CAM_META_SUCCESS) {
68             status = dstMetadata->updateEntry(srcItem.item, srcItem.data.u8, srcItem.count);
69         }
70         CHECK_ERROR_RETURN_RET_LOG(!status, false, "Failed to update metadata item: %{public}d", srcItem.item);
71     }
72     return true;
73 }
74 
CopyMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)75 std::shared_ptr<OHOS::Camera::CameraMetadata> CopyMetadata(
76     const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)
77 {
78     CHECK_ERROR_RETURN_RET_LOG(srcMetadata == nullptr, nullptr, "CopyMetadata fail, src is null");
79     auto metadataHeader = srcMetadata->get();
80     auto newMetadata =
81         std::make_shared<OHOS::Camera::CameraMetadata>(metadataHeader->item_capacity, metadataHeader->data_capacity);
82     MergeMetadata(srcMetadata, newMetadata);
83     return newMetadata;
84 }
85 
UpdateMetadataTag(const camera_metadata_item_t & srcItem,std::shared_ptr<OHOS::Camera::CameraMetadata> dstMetadata)86 bool UpdateMetadataTag(const camera_metadata_item_t& srcItem, std::shared_ptr<OHOS::Camera::CameraMetadata> dstMetadata)
87 {
88     CHECK_ERROR_RETURN_RET_LOG(dstMetadata == nullptr, false, "UpdateMetadataTag fail, dstMetadata is null");
89     uint32_t itemIndex;
90     int32_t result = OHOS::Camera::FindCameraMetadataItemIndex(dstMetadata->get(), srcItem.item, &itemIndex);
91     bool status = false;
92     if (result == CAM_META_ITEM_NOT_FOUND) {
93         status = dstMetadata->addEntry(srcItem.item, srcItem.data.u8, srcItem.count);
94     } else if (result == CAM_META_SUCCESS) {
95         status = dstMetadata->updateEntry(srcItem.item, srcItem.data.u8, srcItem.count);
96     }
97     CHECK_ERROR_RETURN_RET_LOG(!status, false, "UpdateMetadataTag fail, err is %{public}d", result);
98     return true;
99 }
100 
DumpMetadataInfo(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)101 void DumpMetadataInfo(const std::shared_ptr<OHOS::Camera::CameraMetadata> srcMetadata)
102 {
103     CHECK_ERROR_RETURN_LOG(srcMetadata == nullptr, "DumpMetadataInfo srcMetadata is null");
104     auto metadataHeader = srcMetadata->get();
105     uint32_t version = metadataHeader->version;
106     uint32_t itemCount = metadataHeader->item_count;
107     uint32_t dataCount = metadataHeader->data_count;
108     uint32_t size = metadataHeader->size;
109     MEDIA_DEBUG_LOG("DumpMetadataInfo srcMetadata \
110     version:%{public}d, itemCount:%{public}d, dataCount:%{public}d, size:%{public}d",
111         version, itemCount, dataCount, size);
112 
113     for (uint32_t i = 0; i < itemCount; i++) {
114         camera_metadata_item_t item;
115         Camera::GetCameraMetadataItem(metadataHeader, i, &item);
116         DumpMetadataItemInfo(item);
117     }
118 }
119 
DumpMetadataItemInfo(const camera_metadata_item_t & metadataItem)120 void DumpMetadataItemInfo(const camera_metadata_item_t& metadataItem)
121 {
122     uint32_t dataType = metadataItem.data_type;
123     uint32_t dataCount = metadataItem.count;
124     const char* tagName = Camera::GetCameraMetadataItemName(metadataItem.item);
125     MEDIA_DEBUG_LOG("DumpMetadataItemInfo \
126     tag:%{public}d->%{public}s, dataType:%{public}d, dataCount:%{public}d",
127         metadataItem.item, tagName, dataType, dataCount);
128     if (dataType == META_TYPE_BYTE) {
129         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
130             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}d",
131                 metadataItem.item, tagName, index, metadataItem.data.u8[index]);
132         });
133     } else if (dataType == META_TYPE_INT32) {
134         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
135             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}d",
136                 metadataItem.item, tagName, index, metadataItem.data.i32[index]);
137         });
138     } else if (dataType == META_TYPE_UINT32) {
139         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
140             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}d",
141                 metadataItem.item, tagName, index, metadataItem.data.ui32[index]);
142         });
143     } else if (dataType == META_TYPE_FLOAT) {
144         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
145             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}f",
146                 metadataItem.item, tagName, index, metadataItem.data.f[index]);
147         });
148     } else if (dataType == META_TYPE_INT64) {
149         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
150             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}lld",
151                 metadataItem.item, tagName, index, static_cast<long long>(metadataItem.data.i64[index]));
152         });
153     } else if (dataType == META_TYPE_DOUBLE) {
154         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
155             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, value:%{public}lf",
156                 metadataItem.item, tagName, index, metadataItem.data.d[index]);
157         });
158     } else if (dataType == META_TYPE_RATIONAL) {
159         ForEach(dataCount, [&metadataItem, &tagName](uint32_t index) {
160             MEDIA_DEBUG_LOG("DumpMetadataItemInfo:%{public}d->%{public}s, dataIndex:%{public}d, numerator:%{public}d, "
161                             "denominator:%{public}d",
162                 metadataItem.item, tagName, index, metadataItem.data.r[index].numerator,
163                 metadataItem.data.r[index].denominator);
164         });
165     } else {
166         MEDIA_WARNING_LOG("DumpMetadataItemInfo get unknown dataType:%{public}d", dataType);
167     }
168 }
169 
RecreateMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)170 std::shared_ptr<OHOS::Camera::CameraMetadata> RecreateMetadata(
171     const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
172 {
173     CHECK_ERROR_RETURN_RET_LOG(metadata == nullptr, nullptr, "RecreateMetadata is fail, metadata is null");
174     common_metadata_header_t* header = metadata->get();
175     std::shared_ptr<OHOS::Camera::CameraMetadata> newMetadata =
176         std::make_shared<OHOS::Camera::CameraMetadata>(ITEM_CAPACITY, DATA_CAPACITY);
177 
178     for (uint32_t metadataTag : reportMetadataTag) {
179         camera_metadata_item_t item;
180         int ret = Camera::FindCameraMetadataItem(header, metadataTag, &item);
181         if (ret == 0 && item.count != 0) {
182             newMetadata->addEntry(item.item, item.data.u8, item.count);
183         }
184     }
185     return newMetadata;
186 }
187 
LogFormatCameraMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)188 void LogFormatCameraMetadata(const std::shared_ptr<OHOS::Camera::CameraMetadata> metadata)
189 {
190     CHECK_ERROR_RETURN_LOG(metadata == nullptr, "LogFormatCameraMetadata: Metadata pointer is null");
191     auto header = metadata->get();
192     CHECK_ERROR_RETURN_LOG(header == nullptr, "LogFormatCameraMetadata: Metadata header is null");
193 
194     std::string metaStr = OHOS::Camera::FormatCameraMetadataToString(header);
195     MEDIA_DEBUG_LOG("LogFormatCameraMetadata: metaStr %{public}s", metaStr.c_str());
196 }
197 } // namespace CameraFwkMetadataUtils
198 } // namespace CameraStandard
199 } // namespace OHOS