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