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