1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sketch_wrapper.h"
17 
18 #include <cstdint>
19 #include <mutex>
20 
21 #include "abilities/sketch_ability.h"
22 #include "camera_device_ability_items.h"
23 #include "camera_log.h"
24 #include "camera_util.h"
25 #include "capture_scene_const.h"
26 #include "image_format.h"
27 #include "image_source.h"
28 #include "image_type.h"
29 #include "istream_repeat_callback.h"
30 #include "surface_type.h"
31 
32 namespace OHOS {
33 namespace CameraStandard {
34 constexpr uint32_t INVALID_MODE = 0xffffffff;
35 constexpr float INVALID_MODE_FLOAT = -1.0f;
36 constexpr float INVALID_ZOOM_RATIO = -1.0f;
37 constexpr float SKETCH_DIV = 100.0f;
38 std::mutex SketchWrapper::g_sketchReferenceFovRatioMutex_;
39 std::map<SceneFeaturesMode, std::vector<SketchReferenceFovRange>> SketchWrapper::g_sketchReferenceFovRatioMap_;
40 std::mutex SketchWrapper::g_sketchEnableRatioMutex_;
41 std::map<SceneFeaturesMode, float> SketchWrapper::g_sketchEnableRatioMap_;
42 
SketchWrapper(sptr<IStreamCommon> hostStream,const Size size)43 SketchWrapper::SketchWrapper(sptr<IStreamCommon> hostStream, const Size size)
44     : hostStream_(hostStream), sketchSize_(size)
45 {}
46 
Init(std::shared_ptr<OHOS::Camera::CameraMetadata> & deviceMetadata,const SceneFeaturesMode & sceneFeaturesMode)47 int32_t SketchWrapper::Init(
48     std::shared_ptr<OHOS::Camera::CameraMetadata>& deviceMetadata, const SceneFeaturesMode& sceneFeaturesMode)
49 {
50     sptr<IStreamCommon> hostStream = hostStream_.promote();
51     CHECK_ERROR_RETURN_RET(hostStream == nullptr, CAMERA_INVALID_STATE);
52     UpdateSketchStaticInfo(deviceMetadata);
53     sketchEnableRatio_ = GetSketchEnableRatio(sceneFeaturesMode);
54         SceneFeaturesMode dumpSceneFeaturesMode = sceneFeaturesMode;
55         MEDIA_DEBUG_LOG("SketchWrapper::Init sceneFeaturesMode:%{public}s, sketchEnableRatio_:%{public}f",
56             dumpSceneFeaturesMode.Dump().c_str(), sketchEnableRatio_);
57         IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
58         return repeatStream->ForkSketchStreamRepeat(
59             sketchSize_.width, sketchSize_.height, sketchStream_, sketchEnableRatio_);
60 }
61 
AttachSketchSurface(sptr<Surface> sketchSurface)62 int32_t SketchWrapper::AttachSketchSurface(sptr<Surface> sketchSurface)
63 {
64     CHECK_ERROR_RETURN_RET(sketchStream_ == nullptr, CAMERA_INVALID_STATE);
65     CHECK_ERROR_RETURN_RET(sketchSurface == nullptr, CAMERA_INVALID_ARG);
66     return sketchStream_->AddDeferredSurface(sketchSurface->GetProducer());
67 }
68 
UpdateSketchRatio(float sketchRatio)69 int32_t SketchWrapper::UpdateSketchRatio(float sketchRatio)
70 {
71     // SketchRatio value could be negative value
72     MEDIA_DEBUG_LOG("Enter Into SketchWrapper::UpdateSketchRatio");
73     CHECK_ERROR_RETURN_RET(sketchStream_ == nullptr, CAMERA_INVALID_STATE);
74     sptr<IStreamCommon> hostStream = hostStream_.promote();
75     CHECK_ERROR_RETURN_RET_LOG(hostStream == nullptr, CAMERA_INVALID_STATE,
76         "SketchWrapper::UpdateSketchRatio hostStream is null");
77     IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
78     int32_t ret = repeatStream->UpdateSketchRatio(sketchRatio);
79     if (ret == CAMERA_OK) {
80         sketchEnableRatio_ = sketchRatio;
81     }
82     AutoStream();
83     return ret;
84 }
85 
Destroy()86 int32_t SketchWrapper::Destroy()
87 {
88     if (sketchStream_ != nullptr) {
89         sketchStream_->Stop();
90         sketchStream_->Release();
91         sketchStream_ = nullptr;
92     }
93     sptr<IStreamCommon> hostStream = hostStream_.promote();
94     CHECK_ERROR_RETURN_RET(hostStream == nullptr, CAMERA_INVALID_STATE);
95     IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
96     return repeatStream->RemoveSketchStreamRepeat();
97 }
98 
~SketchWrapper()99 SketchWrapper::~SketchWrapper()
100 {
101     Destroy();
102 }
103 
StartSketchStream()104 int32_t SketchWrapper::StartSketchStream()
105 {
106     if (sketchStream_ != nullptr) {
107         MEDIA_DEBUG_LOG("Enter Into SketchWrapper::SketchWrapper::StartSketchStream");
108         int retCode = sketchStream_->Start();
109         return retCode;
110     }
111     return CAMERA_UNKNOWN_ERROR;
112 }
113 
StopSketchStream()114 int32_t SketchWrapper::StopSketchStream()
115 {
116     if (sketchStream_ != nullptr) {
117         MEDIA_DEBUG_LOG("Enter Into SketchWrapper::SketchWrapper::StopSketchStream");
118         int retCode = sketchStream_->Stop();
119         return retCode;
120     }
121     return CAMERA_UNKNOWN_ERROR;
122 }
123 
SetPreviewStateCallback(std::shared_ptr<PreviewStateCallback> callback)124 void SketchWrapper::SetPreviewStateCallback(std::shared_ptr<PreviewStateCallback> callback)
125 {
126     previewStateCallback_ = callback;
127 }
128 
OnSketchStatusChanged(const SceneFeaturesMode & sceneFeaturesMode)129 void SketchWrapper::OnSketchStatusChanged(const SceneFeaturesMode& sceneFeaturesMode)
130 {
131     auto callback = previewStateCallback_.lock();
132     CHECK_ERROR_RETURN(callback == nullptr);
133     float sketchReferenceRatio = GetSketchReferenceFovRatio(sceneFeaturesMode, currentZoomRatio_);
134     std::lock_guard<std::mutex> lock(sketchStatusChangeMutex_);
135     if (currentSketchStatusData_.sketchRatio != sketchReferenceRatio) {
136         SketchStatusData statusData;
137         statusData.status = currentSketchStatusData_.status;
138         statusData.sketchRatio = sketchReferenceRatio;
139         MEDIA_DEBUG_LOG("SketchWrapper::OnSketchStatusDataChanged-:%{public}d->%{public}d,%{public}f->%{public}f",
140             currentSketchStatusData_.status, statusData.status, currentSketchStatusData_.sketchRatio,
141             statusData.sketchRatio);
142         currentSketchStatusData_ = statusData;
143         callback->OnSketchStatusDataChanged(currentSketchStatusData_);
144     }
145 }
146 
OnSketchStatusChanged(SketchStatus sketchStatus,const SceneFeaturesMode & sceneFeaturesMode)147 void SketchWrapper::OnSketchStatusChanged(SketchStatus sketchStatus, const SceneFeaturesMode& sceneFeaturesMode)
148 {
149     auto callback = previewStateCallback_.lock();
150     CHECK_ERROR_RETURN(callback == nullptr);
151     float sketchReferenceRatio = GetSketchReferenceFovRatio(sceneFeaturesMode, currentZoomRatio_);
152     std::lock_guard<std::mutex> lock(sketchStatusChangeMutex_);
153     if (currentSketchStatusData_.status != sketchStatus ||
154         currentSketchStatusData_.sketchRatio != sketchReferenceRatio) {
155         SketchStatusData statusData;
156         statusData.status = sketchStatus;
157         statusData.sketchRatio = sketchReferenceRatio;
158         MEDIA_DEBUG_LOG("SketchWrapper::OnSketchStatusDataChanged:%{public}d->%{public}d,%{public}f->%{public}f",
159             currentSketchStatusData_.status, statusData.status, currentSketchStatusData_.sketchRatio,
160             statusData.sketchRatio);
161         currentSketchStatusData_ = statusData;
162         callback->OnSketchStatusDataChanged(currentSketchStatusData_);
163     }
164 }
165 
UpdateSketchStaticInfo(std::shared_ptr<Camera::CameraMetadata> deviceMetadata)166 void SketchWrapper::UpdateSketchStaticInfo(std::shared_ptr<Camera::CameraMetadata> deviceMetadata)
167 {
168     {
169         std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
170         g_sketchEnableRatioMap_.clear();
171     }
172     {
173         std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
174         g_sketchReferenceFovRatioMap_.clear();
175     }
176     UpdateSketchEnableRatio(deviceMetadata);
177     UpdateSketchReferenceFovRatio(deviceMetadata);
178     UpdateSketchConfigFromMoonCaptureBoostConfig(deviceMetadata);
179 }
180 
GetSceneFeaturesModeFromModeData(float modeFloatData)181 SceneFeaturesMode SketchWrapper::GetSceneFeaturesModeFromModeData(float modeFloatData)
182 {
183     SceneFeaturesMode currentSceneFeaturesMode {};
184     auto sceneMode = static_cast<SceneMode>(round(modeFloatData));
185     currentSceneFeaturesMode.SetSceneMode(sceneMode);
186     return currentSceneFeaturesMode;
187 }
188 
UpdateSketchEnableRatio(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)189 void SketchWrapper::UpdateSketchEnableRatio(std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
190 {
191     CHECK_ERROR_RETURN_LOG(deviceMetadata == nullptr, "SketchWrapper::UpdateSketchEnableRatio deviceMetadata is null");
192     camera_metadata_item_t item;
193     int ret = OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_SKETCH_ENABLE_RATIO, &item);
194     CHECK_ERROR_RETURN_LOG(ret != CAM_META_SUCCESS,
195         "SketchWrapper::UpdateSketchEnableRatio get sketch enable ratio failed");
196     CHECK_ERROR_RETURN_LOG(item.count <= 0, "SketchWrapper::UpdateSketchEnableRatio sketch enable ratio count <= 0");
197 
198     constexpr int32_t dataGroupSize = 2; // 2 data as a group: key,value
199     constexpr int32_t valueOffset = 1;   // 1 is value offset
200     uint32_t groupCount = item.count / dataGroupSize;
201     float* dataEntry = item.data.f;
202     for (uint32_t i = 0; i < groupCount; i++) {
203         float key = dataEntry[i * dataGroupSize];
204         float value = dataEntry[i * dataGroupSize + valueOffset];
205         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchEnableRatio get sketch enable ratio "
206                         "%{public}f:%{public}f",
207             key, value);
208         auto sceneFeaturesMode = GetSceneFeaturesModeFromModeData(key);
209         InsertSketchEnableRatioMapValue(sceneFeaturesMode, value);
210     }
211 }
212 
InsertSketchReferenceFovRatioMapValue(SceneFeaturesMode & sceneFeaturesMode,SketchReferenceFovRange & sketchReferenceFovRange)213 void SketchWrapper::InsertSketchReferenceFovRatioMapValue(
214     SceneFeaturesMode& sceneFeaturesMode, SketchReferenceFovRange& sketchReferenceFovRange)
215 {
216     std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
217     auto it = g_sketchReferenceFovRatioMap_.find(sceneFeaturesMode);
218     std::vector<SketchReferenceFovRange> rangeFov;
219     if (it != g_sketchReferenceFovRatioMap_.end()) {
220         rangeFov = std::move(it->second);
221     }
222     rangeFov.emplace_back(sketchReferenceFovRange);
223     if (sceneFeaturesMode.GetSceneMode() == CAPTURE && sceneFeaturesMode.GetFeatures().empty()) {
224         g_sketchReferenceFovRatioMap_[{ CAPTURE, { FEATURE_TRIPOD_DETECTION } }] = rangeFov;
225     }
226     g_sketchReferenceFovRatioMap_[sceneFeaturesMode] = rangeFov;
227     if (sceneFeaturesMode.GetSceneMode() == CAPTURE_MACRO) {
228         g_sketchReferenceFovRatioMap_[{ CAPTURE, { FEATURE_MACRO } }] = rangeFov;
229         g_sketchReferenceFovRatioMap_[{ CAPTURE_MACRO, { FEATURE_MACRO } }] = rangeFov;
230     } else if (sceneFeaturesMode.GetSceneMode() == VIDEO_MACRO) {
231         g_sketchReferenceFovRatioMap_[{ VIDEO, { FEATURE_MACRO } }] = rangeFov;
232         g_sketchReferenceFovRatioMap_[{ VIDEO_MACRO, { FEATURE_MACRO } }] = rangeFov;
233     }
234 }
235 
InsertSketchEnableRatioMapValue(SceneFeaturesMode & sceneFeaturesMode,float ratioValue)236 void SketchWrapper::InsertSketchEnableRatioMapValue(SceneFeaturesMode& sceneFeaturesMode, float ratioValue)
237 {
238     MEDIA_DEBUG_LOG("SketchWrapper::InsertSketchEnableRatioMapValue %{public}s : %{public}f",
239         sceneFeaturesMode.Dump().c_str(), ratioValue);
240     std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
241     if (sceneFeaturesMode.GetSceneMode() == CAPTURE && sceneFeaturesMode.GetFeatures().empty()) {
242         g_sketchEnableRatioMap_[{ CAPTURE, { FEATURE_TRIPOD_DETECTION } }] = ratioValue;
243     }
244     g_sketchEnableRatioMap_[sceneFeaturesMode] = ratioValue;
245     if (sceneFeaturesMode.GetSceneMode() == CAPTURE_MACRO) {
246         g_sketchEnableRatioMap_[{ CAPTURE, { FEATURE_MACRO } }] = ratioValue;
247         g_sketchEnableRatioMap_[{ CAPTURE_MACRO, { FEATURE_MACRO } }] = ratioValue;
248     } else if (sceneFeaturesMode.GetSceneMode() == VIDEO_MACRO) {
249         g_sketchEnableRatioMap_[{ VIDEO, { FEATURE_MACRO } }] = ratioValue;
250         g_sketchEnableRatioMap_[{ VIDEO_MACRO, { FEATURE_MACRO } }] = ratioValue;
251     }
252 }
253 
UpdateSketchReferenceFovRatio(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)254 void SketchWrapper::UpdateSketchReferenceFovRatio(std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
255 {
256     CHECK_ERROR_RETURN_LOG(deviceMetadata == nullptr,
257         "SketchWrapper::UpdateSketchReferenceFovRatio deviceMetadata is null");
258     camera_metadata_item_t item;
259     int ret =
260         OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_SKETCH_REFERENCE_FOV_RATIO, &item);
261     CHECK_ERROR_RETURN_LOG(ret != CAM_META_SUCCESS || item.count <= 0,
262         "SketchWrapper::UpdateSketchReferenceFovRatio get sketch reference fov ratio failed");
263     UpdateSketchReferenceFovRatio(item);
264 }
265 
UpdateSketchReferenceFovRatio(camera_metadata_item_t & metadataItem)266 void SketchWrapper::UpdateSketchReferenceFovRatio(camera_metadata_item_t& metadataItem)
267 {
268     uint32_t dataCount = metadataItem.count;
269     float currentMode = INVALID_MODE_FLOAT;
270     float currentMinRatio = INVALID_ZOOM_RATIO;
271     float currentMaxRatio = INVALID_ZOOM_RATIO;
272     SceneFeaturesMode currentSceneFeaturesMode;
273     for (uint32_t i = 0; i < dataCount; i++) {
274         if (currentMode == INVALID_MODE_FLOAT) {
275             currentMode = metadataItem.data.f[i];
276             currentSceneFeaturesMode = GetSceneFeaturesModeFromModeData(metadataItem.data.f[i]);
277             continue;
278         }
279         if (currentMinRatio == INVALID_ZOOM_RATIO) {
280             currentMinRatio = metadataItem.data.f[i];
281             continue;
282         }
283         if (currentMaxRatio == INVALID_ZOOM_RATIO) {
284             currentMaxRatio = metadataItem.data.f[i];
285             continue;
286         }
287         SketchReferenceFovRange fovRange;
288         fovRange.zoomMin = metadataItem.data.f[i];
289         fovRange.zoomMax = metadataItem.data.f[i + 1];        // Offset 1 data
290         fovRange.referenceValue = metadataItem.data.f[i + 2]; // Offset 2 data
291         i = i + 2;                                            // Offset 2 data
292         InsertSketchReferenceFovRatioMapValue(currentSceneFeaturesMode, fovRange);
293         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchReferenceFovRatio get sketch reference fov ratio:mode->%{public}f "
294                         "%{public}f-%{public}f value->%{public}f",
295             currentMode, fovRange.zoomMin, fovRange.zoomMax, fovRange.referenceValue);
296         if (fovRange.zoomMax - currentMaxRatio >= -std::numeric_limits<float>::epsilon()) {
297             currentMode = INVALID_MODE_FLOAT;
298             currentMinRatio = INVALID_ZOOM_RATIO;
299             currentMaxRatio = INVALID_ZOOM_RATIO;
300         }
301     }
302 }
303 
GetMoonCaptureBoostAbilityItem(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata,camera_metadata_item_t & metadataItem)304 bool SketchWrapper::GetMoonCaptureBoostAbilityItem(
305     std::shared_ptr<Camera::CameraMetadata>& deviceMetadata, camera_metadata_item_t& metadataItem)
306 {
307     CHECK_ERROR_RETURN_RET_LOG(deviceMetadata == nullptr, false,
308         "SketchWrapper::GetMoonCaptureBoostAbilityItem deviceMetadata is null");
309     int ret =
310         OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_MOON_CAPTURE_BOOST, &metadataItem);
311     CHECK_ERROR_RETURN_RET_LOG(ret != CAM_META_SUCCESS || metadataItem.count <= 0, false,
312         "SketchWrapper::GetMoonCaptureBoostAbilityItem get OHOS_ABILITY_MOON_CAPTURE_BOOST failed");
313     return true;
314 }
315 
UpdateSketchConfigFromMoonCaptureBoostConfig(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)316 void SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig(
317     std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
318 {
319     camera_metadata_item_t item;
320     if (!GetMoonCaptureBoostAbilityItem(deviceMetadata, item)) {
321         MEDIA_ERR_LOG(
322             "SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig get GetMoonCaptureBoostAbilityItem failed");
323         return;
324     }
325     uint32_t currentMode = INVALID_MODE;
326     float currentMinRatio = INVALID_ZOOM_RATIO;
327     float currentMaxRatio = INVALID_ZOOM_RATIO;
328     SceneFeaturesMode currentSceneFeaturesMode;
329     for (uint32_t i = 0; i < item.count; i++) {
330         if (currentMode == INVALID_MODE) {
331             currentMode = static_cast<SceneMode>(item.data.ui32[i]);
332             currentSceneFeaturesMode =
333                 SceneFeaturesMode(static_cast<SceneMode>(currentMode), { FEATURE_MOON_CAPTURE_BOOST });
334             continue;
335         }
336         if (currentMinRatio == INVALID_ZOOM_RATIO) {
337             currentMinRatio = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
338             continue;
339         }
340         if (currentMaxRatio == INVALID_ZOOM_RATIO) {
341             currentMaxRatio = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
342             continue;
343         }
344         SketchReferenceFovRange fovRange;
345         fovRange.zoomMin = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
346         fovRange.zoomMax = static_cast<float>(item.data.ui32[i + 1]) / SKETCH_DIV;        // Offset 1 data
347         fovRange.referenceValue = static_cast<float>(item.data.ui32[i + 2]) / SKETCH_DIV; // Offset 2 data
348         i = i + 2;                                                                        // Offset 2 data
349         InsertSketchReferenceFovRatioMapValue(currentSceneFeaturesMode, fovRange);
350         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig get sketch reference fov "
351                         "ratio:mode->%{public}d %{public}f-%{public}f value->%{public}f",
352             currentMode, fovRange.zoomMin, fovRange.zoomMax, fovRange.referenceValue);
353         if (fovRange.zoomMax - currentMaxRatio >= -std::numeric_limits<float>::epsilon()) {
354             InsertSketchEnableRatioMapValue(currentSceneFeaturesMode, currentMinRatio);
355             currentMode = INVALID_MODE;
356             currentMinRatio = INVALID_ZOOM_RATIO;
357             currentMaxRatio = INVALID_ZOOM_RATIO;
358         }
359     }
360 }
361 
GetSketchReferenceFovRatio(const SceneFeaturesMode & sceneFeaturesMode,float zoomRatio)362 float SketchWrapper::GetSketchReferenceFovRatio(const SceneFeaturesMode& sceneFeaturesMode, float zoomRatio)
363 {
364     float currentZoomRatio = zoomRatio;
365     SceneFeaturesMode filteredFeaturesMode = sceneFeaturesMode;
366     for (int32_t i = SceneFeature::FEATURE_ENUM_MIN; i < SceneFeature::FEATURE_ENUM_MAX; i++) {
367         if (i == SceneFeature::FEATURE_MACRO || i == SceneFeature::FEATURE_MOON_CAPTURE_BOOST) {
368             continue;
369         }
370         filteredFeaturesMode.SwitchFeature(static_cast<SceneFeature>(i), false);
371     }
372     std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
373     auto it = g_sketchReferenceFovRatioMap_.find(filteredFeaturesMode);
374     if (it != g_sketchReferenceFovRatioMap_.end()) {
375         if (it->second.size() == 1) { // only 1 element, just return result;
376             return it->second[0].referenceValue;
377         }
378         // If zoom ratio out of range, try return min or max range value.
379         const auto& minRange = it->second.front();
380         if (currentZoomRatio - minRange.zoomMin <= std::numeric_limits<float>::epsilon()) {
381             return minRange.referenceValue;
382         }
383         const auto& maxRange = it->second.back();
384         if (currentZoomRatio - maxRange.zoomMax >= -std::numeric_limits<float>::epsilon()) {
385             return maxRange.referenceValue;
386         }
387         auto itRange = std::find_if(it->second.begin(), it->second.end(), [currentZoomRatio](const auto& range) {
388             return currentZoomRatio - range.zoomMin >= -std::numeric_limits<float>::epsilon() &&
389                    currentZoomRatio - range.zoomMax < -std::numeric_limits<float>::epsilon();
390         });
391         if (itRange != it->second.end()) {
392             return itRange->referenceValue;
393         }
394     }
395     return INVALID_ZOOM_RATIO;
396 }
397 
GetSketchEnableRatio(const SceneFeaturesMode & sceneFeaturesMode)398 float SketchWrapper::GetSketchEnableRatio(const SceneFeaturesMode& sceneFeaturesMode)
399 {
400     SceneFeaturesMode filteredFeaturesMode = sceneFeaturesMode;
401     for (int32_t i = SceneFeature::FEATURE_ENUM_MIN; i < SceneFeature::FEATURE_ENUM_MAX; i++) {
402         if (i == SceneFeature::FEATURE_MACRO || i == SceneFeature::FEATURE_MOON_CAPTURE_BOOST) {
403             continue;
404         }
405         filteredFeaturesMode.SwitchFeature(static_cast<SceneFeature>(i), false);
406     }
407     std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
408     auto it = g_sketchEnableRatioMap_.find(filteredFeaturesMode);
409     if (it != g_sketchEnableRatioMap_.end()) {
410         return it->second;
411     }
412     return INVALID_ZOOM_RATIO;
413 }
414 
UpdateZoomRatio(float zoomRatio)415 void SketchWrapper::UpdateZoomRatio(float zoomRatio)
416 {
417     currentZoomRatio_ = zoomRatio;
418     AutoStream();
419 }
420 
AutoStream()421 void SketchWrapper::AutoStream()
422 {
423     if (currentZoomRatio_ > 0 && sketchEnableRatio_ > 0 &&
424         currentZoomRatio_ - sketchEnableRatio_ >= -std::numeric_limits<float>::epsilon()) {
425         StartSketchStream();
426     } else {
427         StopSketchStream();
428     }
429 }
430 
OnMetadataDispatch(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)431 int32_t SketchWrapper::OnMetadataDispatch(const SceneFeaturesMode& sceneFeaturesMode,
432     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
433 {
434     if (tag == OHOS_CONTROL_ZOOM_RATIO) {
435         MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get tag:OHOS_CONTROL_ZOOM_RATIO");
436         return OnMetadataChangedZoomRatio(sceneFeaturesMode, tag, metadataItem);
437     } else if (tag == OHOS_CONTROL_SMOOTH_ZOOM_RATIOS) {
438         MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get tag:OHOS_CONTROL_SMOOTH_ZOOM_RATIOS");
439         return OnMetadataChangedZoomRatio(sceneFeaturesMode, tag, metadataItem);
440     } else if (tag == OHOS_CONTROL_CAMERA_MACRO) {
441         return OnMetadataChangedMacro(sceneFeaturesMode, tag, metadataItem);
442     } else if (tag == OHOS_CONTROL_MOON_CAPTURE_BOOST) {
443         return OnMetadataChangedMoonCaptureBoost(sceneFeaturesMode, tag, metadataItem);
444     } else {
445         MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get unhandled tag:%{public}d", static_cast<int32_t>(tag));
446     }
447     return CAM_META_SUCCESS;
448 }
449 
OnMetadataChangedZoomRatio(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)450 int32_t SketchWrapper::OnMetadataChangedZoomRatio(const SceneFeaturesMode& sceneFeaturesMode,
451     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
452 {
453     float tagRatio = *metadataItem.data.f;
454     MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataChangedZoomRatio OHOS_CONTROL_ZOOM_RATIO >>> tagRatio:%{public}f -- "
455                     "sketchRatio:%{public}f",
456         tagRatio, sketchEnableRatio_);
457     UpdateZoomRatio(tagRatio);
458     OnSketchStatusChanged(sceneFeaturesMode);
459     return CAM_META_SUCCESS;
460 }
461 
OnMetadataChangedMacro(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)462 int32_t SketchWrapper::OnMetadataChangedMacro(const SceneFeaturesMode& sceneFeaturesMode,
463     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
464 {
465     float sketchRatio = GetSketchEnableRatio(sceneFeaturesMode);
466     float currentZoomRatio = currentZoomRatio_;
467     MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataChangedMacro OHOS_CONTROL_ZOOM_RATIO >>> currentZoomRatio:%{public}f -- "
468                     "sketchRatio:%{public}f",
469         currentZoomRatio, sketchRatio);
470     UpdateSketchRatio(sketchRatio);
471     OnSketchStatusChanged(sceneFeaturesMode);
472     return CAM_META_SUCCESS;
473 }
474 
OnMetadataChangedMoonCaptureBoost(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)475 int32_t SketchWrapper::OnMetadataChangedMoonCaptureBoost(const SceneFeaturesMode& sceneFeaturesMode,
476     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
477 {
478     float sketchRatio = GetSketchEnableRatio(sceneFeaturesMode);
479     float currentZoomRatio = currentZoomRatio_;
480     MEDIA_DEBUG_LOG(
481         "SketchWrapper::OnMetadataChangedMoonCaptureBoost OHOS_CONTROL_ZOOM_RATIO >>> currentZoomRatio:%{public}f -- "
482         "sketchRatio:%{public}f",
483         currentZoomRatio, sketchRatio);
484     UpdateSketchRatio(sketchRatio);
485     OnSketchStatusChanged(sceneFeaturesMode);
486     return CAM_META_SUCCESS;
487 }
488 } // namespace CameraStandard
489 } // namespace OHOS