• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "istream_repeat_callback.h"
27 
28 namespace OHOS {
29 namespace CameraStandard {
30 constexpr uint32_t INVALID_MODE = 0xffffffff;
31 constexpr float INVALID_MODE_FLOAT = -1.0f;
32 constexpr float INVALID_ZOOM_RATIO = -1.0f;
33 constexpr float SKETCH_DIV = 100.0f;
34 std::mutex SketchWrapper::g_sketchReferenceFovRatioMutex_;
35 std::map<SceneFeaturesMode, std::vector<SketchReferenceFovRange>> SketchWrapper::g_sketchReferenceFovRatioMap_;
36 std::mutex SketchWrapper::g_sketchEnableRatioMutex_;
37 std::map<SceneFeaturesMode, float> SketchWrapper::g_sketchEnableRatioMap_;
38 
SketchWrapper(wptr<IStreamCommon> hostStream,const Size size,bool isDynamicNotify)39 SketchWrapper::SketchWrapper(wptr<IStreamCommon> hostStream, const Size size, bool isDynamicNotify)
40     : hostStream_(hostStream), sketchSize_(size), isDynamicNotify_(isDynamicNotify)
41 {}
42 
Init(std::shared_ptr<OHOS::Camera::CameraMetadata> & deviceMetadata,const SceneFeaturesMode & sceneFeaturesMode)43 int32_t SketchWrapper::Init(
44     std::shared_ptr<OHOS::Camera::CameraMetadata>& deviceMetadata, const SceneFeaturesMode& sceneFeaturesMode)
45 {
46     sptr<IStreamCommon> hostStream = hostStream_.promote();
47     CHECK_RETURN_RET(hostStream == nullptr, CAMERA_INVALID_STATE);
48     if (!isDynamicNotify_) {
49         UpdateSketchStaticInfo(deviceMetadata);
50         sketchEnableRatio_ = GetSketchEnableRatio(sceneFeaturesMode);
51         SceneFeaturesMode dumpSceneFeaturesMode = sceneFeaturesMode;
52         MEDIA_DEBUG_LOG("SketchWrapper::Init sceneFeaturesMode:%{public}s, sketchEnableRatio_:%{public}f",
53             dumpSceneFeaturesMode.Dump().c_str(), sketchEnableRatio_);
54     }
55     IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
56     sptr<IRemoteObject> sketchSream = nullptr;
57     int32_t ret = repeatStream->ForkSketchStreamRepeat(
58         sketchSize_.width, sketchSize_.height, sketchSream, sketchEnableRatio_);
59     CHECK_EXECUTE(sketchSream != nullptr, sketchStream_ = iface_cast<IStreamRepeat>(sketchSream));
60     return ret;
61 }
62 
AttachSketchSurface(sptr<Surface> sketchSurface)63 int32_t SketchWrapper::AttachSketchSurface(sptr<Surface> sketchSurface)
64 {
65     CHECK_RETURN_RET(sketchStream_ == nullptr, CAMERA_INVALID_STATE);
66     CHECK_RETURN_RET(sketchSurface == nullptr, CAMERA_INVALID_ARG);
67     return sketchStream_->AddDeferredSurface(sketchSurface->GetProducer());
68 }
69 
UpdateSketchRatio(float sketchRatio)70 int32_t SketchWrapper::UpdateSketchRatio(float sketchRatio)
71 {
72     if (isDynamicNotify_) {
73         // Ignore update sketch ratio
74         return CAMERA_OK;
75     }
76     // SketchRatio value could be negative value
77     MEDIA_DEBUG_LOG("Enter Into SketchWrapper::UpdateSketchRatio");
78     CHECK_RETURN_RET(sketchStream_ == nullptr, CAMERA_INVALID_STATE);
79     sptr<IStreamCommon> hostStream = hostStream_.promote();
80     CHECK_RETURN_RET_ELOG(hostStream == nullptr, CAMERA_INVALID_STATE,
81         "SketchWrapper::UpdateSketchRatio hostStream is null");
82     IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
83     int32_t ret = repeatStream->UpdateSketchRatio(sketchRatio);
84     if (ret == CAMERA_OK) {
85         sketchEnableRatio_ = sketchRatio;
86     }
87     AutoStream();
88     return ret;
89 }
90 
Destroy()91 int32_t SketchWrapper::Destroy()
92 {
93     if (sketchStream_ != nullptr) {
94         sketchStream_->Stop();
95         sketchStream_->Release();
96         sketchStream_ = nullptr;
97     }
98     sptr<IStreamCommon> hostStream = hostStream_.promote();
99     CHECK_RETURN_RET(hostStream == nullptr, CAMERA_INVALID_STATE);
100     IStreamRepeat* repeatStream = static_cast<IStreamRepeat*>(hostStream.GetRefPtr());
101     return repeatStream->RemoveSketchStreamRepeat();
102 }
103 
~SketchWrapper()104 SketchWrapper::~SketchWrapper()
105 {
106     Destroy();
107 }
108 
StartSketchStream()109 int32_t SketchWrapper::StartSketchStream()
110 {
111     if (sketchStream_ != nullptr) {
112         MEDIA_DEBUG_LOG("Enter Into SketchWrapper::SketchWrapper::StartSketchStream");
113         int retCode = sketchStream_->Start();
114         return retCode;
115     }
116     return CAMERA_UNKNOWN_ERROR;
117 }
118 
StopSketchStream()119 int32_t SketchWrapper::StopSketchStream()
120 {
121     if (sketchStream_ != nullptr) {
122         MEDIA_DEBUG_LOG("Enter Into SketchWrapper::SketchWrapper::StopSketchStream");
123         int retCode = sketchStream_->Stop();
124         return retCode;
125     }
126     return CAMERA_UNKNOWN_ERROR;
127 }
128 
SetPreviewOutputCallbackManager(wptr<PreviewOutputListenerManager> previewOutputCallbackManager)129 void SketchWrapper::SetPreviewOutputCallbackManager(wptr<PreviewOutputListenerManager> previewOutputCallbackManager)
130 {
131     previewOutputCallbackManager_ = previewOutputCallbackManager;
132 }
133 
OnSketchStatusChanged(const SceneFeaturesMode & sceneFeaturesMode)134 void SketchWrapper::OnSketchStatusChanged(const SceneFeaturesMode& sceneFeaturesMode)
135 {
136     auto manager = previewOutputCallbackManager_.promote();
137     CHECK_RETURN(manager == nullptr);
138     // LCOV_EXCL_START
139     float sketchReferenceRatio = -1.0f;
140     if (isDynamicNotify_) {
141         sketchReferenceRatio = sketchDynamicReferenceRatio_;
142     } else {
143         sketchReferenceRatio = GetSketchReferenceFovRatio(sceneFeaturesMode, currentZoomRatio_);
144     }
145     std::lock_guard<std::mutex> lock(sketchStatusChangeMutex_);
146     if (currentSketchStatusData_.sketchRatio != sketchReferenceRatio ||
147         currentSketchStatusData_.offsetx != offset_.x ||
148         currentSketchStatusData_.offsety != offset_.y) {
149         SketchStatusData statusData;
150         statusData.status = currentSketchStatusData_.status;
151         statusData.sketchRatio = sketchReferenceRatio;
152         statusData.offsetx = offset_.x;
153         statusData.offsety = offset_.y;
154         MEDIA_DEBUG_LOG("SketchWrapper::OnSketchStatusDataChanged-:%{public}d->%{public}d,%{public}f->%{public}f"
155                         ", %{public}f->%{public}f, %{public}f->%{public}f",
156             currentSketchStatusData_.status, statusData.status, currentSketchStatusData_.sketchRatio,
157             statusData.sketchRatio, currentSketchStatusData_.offsetx, statusData.offsetx,
158             currentSketchStatusData_.offsety, statusData.offsety);
159         currentSketchStatusData_ = statusData;
160         manager->TriggerListener([&](PreviewStateCallback* previewStateCallback) {
161             previewStateCallback->OnSketchStatusDataChanged(currentSketchStatusData_);
162         });
163     }
164     // LCOV_EXCL_STOP
165 }
166 
OnSketchStatusChanged(SketchStatus sketchStatus,const SceneFeaturesMode & sceneFeaturesMode)167 void SketchWrapper::OnSketchStatusChanged(SketchStatus sketchStatus, const SceneFeaturesMode& sceneFeaturesMode)
168 {
169     auto manager = previewOutputCallbackManager_.promote();
170     CHECK_RETURN(manager == nullptr);
171     // LCOV_EXCL_START
172     float sketchReferenceRatio = -1.0f;
173     if (isDynamicNotify_) {
174         sketchReferenceRatio = sketchDynamicReferenceRatio_;
175     } else {
176         sketchReferenceRatio = GetSketchReferenceFovRatio(sceneFeaturesMode, currentZoomRatio_);
177     }
178     std::lock_guard<std::mutex> lock(sketchStatusChangeMutex_);
179     if (currentSketchStatusData_.status != sketchStatus ||
180         currentSketchStatusData_.sketchRatio != sketchReferenceRatio) {
181         SketchStatusData statusData;
182         statusData.status = sketchStatus;
183         statusData.sketchRatio = sketchReferenceRatio;
184         MEDIA_DEBUG_LOG("SketchWrapper::OnSketchStatusDataChanged:%{public}d->%{public}d,%{public}f->%{public}f",
185             currentSketchStatusData_.status, statusData.status, currentSketchStatusData_.sketchRatio,
186             statusData.sketchRatio);
187         currentSketchStatusData_ = statusData;
188         manager->TriggerListener([&](PreviewStateCallback* previewStateCallback) {
189             previewStateCallback->OnSketchStatusDataChanged(currentSketchStatusData_);
190         });
191     }
192     // LCOV_EXCL_STOP
193 }
194 
UpdateSketchStaticInfo(std::shared_ptr<Camera::CameraMetadata> deviceMetadata)195 void SketchWrapper::UpdateSketchStaticInfo(std::shared_ptr<Camera::CameraMetadata> deviceMetadata)
196 {
197     {
198         std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
199         g_sketchEnableRatioMap_.clear();
200     }
201     {
202         std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
203         g_sketchReferenceFovRatioMap_.clear();
204     }
205     UpdateSketchEnableRatio(deviceMetadata);
206     UpdateSketchReferenceFovRatio(deviceMetadata);
207     UpdateSketchConfigFromMoonCaptureBoostConfig(deviceMetadata);
208 }
209 
GetSceneFeaturesModeFromModeData(float modeFloatData)210 SceneFeaturesMode SketchWrapper::GetSceneFeaturesModeFromModeData(float modeFloatData)
211 {
212     SceneFeaturesMode currentSceneFeaturesMode {};
213     auto sceneMode = static_cast<SceneMode>(round(modeFloatData));
214     currentSceneFeaturesMode.SetSceneMode(sceneMode);
215     return currentSceneFeaturesMode;
216 }
217 
UpdateSketchEnableRatio(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)218 void SketchWrapper::UpdateSketchEnableRatio(std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
219 {
220     CHECK_RETURN_ELOG(deviceMetadata == nullptr, "SketchWrapper::UpdateSketchEnableRatio deviceMetadata is null");
221     camera_metadata_item_t item;
222     int ret = OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_SKETCH_ENABLE_RATIO, &item);
223     CHECK_RETURN_ELOG(ret != CAM_META_SUCCESS,
224         "SketchWrapper::UpdateSketchEnableRatio get sketch enable ratio failed");
225     // LCOV_EXCL_START
226     CHECK_RETURN_ELOG(item.count <= 0, "SketchWrapper::UpdateSketchEnableRatio sketch enable ratio count <= 0");
227 
228     constexpr int32_t dataGroupSize = 2; // 2 data as a group: key,value
229     constexpr int32_t valueOffset = 1;   // 1 is value offset
230     uint32_t groupCount = item.count / dataGroupSize;
231     float* dataEntry = item.data.f;
232     for (uint32_t i = 0; i < groupCount; i++) {
233         float key = dataEntry[i * dataGroupSize];
234         float value = dataEntry[i * dataGroupSize + valueOffset];
235         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchEnableRatio get sketch enable ratio "
236                         "%{public}f:%{public}f",
237             key, value);
238         auto sceneFeaturesMode = GetSceneFeaturesModeFromModeData(key);
239         InsertSketchEnableRatioMapValue(sceneFeaturesMode, value);
240     }
241     // LCOV_EXCL_STOP
242 }
243 
InsertSketchReferenceFovRatioMapValue(SceneFeaturesMode & sceneFeaturesMode,SketchReferenceFovRange & sketchReferenceFovRange)244 void SketchWrapper::InsertSketchReferenceFovRatioMapValue(
245     SceneFeaturesMode& sceneFeaturesMode, SketchReferenceFovRange& sketchReferenceFovRange)
246 {
247     std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
248     auto it = g_sketchReferenceFovRatioMap_.find(sceneFeaturesMode);
249     std::vector<SketchReferenceFovRange> rangeFov;
250     // LCOV_EXCL_START
251     if (it != g_sketchReferenceFovRatioMap_.end()) {
252         rangeFov = std::move(it->second);
253     }
254     rangeFov.emplace_back(sketchReferenceFovRange);
255     if (sceneFeaturesMode.GetSceneMode() == CAPTURE && sceneFeaturesMode.GetFeatures().empty()) {
256         g_sketchReferenceFovRatioMap_[{ CAPTURE, { FEATURE_TRIPOD_DETECTION } }] = rangeFov;
257     }
258     g_sketchReferenceFovRatioMap_[sceneFeaturesMode] = rangeFov;
259     if (sceneFeaturesMode.GetSceneMode() == CAPTURE_MACRO) {
260         g_sketchReferenceFovRatioMap_[{ CAPTURE, { FEATURE_MACRO } }] = rangeFov;
261         g_sketchReferenceFovRatioMap_[{ CAPTURE_MACRO, { FEATURE_MACRO } }] = rangeFov;
262     } else if (sceneFeaturesMode.GetSceneMode() == VIDEO_MACRO) {
263         g_sketchReferenceFovRatioMap_[{ VIDEO, { FEATURE_MACRO } }] = rangeFov;
264         g_sketchReferenceFovRatioMap_[{ VIDEO_MACRO, { FEATURE_MACRO } }] = rangeFov;
265     }
266     // LCOV_EXCL_STOP
267 }
268 
InsertSketchEnableRatioMapValue(SceneFeaturesMode & sceneFeaturesMode,float ratioValue)269 void SketchWrapper::InsertSketchEnableRatioMapValue(SceneFeaturesMode& sceneFeaturesMode, float ratioValue)
270 {
271     MEDIA_DEBUG_LOG("SketchWrapper::InsertSketchEnableRatioMapValue %{public}s : %{public}f",
272         sceneFeaturesMode.Dump().c_str(), ratioValue);
273     std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
274     // LCOV_EXCL_START
275     if (sceneFeaturesMode.GetSceneMode() == CAPTURE && sceneFeaturesMode.GetFeatures().empty()) {
276         g_sketchEnableRatioMap_[{ CAPTURE, { FEATURE_TRIPOD_DETECTION } }] = ratioValue;
277     }
278     g_sketchEnableRatioMap_[sceneFeaturesMode] = ratioValue;
279     if (sceneFeaturesMode.GetSceneMode() == CAPTURE_MACRO) {
280         g_sketchEnableRatioMap_[{ CAPTURE, { FEATURE_MACRO } }] = ratioValue;
281         g_sketchEnableRatioMap_[{ CAPTURE_MACRO, { FEATURE_MACRO } }] = ratioValue;
282     } else if (sceneFeaturesMode.GetSceneMode() == VIDEO_MACRO) {
283         g_sketchEnableRatioMap_[{ VIDEO, { FEATURE_MACRO } }] = ratioValue;
284         g_sketchEnableRatioMap_[{ VIDEO_MACRO, { FEATURE_MACRO } }] = ratioValue;
285     }
286     // LCOV_EXCL_STOP
287 }
288 
UpdateSketchReferenceFovRatio(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)289 void SketchWrapper::UpdateSketchReferenceFovRatio(std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
290 {
291     CHECK_RETURN_ELOG(deviceMetadata == nullptr,
292         "SketchWrapper::UpdateSketchReferenceFovRatio deviceMetadata is null");
293     camera_metadata_item_t item;
294     int ret =
295         OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_SKETCH_REFERENCE_FOV_RATIO, &item);
296     CHECK_RETURN_ELOG(ret != CAM_META_SUCCESS || item.count <= 0,
297         "SketchWrapper::UpdateSketchReferenceFovRatio get sketch reference fov ratio failed");
298     UpdateSketchReferenceFovRatio(item);
299 }
300 
UpdateSketchReferenceFovRatio(camera_metadata_item_t & metadataItem)301 void SketchWrapper::UpdateSketchReferenceFovRatio(camera_metadata_item_t& metadataItem)
302 {
303     uint32_t dataCount = metadataItem.count;
304     float currentMode = INVALID_MODE_FLOAT;
305     float currentMinRatio = INVALID_ZOOM_RATIO;
306     float currentMaxRatio = INVALID_ZOOM_RATIO;
307     SceneFeaturesMode currentSceneFeaturesMode;
308     // LCOV_EXCL_START
309     const int32_t MAX_OFFSET = 2;
310     for (uint32_t i = 0; i + MAX_OFFSET < dataCount; i++) {
311         if (currentMode == INVALID_MODE_FLOAT) {
312             currentMode = metadataItem.data.f[i];
313             currentSceneFeaturesMode = GetSceneFeaturesModeFromModeData(metadataItem.data.f[i]);
314             continue;
315         }
316         if (currentMinRatio == INVALID_ZOOM_RATIO) {
317             currentMinRatio = metadataItem.data.f[i];
318             continue;
319         }
320         if (currentMaxRatio == INVALID_ZOOM_RATIO) {
321             currentMaxRatio = metadataItem.data.f[i];
322             continue;
323         }
324         SketchReferenceFovRange fovRange;
325         fovRange.zoomMin = metadataItem.data.f[i];
326         fovRange.zoomMax = metadataItem.data.f[i + 1];        // Offset 1 data
327         fovRange.referenceValue = metadataItem.data.f[i + 2]; // Offset 2 data
328         i = i + 2;                                            // Offset 2 data
329         InsertSketchReferenceFovRatioMapValue(currentSceneFeaturesMode, fovRange);
330         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchReferenceFovRatio get sketch reference fov ratio:mode->%{public}f "
331                         "%{public}f-%{public}f value->%{public}f",
332             currentMode, fovRange.zoomMin, fovRange.zoomMax, fovRange.referenceValue);
333         if (fovRange.zoomMax - currentMaxRatio >= -std::numeric_limits<float>::epsilon()) {
334             currentMode = INVALID_MODE_FLOAT;
335             currentMinRatio = INVALID_ZOOM_RATIO;
336             currentMaxRatio = INVALID_ZOOM_RATIO;
337         }
338     }
339     // LCOV_EXCL_STOP
340 }
341 
GetMoonCaptureBoostAbilityItem(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata,camera_metadata_item_t & metadataItem)342 bool SketchWrapper::GetMoonCaptureBoostAbilityItem(
343     std::shared_ptr<Camera::CameraMetadata>& deviceMetadata, camera_metadata_item_t& metadataItem)
344 {
345     CHECK_RETURN_RET_ELOG(deviceMetadata == nullptr, false,
346         "SketchWrapper::GetMoonCaptureBoostAbilityItem deviceMetadata is null");
347     int ret =
348         OHOS::Camera::FindCameraMetadataItem(deviceMetadata->get(), OHOS_ABILITY_MOON_CAPTURE_BOOST, &metadataItem);
349     CHECK_RETURN_RET_ELOG(ret != CAM_META_SUCCESS || metadataItem.count <= 0, false,
350         "SketchWrapper::GetMoonCaptureBoostAbilityItem get OHOS_ABILITY_MOON_CAPTURE_BOOST failed");
351     return true;
352 }
353 
UpdateSketchConfigFromMoonCaptureBoostConfig(std::shared_ptr<Camera::CameraMetadata> & deviceMetadata)354 void SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig(
355     std::shared_ptr<Camera::CameraMetadata>& deviceMetadata)
356 {
357     camera_metadata_item_t item;
358     CHECK_RETURN_ELOG(!GetMoonCaptureBoostAbilityItem(deviceMetadata, item),
359         "SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig get GetMoonCaptureBoostAbilityItem failed");
360     // LCOV_EXCL_START
361     uint32_t currentMode = INVALID_MODE;
362     float currentMinRatio = INVALID_ZOOM_RATIO;
363     float currentMaxRatio = INVALID_ZOOM_RATIO;
364     SceneFeaturesMode currentSceneMode;
365     for (uint32_t i = 0; i < item.count; i++) {
366         if (currentMode == INVALID_MODE) {
367             currentMode = static_cast<SceneMode>(item.data.ui32[i]);
368             currentSceneMode =
369                 SceneFeaturesMode(static_cast<SceneMode>(currentMode), { FEATURE_MOON_CAPTURE_BOOST });
370             continue;
371         }
372         if (currentMinRatio == INVALID_ZOOM_RATIO) {
373             currentMinRatio = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
374             continue;
375         }
376         if (currentMaxRatio == INVALID_ZOOM_RATIO) {
377             currentMaxRatio = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
378             continue;
379         }
380         SketchReferenceFovRange fovRange;
381         fovRange.zoomMin = static_cast<float>(item.data.ui32[i]) / SKETCH_DIV;
382         fovRange.zoomMax = static_cast<float>(item.data.ui32[i + 1]) / SKETCH_DIV;        // Offset 1 data
383         fovRange.referenceValue = static_cast<float>(item.data.ui32[i + 2]) / SKETCH_DIV; // Offset 2 data
384         i = i + 2;                                                                        // Offset 2 data
385         InsertSketchReferenceFovRatioMapValue(currentSceneMode, fovRange);
386         MEDIA_DEBUG_LOG("SketchWrapper::UpdateSketchConfigFromMoonCaptureBoostConfig get sketch reference fov "
387                         "ratio:mode->%{public}d %{public}f-%{public}f value->%{public}f",
388             currentMode, fovRange.zoomMin, fovRange.zoomMax, fovRange.referenceValue);
389         if (fovRange.zoomMax - currentMaxRatio >= -std::numeric_limits<float>::epsilon()) {
390             InsertSketchEnableRatioMapValue(currentSceneMode, currentMinRatio);
391             currentMode = INVALID_MODE;
392             currentMinRatio = INVALID_ZOOM_RATIO;
393             currentMaxRatio = INVALID_ZOOM_RATIO;
394         }
395     }
396     // LCOV_EXCL_STOP
397 }
398 
GetSketchReferenceFovRatio(const SceneFeaturesMode & sceneFeaturesMode,float zoomRatio)399 float SketchWrapper::GetSketchReferenceFovRatio(const SceneFeaturesMode& sceneFeaturesMode, float zoomRatio)
400 {
401     float currentZoomRatio = zoomRatio;
402     SceneFeaturesMode filteredFeaturesMode = sceneFeaturesMode;
403     for (int32_t i = SceneFeature::FEATURE_ENUM_MIN; i < SceneFeature::FEATURE_ENUM_MAX; i++) {
404         if (i == SceneFeature::FEATURE_MACRO || i == SceneFeature::FEATURE_MOON_CAPTURE_BOOST) {
405             continue;
406         }
407         filteredFeaturesMode.SwitchFeature(static_cast<SceneFeature>(i), false);
408     }
409     std::lock_guard<std::mutex> lock(g_sketchReferenceFovRatioMutex_);
410     auto it = g_sketchReferenceFovRatioMap_.find(filteredFeaturesMode);
411     // LCOV_EXCL_START
412     if (it != g_sketchReferenceFovRatioMap_.end()) {
413         // only 1 element, just return result;
414         CHECK_RETURN_RET(it->second.size() == 1, it->second[0].referenceValue);
415         // If zoom ratio out of range, try return min or max range value.
416         const auto& minRange = it->second.front();
417         CHECK_RETURN_RET(currentZoomRatio - minRange.zoomMin <= std::numeric_limits<float>::epsilon(),
418             minRange.referenceValue);
419         const auto& maxRange = it->second.back();
420         CHECK_RETURN_RET(currentZoomRatio - maxRange.zoomMax >= -std::numeric_limits<float>::epsilon(),
421             maxRange.referenceValue);
422         auto itRange = std::find_if(it->second.begin(), it->second.end(), [currentZoomRatio](const auto& range) {
423             return currentZoomRatio - range.zoomMin >= -std::numeric_limits<float>::epsilon() &&
424                    currentZoomRatio - range.zoomMax < -std::numeric_limits<float>::epsilon();
425         });
426         CHECK_RETURN_RET(itRange != it->second.end(), itRange->referenceValue);
427     }
428     // LCOV_EXCL_STOP
429     return INVALID_ZOOM_RATIO;
430 }
431 
GetSketchEnableRatio(const SceneFeaturesMode & sceneFeaturesMode)432 float SketchWrapper::GetSketchEnableRatio(const SceneFeaturesMode& sceneFeaturesMode)
433 {
434     SceneFeaturesMode filteredFeaturesMode = sceneFeaturesMode;
435     for (int32_t i = SceneFeature::FEATURE_ENUM_MIN; i < SceneFeature::FEATURE_ENUM_MAX; i++) {
436         if (i == SceneFeature::FEATURE_MACRO || i == SceneFeature::FEATURE_MOON_CAPTURE_BOOST) {
437             continue;
438         }
439         filteredFeaturesMode.SwitchFeature(static_cast<SceneFeature>(i), false);
440     }
441     std::lock_guard<std::mutex> lock(g_sketchEnableRatioMutex_);
442     auto it = g_sketchEnableRatioMap_.find(filteredFeaturesMode);
443     CHECK_RETURN_RET(it != g_sketchEnableRatioMap_.end(), it->second);
444     return INVALID_ZOOM_RATIO;
445 }
446 
UpdateZoomRatio(float zoomRatio)447 void SketchWrapper::UpdateZoomRatio(float zoomRatio)
448 {
449     currentZoomRatio_ = zoomRatio;
450     AutoStream();
451 }
452 
AutoStream()453 void SketchWrapper::AutoStream()
454 {
455     if (currentZoomRatio_ > 0 && sketchEnableRatio_ > 0 &&
456         currentZoomRatio_ - sketchEnableRatio_ >= -std::numeric_limits<float>::epsilon()) {
457         StartSketchStream();
458     } else {
459         StopSketchStream();
460     }
461 }
462 
OnMetadataDispatch(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)463 int32_t SketchWrapper::OnMetadataDispatch(const SceneFeaturesMode& sceneFeaturesMode,
464     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
465 {
466     // LCOV_EXCL_START
467     if (isDynamicNotify_) {
468         if (tag == OHOS_STATUS_SKETCH_STREAM_INFO) {
469             MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get tag:OHOS_STATUS_SKETCH_STREAM_INFO");
470             return OnMetadataChangedSketchDynamicNotify(metadataItem, sceneFeaturesMode);
471         } else {
472             MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch isDynamicNotify_ get unhandled tag:%{public}d",
473                 static_cast<int32_t>(tag));
474         }
475     } else {
476         if (tag == OHOS_CONTROL_ZOOM_RATIO) {
477             MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get tag:OHOS_CONTROL_ZOOM_RATIO");
478             return OnMetadataChangedZoomRatio(sceneFeaturesMode, tag, metadataItem);
479         } else if (tag == OHOS_CONTROL_SMOOTH_ZOOM_RATIOS) {
480             MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataDispatch get tag:OHOS_CONTROL_SMOOTH_ZOOM_RATIOS");
481             return OnMetadataChangedZoomRatio(sceneFeaturesMode, tag, metadataItem);
482         } else if (tag == OHOS_CONTROL_CAMERA_MACRO) {
483             return OnMetadataChangedMacro(sceneFeaturesMode, tag, metadataItem);
484         } else if (tag == OHOS_CONTROL_MOON_CAPTURE_BOOST) {
485             return OnMetadataChangedMoonCaptureBoost(sceneFeaturesMode, tag, metadataItem);
486         } else {
487             MEDIA_DEBUG_LOG(
488                 "SketchWrapper::OnMetadataDispatch get unhandled tag:%{public}d", static_cast<int32_t>(tag));
489         }
490     }
491     return CAM_META_SUCCESS;
492     // LCOV_EXCL_STOP
493 }
494 
OnMetadataChangedSketchDynamicNotify(const camera_metadata_item_t & metadataItem,const SceneFeaturesMode & sceneFeaturesMode)495 int32_t SketchWrapper::OnMetadataChangedSketchDynamicNotify(
496     const camera_metadata_item_t& metadataItem, const SceneFeaturesMode& sceneFeaturesMode)
497 {
498     // LCOV_EXCL_START
499     uint32_t dataLen = metadataItem.count;
500     if (dataLen != 4) { // data size is 4 ==> [isNeedStartSketch, sketchZoomRatio, sketchPoint_x, sketchPoint_y]
501         MEDIA_INFO_LOG("SketchWrapper::OnMetadataChangedSketchDynamicNotify recv error data, size:%{public}d", dataLen);
502         return CAM_META_SUCCESS;
503     }
504     auto infoStatus = static_cast<SketchStreamInfoStatus>(metadataItem.data.f[0]);
505     sketchDynamicReferenceRatio_ = metadataItem.data.f[1];
506     offset_.x = metadataItem.data.f[2]; // 2 ==> sketchPoint_x
507     offset_.y = metadataItem.data.f[3]; // 3 ==> sketchPoint_y
508     MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataChangedSketchDynamicNotify infoStatus:%{public}d ratio:%{public}f"
509                     "offsetx:%{public}f offsety:%{public}f",
510         infoStatus, sketchDynamicReferenceRatio_, offset_.x, offset_.y);
511     if (infoStatus == OHOS_CAMERA_SKETCH_STREAM_SUPPORT) {
512         StartSketchStream();
513     } else if (infoStatus == OHOS_CAMERA_SKETCH_STREAM_UNSUPPORT) {
514         StopSketchStream();
515     }
516     OnSketchStatusChanged(sceneFeaturesMode);
517     return CAM_META_SUCCESS;
518     // LCOV_EXCL_STOP
519 }
520 
OnMetadataChangedZoomRatio(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)521 int32_t SketchWrapper::OnMetadataChangedZoomRatio(const SceneFeaturesMode& sceneFeaturesMode,
522     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
523 {
524     // LCOV_EXCL_START
525     float tagRatio = *metadataItem.data.f;
526     MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataChangedZoomRatio OHOS_CONTROL_ZOOM_RATIO >>> tagRatio:%{public}f -- "
527                     "sketchRatio:%{public}f",
528         tagRatio, sketchEnableRatio_);
529     UpdateZoomRatio(tagRatio);
530     OnSketchStatusChanged(sceneFeaturesMode);
531     return CAM_META_SUCCESS;
532     // LCOV_EXCL_STOP
533 }
534 
OnMetadataChangedMacro(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)535 int32_t SketchWrapper::OnMetadataChangedMacro(const SceneFeaturesMode& sceneFeaturesMode,
536     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
537 {
538     float sketchRatio = GetSketchEnableRatio(sceneFeaturesMode);
539     float currentZoomRatio = currentZoomRatio_;
540     MEDIA_DEBUG_LOG("SketchWrapper::OnMetadataChangedMacro OHOS_CONTROL_ZOOM_RATIO >>> currentZoomRatio:%{public}f -- "
541                     "sketchRatio:%{public}f",
542         currentZoomRatio, sketchRatio);
543     UpdateSketchRatio(sketchRatio);
544     OnSketchStatusChanged(sceneFeaturesMode);
545     return CAM_META_SUCCESS;
546 }
547 
OnMetadataChangedMoonCaptureBoost(const SceneFeaturesMode & sceneFeaturesMode,const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)548 int32_t SketchWrapper::OnMetadataChangedMoonCaptureBoost(const SceneFeaturesMode& sceneFeaturesMode,
549     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
550 {
551     // LCOV_EXCL_START
552     float sketchRatio = GetSketchEnableRatio(sceneFeaturesMode);
553     float currentZoomRatio = currentZoomRatio_;
554     MEDIA_DEBUG_LOG(
555         "SketchWrapper::OnMetadataChangedMoonCaptureBoost OHOS_CONTROL_ZOOM_RATIO >>> currentZoomRatio:%{public}f -- "
556         "sketchRatio:%{public}f",
557         currentZoomRatio, sketchRatio);
558     UpdateSketchRatio(sketchRatio);
559     OnSketchStatusChanged(sceneFeaturesMode);
560     return CAM_META_SUCCESS;
561     // LCOV_EXCL_STOP
562 }
563 } // namespace CameraStandard
564 } // namespace OHOS