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
164 std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
165 if (jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) &&
166 rootValue.isObject()) {
167 if (rootValue.isMember("ProtocolVer") && rootValue["ProtocolVer"].isString()) {
168 protocolVersion_ = rootValue["ProtocolVer"].asString();
169 }
170 if (rootValue.isMember("Position") && rootValue["Position"].isString()) {
171 dCameraPosition_ = rootValue["Position"].asString();
172 }
173 }
174
175 if (dCameraPosition_ == "BACK") {
176 const uint8_t position = OHOS_CAMERA_POSITION_BACK;
177 AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
178 } else if (dCameraPosition_ == "FRONT") {
179 const uint8_t position = OHOS_CAMERA_POSITION_FRONT;
180 AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
181 } else {
182 const uint8_t position = OHOS_CAMERA_POSITION_OTHER;
183 AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1);
184 }
185
186 InitDcameraBaseAbility();
187
188 const uint8_t controlFocusMode = OHOS_CAMERA_FOCUS_MODE_AUTO;
189 AddAbilityEntry(OHOS_CONTROL_FOCUSMODE, &controlFocusMode, 1);
190
191 const uint8_t deviceFlashModes = OHOS_CAMERA_FLASH_MODE_AUTO;
192 AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_FLASHMODES, &deviceFlashModes, 1);
193
194 const uint8_t controlFlashMode = OHOS_CAMERA_FLASH_MODE_CLOSE;
195 AddAbilityEntry(OHOS_CONTROL_FLASHMODE, &controlFlashMode, 1);
196
197 float zoomRatioRange[1] = {1.0};
198 AddAbilityEntry(OHOS_ABILITY_ZOOM_RATIO_RANGE, zoomRatioRange,
199 (sizeof(zoomRatioRange) / sizeof(zoomRatioRange[0])));
200
201 const float zoomRatio = 1.0;
202 AddAbilityEntry(OHOS_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
203
204 int32_t activeArraySize[] = {
205 0, 0, static_cast<int32_t>(maxPreviewResolution_.width_), static_cast<int32_t>(maxPreviewResolution_.height_)
206 };
207 AddAbilityEntry(OHOS_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize,
208 (sizeof(activeArraySize) / sizeof(activeArraySize[0])));
209
210 int32_t pixelArraySize[] = {
211 static_cast<int32_t>(maxPreviewResolution_.width_), static_cast<int32_t>(maxPreviewResolution_.height_)
212 };
213 AddAbilityEntry(OHOS_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize,
214 (sizeof(pixelArraySize) / sizeof(pixelArraySize[0])));
215
216 const int32_t jpegThumbnailSizes[] = {0, 0, DEGREE_240, DEGREE_180};
217 AddAbilityEntry(OHOS_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes,
218 (sizeof(jpegThumbnailSizes) / sizeof(jpegThumbnailSizes[0])));
219
220 return SUCCESS;
221 }
222
InitDCameraOutputAbilityKeys(const std::string & abilityInfo)223 DCamRetCode DMetadataProcessor::InitDCameraOutputAbilityKeys(const std::string &abilityInfo)
224 {
225 std::map<int, std::vector<DCResolution>> supportedFormats = GetDCameraSupportedFormats(abilityInfo);
226
227 std::vector<int32_t> streamConfigurations;
228 std::map<int, std::vector<DCResolution>>::iterator iter;
229 for (iter = supportedFormats.begin(); iter != supportedFormats.end(); ++iter) {
230 std::vector<DCResolution> resolutionList = iter->second;
231 for (auto resolution : resolutionList) {
232 DHLOGI("DMetadataProcessor::supported formats: { format=%d, width=%d, height=%d }", iter->first,
233 resolution.width_, resolution.height_);
234 streamConfigurations.push_back(iter->first);
235 streamConfigurations.push_back(resolution.width_);
236 streamConfigurations.push_back(resolution.height_);
237 }
238 }
239 UpdateAbilityEntry(OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, streamConfigurations.data(),
240 streamConfigurations.size());
241
242 UpdateAbilityEntry(OHOS_SENSOR_INFO_MAX_FRAME_DURATION, &MAX_FRAME_DURATION, 1);
243
244 const int32_t jpegMaxSize = maxPhotoResolution_.width_ * maxPhotoResolution_.height_;
245 UpdateAbilityEntry(OHOS_JPEG_MAX_SIZE, &jpegMaxSize, 1);
246
247 const uint8_t connectionType = OHOS_CAMERA_CONNECTION_TYPE_REMOTE;
248 UpdateAbilityEntry(OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &connectionType, 1);
249
250 return SUCCESS;
251 }
252
AddAbilityEntry(uint32_t tag,const void * data,size_t size)253 DCamRetCode DMetadataProcessor::AddAbilityEntry(uint32_t tag, const void *data, size_t size)
254 {
255 if (dCameraAbility_ == nullptr) {
256 DHLOGE("Distributed camera abilily is null.");
257 return DCamRetCode::INVALID_ARGUMENT;
258 }
259
260 camera_metadata_item_t item;
261 int ret = OHOS::Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item);
262 if (ret) {
263 if (!dCameraAbility_->addEntry(tag, data, size)) {
264 DHLOGE("Add tag %u failed.", tag);
265 return FAILED;
266 }
267 }
268 return SUCCESS;
269 }
270
UpdateAbilityEntry(uint32_t tag,const void * data,size_t size)271 DCamRetCode DMetadataProcessor::UpdateAbilityEntry(uint32_t tag, const void *data, size_t size)
272 {
273 if (dCameraAbility_ == nullptr) {
274 DHLOGE("Distributed camera abilily is null.");
275 return DCamRetCode::INVALID_ARGUMENT;
276 }
277
278 camera_metadata_item_t item;
279 int ret = OHOS::Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item);
280 if (ret) {
281 if (!dCameraAbility_->addEntry(tag, data, size)) {
282 DHLOGE("Add tag %u failed.", tag);
283 return FAILED;
284 }
285 } else {
286 if (!dCameraAbility_->updateEntry(tag, data, size)) {
287 DHLOGE("Update tag %u failed.", tag);
288 return FAILED;
289 }
290 }
291 return SUCCESS;
292 }
293
GetDCameraAbility(std::shared_ptr<CameraAbility> & ability)294 DCamRetCode DMetadataProcessor::GetDCameraAbility(std::shared_ptr<CameraAbility> &ability)
295 {
296 ability = dCameraAbility_;
297 return SUCCESS;
298 }
299
SetMetadataResultMode(const ResultCallbackMode & mode)300 DCamRetCode DMetadataProcessor::SetMetadataResultMode(const ResultCallbackMode &mode)
301 {
302 if (mode < ResultCallbackMode::PER_FRAME || mode > ResultCallbackMode::ON_CHANGED) {
303 DHLOGE("Invalid result callback mode.");
304 return DCamRetCode::INVALID_ARGUMENT;
305 }
306 metaResultMode_ = mode;
307 return SUCCESS;
308 }
309
GetEnabledMetadataResults(std::vector<MetaType> & results)310 DCamRetCode DMetadataProcessor::GetEnabledMetadataResults(std::vector<MetaType> &results)
311 {
312 auto iter = enabledResultSet_.begin();
313 while (iter != enabledResultSet_.end()) {
314 results.push_back(*iter);
315 iter++;
316 }
317 return SUCCESS;
318 }
319
EnableMetadataResult(const std::vector<MetaType> & results)320 DCamRetCode DMetadataProcessor::EnableMetadataResult(const std::vector<MetaType> &results)
321 {
322 if (results.size() == 0) {
323 DHLOGE("Enable metadata result list is empty.");
324 return SUCCESS;
325 }
326
327 for (size_t i = 0; i < results.size(); i++) {
328 auto iter = allResultSet_.find(results[i]);
329 if (iter != allResultSet_.end()) {
330 auto anoIter = enabledResultSet_.find(results[i]);
331 if (anoIter == enabledResultSet_.end()) {
332 enabledResultSet_.insert(results[i]);
333 }
334 } else {
335 DHLOGE("Cannot find match metatype.");
336 return SUCCESS;
337 }
338 }
339 return SUCCESS;
340 }
341
DisableMetadataResult(const std::vector<MetaType> & results)342 DCamRetCode DMetadataProcessor::DisableMetadataResult(const std::vector<MetaType> &results)
343 {
344 if (results.size() == 0) {
345 DHLOGE("Disable metadata result list is empty.");
346 return SUCCESS;
347 }
348
349 for (size_t i = 0; i < results.size(); i++) {
350 auto iter = allResultSet_.find(results[i]);
351 if (iter != allResultSet_.end()) {
352 auto anoIter = enabledResultSet_.find(results[i]);
353 if (anoIter != enabledResultSet_.end()) {
354 enabledResultSet_.erase(*iter);
355 }
356 } else {
357 DHLOGE("Cannot find match metatype.");
358 return SUCCESS;
359 }
360 }
361 return SUCCESS;
362 }
363
ResetEnableResults()364 DCamRetCode DMetadataProcessor::ResetEnableResults()
365 {
366 if (enabledResultSet_.size() < allResultSet_.size()) {
367 for (auto result : allResultSet_) {
368 enabledResultSet_.insert(result);
369 }
370 }
371 return SUCCESS;
372 }
373
UpdateResultMetadata(const uint64_t & resultTimestamp)374 void DMetadataProcessor::UpdateResultMetadata(const uint64_t &resultTimestamp)
375 {
376 DHLOGD("DMetadataProcessor::UpdateResultMetadata result callback mode: %d", metaResultMode_);
377 if (metaResultMode_ != ResultCallbackMode::PER_FRAME) {
378 return;
379 }
380
381 std::lock_guard<std::mutex> autoLock(producerMutex_);
382 if (latestProducerMetadataResult_ == nullptr) {
383 DHLOGD("DMetadataProcessor::UpdateResultMetadata latest producer metadata result is null");
384 return;
385 }
386
387 UpdateAllResult(resultTimestamp);
388 }
389
SetResultCallback(std::function<void (uint64_t,std::shared_ptr<OHOS::Camera::CameraMetadata>)> & resultCbk)390 void DMetadataProcessor::SetResultCallback(
391 std::function<void(uint64_t, std::shared_ptr<OHOS::Camera::CameraMetadata>)> &resultCbk)
392 {
393 resultCallback_ = resultCbk;
394 }
395
UpdateAllResult(const uint64_t & resultTimestamp)396 void DMetadataProcessor::UpdateAllResult(const uint64_t &resultTimestamp)
397 {
398 uint32_t itemCap = OHOS::Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get());
399 uint32_t dataSize = OHOS::Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get());
400 DHLOGD("DMetadataProcessor::UpdateAllResult itemCapacity: %u, dataSize: %u", itemCap, dataSize);
401 std::shared_ptr<OHOS::Camera::CameraMetadata> result =
402 std::make_shared<OHOS::Camera::CameraMetadata>(itemCap, dataSize);
403 int32_t ret = OHOS::Camera::CopyCameraMetadataItems(result->get(), latestProducerMetadataResult_->get());
404 if (ret != CAM_META_SUCCESS) {
405 DHLOGE("DMetadataProcessor::UpdateAllResult copy metadata item failed, ret: %d", ret);
406 return;
407 }
408 resultCallback_(resultTimestamp, result);
409 }
410
UpdateOnChanged(const uint64_t & resultTimestamp)411 void DMetadataProcessor::UpdateOnChanged(const uint64_t &resultTimestamp)
412 {
413 bool needReturn = false;
414 uint32_t itemCap = OHOS::Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get());
415 uint32_t dataSize = OHOS::Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get());
416 DHLOGD("DMetadataProcessor::UpdateOnChanged itemCapacity: %u, dataSize: %u", itemCap, dataSize);
417 std::shared_ptr<OHOS::Camera::CameraMetadata> result =
418 std::make_shared<OHOS::Camera::CameraMetadata>(itemCap, dataSize);
419 DHLOGD("DMetadataProcessor::UpdateOnChanged enabledResultSet size: %d", enabledResultSet_.size());
420 for (auto tag : enabledResultSet_) {
421 DHLOGD("DMetadataProcessor::UpdateOnChanged cameta device metadata tag: %d", tag);
422 camera_metadata_item_t item;
423 camera_metadata_item_t anoItem;
424 int ret1 = OHOS::Camera::FindCameraMetadataItem(latestProducerMetadataResult_->get(), tag, &item);
425 int ret2 = OHOS::Camera::FindCameraMetadataItem(latestConsumerMetadataResult_->get(), tag, &anoItem);
426 DHLOGD("DMetadataProcessor::UpdateOnChanged find metadata item ret: %d, %d", ret1, ret2);
427 if (ret1 != CAM_META_SUCCESS) {
428 continue;
429 }
430
431 if (ret2 == CAM_META_SUCCESS) {
432 if ((item.count != anoItem.count) || (item.data_type != anoItem.data_type)) {
433 needReturn = true;
434 result->addEntry(tag, GetMetadataItemData(item), item.count);
435 continue;
436 }
437 uint32_t size = GetDataSize(item.data_type);
438 DHLOGD("DMetadataProcessor::UpdateOnChanged data size: %u", size);
439 for (uint32_t i = 0; i < (size * static_cast<uint32_t>(item.count)); i++) {
440 if (*(item.data.u8 + i) != *(anoItem.data.u8 + i)) {
441 needReturn = true;
442 result->addEntry(tag, GetMetadataItemData(item), item.count);
443 break;
444 }
445 }
446 } else {
447 needReturn = true;
448 result->addEntry(tag, GetMetadataItemData(item), item.count);
449 continue;
450 }
451 }
452
453 if (needReturn) {
454 resultCallback_(resultTimestamp, result);
455 }
456 }
457
SaveResultMetadata(std::string resultStr)458 DCamRetCode DMetadataProcessor::SaveResultMetadata(std::string resultStr)
459 {
460 if (resultStr.empty()) {
461 DHLOGE("Input result string is null.");
462 return DCamRetCode::INVALID_ARGUMENT;
463 }
464
465 std::string metadataStr = Base64Decode(resultStr);
466 std::lock_guard<std::mutex> autoLock(producerMutex_);
467 latestConsumerMetadataResult_ = latestProducerMetadataResult_;
468 latestProducerMetadataResult_ = OHOS::Camera::MetadataUtils::DecodeFromString(metadataStr);
469 if (latestProducerMetadataResult_ == nullptr) {
470 DHLOGE("Failed to decode metadata setting from string.");
471 return DCamRetCode::INVALID_ARGUMENT;
472 }
473
474 if (!OHOS::Camera::GetCameraMetadataItemCount(latestProducerMetadataResult_->get())) {
475 DHLOGE("Input result metadata item is empty.");
476 return DCamRetCode::INVALID_ARGUMENT;
477 }
478
479 DHLOGD("DMetadataProcessor::SaveResultMetadata result callback mode: %d", metaResultMode_);
480 if (metaResultMode_ != ResultCallbackMode::ON_CHANGED) {
481 return SUCCESS;
482 }
483
484 uint64_t resultTimestamp = GetCurrentLocalTimeStamp();
485 if (latestConsumerMetadataResult_ == nullptr) {
486 UpdateAllResult(resultTimestamp);
487 return SUCCESS;
488 }
489
490 camera_metadata_item_entry_t* itemEntry = OHOS::Camera::GetMetadataItems(latestProducerMetadataResult_->get());
491 uint32_t count = latestProducerMetadataResult_->get()->item_count;
492 for (uint32_t i = 0; i < count; i++, itemEntry++) {
493 enabledResultSet_.insert((MetaType)(itemEntry->item));
494 }
495 UpdateOnChanged(resultTimestamp);
496 return SUCCESS;
497 }
498
ConvertToCameraMetadata(common_metadata_header_t * & input,std::shared_ptr<OHOS::Camera::CameraMetadata> & output)499 void DMetadataProcessor::ConvertToCameraMetadata(common_metadata_header_t *&input,
500 std::shared_ptr<OHOS::Camera::CameraMetadata> &output)
501 {
502 auto ret = OHOS::Camera::CopyCameraMetadataItems(output->get(), input);
503 if (ret != CAM_META_SUCCESS) {
504 DHLOGE("Failed to copy the old metadata to new metadata.");
505 output = nullptr;
506 }
507 }
508
ResizeMetadataHeader(common_metadata_header_t * & header,uint32_t itemCapacity,uint32_t dataCapacity)509 void DMetadataProcessor::ResizeMetadataHeader(common_metadata_header_t *&header,
510 uint32_t itemCapacity, uint32_t dataCapacity)
511 {
512 if (header) {
513 OHOS::Camera::FreeCameraMetadataBuffer(header);
514 }
515 header = OHOS::Camera::AllocateCameraMetadataBuffer(itemCapacity, dataCapacity);
516 }
517
GetDataSize(uint32_t type)518 uint32_t DMetadataProcessor::GetDataSize(uint32_t type)
519 {
520 uint32_t size = 0;
521 if (type == META_TYPE_BYTE) {
522 size = sizeof(uint8_t);
523 } else if (type == META_TYPE_INT32) {
524 size = sizeof(int32_t);
525 } else if (type == META_TYPE_UINT32) {
526 size = sizeof(uint32_t);
527 } else if (type == META_TYPE_FLOAT) {
528 size = sizeof(float);
529 } else if (type == META_TYPE_INT64) {
530 size = sizeof(int64_t);
531 } else if (type == META_TYPE_DOUBLE) {
532 size = sizeof(double);
533 } else if (type == META_TYPE_RATIONAL) {
534 size = sizeof(camera_rational_t);
535 } else {
536 size = 0;
537 }
538 return size;
539 }
540
GetMetadataItemData(const camera_metadata_item_t & item)541 void* DMetadataProcessor::GetMetadataItemData(const camera_metadata_item_t &item)
542 {
543 switch (item.data_type) {
544 case META_TYPE_BYTE: {
545 return item.data.u8;
546 }
547 case META_TYPE_INT32: {
548 return item.data.i32;
549 }
550 case META_TYPE_UINT32: {
551 return item.data.ui32;
552 }
553 case META_TYPE_FLOAT: {
554 return item.data.f;
555 }
556 case META_TYPE_INT64: {
557 return item.data.i64;
558 }
559 case META_TYPE_DOUBLE: {
560 return item.data.d;
561 }
562 case META_TYPE_RATIONAL: {
563 return item.data.r;
564 }
565 default: {
566 DHLOGE("DMetadataProcessor::GetMetadataItemData invalid data type: %u", item.data_type);
567 return nullptr;
568 }
569 }
570 }
571
GetEachNodeSupportedResolution(std::vector<int> & formats,const std::string rootNode,std::map<int,std::vector<DCResolution>> & supportedFormats,Json::Value & rootValue)572 void DMetadataProcessor::GetEachNodeSupportedResolution(std::vector<int>& formats, const std::string rootNode,
573 std::map<int, std::vector<DCResolution>>& supportedFormats, Json::Value& rootValue)
574 {
575 for (const auto &format : formats) {
576 std::string formatStr = std::to_string(format);
577 if (!rootValue[rootNode].isMember("Resolution") || !rootValue[rootNode]["Resolution"].isMember(formatStr) ||
578 !rootValue[rootNode]["Resolution"][formatStr].isArray() ||
579 rootValue[rootNode]["Resolution"][formatStr].size() == 0 ||
580 rootValue[rootNode]["Resolution"][formatStr].size() > JSON_ARRAY_MAX_SIZE) {
581 DHLOGE("Resolution or %s error.", formatStr.c_str());
582 continue;
583 }
584 GetNodeSupportedResolution(format, formatStr, rootNode, supportedFormats, rootValue);
585 }
586 }
587
GetNodeSupportedResolution(int format,std::string formatStr,const std::string rootNode,std::map<int,std::vector<DCResolution>> & supportedFormats,Json::Value & rootValue)588 void DMetadataProcessor::GetNodeSupportedResolution(int format, std::string formatStr, const std::string rootNode,
589 std::map<int, std::vector<DCResolution>>& supportedFormats, Json::Value& rootValue)
590 {
591 std::vector<DCResolution> resolutionVec;
592 uint32_t size = rootValue[rootNode]["Resolution"][formatStr].size();
593 for (uint32_t i = 0; i < size; i++) {
594 if (!rootValue[rootNode]["Resolution"][formatStr][i].isString()) {
595 DHLOGE("Resolution %s %d ,is not string.", formatStr.c_str(), i);
596 continue;
597 }
598 std::string resoStr = rootValue[rootNode]["Resolution"][formatStr][i].asString();
599 std::vector<std::string> reso;
600 SplitString(resoStr, reso, STAR_SEPARATOR);
601 if (reso.size() != SIZE_FMT_LEN) {
602 continue;
603 }
604 uint32_t width = static_cast<uint32_t>(std::stoi(reso[0]));
605 uint32_t height = static_cast<uint32_t>(std::stoi(reso[1]));
606 if (height == 0 || width == 0 ||
607 ((rootNode == "Photo") &&
608 ((width * height) > (MAX_SUPPORT_PHOTO_WIDTH * MAX_SUPPORT_PHOTO_HEIGHT))) ||
609 ((rootNode != "Photo") &&
610 (width > MAX_SUPPORT_PREVIEW_WIDTH || height > MAX_SUPPORT_PREVIEW_HEIGHT))) {
611 continue;
612 }
613 DCResolution resolution(width, height);
614 resolutionVec.push_back(resolution);
615 }
616 if (!resolutionVec.empty()) {
617 std::sort(resolutionVec.begin(), resolutionVec.end());
618 supportedFormats[format] = resolutionVec;
619 if ((rootNode != "Photo") && (maxPreviewResolution_ < resolutionVec[0])) {
620 maxPreviewResolution_.width_ = resolutionVec[0].width_;
621 maxPreviewResolution_.height_ = resolutionVec[0].height_;
622 }
623 if ((rootNode == "Photo") && (maxPhotoResolution_ < resolutionVec[0])) {
624 maxPhotoResolution_.width_ = resolutionVec[0].width_;
625 maxPhotoResolution_.height_ = resolutionVec[0].height_;
626 }
627 }
628 }
629
GetDCameraSupportedFormats(const std::string & abilityInfo)630 std::map<int, std::vector<DCResolution>> DMetadataProcessor::GetDCameraSupportedFormats(const std::string &abilityInfo)
631 {
632 std::map<int, std::vector<DCResolution>> supportedFormats;
633 JSONCPP_STRING errs;
634 Json::CharReaderBuilder readerBuilder;
635 Json::Value rootValue;
636
637 std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
638 if (!jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) ||
639 !rootValue.isObject()) {
640 return supportedFormats;
641 }
642 ParsePhotoFormats(rootValue, supportedFormats);
643 ParsePreviewFormats(rootValue, supportedFormats);
644 ParseVideoFormats(rootValue, supportedFormats);
645 return supportedFormats;
646 }
647
ParsePhotoFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)648 void DMetadataProcessor::ParsePhotoFormats(Json::Value& rootValue,
649 std::map<int, std::vector<DCResolution>>& supportedFormats)
650 {
651 if (!rootValue.isMember("Photo") || !rootValue["Photo"].isMember("OutputFormat") ||
652 !rootValue["Photo"]["OutputFormat"].isArray() || rootValue["Photo"]["OutputFormat"].size() == 0 ||
653 rootValue["Photo"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
654 DHLOGE("Photo or photo output format error.");
655 return;
656 }
657 std::vector<int> photoFormats;
658 uint32_t size = rootValue["Photo"]["OutputFormat"].size();
659 for (uint32_t i = 0; i < size; i++) {
660 if ((rootValue["Photo"]["OutputFormat"][i]).isInt()) {
661 photoFormats.push_back((rootValue["Photo"]["OutputFormat"][i]).asInt());
662 }
663 }
664 GetEachNodeSupportedResolution(photoFormats, "Photo", supportedFormats, rootValue);
665 }
666
ParsePreviewFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)667 void DMetadataProcessor::ParsePreviewFormats(Json::Value& rootValue,
668 std::map<int, std::vector<DCResolution>>& supportedFormats)
669 {
670 if (!rootValue.isMember("Preview") || !rootValue["Preview"].isMember("OutputFormat") ||
671 !rootValue["Preview"]["OutputFormat"].isArray() || rootValue["Preview"]["OutputFormat"].size() == 0 ||
672 rootValue["Preview"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
673 DHLOGE("Preview or preview output format error.");
674 return;
675 }
676 std::vector<int> previewFormats;
677 uint32_t size = rootValue["Preview"]["OutputFormat"].size();
678 for (uint32_t i = 0; i < size; i++) {
679 if ((rootValue["Preview"]["OutputFormat"][i]).isInt()) {
680 previewFormats.push_back((rootValue["Preview"]["OutputFormat"][i]).asInt());
681 }
682 }
683 GetEachNodeSupportedResolution(previewFormats, "Preview", supportedFormats, rootValue);
684 }
685
ParseVideoFormats(Json::Value & rootValue,std::map<int,std::vector<DCResolution>> & supportedFormats)686 void DMetadataProcessor::ParseVideoFormats(Json::Value& rootValue,
687 std::map<int, std::vector<DCResolution>>& supportedFormats)
688 {
689 if (!rootValue.isMember("Video") || !rootValue["Video"].isMember("OutputFormat") ||
690 !rootValue["Video"]["OutputFormat"].isArray() || rootValue["Video"]["OutputFormat"].size() == 0 ||
691 rootValue["Video"]["OutputFormat"].size() > JSON_ARRAY_MAX_SIZE) {
692 DHLOGE("Video or video output format error.");
693 return;
694 }
695 std::vector<int> videoFormats;
696 uint32_t size = rootValue["Video"]["OutputFormat"].size();
697 for (uint32_t i = 0; i < size; i++) {
698 if ((rootValue["Video"]["OutputFormat"][i]).isInt()) {
699 videoFormats.push_back((rootValue["Video"]["OutputFormat"][i]).asInt());
700 }
701 }
702 GetEachNodeSupportedResolution(videoFormats, "Video", supportedFormats, rootValue);
703 }
704
PrintDCameraMetadata(const common_metadata_header_t * metadata)705 void DMetadataProcessor::PrintDCameraMetadata(const common_metadata_header_t *metadata)
706 {
707 if (metadata == nullptr) {
708 DHLOGE("Failed to print metadata, input metadata is null.");
709 return;
710 }
711
712 uint32_t tagCount = OHOS::Camera::GetCameraMetadataItemCount(metadata);
713 DHLOGD("DMetadataProcessor::PrintDCameraMetadata, input metadata item count = %d.", tagCount);
714 for (uint32_t i = 0; i < tagCount; i++) {
715 camera_metadata_item_t item;
716 int ret = OHOS::Camera::GetCameraMetadataItem(metadata, i, &item);
717 if (ret != 0) {
718 continue;
719 }
720
721 const char *name = OHOS::Camera::GetCameraMetadataItemName(item.item);
722 if (item.data_type == META_TYPE_BYTE) {
723 for (size_t k = 0; k < item.count; k++) {
724 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint8_t)(item.data.u8[k]));
725 }
726 } else if (item.data_type == META_TYPE_INT32) {
727 for (size_t k = 0; k < item.count; k++) {
728 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (int32_t)(item.data.i32[k]));
729 }
730 } else if (item.data_type == META_TYPE_UINT32) {
731 for (size_t k = 0; k < item.count; k++) {
732 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint32_t)(item.data.ui32[k]));
733 }
734 } else if (item.data_type == META_TYPE_FLOAT) {
735 for (size_t k = 0; k < item.count; k++) {
736 DHLOGI("tag index:%d, name:%s, value:%f", item.index, name, (float)(item.data.f[k]));
737 }
738 } else if (item.data_type == META_TYPE_INT64) {
739 for (size_t k = 0; k < item.count; k++) {
740 DHLOGI("tag index:%d, name:%s, value:%lld", item.index, name, (long long)(item.data.i64[k]));
741 }
742 } else if (item.data_type == META_TYPE_DOUBLE) {
743 for (size_t k = 0; k < item.count; k++) {
744 DHLOGI("tag index:%d, name:%s, value:%lf", item.index, name, (double)(item.data.d[k]));
745 }
746 } else {
747 DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, *(item.data.r));
748 }
749 }
750 }
751 } // namespace DistributedHardware
752 } // namespace OHOS
753