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