• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "dmetadata_processor.h"
17 
18 #include "dbuffer_manager.h"
19 #include "dcamera.h"
20 #include "distributed_hardware_log.h"
21 #include "json/json.h"
22 #include "metadata_utils.h"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
InitDCameraAbility(const std::string & abilityInfo)26 DCamRetCode DMetadataProcessor::InitDCameraAbility(const std::string &abilityInfo)
27 {
28     JSONCPP_STRING errs;
29     Json::CharReaderBuilder readerBuilder;
30     Json::Value rootValue;
31 
32     std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
33     if (jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) &&
34         rootValue.isObject()) {
35         if (rootValue.isMember("MetaData") && rootValue["MetaData"].isString()) {
36             std::string metadataStr = rootValue["MetaData"].asString();
37             if (!metadataStr.empty()) {
38                 std::hash<std::string> h;
39                 DHLOGI("Decode distributed camera metadata from base64, hash: %zu, length: %zu",
40                     h(metadataStr), metadataStr.length());
41                 std::string decodeString = Base64Decode(metadataStr);
42                 DHLOGI("Decode distributed camera metadata from string, hash: %zu, length: %zu",
43                     h(decodeString), decodeString.length());
44                 dCameraAbility_ = OHOS::Camera::MetadataUtils::DecodeFromString(decodeString);
45                 DHLOGI("Decode distributed camera metadata from string success.");
46             }
47         }
48     }
49 
50     if (dCameraAbility_ == nullptr) {
51         DHLOGE("Metadata is null in ability set or failed to decode metadata ability from string.");
52         dCameraAbility_ = std::make_shared<CameraAbility>(DEFAULT_ENTRY_CAPACITY, DEFAULT_DATA_CAPACITY);
53     }
54 
55     if (OHOS::Camera::GetCameraMetadataItemCount(dCameraAbility_->get()) <= 0) {
56         DCamRetCode ret = InitDCameraDefaultAbilityKeys(abilityInfo);
57         if (ret != SUCCESS) {
58             DHLOGE("Init distributed camera defalult abilily keys failed.");
59             dCameraAbility_ = nullptr;
60             return ret;
61         }
62     }
63 
64     DCamRetCode ret = InitDCameraOutputAbilityKeys(abilityInfo);
65     if (ret != SUCCESS) {
66         DHLOGE("Init distributed camera output abilily keys failed.");
67         dCameraAbility_ = nullptr;
68         return ret;
69     }
70 
71     camera_metadata_item_entry_t* itemEntry = OHOS::Camera::GetMetadataItems(dCameraAbility_->get());
72     uint32_t count = dCameraAbility_->get()->item_count;
73     for (uint32_t i = 0; i < count; i++, itemEntry++) {
74         allResultSet_.insert((MetaType)(itemEntry->item));
75     }
76     return SUCCESS;
77 }
78 
InitDcameraBaseAbility()79 void DMetadataProcessor::InitDcameraBaseAbility()
80 {
81     const uint8_t cameraType = OHOS_CAMERA_TYPE_LOGICAL;
82     AddAbilityEntry(OHOS_ABILITY_CAMERA_TYPE, &cameraType, 1);
83 
84     const int64_t exposureTime = 0xFFFFFFFFFFFFFFFF;
85     AddAbilityEntry(OHOS_SENSOR_EXPOSURE_TIME, &exposureTime, 1);
86 
87     const float correctionGain = 0.0;
88     AddAbilityEntry(OHOS_SENSOR_COLOR_CORRECTION_GAINS, &correctionGain, 1);
89 
90     const uint8_t faceDetectMode = OHOS_CAMERA_FACE_DETECT_MODE_OFF;
91     AddAbilityEntry(OHOS_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
92 
93     const uint8_t histogramMode = OHOS_CAMERA_HISTOGRAM_MODE_OFF;
94     AddAbilityEntry(OHOS_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
95 
96     const uint8_t aeAntibandingMode = OHOS_CAMERA_AE_ANTIBANDING_MODE_OFF;
97     AddAbilityEntry(OHOS_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);
98 
99     int32_t aeExposureCompensation = 0xFFFFFFFF;
100     AddAbilityEntry(OHOS_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExposureCompensation, 1);
101 
102     const uint8_t aeLock = OHOS_CAMERA_AE_LOCK_OFF;
103     AddAbilityEntry(OHOS_CONTROL_AE_LOCK, &aeLock, 1);
104 
105     const uint8_t aeMode = OHOS_CAMERA_AE_MODE_OFF;
106     AddAbilityEntry(OHOS_CONTROL_AE_MODE, &aeMode, 1);
107 
108     const uint8_t afMode = OHOS_CAMERA_AF_MODE_OFF;
109     AddAbilityEntry(OHOS_CONTROL_AF_MODE, &afMode, 1);
110 
111     const uint8_t awbLock = OHOS_CAMERA_AWB_LOCK_OFF;
112     AddAbilityEntry(OHOS_CONTROL_AWB_LOCK, &awbLock, 1);
113 
114     const uint8_t awbMode = OHOS_CAMERA_AWB_MODE_OFF;
115     AddAbilityEntry(OHOS_CONTROL_AWB_MODE, &awbMode, 1);
116 
117     const uint8_t aeAntibandingModes = OHOS_CAMERA_AE_ANTIBANDING_MODE_AUTO;
118     AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, &aeAntibandingModes, 1);
119 
120     const uint8_t aeAvailableModes = OHOS_CAMERA_AE_MODE_ON;
121     AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_MODES, &aeAvailableModes, 1);
122 
123     const int32_t compensationRange[] = { 0, 0 };
124     AddAbilityEntry(OHOS_CONTROL_AE_COMPENSATION_RANGE, compensationRange,
125         (sizeof(compensationRange) / sizeof(compensationRange[0])));
126 
127     const camera_rational_t compensationStep[] = { { 0, 1 } };
128     AddAbilityEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, compensationStep,
129         (sizeof(compensationStep) / sizeof(compensationStep[0])));
130 
131     const uint8_t afAvailableModes[] = { OHOS_CAMERA_AF_MODE_AUTO, OHOS_CAMERA_AF_MODE_OFF };
132     AddAbilityEntry(OHOS_CONTROL_AF_AVAILABLE_MODES, afAvailableModes,
133         (sizeof(afAvailableModes) / sizeof(afAvailableModes[0])));
134 
135     const uint8_t awbAvailableModes = OHOS_CAMERA_AWB_MODE_AUTO;
136     AddAbilityEntry(OHOS_CONTROL_AWB_AVAILABLE_MODES, &awbAvailableModes, 1);
137 
138     const uint8_t deviceExposureMode = OHOS_CAMERA_EXPOSURE_MODE_CONTINUOUS_AUTO;
139     AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_EXPOSUREMODES, &deviceExposureMode, 1);
140 
141     const uint8_t controlExposureMode = OHOS_CAMERA_EXPOSURE_MODE_CONTINUOUS_AUTO;
142     AddAbilityEntry(OHOS_CONTROL_EXPOSUREMODE, &controlExposureMode, 1);
143 
144     const uint8_t deviceFocusModes = OHOS_CAMERA_FOCUS_MODE_AUTO;
145     AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_FOCUSMODES, &deviceFocusModes, 1);
146     SetFpsRanges();
147 }
148 
SetFpsRanges()149 void DMetadataProcessor::SetFpsRanges()
150 {
151     std::vector<int32_t> fpsRanges;
152     fpsRanges.push_back(MIN_SUPPORT_DEFAULT_FPS);
153     fpsRanges.push_back(MAX_SUPPORT_DEFAULT_FPS);
154     AddAbilityEntry(OHOS_CONTROL_AE_TARGET_FPS_RANGE, fpsRanges.data(), fpsRanges.size());
155     AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), fpsRanges.size());
156 }
157 
InitDCameraDefaultAbilityKeys(const std::string & abilityInfo)158 DCamRetCode DMetadataProcessor::InitDCameraDefaultAbilityKeys(const std::string &abilityInfo)
159 {
160     JSONCPP_STRING errs;
161     Json::CharReaderBuilder readerBuilder;
162     Json::Value rootValue;
163     std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
164     if (jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) &&
165         rootValue.isObject()) {
166         if (rootValue.isMember("ProtocolVer") && rootValue["ProtocolVer"].isString()) {
167             protocolVersion_ = rootValue["ProtocolVer"].asString();
168         }
169         if (rootValue.isMember("Position") && rootValue["Position"].isString()) {
170             dCameraPosition_ = rootValue["Position"].asString();
171         }
172     }
173     if (dCameraPosition_ == "BACK") {
174         const uint8_t position = OHOS_CAMERA_POSITION_BACK;
175         AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
176     } else if (dCameraPosition_ == "FRONT") {
177         const uint8_t position = OHOS_CAMERA_POSITION_FRONT;
178         AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
179     } else {
180         const uint8_t position = OHOS_CAMERA_POSITION_OTHER;
181         AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
182     }
183     InitDcameraBaseAbility();
184     const uint8_t controlFocusMode = OHOS_CAMERA_FOCUS_MODE_AUTO;
185     AddAbilityEntry(OHOS_CONTROL_FOCUSMODE, &controlFocusMode, 1);
186     const uint8_t deviceFlashModes = OHOS_CAMERA_FLASH_MODE_AUTO;
187     AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_FLASHMODES, &deviceFlashModes, 1);
188     const uint8_t controlFlashMode = OHOS_CAMERA_FLASH_MODE_CLOSE;
189     AddAbilityEntry(OHOS_CONTROL_FLASHMODE, &controlFlashMode, 1);
190     float zoomRatioRange[1] = {1.0};
191     AddAbilityEntry(OHOS_ABILITY_ZOOM_RATIO_RANGE, zoomRatioRange,
192         (sizeof(zoomRatioRange) / sizeof(zoomRatioRange[0])));
193     const float zoomRatio = 1.0;
194     AddAbilityEntry(OHOS_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
195     int32_t activeArraySize[] = {
196         0, 0, static_cast<int32_t>(maxPreviewResolution_.width_), static_cast<int32_t>(maxPreviewResolution_.height_)};
197     AddAbilityEntry(OHOS_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize,
198         (sizeof(activeArraySize) / sizeof(activeArraySize[0])));
199     int32_t pixelArraySize[] = {
200         static_cast<int32_t>(maxPreviewResolution_.width_), static_cast<int32_t>(maxPreviewResolution_.height_)};
201     AddAbilityEntry(OHOS_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize,
202         (sizeof(pixelArraySize) / sizeof(pixelArraySize[0])));
203     const int32_t jpegThumbnailSizes[] = {0, 0, DEGREE_240, DEGREE_180};
204     AddAbilityEntry(OHOS_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes,
205         (sizeof(jpegThumbnailSizes) / sizeof(jpegThumbnailSizes[0])));
206     return SUCCESS;
207 }
208 
InitDCameraOutputAbilityKeys(const std::string & abilityInfo)209 DCamRetCode DMetadataProcessor::InitDCameraOutputAbilityKeys(const std::string &abilityInfo)
210 {
211     std::map<int, std::vector<DCResolution>> supportedFormats = GetDCameraSupportedFormats(abilityInfo);
212 
213     std::vector<int32_t> streamConfigurations;
214     std::map<int, std::vector<DCResolution>>::iterator iter;
215     for (iter = supportedFormats.begin(); iter != supportedFormats.end(); ++iter) {
216         std::vector<DCResolution> resolutionList = iter->second;
217         for (auto resolution : resolutionList) {
218             DHLOGI("DMetadataProcessor::supported formats: { format=%d, width=%d, height=%d }", iter->first,
219                 resolution.width_, resolution.height_);
220             streamConfigurations.push_back(iter->first);
221             streamConfigurations.push_back(resolution.width_);
222             streamConfigurations.push_back(resolution.height_);
223         }
224     }
225     UpdateAbilityEntry(OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, streamConfigurations.data(),
226         streamConfigurations.size());
227 
228     UpdateAbilityEntry(OHOS_SENSOR_INFO_MAX_FRAME_DURATION, &MAX_FRAME_DURATION, 1);
229 
230     const int32_t jpegMaxSize = maxPhotoResolution_.width_ * maxPhotoResolution_.height_;
231     UpdateAbilityEntry(OHOS_JPEG_MAX_SIZE, &jpegMaxSize, 1);
232 
233     const uint8_t connectionType = OHOS_CAMERA_CONNECTION_TYPE_REMOTE;
234     UpdateAbilityEntry(OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &connectionType, 1);
235 
236     return SUCCESS;
237 }
238 
AddAbilityEntry(uint32_t tag,const void * data,size_t size)239 DCamRetCode DMetadataProcessor::AddAbilityEntry(uint32_t tag, const void *data, size_t size)
240 {
241     if (dCameraAbility_ == nullptr) {
242         DHLOGE("Distributed camera abilily is null.");
243         return DCamRetCode::INVALID_ARGUMENT;
244     }
245 
246     camera_metadata_item_t item;
247     int ret = OHOS::Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item);
248     if (ret) {
249         if (!dCameraAbility_->addEntry(tag, data, size)) {
250             DHLOGE("Add tag %u failed.", tag);
251             return FAILED;
252         }
253     }
254     return SUCCESS;
255 }
256 
UpdateAbilityEntry(uint32_t tag,const void * data,size_t size)257 DCamRetCode DMetadataProcessor::UpdateAbilityEntry(uint32_t tag, const void *data, size_t size)
258 {
259     if (dCameraAbility_ == nullptr) {
260         DHLOGE("Distributed camera abilily is null.");
261         return DCamRetCode::INVALID_ARGUMENT;
262     }
263 
264     camera_metadata_item_t item;
265     int ret = OHOS::Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item);
266     if (ret) {
267         if (!dCameraAbility_->addEntry(tag, data, size)) {
268             DHLOGE("Add tag %u failed.", tag);
269             return FAILED;
270         }
271     } else {
272         if (!dCameraAbility_->updateEntry(tag, data, size)) {
273             DHLOGE("Update tag %u failed.", tag);
274             return FAILED;
275         }
276     }
277     return SUCCESS;
278 }
279 
GetDCameraAbility(std::shared_ptr<CameraAbility> & ability)280 DCamRetCode DMetadataProcessor::GetDCameraAbility(std::shared_ptr<CameraAbility> &ability)
281 {
282     ability = dCameraAbility_;
283     return SUCCESS;
284 }
285 
SetMetadataResultMode(const ResultCallbackMode & mode)286 DCamRetCode DMetadataProcessor::SetMetadataResultMode(const ResultCallbackMode &mode)
287 {
288     if (mode < ResultCallbackMode::PER_FRAME || mode > ResultCallbackMode::ON_CHANGED) {
289         DHLOGE("Invalid result callback mode.");
290         return DCamRetCode::INVALID_ARGUMENT;
291     }
292     metaResultMode_ = mode;
293     return SUCCESS;
294 }
295 
GetEnabledMetadataResults(std::vector<MetaType> & results)296 DCamRetCode DMetadataProcessor::GetEnabledMetadataResults(std::vector<MetaType> &results)
297 {
298     auto iter = enabledResultSet_.begin();
299     while (iter != enabledResultSet_.end()) {
300         results.push_back(*iter);
301         iter++;
302     }
303     return SUCCESS;
304 }
305 
EnableMetadataResult(const std::vector<MetaType> & results)306 DCamRetCode DMetadataProcessor::EnableMetadataResult(const std::vector<MetaType> &results)
307 {
308     if (results.size() == 0) {
309         DHLOGE("Enable metadata result list is empty.");
310         return SUCCESS;
311     }
312 
313     for (size_t i = 0; i < results.size(); i++) {
314         auto iter = allResultSet_.find(results[i]);
315         if (iter != allResultSet_.end()) {
316             auto anoIter = enabledResultSet_.find(results[i]);
317             if (anoIter == enabledResultSet_.end()) {
318                 enabledResultSet_.insert(results[i]);
319             }
320         } else {
321             DHLOGE("Cannot find match metatype.");
322             return SUCCESS;
323         }
324     }
325     return SUCCESS;
326 }
327 
DisableMetadataResult(const std::vector<MetaType> & results)328 DCamRetCode DMetadataProcessor::DisableMetadataResult(const std::vector<MetaType> &results)
329 {
330     if (results.size() == 0) {
331         DHLOGE("Disable metadata result list is empty.");
332         return SUCCESS;
333     }
334 
335     for (size_t i = 0; i < results.size(); i++) {
336         auto iter = allResultSet_.find(results[i]);
337         if (iter != allResultSet_.end()) {
338             auto anoIter = enabledResultSet_.find(results[i]);
339             if (anoIter != enabledResultSet_.end()) {
340                 enabledResultSet_.erase(*iter);
341             }
342         } else {
343             DHLOGE("Cannot find match metatype.");
344             return SUCCESS;
345         }
346     }
347     return SUCCESS;
348 }
349 
ResetEnableResults()350 DCamRetCode DMetadataProcessor::ResetEnableResults()
351 {
352     if (enabledResultSet_.size() < allResultSet_.size()) {
353         for (auto result : allResultSet_) {
354             enabledResultSet_.insert(result);
355         }
356     }
357     return SUCCESS;
358 }
359 
UpdateResultMetadata(const uint64_t & resultTimestamp)360 void DMetadataProcessor::UpdateResultMetadata(const uint64_t &resultTimestamp)
361 {
362     DHLOGD("DMetadataProcessor::UpdateResultMetadata result callback mode: %d", metaResultMode_);
363     if (metaResultMode_ != ResultCallbackMode::PER_FRAME) {
364         return;
365     }
366 
367     std::lock_guard<std::mutex> autoLock(producerMutex_);
368     if (latestProducerMetadataResult_ == nullptr) {
369         DHLOGD("DMetadataProcessor::UpdateResultMetadata latest producer metadata result is null");
370         return;
371     }
372 
373     UpdateAllResult(resultTimestamp);
374 }
375 
SetResultCallback(std::function<void (uint64_t,std::shared_ptr<OHOS::Camera::CameraMetadata>)> & resultCbk)376 void DMetadataProcessor::SetResultCallback(
377     std::function<void(uint64_t, std::shared_ptr<OHOS::Camera::CameraMetadata>)> &resultCbk)
378 {
379     resultCallback_ = resultCbk;
380 }
381 
UpdateAllResult(const uint64_t & resultTimestamp)382 void DMetadataProcessor::UpdateAllResult(const uint64_t &resultTimestamp)
383 {
384     uint32_t itemCap = OHOS::Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get());
385     uint32_t dataSize = OHOS::Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get());
386     DHLOGD("DMetadataProcessor::UpdateAllResult itemCapacity: %u, dataSize: %u", itemCap, dataSize);
387     std::shared_ptr<OHOS::Camera::CameraMetadata> result =
388         std::make_shared<OHOS::Camera::CameraMetadata>(itemCap, dataSize);
389     int32_t ret = OHOS::Camera::CopyCameraMetadataItems(result->get(), latestProducerMetadataResult_->get());
390     if (ret != CAM_META_SUCCESS) {
391         DHLOGE("DMetadataProcessor::UpdateAllResult copy metadata item failed, ret: %d", ret);
392         return;
393     }
394     resultCallback_(resultTimestamp, result);
395 }
396 
UpdateOnChanged(const uint64_t & resultTimestamp)397 void DMetadataProcessor::UpdateOnChanged(const uint64_t &resultTimestamp)
398 {
399     bool needReturn = false;
400     uint32_t itemCap = OHOS::Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get());
401     uint32_t dataSize = OHOS::Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get());
402     DHLOGD("DMetadataProcessor::UpdateOnChanged itemCapacity: %u, dataSize: %u", itemCap, dataSize);
403     std::shared_ptr<OHOS::Camera::CameraMetadata> result =
404         std::make_shared<OHOS::Camera::CameraMetadata>(itemCap, dataSize);
405     DHLOGD("DMetadataProcessor::UpdateOnChanged enabledResultSet size: %d", enabledResultSet_.size());
406     for (auto tag : enabledResultSet_) {
407         DHLOGD("DMetadataProcessor::UpdateOnChanged cameta device metadata tag: %d", tag);
408         camera_metadata_item_t item;
409         camera_metadata_item_t anoItem;
410         int ret1 = OHOS::Camera::FindCameraMetadataItem(latestProducerMetadataResult_->get(), tag, &item);
411         int ret2 = OHOS::Camera::FindCameraMetadataItem(latestConsumerMetadataResult_->get(), tag, &anoItem);
412         DHLOGD("DMetadataProcessor::UpdateOnChanged find metadata item ret: %d, %d", ret1, ret2);
413         if (ret1 != CAM_META_SUCCESS) {
414             continue;
415         }
416 
417         if (ret2 == CAM_META_SUCCESS) {
418             if ((item.count != anoItem.count) || (item.data_type != anoItem.data_type)) {
419                 needReturn = true;
420                 result->addEntry(tag, GetMetadataItemData(item), item.count);
421                 continue;
422             }
423             uint32_t size = GetDataSize(item.data_type);
424             DHLOGD("DMetadataProcessor::UpdateOnChanged data size: %u", size);
425             for (uint32_t i = 0; i < (size * static_cast<uint32_t>(item.count)); i++) {
426                 if (*(item.data.u8 + i) != *(anoItem.data.u8 + i)) {
427                     needReturn = true;
428                     result->addEntry(tag, GetMetadataItemData(item), item.count);
429                     break;
430                 }
431             }
432         } else {
433             needReturn = true;
434             result->addEntry(tag, GetMetadataItemData(item), item.count);
435             continue;
436         }
437     }
438 
439     if (needReturn) {
440         resultCallback_(resultTimestamp, result);
441     }
442 }
443 
SaveResultMetadata(std::string resultStr)444 DCamRetCode DMetadataProcessor::SaveResultMetadata(std::string resultStr)
445 {
446     if (resultStr.empty()) {
447         DHLOGE("Input result string is null.");
448         return DCamRetCode::INVALID_ARGUMENT;
449     }
450 
451     std::string metadataStr = Base64Decode(resultStr);
452     std::lock_guard<std::mutex> autoLock(producerMutex_);
453     latestConsumerMetadataResult_ = latestProducerMetadataResult_;
454     latestProducerMetadataResult_ = OHOS::Camera::MetadataUtils::DecodeFromString(metadataStr);
455     if (latestProducerMetadataResult_ == nullptr) {
456         DHLOGE("Failed to decode metadata setting from string.");
457         return DCamRetCode::INVALID_ARGUMENT;
458     }
459 
460     if (!OHOS::Camera::GetCameraMetadataItemCount(latestProducerMetadataResult_->get())) {
461         DHLOGE("Input result metadata item is empty.");
462         return DCamRetCode::INVALID_ARGUMENT;
463     }
464 
465     DHLOGD("DMetadataProcessor::SaveResultMetadata result callback mode: %d", metaResultMode_);
466     if (metaResultMode_ != ResultCallbackMode::ON_CHANGED) {
467         return SUCCESS;
468     }
469 
470     uint64_t resultTimestamp = GetCurrentLocalTimeStamp();
471     if (latestConsumerMetadataResult_ == nullptr) {
472         UpdateAllResult(resultTimestamp);
473         return SUCCESS;
474     }
475 
476     camera_metadata_item_entry_t* itemEntry = OHOS::Camera::GetMetadataItems(latestProducerMetadataResult_->get());
477     uint32_t count = latestProducerMetadataResult_->get()->item_count;
478     for (uint32_t i = 0; i < count; i++, itemEntry++) {
479         enabledResultSet_.insert((MetaType)(itemEntry->item));
480     }
481     UpdateOnChanged(resultTimestamp);
482     return SUCCESS;
483 }
484 
ConvertToCameraMetadata(common_metadata_header_t * & input,std::shared_ptr<OHOS::Camera::CameraMetadata> & output)485 void DMetadataProcessor::ConvertToCameraMetadata(common_metadata_header_t *&input,
486     std::shared_ptr<OHOS::Camera::CameraMetadata> &output)
487 {
488     auto ret = OHOS::Camera::CopyCameraMetadataItems(output->get(), input);
489     if (ret != CAM_META_SUCCESS) {
490         DHLOGE("Failed to copy the old metadata to new metadata.");
491         output = nullptr;
492     }
493 }
494 
ResizeMetadataHeader(common_metadata_header_t * & header,uint32_t itemCapacity,uint32_t dataCapacity)495 void DMetadataProcessor::ResizeMetadataHeader(common_metadata_header_t *&header,
496     uint32_t itemCapacity, uint32_t dataCapacity)
497 {
498     if (header) {
499         OHOS::Camera::FreeCameraMetadataBuffer(header);
500     }
501     header = OHOS::Camera::AllocateCameraMetadataBuffer(itemCapacity, dataCapacity);
502 }
503 
GetDataSize(uint32_t type)504 uint32_t DMetadataProcessor::GetDataSize(uint32_t type)
505 {
506     uint32_t size = 0;
507     if (type == META_TYPE_BYTE) {
508         size = sizeof(uint8_t);
509     } else if (type == META_TYPE_INT32) {
510         size = sizeof(int32_t);
511     } else if (type == META_TYPE_UINT32) {
512         size = sizeof(uint32_t);
513     } else if (type == META_TYPE_FLOAT) {
514         size = sizeof(float);
515     } else if (type == META_TYPE_INT64) {
516         size = sizeof(int64_t);
517     } else if (type == META_TYPE_DOUBLE) {
518         size = sizeof(double);
519     } else if (type == META_TYPE_RATIONAL) {
520         size = sizeof(camera_rational_t);
521     } else {
522         size = 0;
523     }
524     return size;
525 }
526 
GetMetadataItemData(const camera_metadata_item_t & item)527 void* DMetadataProcessor::GetMetadataItemData(const camera_metadata_item_t &item)
528 {
529     switch (item.data_type) {
530         case META_TYPE_BYTE: {
531             return item.data.u8;
532         }
533         case META_TYPE_INT32: {
534             return item.data.i32;
535         }
536         case META_TYPE_UINT32: {
537             return item.data.ui32;
538         }
539         case META_TYPE_FLOAT: {
540             return item.data.f;
541         }
542         case META_TYPE_INT64: {
543             return item.data.i64;
544         }
545         case META_TYPE_DOUBLE: {
546             return item.data.d;
547         }
548         case META_TYPE_RATIONAL: {
549             return item.data.r;
550         }
551         default: {
552             DHLOGE("DMetadataProcessor::GetMetadataItemData invalid data type: %u", item.data_type);
553             return nullptr;
554         }
555     }
556 }
557 
GetEachNodeSupportedResolution(std::vector<int> & formats,const std::string rootNode,std::map<int,std::vector<DCResolution>> & supportedFormats,Json::Value & rootValue)558 void DMetadataProcessor::GetEachNodeSupportedResolution(std::vector<int>& formats, const std::string rootNode,
559     std::map<int, std::vector<DCResolution>>& supportedFormats, Json::Value& rootValue)
560 {
561     for (const auto &format : formats) {
562         std::string formatStr = std::to_string(format);
563         if (!rootValue[rootNode].isMember("Resolution") || !rootValue[rootNode]["Resolution"].isMember(formatStr) ||
564             !rootValue[rootNode]["Resolution"][formatStr].isArray() ||
565             rootValue[rootNode]["Resolution"][formatStr].size() == 0 ||
566             rootValue[rootNode]["Resolution"][formatStr].size() > JSON_ARRAY_MAX_SIZE) {
567             DHLOGE("Resolution or %s error.", formatStr.c_str());
568             continue;
569         }
570         GetNodeSupportedResolution(format, formatStr, rootNode, supportedFormats, rootValue);
571     }
572 }
573 
GetNodeSupportedResolution(int format,std::string formatStr,const std::string rootNode,std::map<int,std::vector<DCResolution>> & supportedFormats,Json::Value & rootValue)574 void DMetadataProcessor::GetNodeSupportedResolution(int format, std::string formatStr, const std::string rootNode,
575     std::map<int, std::vector<DCResolution>>& supportedFormats, Json::Value& rootValue)
576 {
577     std::vector<DCResolution> resolutionVec;
578     uint32_t size = rootValue[rootNode]["Resolution"][formatStr].size();
579     for (uint32_t i = 0; i < size; i++) {
580         if (!rootValue[rootNode]["Resolution"][formatStr][i].isString()) {
581             DHLOGE("Resolution %s %d ,is not string.", formatStr.c_str(), i);
582             continue;
583         }
584         std::string resoStr = rootValue[rootNode]["Resolution"][formatStr][i].asString();
585         std::vector<std::string> reso;
586         SplitString(resoStr, reso, STAR_SEPARATOR);
587         if (reso.size() != SIZE_FMT_LEN) {
588             continue;
589         }
590         uint32_t width = static_cast<uint32_t>(std::stoi(reso[0]));
591         uint32_t height = static_cast<uint32_t>(std::stoi(reso[1]));
592         if (height == 0 || width == 0 ||
593             ((rootNode == "Photo") &&
594                 ((width * height) > (MAX_SUPPORT_PHOTO_WIDTH * MAX_SUPPORT_PHOTO_HEIGHT))) ||
595             ((rootNode != "Photo") &&
596                 (width > MAX_SUPPORT_PREVIEW_WIDTH || height > MAX_SUPPORT_PREVIEW_HEIGHT))) {
597             continue;
598         }
599         DCResolution resolution(width, height);
600         resolutionVec.push_back(resolution);
601     }
602     if (!resolutionVec.empty()) {
603         std::sort(resolutionVec.begin(), resolutionVec.end());
604         supportedFormats[format] = resolutionVec;
605         if ((rootNode != "Photo") && (maxPreviewResolution_ < resolutionVec[0])) {
606             maxPreviewResolution_.width_ = resolutionVec[0].width_;
607             maxPreviewResolution_.height_ = resolutionVec[0].height_;
608         }
609         if ((rootNode == "Photo") && (maxPhotoResolution_ < resolutionVec[0])) {
610             maxPhotoResolution_.width_ = resolutionVec[0].width_;
611             maxPhotoResolution_.height_ = resolutionVec[0].height_;
612         }
613     }
614 }
615 
GetDCameraSupportedFormats(const std::string & abilityInfo)616 std::map<int, std::vector<DCResolution>> DMetadataProcessor::GetDCameraSupportedFormats(const std::string &abilityInfo)
617 {
618     std::map<int, std::vector<DCResolution>> supportedFormats;
619     JSONCPP_STRING errs;
620     Json::CharReaderBuilder readerBuilder;
621     Json::Value rootValue;
622 
623     std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
624     if (!jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) ||
625         !rootValue.isObject()) {
626         return supportedFormats;
627     }
628     ParsePhotoFormats(rootValue, supportedFormats);
629     ParsePreviewFormats(rootValue, supportedFormats);
630     ParseVideoFormats(rootValue, supportedFormats);
631     return supportedFormats;
632 }
633 
ParsePhotoFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)634 void DMetadataProcessor::ParsePhotoFormats(Json::Value& rootValue,
635     std::map<int, std::vector<DCResolution>>& supportedFormats)
636 {
637     if (!rootValue.isMember("Photo") || !rootValue["Photo"].isMember("OutputFormat") ||
638         !rootValue["Photo"]["OutputFormat"].isArray() || rootValue["Photo"]["OutputFormat"].size() == 0 ||
639         rootValue["Photo"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
640         DHLOGE("Photo or photo output format error.");
641         return;
642     }
643     std::vector<int> photoFormats;
644     uint32_t size = rootValue["Photo"]["OutputFormat"].size();
645     for (uint32_t i = 0; i < size; i++) {
646         if ((rootValue["Photo"]["OutputFormat"][i]).isInt()) {
647             photoFormats.push_back((rootValue["Photo"]["OutputFormat"][i]).asInt());
648         }
649     }
650     GetEachNodeSupportedResolution(photoFormats, "Photo", supportedFormats, rootValue);
651 }
652 
ParsePreviewFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)653 void DMetadataProcessor::ParsePreviewFormats(Json::Value& rootValue,
654     std::map<int, std::vector<DCResolution>>& supportedFormats)
655 {
656     if (!rootValue.isMember("Preview") || !rootValue["Preview"].isMember("OutputFormat") ||
657         !rootValue["Preview"]["OutputFormat"].isArray() || rootValue["Preview"]["OutputFormat"].size() == 0 ||
658         rootValue["Preview"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
659         DHLOGE("Preview or preview output format error.");
660         return;
661     }
662     std::vector<int> previewFormats;
663     uint32_t size = rootValue["Preview"]["OutputFormat"].size();
664     for (uint32_t i = 0; i < size; i++) {
665         if ((rootValue["Preview"]["OutputFormat"][i]).isInt()) {
666             previewFormats.push_back((rootValue["Preview"]["OutputFormat"][i]).asInt());
667         }
668     }
669     GetEachNodeSupportedResolution(previewFormats, "Preview", supportedFormats, rootValue);
670 }
671 
ParseVideoFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)672 void DMetadataProcessor::ParseVideoFormats(Json::Value& rootValue,
673     std::map<int, std::vector<DCResolution>>& supportedFormats)
674 {
675     if (!rootValue.isMember("Video") || !rootValue["Video"].isMember("OutputFormat") ||
676         !rootValue["Video"]["OutputFormat"].isArray() || rootValue["Video"]["OutputFormat"].size() == 0 ||
677         rootValue["Video"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
678         DHLOGE("Video or video output format error.");
679         return;
680     }
681     std::vector<int> videoFormats;
682     uint32_t size = rootValue["Video"]["OutputFormat"].size();
683     for (uint32_t i = 0; i < size; i++) {
684         if ((rootValue["Video"]["OutputFormat"][i]).isInt()) {
685             videoFormats.push_back((rootValue["Video"]["OutputFormat"][i]).asInt());
686         }
687     }
688     GetEachNodeSupportedResolution(videoFormats, "Video", supportedFormats, rootValue);
689 }
690 
PrintDCameraMetadata(const common_metadata_header_t * metadata)691 void DMetadataProcessor::PrintDCameraMetadata(const common_metadata_header_t *metadata)
692 {
693     if (metadata == nullptr) {
694         DHLOGE("Failed to print metadata, input metadata is null.");
695         return;
696     }
697 
698     uint32_t tagCount = OHOS::Camera::GetCameraMetadataItemCount(metadata);
699     DHLOGD("DMetadataProcessor::PrintDCameraMetadata, input metadata item count = %d.", tagCount);
700     for (uint32_t i = 0; i < tagCount; i++) {
701         camera_metadata_item_t item;
702         int ret = OHOS::Camera::GetCameraMetadataItem(metadata, i, &item);
703         if (ret != 0) {
704             continue;
705         }
706 
707         const char *name = OHOS::Camera::GetCameraMetadataItemName(item.item);
708         if (item.data_type == META_TYPE_BYTE) {
709             for (size_t k = 0; k < item.count; k++) {
710                 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint8_t)(item.data.u8[k]));
711             }
712         } else if (item.data_type == META_TYPE_INT32) {
713             for (size_t k = 0; k < item.count; k++) {
714                 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (int32_t)(item.data.i32[k]));
715             }
716         } else if (item.data_type == META_TYPE_UINT32) {
717             for (size_t k = 0; k < item.count; k++) {
718                 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint32_t)(item.data.ui32[k]));
719             }
720         } else if (item.data_type == META_TYPE_FLOAT) {
721             for (size_t k = 0; k < item.count; k++) {
722                 DHLOGI("tag index:%d, name:%s, value:%f", item.index, name, (float)(item.data.f[k]));
723             }
724         } else if (item.data_type == META_TYPE_INT64) {
725             for (size_t k = 0; k < item.count; k++) {
726                 DHLOGI("tag index:%d, name:%s, value:%lld", item.index, name, (long long)(item.data.i64[k]));
727             }
728         } else if (item.data_type == META_TYPE_DOUBLE) {
729             for (size_t k = 0; k < item.count; k++) {
730                 DHLOGI("tag index:%d, name:%s, value:%lf", item.index, name, (double)(item.data.d[k]));
731             }
732         } else {
733             DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, *(item.data.r));
734         }
735     }
736 }
737 } // namespace DistributedHardware
738 } // namespace OHOS
739