• 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 
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