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/v1_3/types.h"
27 #include "camera_device_ability_items.h"
28 #include "camera_error_code.h"
29 #include "camera_log.h"
30 #include "camera_manager.h"
31 #include "camera_metadata_operator.h"
32 #include "camera_output_capability.h"
33 #include "camera_rotation_api_utils.h"
34 #include "camera_util.h"
35 #include "display_manager.h"
36 #include "stream_repeat_callback_stub.h"
37 #include "image_format.h"
38 #include "istream_repeat.h"
39 #include "istream_repeat_callback.h"
40 #include "metadata_common_utils.h"
41 #include "parameters.h"
42 #include "session/capture_session.h"
43 #include "sketch_wrapper.h"
44 #include "xcomponent_controller.h"
45 #include "surface.h"
46 #include "surface_utils.h"
47
48 namespace OHOS {
49 namespace CameraStandard {
50 namespace {
GetHdiFormatFromCameraFormat(CameraFormat cameraFormat)51 camera_format_t GetHdiFormatFromCameraFormat(CameraFormat cameraFormat)
52 {
53 // LCOV_EXCL_START
54 switch (cameraFormat) {
55 case CAMERA_FORMAT_YCBCR_420_888:
56 return OHOS_CAMERA_FORMAT_YCBCR_420_888;
57 case CAMERA_FORMAT_YUV_420_SP: // nv21
58 return OHOS_CAMERA_FORMAT_YCRCB_420_SP;
59 case CAMERA_FORMAT_YCBCR_P010:
60 return OHOS_CAMERA_FORMAT_YCBCR_P010;
61 case CAMERA_FORMAT_YCRCB_P010:
62 return OHOS_CAMERA_FORMAT_YCRCB_P010;
63 case CAMERA_FORMAT_NV12: // nv12
64 return OHOS_CAMERA_FORMAT_YCBCR_420_SP;
65 case CAMERA_FORMAT_YUV_422_YUYV:
66 return OHOS_CAMERA_FORMAT_422_YUYV;
67 case CAMERA_FORMAT_YUV_422_UYVY:
68 return OHOS_CAMERA_FORMAT_422_UYVY;
69 default:
70 return OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED;
71 }
72 return OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED;
73 // LCOV_EXCL_STOP
74 }
75 } // namespace
76
77 static constexpr int32_t SKETCH_MIN_WIDTH = 480;
78 static constexpr int32_t RENDER_FIL_FILL = 9;
79 static constexpr int32_t RENDER_FIL_COVER = 13;
80 static constexpr float TARGET_MIN_RATIO = 0.01;
PreviewOutput(sptr<IBufferProducer> bufferProducer)81 PreviewOutput::PreviewOutput(sptr<IBufferProducer> bufferProducer)
82 : CaptureOutput(CAPTURE_OUTPUT_TYPE_PREVIEW, StreamType::REPEAT, bufferProducer, nullptr)
83 {
84 MEDIA_INFO_LOG("PreviewOutput::PreviewOutput construct");
85 PreviewFormat_ = 0;
86 PreviewSize_.height = 0;
87 PreviewSize_.width = 0;
88 previewOutputListenerManager_->SetPreviewOutput(this);
89 }
90
PreviewOutput()91 PreviewOutput::PreviewOutput() : PreviewOutput(nullptr) {}
92
~PreviewOutput()93 PreviewOutput::~PreviewOutput()
94 {
95 MEDIA_INFO_LOG("PreviewOutput::PreviewOutput destruct");
96 }
97
Release()98 int32_t PreviewOutput::Release()
99 {
100 // LCOV_EXCL_START
101 previewOutputListenerManager_->ClearListeners();
102 std::lock_guard<std::mutex> lock(asyncOpMutex_);
103 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Release");
104 auto stream = GetStream();
105 CHECK_RETURN_RET_ELOG(stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
106 "PreviewOutput Failed to Release!, GetStream is nullptr");
107 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
108 int32_t errCode = CAMERA_UNKNOWN_ERROR;
109 CHECK_PRINT_ELOG(itemStream == nullptr, "register surface consumer listener failed!");
110 if (itemStream) {
111 errCode = itemStream->Release();
112 CHECK_PRINT_ELOG(errCode != CAMERA_OK, "Failed to release PreviewOutput!, errCode: %{public}d", errCode);
113 }
114 CaptureOutput::Release();
115 return ServiceToCameraError(errCode);
116 // LCOV_EXCL_STOP
117 }
118
OnFrameStarted()119 int32_t PreviewOutputListenerManager::OnFrameStarted()
120 {
121 // LCOV_EXCL_START
122 CAMERA_SYNC_TRACE;
123 auto previewOutput = GetPreviewOutput();
124 CHECK_RETURN_RET_ELOG(
125 previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameStarted previewOutput is null");
126 previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
127 [](auto listener) { listener->OnFrameStarted(); });
128 return CAMERA_OK;
129 // LCOV_EXCL_STOP
130 }
131
OnFrameEnded(int32_t frameCount)132 int32_t PreviewOutputListenerManager::OnFrameEnded(int32_t frameCount)
133 {
134 // LCOV_EXCL_START
135 CAMERA_SYNC_TRACE;
136 auto previewOutput = GetPreviewOutput();
137 CHECK_RETURN_RET_ELOG(
138 previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameEnded previewOutput is null");
139 previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
140 [&frameCount](auto listener) { listener->OnFrameEnded(frameCount); });
141 return CAMERA_OK;
142 // LCOV_EXCL_STOP
143 }
144
OnFrameError(int32_t errorCode)145 int32_t PreviewOutputListenerManager::OnFrameError(int32_t errorCode)
146 {
147 // LCOV_EXCL_START
148 CAMERA_SYNC_TRACE;
149 auto previewOutput = GetPreviewOutput();
150 CHECK_RETURN_RET_ELOG(
151 previewOutput == nullptr, CAMERA_OK, "PreviewOutputListenerManager::OnFrameError previewOutput is null");
152 previewOutput->GetPreviewOutputListenerManager()->TriggerListener(
153 [&errorCode](auto listener) { listener->OnError(errorCode); });
154 return CAMERA_OK;
155 // LCOV_EXCL_STOP
156 }
157
OnSketchStatusChanged(SketchStatus status)158 int32_t PreviewOutputListenerManager::OnSketchStatusChanged(SketchStatus status)
159 {
160 // LCOV_EXCL_START
161 CAMERA_SYNC_TRACE;
162 auto previewOutput = GetPreviewOutput();
163 CHECK_RETURN_RET_ELOG(previewOutput == nullptr, CAMERA_OK,
164 "PreviewOutputListenerManager::OnSketchStatusChanged previewOutput is null");
165 previewOutput->OnSketchStatusChanged(status);
166 return CAMERA_OK;
167 // LCOV_EXCL_STOP
168 }
169
OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt & captureEndedInfo)170 int32_t PreviewOutputListenerManager::OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt &captureEndedInfo)
171 {
172 // LCOV_EXCL_START
173 MEDIA_INFO_LOG("PreviewOutput::OnDeferredVideoEnhancementInfo called");
174 // empty impl
175 return CAMERA_OK;
176 // LCOV_EXCL_STOP
177 }
178
SetPreviewOutput(wptr<PreviewOutput> previewOutput)179 void PreviewOutputListenerManager::SetPreviewOutput(wptr<PreviewOutput> previewOutput)
180 {
181 previewOutput_ = previewOutput;
182 }
183
GetPreviewOutput()184 sptr<PreviewOutput> PreviewOutputListenerManager::GetPreviewOutput()
185 {
186 return previewOutput_.promote();
187 }
188
OnSketchStatusChanged(SketchStatus status)189 int32_t PreviewOutput::OnSketchStatusChanged(SketchStatus status)
190 {
191 // LCOV_EXCL_START
192 CHECK_RETURN_RET(sketchWrapper_ == nullptr, CAMERA_INVALID_STATE);
193 auto session = GetSession();
194 CHECK_RETURN_RET(session == nullptr, CAMERA_INVALID_STATE);
195 SketchWrapper* wrapper = static_cast<SketchWrapper*>(sketchWrapper_.get());
196 wrapper->OnSketchStatusChanged(status, session->GetFeaturesMode());
197 return CAMERA_OK;
198 // LCOV_EXCL_STOP
199 }
200
AddDeferredSurface(sptr<Surface> surface)201 void PreviewOutput::AddDeferredSurface(sptr<Surface> surface)
202 {
203 MEDIA_INFO_LOG("PreviewOutput::AddDeferredSurface called");
204 CHECK_RETURN_ELOG(surface == nullptr, "PreviewOutput::AddDeferredSurface surface is null");
205 auto stream = GetStream();
206 CHECK_RETURN_ELOG(!stream, "PreviewOutput::AddDeferredSurface itemStream is null");
207 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
208 itemStream->AddDeferredSurface(surface->GetProducer());
209 }
210
Start()211 int32_t PreviewOutput::Start()
212 {
213 std::lock_guard<std::mutex> lock(asyncOpMutex_);
214 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Start");
215 auto session = GetSession();
216 CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(), CameraErrorCode::SESSION_NOT_CONFIG,
217 "PreviewOutput Failed to Start, session not commited");
218 // LCOV_EXCL_START
219 auto stream = GetStream();
220 CHECK_RETURN_RET_ELOG(
221 stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput Failed to Start, GetStream is nullptr");
222 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
223 int32_t errCode = CAMERA_UNKNOWN_ERROR;
224 if (itemStream) {
225 errCode = itemStream->Start();
226 CHECK_PRINT_ELOG(errCode != CAMERA_OK, "PreviewOutput Failed to Start!, errCode: %{public}d", errCode);
227 } else {
228 MEDIA_ERR_LOG("PreviewOutput::Start itemStream is nullptr");
229 }
230 return ServiceToCameraError(errCode);
231 // LCOV_EXCL_STOP
232 }
233
Stop()234 int32_t PreviewOutput::Stop()
235 {
236 std::lock_guard<std::mutex> lock(asyncOpMutex_);
237 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::Stop");
238 auto stream = GetStream();
239 CHECK_RETURN_RET_ELOG(
240 stream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput Failed to Stop, GetStream is nullptr");
241 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
242 int32_t errCode = CAMERA_UNKNOWN_ERROR;
243 if (itemStream) {
244 errCode = itemStream->Stop();
245 CHECK_PRINT_ELOG(errCode != CAMERA_OK, "PreviewOutput Failed to Stop!, errCode: %{public}d", errCode);
246 } else {
247 MEDIA_ERR_LOG("PreviewOutput::Stop itemStream is nullptr");
248 }
249 return ServiceToCameraError(errCode);
250 }
251
IsDynamicSketchNotifySupported()252 bool PreviewOutput::IsDynamicSketchNotifySupported()
253 {
254 // LCOV_EXCL_START
255 auto session = GetSession();
256 CHECK_RETURN_RET(session == nullptr, false);
257 auto metadata = GetDeviceMetadata();
258 CHECK_RETURN_RET(metadata == nullptr, false);
259
260 camera_metadata_item_t item;
261 int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_SKETCH_INFO_NOTIFICATION, &item);
262 CHECK_RETURN_RET_ELOG(ret != CAM_META_SUCCESS || item.count == 0, false,
263 "PreviewOutput::IsDynamicSketchNotifySupported Failed with return code %{public}d", ret);
264 std::vector<int32_t> supportedModes = {};
265 for (uint32_t i = 0; i < item.count; i++) {
266 auto opMode = static_cast<OHOS::HDI::Camera::V1_3::OperationMode>(item.data.i32[i]);
267 auto it = g_metaToFwSupportedMode_.find(opMode);
268 if (it == g_metaToFwSupportedMode_.end()) {
269 continue;
270 }
271 if (session->GetMode() == it->second) {
272 return true;
273 }
274 supportedModes.emplace_back(item.data.i32[i]);
275 }
276 MEDIA_DEBUG_LOG("PreviewOutput::IsDynamicSketchNotifySupported modes:%{public}s",
277 Container2String(supportedModes.begin(), supportedModes.end()).c_str());
278 return false;
279 // LCOV_EXCL_STOP
280 }
281
IsSketchSupported()282 bool PreviewOutput::IsSketchSupported()
283 {
284 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::IsSketchSupported");
285
286 auto sketchSize = FindSketchSize();
287 CHECK_RETURN_RET(sketchSize == nullptr, false);
288 // LCOV_EXCL_START
289 if (IsDynamicSketchNotifySupported()) {
290 return true;
291 }
292 MEDIA_INFO_LOG(
293 "IsSketchSupported FindSketchSize Size is %{public}dx%{public}d", sketchSize->width, sketchSize->height);
294 auto sketchRatio = GetSketchRatio();
295 CHECK_RETURN_RET(sketchRatio > 0, true);
296 MEDIA_DEBUG_LOG("IsSketchSupported GetSketchRatio failed, %{public}f ", sketchRatio);
297 auto session = GetSession();
298 CHECK_RETURN_RET(session == nullptr, false);
299 SketchWrapper::UpdateSketchStaticInfo(GetDeviceMetadata());
300 auto subModeNames = session->GetSubFeatureMods();
301 for (auto subModeName : subModeNames) {
302 float ratio = SketchWrapper::GetSketchEnableRatio(subModeName);
303 if (ratio > 0) {
304 MEDIA_DEBUG_LOG("IsSketchSupported GetSketchEnableRatio success,subMode:%{public}s, ratio:%{public}f ",
305 subModeName.Dump().c_str(), ratio);
306 return true;
307 }
308 }
309 return false;
310 // LCOV_EXCL_STOP
311 }
312
GetSketchRatio()313 float PreviewOutput::GetSketchRatio()
314 {
315 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::GetSketchRatio");
316
317 auto session = GetSession();
318 if (session == nullptr) {
319 MEDIA_WARNING_LOG("PreviewOutput::GetSketchRatio session is null");
320 return -1.0f;
321 }
322 // LCOV_EXCL_START
323 auto currentMode = session->GetFeaturesMode();
324 SketchWrapper::UpdateSketchStaticInfo(GetDeviceMetadata());
325 float ratio = SketchWrapper::GetSketchEnableRatio(currentMode);
326 if (ratio <= 0) {
327 MEDIA_WARNING_LOG("PreviewOutput::GetSketchRatio mode:%{public}s", currentMode.Dump().c_str());
328 }
329 return ratio;
330 // LCOV_EXCL_STOP
331 }
332
CreateSketchWrapper(Size sketchSize)333 int32_t PreviewOutput::CreateSketchWrapper(Size sketchSize)
334 {
335 // LCOV_EXCL_START
336 MEDIA_DEBUG_LOG("PreviewOutput::CreateSketchWrapper enter sketchSize is:%{public}d x %{public}d", sketchSize.width,
337 sketchSize.height);
338 auto session = GetSession();
339 CHECK_RETURN_RET_ELOG(
340 session == nullptr, ServiceToCameraError(CAMERA_INVALID_STATE), "EnableSketch session null");
341 auto wrapper = std::make_shared<SketchWrapper>(GetStream(), sketchSize, IsDynamicSketchNotifySupported());
342 sketchWrapper_ = wrapper;
343 wrapper->SetPreviewOutputCallbackManager(previewOutputListenerManager_);
344 auto metadata = GetDeviceMetadata();
345 int32_t retCode = wrapper->Init(metadata, session->GetFeaturesMode());
346 return ServiceToCameraError(retCode);
347 // LCOV_EXCL_STOP
348 }
349
EnableSketch(bool isEnable)350 int32_t PreviewOutput::EnableSketch(bool isEnable)
351 {
352 MEDIA_DEBUG_LOG("Enter Into PreviewOutput::EnableSketch %{public}d", isEnable);
353 CHECK_RETURN_RET_ELOG(!IsSketchSupported(), CameraErrorCode::OPERATION_NOT_ALLOWED,
354 "EnableSketch IsSketchSupported is false");
355 // LCOV_EXCL_START
356 int32_t errCode = CAMERA_UNKNOWN_ERROR;
357 std::lock_guard<std::mutex> lock(asyncOpMutex_);
358
359 auto session = GetSession();
360 CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionConfiged(),
361 CameraErrorCode::SESSION_NOT_CONFIG, "PreviewOutput Failed EnableSketch!, session not config");
362
363 if (isEnable) {
364 CHECK_RETURN_RET(sketchWrapper_ != nullptr, ServiceToCameraError(CAMERA_OPERATION_NOT_ALLOWED));
365 auto sketchSize = FindSketchSize();
366 CHECK_RETURN_RET_ELOG(sketchSize == nullptr, ServiceToCameraError(errCode),
367 "PreviewOutput EnableSketch FindSketchSize is null");
368 MEDIA_INFO_LOG("EnableSketch FindSketchSize Size is %{public}dx%{public}d",
369 sketchSize->width, sketchSize->height);
370 return CreateSketchWrapper(*sketchSize);
371 }
372
373 // Disable sketch branch
374 CHECK_RETURN_RET(sketchWrapper_ == nullptr, ServiceToCameraError(CAMERA_OPERATION_NOT_ALLOWED));
375 errCode = sketchWrapper_->Destroy();
376 sketchWrapper_ = nullptr;
377 return ServiceToCameraError(errCode);
378 // LCOV_EXCL_STOP
379 }
380
AttachSketchSurface(sptr<Surface> sketchSurface)381 int32_t PreviewOutput::AttachSketchSurface(sptr<Surface> sketchSurface)
382 {
383 // LCOV_EXCL_START
384 auto session = GetSession();
385 CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(),
386 CameraErrorCode::SESSION_NOT_CONFIG, "PreviewOutput Failed to AttachSketchSurface, session not commited");
387 CHECK_RETURN_RET(sketchWrapper_ == nullptr, CameraErrorCode::INVALID_ARGUMENT);
388 CHECK_RETURN_RET(sketchSurface == nullptr, CameraErrorCode::INVALID_ARGUMENT);
389 int32_t errCode = sketchWrapper_->AttachSketchSurface(sketchSurface);
390 return ServiceToCameraError(errCode);
391 // LCOV_EXCL_STOP
392 }
393
SetStream(sptr<IStreamCommon> stream)394 void PreviewOutput::SetStream(sptr<IStreamCommon> stream)
395 {
396 CaptureOutput::SetStream(stream);
397 CHECK_RETURN_ELOG(stream == nullptr, "PreviewOutput::SetStream stream is null");
398 sptr<IStreamRepeatCallback> callback = previewOutputListenerManager_;
399 static_cast<IStreamRepeat*>(stream.GetRefPtr())->SetCallback(callback);
400 }
401
CreateStream()402 int32_t PreviewOutput::CreateStream()
403 {
404 auto stream = GetStream();
405 CHECK_RETURN_RET_ELOG(
406 stream != nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED, "PreviewOutput::CreateStream stream is not null");
407 // LCOV_EXCL_START
408 auto producer = GetBufferProducer();
409 CHECK_RETURN_RET_ELOG(
410 producer == nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED, "PreviewOutput::CreateStream producer is null");
411 sptr<IStreamRepeat> streamPtr = nullptr;
412 auto previewProfile = GetPreviewProfile();
413 CHECK_RETURN_RET_ELOG(previewProfile == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
414 "PreviewOutput::CreateStream previewProfile is null");
415 int32_t res =
416 CameraManager::GetInstance()->CreatePreviewOutputStream(streamPtr, *previewProfile, GetBufferProducer());
417 SetStream(streamPtr);
418 CHECK_RETURN_RET_ELOG(
419 streamPtr == nullptr, CameraErrorCode::SERVICE_FATL_ERROR, "PreviewOutput::CreateStream streamPtr is null");
420 sptr<IStreamRepeatCallback> callback = previewOutputListenerManager_;
421 streamPtr->SetCallback(callback);
422 return res;
423 // LCOV_EXCL_STOP
424 }
425
GetFrameRateRange()426 const std::vector<int32_t>& PreviewOutput::GetFrameRateRange()
427 {
428 return previewFrameRateRange_;
429 }
430
SetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)431 void PreviewOutput::SetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
432 {
433 MEDIA_DEBUG_LOG("PreviewOutput::SetFrameRateRange min = %{public}d and max = %{public}d",
434 minFrameRate, maxFrameRate);
435 previewFrameRateRange_ = { minFrameRate, maxFrameRate };
436 }
437
SetOutputFormat(int32_t format)438 void PreviewOutput::SetOutputFormat(int32_t format)
439 {
440 MEDIA_DEBUG_LOG("PreviewOutput::SetOutputFormat set format %{public}d", format);
441 PreviewFormat_ = format;
442 }
443
SetSize(Size size)444 void PreviewOutput::SetSize(Size size)
445 {
446 MEDIA_DEBUG_LOG("PreviewOutput::SetSize set size %{public}d, %{public}d", size.width, size.height);
447 PreviewSize_ = size;
448 }
449
SetFrameRate(int32_t minFrameRate,int32_t maxFrameRate)450 int32_t PreviewOutput::SetFrameRate(int32_t minFrameRate, int32_t maxFrameRate)
451 {
452 int32_t result = canSetFrameRateRange(minFrameRate, maxFrameRate);
453 CHECK_RETURN_RET(result != CameraErrorCode::SUCCESS, result);
454 // LCOV_EXCL_START
455 CHECK_RETURN_RET_ELOG(minFrameRate == previewFrameRateRange_[0] && maxFrameRate == previewFrameRateRange_[1],
456 CameraErrorCode::INVALID_ARGUMENT, "PreviewOutput::SetFrameRate The frame rate does not need to be set.");
457 std::vector<int32_t> frameRateRange = {minFrameRate, maxFrameRate};
458 auto stream = GetStream();
459 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
460 if (itemStream) {
461 int32_t ret = itemStream->SetFrameRate(minFrameRate, maxFrameRate);
462 CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, ServiceToCameraError(ret),
463 "PreviewOutput::setFrameRate failed to set stream frame rate");
464 SetFrameRateRange(minFrameRate, maxFrameRate);
465 }
466 auto session = GetSession();
467 wptr<PreviewOutput> weakThis(this);
468 CHECK_EXECUTE(session != nullptr, session->AddFunctionToMap("preview" + std::to_string(OHOS_CONTROL_FPS_RANGES),
469 [weakThis, minFrameRate, maxFrameRate]() {
470 auto sharedThis = weakThis.promote();
471 CHECK_RETURN_ELOG(!sharedThis, "SetFrameRate previewOutput is nullptr.");
472 sharedThis->SetFrameRate(minFrameRate, maxFrameRate);
473 }));
474 return CameraErrorCode::SUCCESS;
475 // LCOV_EXCL_STOP
476 }
477
GetSupportedFrameRates()478 std::vector<std::vector<int32_t>> PreviewOutput::GetSupportedFrameRates()
479 {
480 MEDIA_DEBUG_LOG("PreviewOutput::GetSupportedFrameRates called.");
481 auto session = GetSession();
482 CHECK_RETURN_RET(session == nullptr, {});
483 // LCOV_EXCL_START
484 auto inputDevice = session->GetInputDevice();
485 CHECK_RETURN_RET(inputDevice == nullptr, {});
486 sptr<CameraDevice> camera = inputDevice->GetCameraDeviceInfo();
487 SceneMode curMode = session->GetMode();
488
489 sptr<CameraOutputCapability> cameraOutputCapability = CameraManager::GetInstance()->
490 GetSupportedOutputCapability(camera, curMode);
491 CHECK_RETURN_RET(cameraOutputCapability == nullptr, {});
492 std::vector<Profile> supportedProfiles = cameraOutputCapability->GetPreviewProfiles();
493 supportedProfiles.erase(std::remove_if(
494 supportedProfiles.begin(), supportedProfiles.end(),
495 [&](Profile& profile) {
496 return profile.format_ != PreviewFormat_ ||
497 profile.GetSize().height != PreviewSize_.height ||
498 profile.GetSize().width != PreviewSize_.width;
499 }), supportedProfiles.end());
500 std::vector<std::vector<int32_t>> supportedFrameRatesRange;
501 for (auto item : supportedProfiles) {
502 std::vector<int32_t> supportedFrameRatesItem = {item.fps_.minFps, item.fps_.maxFps};
503 supportedFrameRatesRange.emplace_back(supportedFrameRatesItem);
504 }
505 std::set<std::vector<int>> set(supportedFrameRatesRange.begin(), supportedFrameRatesRange.end());
506 supportedFrameRatesRange.assign(set.begin(), set.end());
507 MEDIA_DEBUG_LOG("PreviewOutput::GetSupportedFrameRates frameRateRange size:%{public}zu",
508 supportedFrameRatesRange.size());
509 return supportedFrameRatesRange;
510 // LCOV_EXCL_STOP
511 }
512
StartSketch()513 int32_t PreviewOutput::StartSketch()
514 {
515 int32_t errCode = CAMERA_UNKNOWN_ERROR;
516
517 auto session = GetSession();
518 CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(),
519 CameraErrorCode::SESSION_NOT_CONFIG,
520 "PreviewOutput Failed to StartSketch, session not commited");
521 // LCOV_EXCL_START
522 if (sketchWrapper_ != nullptr) {
523 errCode = sketchWrapper_->StartSketchStream();
524 }
525 return ServiceToCameraError(errCode);
526 // LCOV_EXCL_STOP
527 }
528
StopSketch()529 int32_t PreviewOutput::StopSketch()
530 {
531 int32_t errCode = CAMERA_UNKNOWN_ERROR;
532
533 auto session = GetSession();
534 CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(),
535 CameraErrorCode::SESSION_NOT_CONFIG,
536 "PreviewOutput Failed to StopSketch, session not commited");
537 // LCOV_EXCL_START
538 if (sketchWrapper_ != nullptr) {
539 errCode = sketchWrapper_->StopSketchStream();
540 }
541 return ServiceToCameraError(errCode);
542 // LCOV_EXCL_STOP
543 }
544
GetDeviceMetadata()545 std::shared_ptr<Camera::CameraMetadata> PreviewOutput::GetDeviceMetadata()
546 {
547 auto session = GetSession();
548 CHECK_RETURN_RET_ELOG(session == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata session is null");
549 // LCOV_EXCL_START
550 auto inputDevice = session->GetInputDevice();
551 CHECK_RETURN_RET_ELOG(inputDevice == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata input is null");
552 auto deviceInfo = inputDevice->GetCameraDeviceInfo();
553 CHECK_RETURN_RET_ELOG(deviceInfo == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata info is null");
554 auto metaData = deviceInfo->GetCachedMetadata();
555 CHECK_RETURN_RET_ELOG(metaData == nullptr, nullptr, "PreviewOutput::GetDeviceMetadata metaData is null");
556 return metaData;
557 // LCOV_EXCL_STOP
558 }
559
FindSketchSize()560 std::shared_ptr<Size> PreviewOutput::FindSketchSize()
561 {
562 auto session = GetSession();
563 auto metaData = GetDeviceMetadata();
564 CHECK_RETURN_RET_ELOG(session == nullptr || metaData == nullptr, nullptr,
565 "PreviewOutput::FindSketchSize GetDeviceMetadata failed");
566 // LCOV_EXCL_START
567 auto profile = GetPreviewProfile();
568 CHECK_RETURN_RET_ELOG(profile == nullptr, nullptr, "PreviewOutput::FindSketchSize profile is nullptr");
569 camera_format_t hdi_format = GetHdiFormatFromCameraFormat(profile->GetCameraFormat());
570 CHECK_RETURN_RET_ELOG(hdi_format == OHOS_CAMERA_FORMAT_IMPLEMENTATION_DEFINED, nullptr,
571 "PreviewOutput::FindSketchSize preview format is illegal");
572 auto sizeList = MetadataCommonUtils::GetSupportedPreviewSizeRange(
573 session->GetFeaturesMode().GetSceneMode(), hdi_format, metaData);
574 CHECK_RETURN_RET(sizeList == nullptr || sizeList->size() == 0, nullptr);
575 Size previewSize = profile->GetSize();
576 CHECK_RETURN_RET(previewSize.width <= 0 || previewSize.height <= 0, nullptr);
577 float ratio = static_cast<float>(previewSize.width) / previewSize.height;
578 MEDIA_INFO_LOG("PreviewOutput::FindSketchSize preview size:%{public}dx%{public}d,ratio:%{public}f",
579 previewSize.width, previewSize.height, ratio);
580 std::shared_ptr<Size> outSize;
581 for (auto size : *sizeList.get()) {
582 if (size.width >= previewSize.width || size.width < SKETCH_MIN_WIDTH) {
583 continue;
584 }
585 float checkRatio = static_cast<float>(size.width) / size.height;
586 MEDIA_DEBUG_LOG("PreviewOutput::FindSketchSize List size:%{public}dx%{public}d,ratio:%{public}f", size.width,
587 size.height, checkRatio);
588 if (abs(checkRatio - ratio) / ratio <= 0.05f) { // 0.05f is 5% tolerance
589 if (outSize == nullptr) {
590 outSize = std::make_shared<Size>(size);
591 } else if (size.width < outSize->width) {
592 outSize = std::make_shared<Size>(size);
593 }
594 }
595 }
596 return outSize;
597 // LCOV_EXCL_STOP
598 }
599
SetCallback(std::shared_ptr<PreviewStateCallback> callback)600 void PreviewOutput::SetCallback(std::shared_ptr<PreviewStateCallback> callback)
601 {
602 // LCOV_EXCL_START
603 auto stream = GetStream();
604 CHECK_RETURN(stream == nullptr);
605 bool isSuccess = previewOutputListenerManager_->AddListener(callback);
606 CHECK_RETURN(!isSuccess);
607 CHECK_RETURN(!(previewOutputListenerManager_->GetListenerCount() == 1));
608 sptr<IStreamRepeatCallback> ipcCallback = previewOutputListenerManager_;
609 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
610 int32_t errCode = itemStream->SetCallback(ipcCallback);
611 CHECK_RETURN(errCode == CAMERA_OK);
612 MEDIA_ERR_LOG("PreviewOutput::SetCallback fail");
613 previewOutputListenerManager_->RemoveListener(callback);
614 // LCOV_EXCL_STOP
615 }
616
RemoveCallback(std::shared_ptr<PreviewStateCallback> callback)617 void PreviewOutput::RemoveCallback(std::shared_ptr<PreviewStateCallback> callback)
618 {
619 // LCOV_EXCL_START
620 previewOutputListenerManager_->RemoveListener(callback);
621 if (previewOutputListenerManager_->GetListenerCount() == 0) {
622 auto stream = GetStream();
623 CHECK_RETURN(stream == nullptr);
624 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
625 itemStream->UnSetCallback();
626 }
627 // LCOV_EXCL_STOP
628 }
629
GetObserverControlTags()630 const std::set<camera_device_metadata_tag_t>& PreviewOutput::GetObserverControlTags()
631 {
632 const static std::set<camera_device_metadata_tag_t> tags = { OHOS_CONTROL_ZOOM_RATIO, OHOS_CONTROL_CAMERA_MACRO,
633 OHOS_CONTROL_MOON_CAPTURE_BOOST, OHOS_CONTROL_SMOOTH_ZOOM_RATIOS };
634 return tags;
635 }
636
GetObserverResultTags()637 const std::set<camera_device_metadata_tag_t>& PreviewOutput::GetObserverResultTags()
638 {
639 // LCOV_EXCL_START
640 const static std::set<camera_device_metadata_tag_t> tags = { OHOS_STATUS_SKETCH_STREAM_INFO };
641 return tags;
642 // LCOV_EXCL_STOP
643 }
644
OnControlMetadataChanged(const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)645 int32_t PreviewOutput::OnControlMetadataChanged(
646 const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
647 {
648 // LCOV_EXCL_START
649 // Don't trust outer public interface passthrough data. Check the legitimacy of the data.
650 CHECK_RETURN_RET(metadataItem.count <= 0, CAM_META_INVALID_PARAM);
651 CHECK_RETURN_RET(sketchWrapper_ == nullptr, CAM_META_FAILURE);
652 auto session = GetSession();
653 CHECK_RETURN_RET(session == nullptr, CAM_META_FAILURE);
654 std::lock_guard<std::mutex> lock(asyncOpMutex_);
655 SketchWrapper* wrapper = reinterpret_cast<SketchWrapper*>(sketchWrapper_.get());
656 wrapper->OnMetadataDispatch(session->GetFeaturesMode(), tag, metadataItem);
657 return CAM_META_SUCCESS;
658 // LCOV_EXCL_STOP
659 }
660
OnResultMetadataChanged(const camera_device_metadata_tag_t tag,const camera_metadata_item_t & metadataItem)661 int32_t PreviewOutput::OnResultMetadataChanged(
662 const camera_device_metadata_tag_t tag, const camera_metadata_item_t& metadataItem)
663 {
664 // LCOV_EXCL_START
665 // Don't trust outer public interface passthrough data. Check the legitimacy of the data.
666 CHECK_RETURN_RET(metadataItem.count <= 0, CAM_META_INVALID_PARAM);
667 CHECK_RETURN_RET(sketchWrapper_ == nullptr, CAM_META_FAILURE);
668 auto session = GetSession();
669 CHECK_RETURN_RET(session == nullptr, CAM_META_FAILURE);
670 std::lock_guard<std::mutex> lock(asyncOpMutex_);
671 SketchWrapper* wrapper = reinterpret_cast<SketchWrapper*>(sketchWrapper_.get());
672 wrapper->OnMetadataDispatch(session->GetFeaturesMode(), tag, metadataItem);
673 return CAM_META_SUCCESS;
674 // LCOV_EXCL_STOP
675 }
676
GetPreviewOutputListenerManager()677 sptr<PreviewOutputListenerManager> PreviewOutput::GetPreviewOutputListenerManager()
678 {
679 return previewOutputListenerManager_;
680 }
681
OnNativeRegisterCallback(const std::string & eventString)682 void PreviewOutput::OnNativeRegisterCallback(const std::string& eventString)
683 {
684 // LCOV_EXCL_START
685 if (eventString == CONST_SKETCH_STATUS_CHANGED) {
686 std::lock_guard<std::mutex> lock(asyncOpMutex_);
687 CHECK_RETURN(sketchWrapper_ == nullptr);
688 auto session = GetSession();
689 CHECK_RETURN(session == nullptr || !session->IsSessionCommited());
690 auto metadata = GetDeviceMetadata();
691 CHECK_RETURN_ELOG(metadata == nullptr, "metadata is nullptr");
692 camera_metadata_item_t item;
693 int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_ZOOM_RATIO, &item);
694 CHECK_RETURN(ret != CAM_META_SUCCESS || item.count <= 0);
695 float tagRatio = *item.data.f;
696 CHECK_RETURN(tagRatio <= 0);
697 float sketchRatio = sketchWrapper_->GetSketchEnableRatio(session->GetFeaturesMode());
698 MEDIA_DEBUG_LOG("PreviewOutput::OnNativeRegisterCallback OHOS_CONTROL_ZOOM_RATIO >>> tagRatio:%{public}f -- "
699 "sketchRatio:%{public}f",
700 tagRatio, sketchRatio);
701 sketchWrapper_->UpdateSketchRatio(sketchRatio);
702 sketchWrapper_->UpdateZoomRatio(tagRatio);
703 }
704 // LCOV_EXCL_STOP
705 }
706
OnNativeUnregisterCallback(const std::string & eventString)707 void PreviewOutput::OnNativeUnregisterCallback(const std::string& eventString)
708 {
709 // LCOV_EXCL_START
710 if (eventString == CONST_SKETCH_STATUS_CHANGED) {
711 std::lock_guard<std::mutex> lock(asyncOpMutex_);
712 CHECK_RETURN(sketchWrapper_ == nullptr);
713 sketchWrapper_->StopSketchStream();
714 }
715 // LCOV_EXCL_STOP
716 }
717
CameraServerDied(pid_t pid)718 void PreviewOutput::CameraServerDied(pid_t pid)
719 {
720 // LCOV_EXCL_START
721 MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
722 previewOutputListenerManager_->TriggerListener([](auto listener) {
723 int32_t serviceErrorType = ServiceToCameraError(CAMERA_INVALID_STATE);
724 listener->OnError(serviceErrorType);
725 });
726 // LCOV_EXCL_STOP
727 }
728
canSetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)729 int32_t PreviewOutput::canSetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
730 {
731 auto session = GetSession();
732 CHECK_RETURN_RET_ELOG(session == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
733 "PreviewOutput::canSetFrameRateRange Can not set frame rate range without commit session");
734 // LCOV_EXCL_START
735 CHECK_RETURN_RET_ELOG(!session->CanSetFrameRateRange(minFrameRate, maxFrameRate, this),
736 CameraErrorCode::UNRESOLVED_CONFLICTS_BETWEEN_STREAMS,
737 "PreviewOutput::canSetFrameRateRange Can not set frame rate range with wrong state of output");
738 int32_t minIndex = 0;
739 int32_t maxIndex = 1;
740 std::vector<std::vector<int32_t>> supportedFrameRange = GetSupportedFrameRates();
741 for (auto item : supportedFrameRange) {
742 CHECK_RETURN_RET(item[minIndex] <= minFrameRate && item[maxIndex] >= maxFrameRate,
743 CameraErrorCode::SUCCESS);
744 }
745 MEDIA_WARNING_LOG("PreviewOutput::canSetFrameRateRange Can not set frame rate range with invalid parameters");
746 return CameraErrorCode::INVALID_ARGUMENT;
747 // LCOV_EXCL_STOP
748 }
749
GetPreviewRotation(int32_t imageRotation)750 int32_t PreviewOutput::GetPreviewRotation(int32_t imageRotation)
751 {
752 MEDIA_INFO_LOG("PreviewOutput GetPreviewRotation is called");
753 CHECK_RETURN_RET_ELOG(imageRotation % ROTATION_90_DEGREES != 0, INVALID_ARGUMENT,
754 "PreviewOutput GetPreviewRotation error!, invalid argument");
755 int32_t sensorOrientation = 0;
756 ImageRotation result = ImageRotation::ROTATION_0;
757 sptr<CameraDevice> cameraObj;
758 auto session = GetSession();
759 CHECK_RETURN_RET_ELOG(session == nullptr, SERVICE_FATL_ERROR,
760 "PreviewOutput GetPreviewRotation error!, session is nullptr");
761 // LCOV_EXCL_START
762 auto inputDevice = session->GetInputDevice();
763 CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
764 "PreviewOutput GetPreviewRotation error!, inputDevice is nullptr");
765 cameraObj = inputDevice->GetCameraDeviceInfo();
766 CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
767 "PreviewOutput GetPreviewRotation error!, cameraObj is nullptr");
768 uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
769 if (apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN) {
770 imageRotation = JudegRotationFunc(imageRotation);
771 }
772 sensorOrientation = static_cast<int32_t>(cameraObj->GetCameraOrientation());
773 result = (ImageRotation)((imageRotation + sensorOrientation) % CAPTURE_ROTATION_BASE);
774 MEDIA_INFO_LOG("PreviewOutput GetPreviewRotation :result %{public}d, sensorOrientation:%{public}d",
775 result, sensorOrientation);
776 return result;
777 // LCOV_EXCL_STOP
778 }
779
JudegRotationFunc(int32_t imageRotation)780 int32_t PreviewOutput::JudegRotationFunc(int32_t imageRotation)
781 {
782 std::string deviceType = OHOS::system::GetDeviceType();
783 if (imageRotation > CAPTURE_ROTATION_BASE) {
784 return INVALID_ARGUMENT;
785 }
786 bool isTableFlag = system::GetBoolParameter("const.multimedia.enable_camera_rotation_compensation", 0);
787 uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
788 if (isTableFlag && apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN) {
789 imageRotation = ((imageRotation - ROTATION_90_DEGREES + CAPTURE_ROTATION_BASE) % CAPTURE_ROTATION_BASE);
790 }
791 return imageRotation;
792 }
793
SetPreviewRotation(int32_t imageRotation,bool isDisplayLocked)794 int32_t PreviewOutput::SetPreviewRotation(int32_t imageRotation, bool isDisplayLocked)
795 {
796 MEDIA_INFO_LOG("PreviewOutput SetPreviewRotation is called");
797 CHECK_RETURN_RET_ELOG(imageRotation % ROTATION_90_DEGREES != 0, INVALID_ARGUMENT,
798 "PreviewOutput SetPreviewRotation error!, invalid argument");
799 int32_t sensorOrientation = 0;
800 ImageRotation result = ROTATION_0;
801 sptr<CameraDevice> cameraObj;
802 auto session = GetSession();
803 CHECK_RETURN_RET_ELOG(session == nullptr, SERVICE_FATL_ERROR,
804 "PreviewOutput SetPreviewRotation error!, session is nullptr");
805 // LCOV_EXCL_START
806 session->SetHasFitedRotation(true);
807 auto inputDevice = session->GetInputDevice();
808 CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
809 "PreviewOutput SetPreviewRotation error!, inputDevice is nullptr");
810 cameraObj = inputDevice->GetCameraDeviceInfo();
811 CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
812 "PreviewOutput SetPreviewRotation error!, cameraObj is nullptr");
813 sensorOrientation = static_cast<int32_t>(cameraObj->GetCameraOrientation());
814 result = isDisplayLocked ? ImageRotation(sensorOrientation) : ImageRotation(imageRotation);
815 MEDIA_INFO_LOG("PreviewOutput SetPreviewRotation :result %{public}d, sensorOrientation:%{public}d",
816 result, sensorOrientation);
817 auto stream = GetStream();
818 sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
819 int32_t errCode = CAMERA_UNKNOWN_ERROR;
820 CHECK_RETURN_RET_ELOG(itemStream == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
821 "PreviewOutput::SetCameraRotation() itemStream is nullptr");
822 if (itemStream) {
823 errCode = itemStream->SetCameraRotation(true, result);
824 CHECK_RETURN_RET_ELOG(errCode != CAMERA_OK, SERVICE_FATL_ERROR,
825 "Failed to SetCameraRotation!, errCode: %{public}d", errCode);
826 }
827 MEDIA_ERR_LOG("PreviewOutput SetPreviewRotation sucess");
828 return CameraErrorCode::SUCCESS;
829 // LCOV_EXCL_STOP
830 }
831
IsXComponentSwap()832 bool PreviewOutput::IsXComponentSwap()
833 {
834 // LCOV_EXCL_START
835 sptr<OHOS::Rosen::Display> display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
836 if (display == nullptr) {
837 MEDIA_ERR_LOG("Get display info failed");
838 display = OHOS::Rosen::DisplayManager::GetInstance().GetDisplayById(0);
839 CHECK_RETURN_RET_ELOG(display == nullptr, true, "Get display info failed, display is nullptr");
840 }
841 uint32_t currentRotation = static_cast<uint32_t>(display->GetRotation()) * 90;
842 std::string deviceType = OHOS::system::GetDeviceType();
843 uint32_t apiCompatibleVersion = CameraApiVersion::GetApiVersion();
844 MEDIA_INFO_LOG("deviceType=%{public}s, apiCompatibleVersion=%{public}d", deviceType.c_str(),
845 apiCompatibleVersion);
846 // The tablet has incompatible changes in API14; use version isolation for compilation.
847 CHECK_EXECUTE(apiCompatibleVersion < CameraApiVersion::APIVersion::API_FOURTEEN && deviceType == "tablet",
848 currentRotation = (currentRotation + STREAM_ROTATE_270) % (STREAM_ROTATE_270 + STREAM_ROTATE_90));
849 uint32_t cameraRotation = 0;
850 CHECK_RETURN_RET_ELOG(GetCameraDeviceRotationAngle(cameraRotation) != CAMERA_OK,
851 false, "Get camera rotation failed");
852 MEDIA_INFO_LOG("display rotation: %{public}d, camera rotation: %{public}d", currentRotation, cameraRotation);
853 uint32_t rotationAngle = (currentRotation + cameraRotation) % (STREAM_ROTATE_270 + STREAM_ROTATE_90);
854 CHECK_RETURN_RET(rotationAngle == STREAM_ROTATE_90 || rotationAngle == STREAM_ROTATE_270, true);
855 return false;
856 // LCOV_EXCL_STOP
857 }
858
GetCameraDeviceRotationAngle(uint32_t & cameraRotation)859 int32_t PreviewOutput::GetCameraDeviceRotationAngle(uint32_t &cameraRotation)
860 {
861 // LCOV_EXCL_START
862 auto session = GetSession();
863 CHECK_RETURN_RET_ELOG(session == nullptr, SERVICE_FATL_ERROR,
864 "GetCameraDeviceRotationAngle sesion is null");
865 auto inputDevice = session->GetInputDevice();
866 CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
867 "GetCameraDeviceRotationAngle inputDevice is null");
868 auto deviceInfo = inputDevice->GetCameraDeviceInfo();
869 CHECK_RETURN_RET_ELOG(deviceInfo == nullptr, SERVICE_FATL_ERROR,
870 "GetCameraDeviceRotationAngle deviceInfo is null");
871 cameraRotation = deviceInfo->GetCameraOrientation();
872 return CAMERA_OK;
873 // LCOV_EXCL_STOP
874 }
875
876 // LCOV_EXCL_START
AdjustRenderFit()877 void PreviewOutput::AdjustRenderFit()
878 {
879 int32_t renderFitNumber = 0;
880 bool isRenderFitNewVersionEnabled = false;
881 auto surfaceId = GetSurfaceId();
882 int32_t ret = OHOS::Ace::XComponentController::GetRenderFitBySurfaceId(
883 surfaceId, renderFitNumber, isRenderFitNewVersionEnabled);
884 MEDIA_INFO_LOG("GetRenderFitBySurfaceId ret: %{public}d, renderFitNumber: %{public}d,"
885 "isRenderFitNewVersionEnabled: %{public}d",
886 ret, renderFitNumber, isRenderFitNewVersionEnabled);
887 CHECK_RETURN_ELOG(ret != 0 || renderFitNumber != RENDER_FIL_FILL, "Conditions not met");
888 uint64_t outputSurfaceId;
889 std::stringstream iss(surfaceId);
890 iss >> outputSurfaceId;
891 OHNativeWindow *outputNativeWindow = nullptr;
892 ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(outputSurfaceId, &outputNativeWindow);
893 CHECK_RETURN_ELOG(ret != 0,
894 "The AdjustRenderFit call failed due to a failure in the CreateNativeWindowFromSurfaceId interface call,"
895 "ret: %{public}d", ret);
896 int code = GET_BUFFER_GEOMETRY;
897 int xComponentWidth = 0;
898 int xComponentHeight = 0;
899 // Get the width and height of XComponent
900 ret = OH_NativeWindow_NativeWindowHandleOpt(outputNativeWindow, code, &xComponentHeight, &xComponentWidth);
901 MEDIA_INFO_LOG("The width of the XComponent is %{public}d, and the height is %{public}d",
902 xComponentWidth, xComponentHeight);
903 OH_NativeWindow_DestroyNativeWindow(outputNativeWindow);
904 CHECK_RETURN_ELOG(ret != 0 || xComponentHeight * xComponentWidth == 0,
905 "The AdjustRenderFit call failed because the xComponentWidth x xComponentHeight equals 0."
906 "ret: %{public}d", ret);
907 if (IsXComponentSwap()) {
908 MEDIA_INFO_LOG("XComponent width and height need to swap");
909 int temp = xComponentWidth;
910 xComponentWidth = xComponentHeight;
911 xComponentHeight = temp;
912 }
913 CHECK_RETURN_ELOG(PreviewSize_.width * PreviewSize_.height == 0,
914 "The AdjustRenderFit call failed because the previewWidth x previewHeight equals 0");
915 float cameraRatio = (float)PreviewSize_.width / (float)PreviewSize_.height;
916 float XComponentRatio = (float)xComponentWidth / (float)xComponentHeight;
917 CHECK_RETURN_ELOG(abs(cameraRatio - XComponentRatio) < TARGET_MIN_RATIO,
918 "XComponent ratio matched camera ratio, no need adjust renderFit");
919 ret = OHOS::Ace::XComponentController::SetRenderFitBySurfaceId(surfaceId, RENDER_FIL_COVER, true);
920 CHECK_RETURN_ELOG(ret != 0, "SetRenderFitBySurfaceId ret: %{public}d", ret);
921 } // LCOV_EXCL_STOP
922
SetSurfaceId(const std::string & surfaceId)923 void PreviewOutput::SetSurfaceId(const std::string& surfaceId)
924 {
925 // LCOV_EXCL_START
926 std::lock_guard<std::mutex> lock(surfaceIdMutex_);
927 surfaceId_ = surfaceId;
928 // LCOV_EXCL_STOP
929 }
930
GetSurfaceId()931 std::string PreviewOutput::GetSurfaceId()
932 {
933 // LCOV_EXCL_START
934 std::lock_guard<std::mutex> lock(surfaceIdMutex_);
935 return surfaceId_;
936 // LCOV_EXCL_STOP
937 }
938 } // namespace CameraStandard
939 } // namespace OHOS
940