• 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 "output/preview_output.h"
17 
18 #include <cstdint>
19 #include <fstream>
20 #include <limits>
21 #include <memory>
22 #include <mutex>
23 #include <utility>
24 #include <variant>
25 
26 #include "camera_device_ability_items.h"
27 #include "camera_error_code.h"
28 #include "camera_log.h"
29 #include "camera_manager.h"
30 #include "camera_metadata_operator.h"
31 #include "camera_output_capability.h"
32 #include "camera_rotation_api_utils.h"
33 #include "camera_util.h"
34 #include "hstream_repeat_callback_stub.h"
35 #include "image_format.h"
36 #include "istream_repeat.h"
37 #include "istream_repeat_callback.h"
38 #include "metadata_common_utils.h"
39 #include "parameters.h"
40 #include "session/capture_session.h"
41 #include "sketch_wrapper.h"
42 
43 namespace OHOS {
44 namespace CameraStandard {
45 namespace {
GetHdiFormatFromCameraFormat(CameraFormat cameraFormat)46 camera_format_t GetHdiFormatFromCameraFormat(CameraFormat cameraFormat)
47 {
48     switch (cameraFormat) {
49         case CAMERA_FORMAT_YCBCR_420_888:
50             return OHOS_CAMERA_FORMAT_YCBCR_420_888;
51         case CAMERA_FORMAT_YUV_420_SP: // nv21
52             return OHOS_CAMERA_FORMAT_YCRCB_420_SP;
53         case CAMERA_FORMAT_YCBCR_P010:
54             return OHOS_CAMERA_FORMAT_YCBCR_P010;
55         case CAMERA_FORMAT_YCRCB_P010:
56             return OHOS_CAMERA_FORMAT_YCRCB_P010;
57         case CAMERA_FORMAT_NV12: // nv12
58             return OHOS_CAMERA_FORMAT_YCBCR_420_SP;
59         case CAMERA_FORMAT_YUV_422_YUYV:
60             return OHOS_CAMERA_FORMAT_422_YUYV;
61         default:
62             return OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED;
63     }
64     return OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED;
65 }
66 } // namespace
67 
68 static constexpr int32_t SKETCH_MIN_WIDTH = 480;
PreviewOutput(sptr<IBufferProducer> bufferProducer)69 PreviewOutput::PreviewOutput(sptr<IBufferProducer> bufferProducer)
70     : CaptureOutput(CAPTURE_OUTPUT_TYPE_PREVIEW, StreamType::REPEAT, bufferProducer, nullptr)
71 {
72     MEDIA_INFO_LOG("PreviewOutput::PreviewOutput construct");
73     PreviewFormat_ = 0;
74     PreviewSize_.height = 0;
75     PreviewSize_.width = 0;
76     previewOutputListenerManager_->SetPreviewOutput(this);
77 }
78 
PreviewOutput()79 PreviewOutput::PreviewOutput() : PreviewOutput(nullptr) {}
80 
~PreviewOutput()81 PreviewOutput::~PreviewOutput()
82 {
83     MEDIA_INFO_LOG("PreviewOutput::PreviewOutput destruct");
84 }
85 
Release()86 int32_t PreviewOutput::Release()
87 {
88     previewOutputListenerManager_->ClearListeners();
89     std::lock_guard<std::mutex> lock(asyncOpMutex_);
90     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Release");
91     auto stream = GetStream();
92     CHECK_ERROR_RETURN_RET_LOG(stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
93         "PreviewOutput Failed to Release!, GetStream is nullptr");
94     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
95     int32_t errCode = CAMERA_UNKNOWN_ERROR;
96     if (itemStream) {
97         errCode = itemStream->Release();
98         CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "Failed to release PreviewOutput!, errCode: %{public}d", errCode);
99     } else {
100         MEDIA_ERR_LOG("PreviewOutput::Release() itemStream is nullptr");
101     }
102     CaptureOutput::Release();
103     return ServiceToCameraError(errCode);
104 }
105 
OnFrameStarted()106 int32_t PreviewOutputListenerManager::OnFrameStarted()
107 {
108     CAMERA_SYNC_TRACE;
109     auto previewOutput = GetPreviewOutput();
110     CHECK_ERROR_RETURN_RET_LOG(
111         previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameStarted previewOutput is null");
112     previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
113         [](auto listener) { listener->OnFrameStarted(); });
114     return CAMERA_OK;
115 }
116 
OnFrameEnded(int32_t frameCount)117 int32_t PreviewOutputListenerManager::OnFrameEnded(int32_t frameCount)
118 {
119     CAMERA_SYNC_TRACE;
120     auto previewOutput = GetPreviewOutput();
121     CHECK_ERROR_RETURN_RET_LOG(
122         previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameEnded previewOutput is null");
123     previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
124         [&frameCount](auto listener) { listener->OnFrameEnded(frameCount); });
125     return CAMERA_OK;
126 }
127 
OnFrameError(int32_t errorCode)128 int32_t PreviewOutputListenerManager::OnFrameError(int32_t errorCode)
129 {
130     CAMERA_SYNC_TRACE;
131     auto previewOutput = GetPreviewOutput();
132     CHECK_ERROR_RETURN_RET_LOG(
133         previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameError previewOutput is null");
134     previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
135         [&errorCode](auto listener) { listener->OnError(errorCode); });
136     return CAMERA_OK;
137 }
138 
OnSketchStatusChanged(SketchStatus status)139 int32_t PreviewOutputListenerManager::OnSketchStatusChanged(SketchStatus status)
140 {
141     CAMERA_SYNC_TRACE;
142     auto previewOutput = GetPreviewOutput();
143     CHECK_ERROR_RETURN_RET_LOG(previewOutput == nullptr, CAMERA_OK,
144         "PreviewOutputListenerManager::OnSketchStatusChanged previewOutput is null");
145     previewOutput->OnSketchStatusChanged(status);
146     return CAMERA_OK;
147 }
148 
OnDeferredVideoEnhancementInfo(CaptureEndedInfoExt captureEndedInfo)149 int32_t PreviewOutputListenerManager::OnDeferredVideoEnhancementInfo(CaptureEndedInfoExt captureEndedInfo)
150 {
151     MEDIA_INFO_LOG("PreviewOutput::OnDeferredVideoEnhancementInfo called");
152     // empty impl
153     return CAMERA_OK;
154 }
155 
SetPreviewOutput(wptr<PreviewOutput> previewOutput)156 void PreviewOutputListenerManager::SetPreviewOutput(wptr<PreviewOutput> previewOutput)
157 {
158     previewOutput_ = previewOutput;
159 }
160 
GetPreviewOutput()161 sptr<PreviewOutput> PreviewOutputListenerManager::GetPreviewOutput()
162 {
163     return previewOutput_.promote();
164 }
165 
OnSketchStatusChanged(SketchStatus status)166 int32_t PreviewOutput::OnSketchStatusChanged(SketchStatus status)
167 {
168     CHECK_ERROR_RETURN_RET(sketchWrapper_ == nullptr, CAMERA_INVALID_STATE);
169     auto session = GetSession();
170     CHECK_ERROR_RETURN_RET(session == nullptr, CAMERA_INVALID_STATE);
171     SketchWrapper* wrapper = static_cast<SketchWrapper*>(sketchWrapper_.get());
172     wrapper->OnSketchStatusChanged(status, session->GetFeaturesMode());
173     return CAMERA_OK;
174 }
175 
AddDeferredSurface(sptr<Surface> surface)176 void PreviewOutput::AddDeferredSurface(sptr<Surface> surface)
177 {
178     MEDIA_INFO_LOG("PreviewOutput::AddDeferredSurface called");
179     CHECK_ERROR_RETURN_LOG(surface == nullptr, "PreviewOutput::AddDeferredSurface surface is null");
180     auto stream = GetStream();
181     CHECK_ERROR_RETURN_LOG(!stream, "PreviewOutput::AddDeferredSurface itemStream is null");
182     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
183     itemStream->AddDeferredSurface(surface->GetProducer());
184 }
185 
Start()186 int32_t PreviewOutput::Start()
187 {
188     std::lock_guard<std::mutex> lock(asyncOpMutex_);
189     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Start");
190     auto session = GetSession();
191     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(), CameraErrorCode::SESSION_NOT_CONFIG,
192         "PreviewOutput Failed to Start, session not commited");
193     auto stream = GetStream();
194     CHECK_ERROR_RETURN_RET_LOG(
195         stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput Failed to Start, GetStream is nullptr");
196     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
197     int32_t errCode = CAMERA_UNKNOWN_ERROR;
198     if (itemStream) {
199         errCode = itemStream->Start();
200         CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PreviewOutput Failed to Start!, errCode: %{public}d", errCode);
201     } else {
202         MEDIA_ERR_LOG("PreviewOutput::Start itemStream is nullptr");
203     }
204     return ServiceToCameraError(errCode);
205 }
206 
Stop()207 int32_t PreviewOutput::Stop()
208 {
209     std::lock_guard<std::mutex> lock(asyncOpMutex_);
210     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Stop");
211     auto stream = GetStream();
212     CHECK_ERROR_RETURN_RET_LOG(
213         stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput Failed to Stop, GetStream is nullptr");
214     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
215     int32_t errCode = CAMERA_UNKNOWN_ERROR;
216     if (itemStream) {
217         errCode = itemStream->Stop();
218         CHECK_ERROR_PRINT_LOG(errCode != CAMERA_OK, "PreviewOutput Failed to Stop!, errCode: %{public}d", errCode);
219     } else {
220         MEDIA_ERR_LOG("PreviewOutput::Stop itemStream is nullptr");
221     }
222     return ServiceToCameraError(errCode);
223 }
224 
IsSketchSupported()225 bool PreviewOutput::IsSketchSupported()
226 {
227     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::IsSketchSupported");
228 
229     auto sketchSize = FindSketchSize();
230     CHECK_ERROR_RETURN_RET(sketchSize == nullptr, false);
231     MEDIA_INFO_LOG(
232         "IsSketchSupported FindSketchSize Size is %{public}dx%{public}d", sketchSize->width, sketchSize->height);
233     auto sketchRatio = GetSketchRatio();
234     CHECK_ERROR_RETURN_RET(sketchRatio > 0, true);
235     MEDIA_DEBUG_LOG("IsSketchSupported GetSketchRatio failed, %{public}f ", sketchRatio);
236     auto session = GetSession();
237     CHECK_ERROR_RETURN_RET(session == nullptr, false);
238     SketchWrapper::UpdateSketchStaticInfo(GetDeviceMetadata());
239     auto subModeNames = session->GetSubFeatureMods();
240     for (auto subModeName : subModeNames) {
241         float ratio = SketchWrapper::GetSketchEnableRatio(subModeName);
242         if (ratio > 0) {
243             MEDIA_DEBUG_LOG("IsSketchSupported GetSketchEnableRatio success,subMode:%{public}s, ratio:%{public}f ",
244                 subModeName.Dump().c_str(), ratio);
245             return true;
246         }
247     }
248     return false;
249 }
250 
GetSketchRatio()251 float PreviewOutput::GetSketchRatio()
252 {
253     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::GetSketchRatio");
254 
255     auto session = GetSession();
256     if (session == nullptr) {
257         MEDIA_WARNING_LOG("PreviewOutput::GetSketchRatio session is null");
258         return -1.0f;
259     }
260     auto currentMode = session->GetFeaturesMode();
261     SketchWrapper::UpdateSketchStaticInfo(GetDeviceMetadata());
262     float ratio = SketchWrapper::GetSketchEnableRatio(currentMode);
263     if (ratio <= 0) {
264         MEDIA_WARNING_LOG("PreviewOutput::GetSketchRatio mode:%{public}s", currentMode.Dump().c_str());
265     }
266     return ratio;
267 }
268 
CreateSketchWrapper(Size sketchSize)269 int32_t PreviewOutput::CreateSketchWrapper(Size sketchSize)
270 {
271     MEDIA_DEBUG_LOG("PreviewOutput::CreateSketchWrapper enter sketchSize is:%{public}d x %{public}d", sketchSize.width,
272         sketchSize.height);
273     auto session = GetSession();
274     CHECK_ERROR_RETURN_RET_LOG(
275         session == nullptr, ServiceToCameraError(CAMERA_INVALID_STATE), "EnableSketch session null");
276     auto wrapper = std::make_shared<SketchWrapper>(GetStream(), sketchSize);
277     sketchWrapper_ = wrapper;
278     wrapper->SetPreviewOutputCallbackManager(previewOutputListenerManager_);
279     auto metadata = GetDeviceMetadata();
280     int32_t retCode = wrapper->Init(metadata, session->GetFeaturesMode());
281     return ServiceToCameraError(retCode);
282 }
283 
EnableSketch(bool isEnable)284 int32_t PreviewOutput::EnableSketch(bool isEnable)
285 {
286     MEDIA_DEBUG_LOG("Enter Into PreviewOutput::EnableSketch %{public}d", isEnable);
287     CHECK_ERROR_RETURN_RET_LOG(!IsSketchSupported(), CameraErrorCode::OPERATION_NOT_ALLOWED,
288         "EnableSketch IsSketchSupported is false");
289     int32_t errCode = CAMERA_UNKNOWN_ERROR;
290     std::lock_guard<std::mutex> lock(asyncOpMutex_);
291 
292     auto session = GetSession();
293     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionConfiged(),
294         CameraErrorCode::SESSION_NOT_CONFIG, "PreviewOutput Failed EnableSketch!, session not config");
295 
296     if (isEnable) {
297         CHECK_ERROR_RETURN_RET(sketchWrapper_ != nullptr, ServiceToCameraError(CAMERA_OPERATION_NOT_ALLOWED));
298         auto sketchSize = FindSketchSize();
299         CHECK_ERROR_RETURN_RET_LOG(sketchSize == nullptr, ServiceToCameraError(errCode),
300             "PreviewOutput EnableSketch FindSketchSize is null");
301         MEDIA_INFO_LOG("EnableSketch FindSketchSize Size is %{public}dx%{public}d",
302             sketchSize->width, sketchSize->height);
303         return CreateSketchWrapper(*sketchSize);
304     }
305 
306     // Disable sketch branch
307     CHECK_ERROR_RETURN_RET(sketchWrapper_ == nullptr, ServiceToCameraError(CAMERA_OPERATION_NOT_ALLOWED));
308     errCode = sketchWrapper_->Destroy();
309     sketchWrapper_ = nullptr;
310     return ServiceToCameraError(errCode);
311 }
312 
AttachSketchSurface(sptr<Surface> sketchSurface)313 int32_t PreviewOutput::AttachSketchSurface(sptr<Surface> sketchSurface)
314 {
315     auto session = GetSession();
316     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
317         CameraErrorCode::SESSION_NOT_CONFIG, "PreviewOutput Failed to AttachSketchSurface, session not commited");
318     CHECK_ERROR_RETURN_RET(sketchWrapper_ == nullptr, CameraErrorCode::INVALID_ARGUMENT);
319     CHECK_ERROR_RETURN_RET(sketchSurface == nullptr, CameraErrorCode::INVALID_ARGUMENT);
320     int32_t errCode = sketchWrapper_->AttachSketchSurface(sketchSurface);
321     return ServiceToCameraError(errCode);
322 }
323 
SetStream(sptr<IStreamCommon> stream)324 void PreviewOutput::SetStream(sptr<IStreamCommon> stream)
325 {
326     CaptureOutput::SetStream(stream);
327     CHECK_ERROR_RETURN_LOG(stream == nullptr, "PreviewOutput::SetStream stream is null");
328     sptr<IStreamRepeatCallback> callback = previewOutputListenerManager_;
329     static_cast<IStreamRepeat*>(stream.GetRefPtr())->SetCallback(callback);
330 }
331 
CreateStream()332 int32_t PreviewOutput::CreateStream()
333 {
334     auto stream = GetStream();
335     CHECK_ERROR_RETURN_RET_LOG(
336         stream != nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED, "PreviewOutput::CreateStream stream is not null");
337     auto producer = GetBufferProducer();
338     CHECK_ERROR_RETURN_RET_LOG(
339         producer == nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED, "PreviewOutput::CreateStream producer is null");
340     sptr<IStreamRepeat> streamPtr = nullptr;
341     auto previewProfile = GetPreviewProfile();
342     CHECK_ERROR_RETURN_RET_LOG(previewProfile == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
343         "PreviewOutput::CreateStream previewProfile is null");
344     int32_t res =
345         CameraManager::GetInstance()->CreatePreviewOutputStream(streamPtr, *previewProfile, GetBufferProducer());
346     SetStream(streamPtr);
347     CHECK_ERROR_RETURN_RET_LOG(
348         streamPtr == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput::CreateStream streamPtr is null");
349     sptr<IStreamRepeatCallback> callback = previewOutputListenerManager_;
350     streamPtr->SetCallback(callback);
351     return res;
352 }
353 
GetFrameRateRange()354 const std::vector<int32_t>& PreviewOutput::GetFrameRateRange()
355 {
356     return previewFrameRateRange_;
357 }
358 
SetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)359 void PreviewOutput::SetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
360 {
361     MEDIA_DEBUG_LOG("PreviewOutput::SetFrameRateRange min = %{public}d and max = %{public}d",
362                     minFrameRate, maxFrameRate);
363     previewFrameRateRange_ = { minFrameRate, maxFrameRate };
364 }
365 
SetOutputFormat(int32_t format)366 void PreviewOutput::SetOutputFormat(int32_t format)
367 {
368     MEDIA_DEBUG_LOG("PreviewOutput::SetOutputFormat set format %{public}d", format);
369     PreviewFormat_ = format;
370 }
371 
SetSize(Size size)372 void PreviewOutput::SetSize(Size size)
373 {
374     MEDIA_DEBUG_LOG("PreviewOutput::SetSize set size %{public}d, %{public}d", size.width, size.height);
375     PreviewSize_ = size;
376 }
377 
SetFrameRate(int32_t minFrameRate,int32_t maxFrameRate)378 int32_t PreviewOutput::SetFrameRate(int32_t minFrameRate, int32_t maxFrameRate)
379 {
380     int32_t result = canSetFrameRateRange(minFrameRate, maxFrameRate);
381     CHECK_ERROR_RETURN_RET(result != CameraErrorCode::SUCCESS, result);
382     CHECK_ERROR_RETURN_RET_LOG(minFrameRate == previewFrameRateRange_[0] && maxFrameRate == previewFrameRateRange_[1],
383         CameraErrorCode::INVALID_ARGUMENT, "PreviewOutput::SetFrameRate The frame rate does not need to be set.");
384     std::vector<int32_t> frameRateRange = {minFrameRate, maxFrameRate};
385     auto stream = GetStream();
386     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
387     if (itemStream) {
388         int32_t ret = itemStream->SetFrameRate(minFrameRate, maxFrameRate);
389         CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, ServiceToCameraError(ret),
390             "PreviewOutput::setFrameRate failed to set stream frame rate");
391         SetFrameRateRange(minFrameRate, maxFrameRate);
392     }
393     auto session = GetSession();
394     wptr<PreviewOutput> weakThis(this);
395     CHECK_EXECUTE(session != nullptr, session->AddFunctionToMap("preview" + std::to_string(OHOS_CONTROL_FPS_RANGES),
396         [weakThis, minFrameRate, maxFrameRate]() {
397             auto sharedThis = weakThis.promote();
398             CHECK_ERROR_RETURN_LOG(!sharedThis, "SetFrameRate previewOutput is nullptr.");
399             sharedThis->SetFrameRate(minFrameRate, maxFrameRate);
400         }));
401     return CameraErrorCode::SUCCESS;
402 }
403 
GetSupportedFrameRates()404 std::vector<std::vector<int32_t>> PreviewOutput::GetSupportedFrameRates()
405 {
406     MEDIA_DEBUG_LOG("PreviewOutput::GetSupportedFrameRates called.");
407     auto session = GetSession();
408     CHECK_ERROR_RETURN_RET(session == nullptr, {});
409     auto inputDevice = session->GetInputDevice();
410     CHECK_ERROR_RETURN_RET(inputDevice == nullptr, {});
411     sptr<CameraDevice> camera = inputDevice->GetCameraDeviceInfo();
412     SceneMode curMode = session->GetMode();
413 
414     sptr<CameraOutputCapability> cameraOutputCapability = CameraManager::GetInstance()->
415                                                           GetSupportedOutputCapability(camera, curMode);
416     CHECK_ERROR_RETURN_RET(cameraOutputCapability == nullptr, {});
417     std::vector<Profile> supportedProfiles = cameraOutputCapability->GetPreviewProfiles();
418     supportedProfiles.erase(std::remove_if(
419         supportedProfiles.begin(), supportedProfiles.end(),
420         [&](Profile& profile) {
421             return profile.format_ != PreviewFormat_ ||
422                    profile.GetSize().height != PreviewSize_.height ||
423                    profile.GetSize().width != PreviewSize_.width;
424         }), supportedProfiles.end());
425     std::vector<std::vector<int32_t>> supportedFrameRatesRange;
426     for (auto item : supportedProfiles) {
427         std::vector<int32_t> supportedFrameRatesItem = {item.fps_.minFps, item.fps_.maxFps};
428         supportedFrameRatesRange.emplace_back(supportedFrameRatesItem);
429     }
430     std::set<std::vector<int>> set(supportedFrameRatesRange.begin(), supportedFrameRatesRange.end());
431     supportedFrameRatesRange.assign(set.begin(), set.end());
432     MEDIA_DEBUG_LOG("PreviewOutput::GetSupportedFrameRates frameRateRange size:%{public}zu",
433                     supportedFrameRatesRange.size());
434     return supportedFrameRatesRange;
435 }
436 
StartSketch()437 int32_t PreviewOutput::StartSketch()
438 {
439     int32_t errCode = CAMERA_UNKNOWN_ERROR;
440 
441     auto session = GetSession();
442     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
443         CameraErrorCode::SESSION_NOT_CONFIG,
444         "PreviewOutput Failed to StartSketch, session not commited");
445     if (sketchWrapper_ != nullptr) {
446         errCode = sketchWrapper_->StartSketchStream();
447     }
448     return ServiceToCameraError(errCode);
449 }
450 
StopSketch()451 int32_t PreviewOutput::StopSketch()
452 {
453     int32_t errCode = CAMERA_UNKNOWN_ERROR;
454 
455     auto session = GetSession();
456     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || !session->IsSessionCommited(),
457         CameraErrorCode::SESSION_NOT_CONFIG,
458         "PreviewOutput Failed to StopSketch, session not commited");
459     if (sketchWrapper_ != nullptr) {
460         errCode = sketchWrapper_->StopSketchStream();
461     }
462     return ServiceToCameraError(errCode);
463 }
464 
GetDeviceMetadata()465 std::shared_ptr<Camera::CameraMetadata> PreviewOutput::GetDeviceMetadata()
466 {
467     auto session = GetSession();
468     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata session is null");
469     auto inputDevice = session->GetInputDevice();
470     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata input is null");
471     auto deviceInfo = inputDevice->GetCameraDeviceInfo();
472     CHECK_ERROR_RETURN_RET_LOG(deviceInfo == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata info is null");
473     auto metaData = deviceInfo->GetCachedMetadata();
474     CHECK_ERROR_RETURN_RET_LOG(metaData == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata metaData is null");
475     return metaData;
476 }
477 
FindSketchSize()478 std::shared_ptr<Size> PreviewOutput::FindSketchSize()
479 {
480     auto session = GetSession();
481     auto metaData = GetDeviceMetadata();
482     CHECK_ERROR_RETURN_RET_LOG(session == nullptr || metaData == nullptr, nullptr,
483         "PreviewOutput::FindSketchSize GetDeviceMetadata failed");
484     auto profile = GetPreviewProfile();
485     CHECK_ERROR_RETURN_RET_LOG(profile == nullptr, nullptr, "PreviewOutput::FindSketchSize profile is nullptr");
486     camera_format_t hdi_format = GetHdiFormatFromCameraFormat(profile->GetCameraFormat());
487     CHECK_ERROR_RETURN_RET_LOG(hdi_format == OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED, nullptr,
488         "PreviewOutput::FindSketchSize preview format is illegal");
489     auto sizeList = MetadataCommonUtils::GetSupportedPreviewSizeRange(
490         session->GetFeaturesMode().GetSceneMode(), hdi_format, metaData);
491     CHECK_ERROR_RETURN_RET(sizeList == nullptr || sizeList->size() == 0, nullptr);
492     Size previewSize = profile->GetSize();
493     CHECK_ERROR_RETURN_RET(previewSize.width <= 0 || previewSize.height <= 0, nullptr);
494     float ratio = static_cast<float>(previewSize.width) / previewSize.height;
495     MEDIA_INFO_LOG("PreviewOutput::FindSketchSize preview size:%{public}dx%{public}d,ratio:%{public}f",
496         previewSize.width, previewSize.height, ratio);
497     std::shared_ptr<Size> outSize;
498     for (auto size : *sizeList.get()) {
499         if (size.width >= previewSize.width || size.width < SKETCH_MIN_WIDTH) {
500             continue;
501         }
502         float checkRatio = static_cast<float>(size.width) / size.height;
503         MEDIA_DEBUG_LOG("PreviewOutput::FindSketchSize List size:%{public}dx%{public}d,ratio:%{public}f", size.width,
504             size.height, checkRatio);
505         if (abs(checkRatio - ratio) / ratio <= 0.05f) { // 0.05f is 5% tolerance
506             if (outSize == nullptr) {
507                 outSize = std::make_shared<Size>(size);
508             } else if (size.width < outSize->width) {
509                 outSize = std::make_shared<Size>(size);
510             }
511         }
512     }
513     return outSize;
514 }
515 
SetCallback(std::shared_ptr<PreviewStateCallback> callback)516 void PreviewOutput::SetCallback(std::shared_ptr<PreviewStateCallback> callback)
517 {
518     auto stream = GetStream();
519     CHECK_ERROR_RETURN(stream == nullptr);
520     bool isSuccess = previewOutputListenerManager_->AddListener(callback);
521     CHECK_ERROR_RETURN(!isSuccess);
522     if (previewOutputListenerManager_->GetListenerCount() == 1) {
523         sptr<IStreamRepeatCallback> ipcCallback = previewOutputListenerManager_;
524         sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
525         int32_t errCode = itemStream->SetCallback(ipcCallback);
526         if (errCode != CAMERA_OK) {
527             MEDIA_ERR_LOG("PreviewOutput::SetCallback fail");
528             previewOutputListenerManager_->RemoveListener(callback);
529         }
530     }
531 }
532 
RemoveCallback(std::shared_ptr<PreviewStateCallback> callback)533 void PreviewOutput::RemoveCallback(std::shared_ptr<PreviewStateCallback> callback)
534 {
535     previewOutputListenerManager_->RemoveListener(callback);
536     if (previewOutputListenerManager_->GetListenerCount() == 0) {
537         auto stream = GetStream();
538         CHECK_ERROR_RETURN(stream == nullptr);
539         sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
540         itemStream->UnSetCallback();
541     }
542 }
543 
GetObserverControlTags()544 const std::set<camera_device_metadata_tag_t>& PreviewOutput::GetObserverControlTags()
545 {
546     const static std::set<camera_device_metadata_tag_t> tags = { OHOS_CONTROL_ZOOM_RATIO, OHOS_CONTROL_CAMERA_MACRO,
547         OHOS_CONTROL_MOON_CAPTURE_BOOST, OHOS_CONTROL_SMOOTH_ZOOM_RATIOS };
548     return tags;
549 }
550 
OnControlMetadataChanged(const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)551 int32_t PreviewOutput::OnControlMetadataChanged(
552     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
553 {
554     // Don't trust outer public interface passthrough data. Check the legitimacy of the data.
555     CHECK_ERROR_RETURN_RET(metadataItem.count <= 0, CAM_META_INVALID_PARAM);
556     CHECK_ERROR_RETURN_RET(sketchWrapper_ == nullptr, CAM_META_FAILURE);
557     auto session = GetSession();
558     CHECK_ERROR_RETURN_RET(session == nullptr, CAM_META_FAILURE);
559     std::lock_guard<std::mutex> lock(asyncOpMutex_);
560     SketchWrapper* wrapper = reinterpret_cast<SketchWrapper*>(sketchWrapper_.get());
561     wrapper->OnMetadataDispatch(session->GetFeaturesMode(), tag, metadataItem);
562     return CAM_META_SUCCESS;
563 }
564 
OnResultMetadataChanged(const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)565 int32_t PreviewOutput::OnResultMetadataChanged(
566     const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
567 {
568     // Don't trust outer public interface passthrough data. Check the legitimacy of the data.
569     CHECK_ERROR_RETURN_RET(metadataItem.count <= 0, CAM_META_INVALID_PARAM);
570     CHECK_ERROR_RETURN_RET(sketchWrapper_ == nullptr, CAM_META_FAILURE);
571     auto session = GetSession();
572     CHECK_ERROR_RETURN_RET(session == nullptr, CAM_META_FAILURE);
573     std::lock_guard<std::mutex> lock(asyncOpMutex_);
574     SketchWrapper* wrapper = reinterpret_cast<SketchWrapper*>(sketchWrapper_.get());
575     wrapper->OnMetadataDispatch(session->GetFeaturesMode(), tag, metadataItem);
576     return CAM_META_SUCCESS;
577 }
578 
GetPreviewOutputListenerManager()579 sptr<PreviewOutputListenerManager> PreviewOutput::GetPreviewOutputListenerManager()
580 {
581     return previewOutputListenerManager_;
582 }
583 
OnNativeRegisterCallback(const std::string & eventString)584 void PreviewOutput::OnNativeRegisterCallback(const std::string& eventString)
585 {
586     if (eventString == CONST_SKETCH_STATUS_CHANGED) {
587         std::lock_guard<std::mutex> lock(asyncOpMutex_);
588         CHECK_ERROR_RETURN(sketchWrapper_ == nullptr);
589         auto session = GetSession();
590         CHECK_ERROR_RETURN(session == nullptr || !session->IsSessionCommited());
591         auto metadata = GetDeviceMetadata();
592         CHECK_ERROR_RETURN_LOG(metadata == nullptr, "metadata is nullptr");
593         camera_metadata_item_t item;
594         int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_ZOOM_RATIO, &item);
595         CHECK_ERROR_RETURN(ret != CAM_META_SUCCESS || item.count <= 0);
596         float tagRatio = *item.data.f;
597         CHECK_ERROR_RETURN(tagRatio <= 0);
598         float sketchRatio = sketchWrapper_->GetSketchEnableRatio(session->GetFeaturesMode());
599         MEDIA_DEBUG_LOG("PreviewOutput::OnNativeRegisterCallback OHOS_CONTROL_ZOOM_RATIO >>> tagRatio:%{public}f -- "
600                         "sketchRatio:%{public}f",
601             tagRatio, sketchRatio);
602         sketchWrapper_->UpdateSketchRatio(sketchRatio);
603         sketchWrapper_->UpdateZoomRatio(tagRatio);
604     }
605 }
606 
OnNativeUnregisterCallback(const std::string & eventString)607 void PreviewOutput::OnNativeUnregisterCallback(const std::string& eventString)
608 {
609     if (eventString == CONST_SKETCH_STATUS_CHANGED) {
610         std::lock_guard<std::mutex> lock(asyncOpMutex_);
611         CHECK_ERROR_RETURN(sketchWrapper_ == nullptr);
612         sketchWrapper_->StopSketchStream();
613     }
614 }
615 
CameraServerDied(pid_t pid)616 void PreviewOutput::CameraServerDied(pid_t pid)
617 {
618     MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
619     previewOutputListenerManager_->TriggerListener([](auto listener) {
620         int32_t serviceErrorType = ServiceToCameraError(CAMERA_INVALID_STATE);
621         listener->OnError(serviceErrorType);
622     });
623 }
624 
canSetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)625 int32_t PreviewOutput::canSetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
626 {
627     auto session = GetSession();
628     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
629         "PreviewOutput::canSetFrameRateRange Can not set frame rate range without commit session");
630     CHECK_ERROR_RETURN_RET_LOG(!session->CanSetFrameRateRange(minFrameRate, maxFrameRate, this),
631         CameraErrorCode::UNRESOLVED_CONFLICTS_BETWEEN_STREAMS,
632         "PreviewOutput::canSetFrameRateRange Can not set frame rate range with wrong state of output");
633     int32_t minIndex = 0;
634     int32_t maxIndex = 1;
635     std::vector<std::vector<int32_t>> supportedFrameRange = GetSupportedFrameRates();
636     for (auto item : supportedFrameRange) {
637         CHECK_ERROR_RETURN_RET(item[minIndex] <= minFrameRate && item[maxIndex] >= maxFrameRate,
638             CameraErrorCode::SUCCESS);
639     }
640     MEDIA_WARNING_LOG("Can not set frame rate range with invalid parameters");
641     return CameraErrorCode::INVALID_ARGUMENT;
642 }
643 
GetPreviewRotation(int32_t imageRotation)644 int32_t PreviewOutput::GetPreviewRotation(int32_t imageRotation)
645 {
646     MEDIA_INFO_LOG("PreviewOutput GetPreviewRotation is called");
647     CHECK_ERROR_RETURN_RET_LOG(imageRotation % ROTATION_90_DEGREES != 0, INVALID_ARGUMENT,
648         "PreviewOutput GetPreviewRotation error!, invalid argument");
649     int32_t sensorOrientation = 0;
650     ImageRotation result = ImageRotation::ROTATION_0;
651     sptr<CameraDevice> cameraObj;
652     auto session = GetSession();
653     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SERVICE_FATL_ERROR,
654         "PreviewOutput GetPreviewRotation error!, session is nullptr");
655     auto inputDevice = session->GetInputDevice();
656     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
657         "PreviewOutput GetPreviewRotation error!, inputDevice is nullptr");
658     cameraObj = inputDevice->GetCameraDeviceInfo();
659     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
660         "PreviewOutput GetPreviewRotation error!, cameraObj is nullptr");
661     uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
662     if (apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN) {
663         imageRotation = JudegRotationFunc(imageRotation);
664     }
665     sensorOrientation = static_cast<int32_t>(cameraObj->GetCameraOrientation());
666     result = (ImageRotation)((imageRotation + sensorOrientation) % CAPTURE_ROTATION_BASE);
667     MEDIA_INFO_LOG("PreviewOutput GetPreviewRotation :result %{public}d, sensorOrientation:%{public}d",
668         result, sensorOrientation);
669     return result;
670 }
671 
JudegRotationFunc(int32_t imageRotation)672 int32_t PreviewOutput::JudegRotationFunc(int32_t imageRotation)
673 {
674     std::string deviceType = OHOS::system::GetDeviceType();
675     if (imageRotation > CAPTURE_ROTATION_BASE) {
676         return INVALID_ARGUMENT;
677     }
678     bool isTableFlag = system::GetBoolParameter("const.multimedia.enable_camera_rotation_compensation", 0);
679     uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
680     if (isTableFlag && apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN) {
681         imageRotation = ((imageRotation - ROTATION_90_DEGREES + CAPTURE_ROTATION_BASE) % CAPTURE_ROTATION_BASE);
682     }
683     return imageRotation;
684 }
685 
SetPreviewRotation(int32_t imageRotation,bool isDisplayLocked)686 int32_t PreviewOutput::SetPreviewRotation(int32_t imageRotation, bool isDisplayLocked)
687 {
688     MEDIA_INFO_LOG("PreviewOutput SetPreviewRotation is called");
689     CHECK_ERROR_RETURN_RET_LOG(imageRotation % ROTATION_90_DEGREES != 0, INVALID_ARGUMENT,
690         "PreviewOutput SetPreviewRotation error!, invalid argument");
691     int32_t sensorOrientation = 0;
692     ImageRotation result = ROTATION_0;
693     sptr<CameraDevice> cameraObj;
694     auto session = GetSession();
695     CHECK_ERROR_RETURN_RET_LOG(session == nullptr, SERVICE_FATL_ERROR,
696         "PreviewOutput SetPreviewRotation error!, session is nullptr");
697     auto inputDevice = session->GetInputDevice();
698     CHECK_ERROR_RETURN_RET_LOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
699         "PreviewOutput SetPreviewRotation error!, inputDevice is nullptr");
700     cameraObj = inputDevice->GetCameraDeviceInfo();
701     CHECK_ERROR_RETURN_RET_LOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
702         "PreviewOutput SetPreviewRotation error!, cameraObj is nullptr");
703     sensorOrientation = static_cast<int32_t>(cameraObj->GetCameraOrientation());
704     result = isDisplayLocked ? ImageRotation(sensorOrientation) : ImageRotation(imageRotation);
705     MEDIA_INFO_LOG("PreviewOutput SetPreviewRotation :result %{public}d, sensorOrientation:%{public}d",
706         result, sensorOrientation);
707     auto stream = GetStream();
708     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
709     int32_t errCode = CAMERA_UNKNOWN_ERROR;
710     if (itemStream) {
711         errCode = itemStream->SetCameraRotation(true, result);
712         CHECK_ERROR_RETURN_RET_LOG(errCode != CAMERA_OK, SERVICE_FATL_ERROR,
713             "Failed to SetCameraRotation!, errCode: %{public}d", errCode);
714     } else {
715         MEDIA_ERR_LOG("PreviewOutput::SetCameraRotation() itemStream is nullptr");
716         return CameraErrorCode::SERVICE_FATL_ERROR;
717     }
718     MEDIA_ERR_LOG("PreviewOutput SetPreviewRotation sucess");
719     return CameraErrorCode::SUCCESS;
720 }
721 } // namespace CameraStandard
722 } // namespace OHOS
723