• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "output/preview_output.h"
17 
18 #include <cstdint>
19 #include <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