• 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/video_output.h"
17 
18 #include "camera_log.h"
19 #include "camera_manager.h"
20 #include "camera_util.h"
21 #include "input/camera_device.h"
22 #include "istream_repeat.h"
23 
24 namespace OHOS {
25 namespace CameraStandard {
26 constexpr int32_t FRAMERATE_120 = 120;
VideoOutput(sptr<IBufferProducer> bufferProducer)27 VideoOutput::VideoOutput(sptr<IBufferProducer> bufferProducer)
28     : CaptureOutput(CAPTURE_OUTPUT_TYPE_VIDEO, StreamType::REPEAT, bufferProducer, nullptr)
29 {
30     videoFormat_ = 0;
31     videoSize_.height = 0;
32     videoSize_.width = 0;
33 }
34 
~VideoOutput()35 VideoOutput::~VideoOutput()
36 {
37 }
38 
OnFrameStarted()39 int32_t VideoOutputCallbackImpl::OnFrameStarted()
40 {
41     // LCOV_EXCL_START
42     CAMERA_SYNC_TRACE;
43     auto item = videoOutput_.promote();
44     if (item != nullptr && item->GetApplicationCallback() != nullptr) {
45         item->GetApplicationCallback()->OnFrameStarted();
46     } else {
47         MEDIA_INFO_LOG("Discarding VideoOutputCallbackImpl::OnFrameStarted callback in video");
48     }
49     return CAMERA_OK;
50     // LCOV_EXCL_STOP
51 }
52 
OnFrameEnded(const int32_t frameCount)53 int32_t VideoOutputCallbackImpl::OnFrameEnded(const int32_t frameCount)
54 {
55     // LCOV_EXCL_START
56     CAMERA_SYNC_TRACE;
57     auto item = videoOutput_.promote();
58     if (item != nullptr && item->GetApplicationCallback() != nullptr) {
59         item->GetApplicationCallback()->OnFrameEnded(frameCount);
60     } else {
61         MEDIA_INFO_LOG("Discarding VideoOutputCallbackImpl::OnFrameEnded callback in video");
62     }
63     return CAMERA_OK;
64     // LCOV_EXCL_STOP
65 }
66 
OnFrameError(const int32_t errorCode)67 int32_t VideoOutputCallbackImpl::OnFrameError(const int32_t errorCode)
68 {
69     // LCOV_EXCL_START
70     auto item = videoOutput_.promote();
71     if (item != nullptr && item->GetApplicationCallback() != nullptr) {
72         item->GetApplicationCallback()->OnError(errorCode);
73     } else {
74         MEDIA_INFO_LOG("Discarding VideoOutputCallbackImpl::OnFrameError callback in video");
75     }
76     return CAMERA_OK;
77     // LCOV_EXCL_STOP
78 }
79 
OnSketchStatusChanged(SketchStatus status)80 int32_t VideoOutputCallbackImpl::OnSketchStatusChanged(SketchStatus status)
81 {
82     // Empty implement
83     return CAMERA_OK;
84 }
85 
OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt & captureEndedInfo)86 int32_t VideoOutputCallbackImpl::OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt &captureEndedInfo)
87 {
88     // LCOV_EXCL_START
89     MEDIA_INFO_LOG("VideoOutputCallbackImpl::OnDeferredVideoEnhancementInfo callback in video");
90     auto item = videoOutput_.promote();
91     if (item != nullptr && item->GetApplicationCallback() != nullptr) {
92         item->GetApplicationCallback()->OnDeferredVideoEnhancementInfo(captureEndedInfo);
93     } else {
94         MEDIA_INFO_LOG("Discarding VideoOutputCallbackImpl::OnDeferredVideoEnhancementInfo callback in video");
95     }
96     return CAMERA_OK;
97     // LCOV_EXCL_STOP
98 }
99 
SetCallback(std::shared_ptr<VideoStateCallback> callback)100 void VideoOutput::SetCallback(std::shared_ptr<VideoStateCallback> callback)
101 {
102     // LCOV_EXCL_START
103     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
104     appCallback_ = callback;
105     if (appCallback_ != nullptr) {
106         if (svcCallback_ == nullptr) {
107             svcCallback_ = new (std::nothrow) VideoOutputCallbackImpl(this);
108             if (svcCallback_ == nullptr) {
109                 MEDIA_ERR_LOG("new VideoOutputCallbackImpl Failed to register callback");
110                 appCallback_ = nullptr;
111                 return;
112             }
113         }
114         CHECK_RETURN_ELOG(GetStream() == nullptr, "VideoOutput Failed to SetCallback!, GetStream is nullptr");
115         int32_t errorCode = CAMERA_OK;
116         auto stream = GetStream();
117         sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
118         CHECK_PRINT_ELOG(itemStream == nullptr, "VideoOutput::SetCallback itemStream is nullptr");
119         if (itemStream) {
120             errorCode = itemStream->SetCallback(svcCallback_);
121         }
122 
123         CHECK_RETURN(errorCode == CAMERA_OK);
124         MEDIA_ERR_LOG("VideoOutput::SetCallback: Failed to register callback, errorCode: %{public}d", errorCode);
125         svcCallback_ = nullptr;
126         appCallback_ = nullptr;
127     }
128     // LCOV_EXCL_STOP
129 }
130 
Start()131 int32_t VideoOutput::Start()
132 {
133     std::lock_guard<std::mutex> lock(asyncOpMutex_);
134     MEDIA_DEBUG_LOG("Enter Into VideoOutput::Start");
135     auto session = GetSession();
136     CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(),
137         CameraErrorCode::SESSION_NOT_CONFIG, "VideoOutput Failed to Start, session not commited");
138     // LCOV_EXCL_START
139     CHECK_RETURN_RET_ELOG(GetStream() == nullptr,
140         CameraErrorCode::SERVICE_FATL_ERROR, "VideoOutput Failed to Start!, GetStream is nullptr");
141     if (!GetFrameRateRange().empty() && GetFrameRateRange()[0] >= FRAMERATE_120) {
142         MEDIA_INFO_LOG("EnableFaceDetection is call");
143         session->EnableFaceDetection(false);
144     }
145     auto stream = GetStream();
146     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
147     int32_t errCode = CAMERA_UNKNOWN_ERROR;
148     CHECK_RETURN_RET_ELOG(itemStream == nullptr, ServiceToCameraError(errCode),
149         "VideoOutput::Start() itemStream is nullptr");
150     if (itemStream) {
151         errCode = itemStream->Start();
152         CHECK_PRINT_ELOG(errCode != CAMERA_OK, "VideoOutput Failed to Start!, errCode: %{public}d", errCode);
153         isVideoStarted_ = true;
154     }
155     return ServiceToCameraError(errCode);
156     // LCOV_EXCL_STOP
157 }
158 
Stop()159 int32_t VideoOutput::Stop()
160 {
161     std::lock_guard<std::mutex> lock(asyncOpMutex_);
162     MEDIA_DEBUG_LOG("Enter Into VideoOutput::Stop");
163     CHECK_RETURN_RET_ELOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
164         "VideoOutput Failed to Stop!, GetStream is nullptr");
165     auto stream = GetStream();
166     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
167     int32_t errCode = CAMERA_UNKNOWN_ERROR;
168     CHECK_PRINT_ELOG(itemStream == nullptr, "VideoOutput::Stop() itemStream is nullptr");
169     if (itemStream) {
170         errCode = itemStream->Stop();
171         CHECK_PRINT_ELOG(errCode != CAMERA_OK, "VideoOutput Failed to Stop!, errCode: %{public}d", errCode);
172         isVideoStarted_ = false;
173     }
174     // LCOV_EXCL_START
175     if (!GetFrameRateRange().empty() && GetFrameRateRange()[0] >= FRAMERATE_120) {
176         auto session = GetSession();
177         CHECK_RETURN_RET_ELOG(session == nullptr || !session->IsSessionCommited(),
178             CameraErrorCode::SESSION_NOT_CONFIG, "VideoOutput Failed to Start, session not commited");
179         MEDIA_INFO_LOG("EnableFaceDetection is call");
180         session->EnableFaceDetection(true);
181     }
182     // LCOV_EXCL_STOP
183     return ServiceToCameraError(errCode);
184 }
185 
Resume()186 int32_t VideoOutput::Resume()
187 {
188     std::lock_guard<std::mutex> lock(asyncOpMutex_);
189     MEDIA_DEBUG_LOG("Enter Into VideoOutput::Resume");
190     CHECK_RETURN_RET_ELOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
191         "VideoOutput Failed to Resume!, GetStream is nullptr");
192     auto stream = GetStream();
193     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
194     int32_t errCode = CAMERA_UNKNOWN_ERROR;
195     CHECK_RETURN_RET_ELOG(itemStream == nullptr, ServiceToCameraError(errCode),
196         "VideoOutput::Resume() itemStream is nullptr");
197     if (itemStream) {
198         errCode = itemStream->Start();
199         isVideoStarted_ = true;
200     }
201     return ServiceToCameraError(errCode);
202 }
203 
Pause()204 int32_t VideoOutput::Pause()
205 {
206     std::lock_guard<std::mutex> lock(asyncOpMutex_);
207     MEDIA_DEBUG_LOG("Enter Into VideoOutput::Pause");
208     CHECK_RETURN_RET_ELOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
209         "VideoOutput Failed to Pause!, GetStream is nullptr");
210     auto stream = GetStream();
211     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
212     int32_t errCode = CAMERA_UNKNOWN_ERROR;
213     CHECK_RETURN_RET_ELOG(itemStream == nullptr, errCode,
214         "VideoOutput::Pause() itemStream is nullptr");
215     if (itemStream) {
216         errCode = itemStream->Stop();
217         isVideoStarted_ = false;
218     }
219     return errCode;
220 }
221 
CreateStream()222 int32_t VideoOutput::CreateStream()
223 {
224     auto stream = GetStream();
225     CHECK_RETURN_RET_ELOG(stream != nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED,
226         "VideoOutput::CreateStream stream is not null");
227     // LCOV_EXCL_START
228     auto producer = GetBufferProducer();
229     CHECK_RETURN_RET_ELOG(producer == nullptr, CameraErrorCode::OPERATION_NOT_ALLOWED,
230         "VideoOutput::CreateStream producer is not null");
231     sptr<IStreamRepeat> streamPtr = nullptr;
232     auto videoProfile = GetVideoProfile();
233     CHECK_RETURN_RET_ELOG(videoProfile == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
234         "VideoOutput::CreateStream video profile is not null");
235     int32_t retCode =
236         CameraManager::GetInstance()->CreateVideoOutputStream(streamPtr, *videoProfile, GetBufferProducer());
237     CHECK_PRINT_ELOG(retCode != CameraErrorCode::SUCCESS,
238         "VideoOutput::CreateStream fail! error code :%{public}d", retCode);
239     SetStream(streamPtr);
240     return retCode;
241     // LCOV_EXCL_STOP
242 }
243 
Release()244 int32_t VideoOutput::Release()
245 {
246     {
247         std::lock_guard<std::mutex> lock(outputCallbackMutex_);
248         svcCallback_ = nullptr;
249         appCallback_ = nullptr;
250     }
251     std::lock_guard<std::mutex> lock(asyncOpMutex_);
252     MEDIA_DEBUG_LOG("Enter Into VideoOutput::Release");
253     CHECK_RETURN_RET_ELOG(GetStream() == nullptr, CameraErrorCode::SERVICE_FATL_ERROR,
254         "VideoOutput Failed to Release!, GetStream is nullptr");
255     auto stream = GetStream();
256     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
257     int32_t errCode = CAMERA_UNKNOWN_ERROR;
258     CHECK_PRINT_ELOG(itemStream == nullptr, "VideoOutput::Release() itemStream is nullptr");
259     if (itemStream) {
260         errCode = itemStream->Release();
261     }
262     CHECK_PRINT_ELOG(errCode != CAMERA_OK, "Failed to release VideoOutput!, errCode: %{public}d", errCode);
263     CaptureOutput::Release();
264     isVideoStarted_ = false;
265     return ServiceToCameraError(errCode);
266 }
267 
GetApplicationCallback()268 std::shared_ptr<VideoStateCallback> VideoOutput::GetApplicationCallback()
269 {
270     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
271     return appCallback_;
272 }
273 
GetFrameRateRange()274 const std::vector<int32_t>& VideoOutput::GetFrameRateRange()
275 {
276     return videoFrameRateRange_;
277 }
278 
SetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)279 void VideoOutput::SetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
280 {
281     MEDIA_DEBUG_LOG("VideoOutput::SetFrameRateRange min = %{public}d and max = %{public}d", minFrameRate, maxFrameRate);
282 
283     videoFrameRateRange_ = { minFrameRate, maxFrameRate };
284 }
285 
SetOutputFormat(int32_t format)286 void VideoOutput::SetOutputFormat(int32_t format)
287 {
288     MEDIA_DEBUG_LOG("VideoOutput::SetOutputFormat set format %{public}d", format);
289     videoFormat_ = format;
290 }
291 
SetSize(Size size)292 void VideoOutput::SetSize(Size size)
293 {
294     videoSize_ = size;
295 }
296 
SetFrameRate(int32_t minFrameRate,int32_t maxFrameRate)297 int32_t VideoOutput::SetFrameRate(int32_t minFrameRate, int32_t maxFrameRate)
298 {
299     int32_t result = canSetFrameRateRange(minFrameRate, maxFrameRate);
300     CHECK_RETURN_RET(result != CameraErrorCode::SUCCESS, result);
301     // LCOV_EXCL_START
302     CHECK_RETURN_RET_ELOG(minFrameRate == videoFrameRateRange_[0] && maxFrameRate == videoFrameRateRange_[1],
303         CameraErrorCode::INVALID_ARGUMENT, "VideoOutput::SetFrameRate The frame rate does not need to be set.");
304     auto stream = GetStream();
305     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
306     if (itemStream) {
307         int32_t ret = itemStream->SetFrameRate(minFrameRate, maxFrameRate);
308         CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, ServiceToCameraError(ret),
309             "VideoOutput::setFrameRate failed to set stream frame rate");
310         SetFrameRateRange(minFrameRate, maxFrameRate);
311     }
312     return CameraErrorCode::SUCCESS;
313     // LCOV_EXCL_STOP
314 }
315 
GetSupportedFrameRates()316 std::vector<std::vector<int32_t>> VideoOutput::GetSupportedFrameRates()
317 {
318     MEDIA_DEBUG_LOG("VideoOutput::GetSupportedFrameRates called.");
319     auto session = GetSession();
320     CHECK_RETURN_RET(session == nullptr, {});
321     // LCOV_EXCL_START
322     auto inputDevice = session->GetInputDevice();
323     CHECK_RETURN_RET(inputDevice == nullptr, {});
324 
325     sptr<CameraDevice> camera = inputDevice->GetCameraDeviceInfo();
326     sptr<CameraOutputCapability> cameraOutputCapability =
327                                  CameraManager::GetInstance()->GetSupportedOutputCapability(camera, SceneMode::VIDEO);
328     CHECK_RETURN_RET(cameraOutputCapability == nullptr, {});
329     std::vector<VideoProfile> supportedProfiles = cameraOutputCapability->GetVideoProfiles();
330     supportedProfiles.erase(std::remove_if(
331         supportedProfiles.begin(), supportedProfiles.end(),
332         [&](Profile& profile) {
333             return profile.format_ != videoFormat_ ||
334                    profile.GetSize().height != videoSize_.height ||
335                    profile.GetSize().width != videoSize_.width;
336         }), supportedProfiles.end());
337     std::vector<std::vector<int32_t>> supportedFrameRatesRange;
338     for (auto item : supportedProfiles) {
339         supportedFrameRatesRange.emplace_back(item.GetFrameRates());
340     }
341     std::set<std::vector<int>> set(supportedFrameRatesRange.begin(), supportedFrameRatesRange.end());
342     supportedFrameRatesRange.assign(set.begin(), set.end());
343     MEDIA_DEBUG_LOG("VideoOutput::GetSupportedFrameRates frameRateRange size:%{public}zu",
344                     supportedFrameRatesRange.size());
345     return supportedFrameRatesRange;
346     // LCOV_EXCL_STOP
347 }
348 
enableMirror(bool enabled)349 int32_t VideoOutput::enableMirror(bool enabled)
350 {
351     auto session = GetSession();
352     CHECK_RETURN_RET_ELOG(session == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
353         "Can not enable mirror, session is not config");
354     // LCOV_EXCL_START
355     auto stream = GetStream();
356     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
357     CHECK_RETURN_RET_ELOG(!itemStream || !IsMirrorSupported(), CameraErrorCode::INVALID_ARGUMENT,
358         "VideoOutput::enableMirror not supported mirror or stream is null");
359     int32_t retCode = itemStream->SetMirror(enabled);
360     CHECK_RETURN_RET_ELOG(retCode != CAMERA_OK, ServiceToCameraError(retCode),
361         "VideoOutput::enableMirror failed to set mirror");
362     return CameraErrorCode::SUCCESS;
363     // LCOV_EXCL_STOP
364 }
365 
IsMirrorSupported()366 bool VideoOutput::IsMirrorSupported()
367 {
368     auto session = GetSession();
369     CHECK_RETURN_RET_ELOG(session == nullptr, false, "VideoOutput IsMirrorSupported error!, session is nullptr");
370     // LCOV_EXCL_START
371     auto inputDevice = session->GetInputDevice();
372     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, false,
373         "VideoOutput IsMirrorSupported error!, inputDevice is nullptr");
374     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
375     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, false,
376         "VideoOutput IsMirrorSupported error!, cameraObj is nullptr");
377     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetCachedMetadata();
378     CHECK_RETURN_RET(metadata == nullptr, false);
379     camera_metadata_item_t item;
380     int32_t retCode = Camera::FindCameraMetadataItem(metadata->get(), OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED, &item);
381     CHECK_RETURN_RET_ELOG(retCode != CAM_META_SUCCESS, false,
382         "VideoOutput Can not find OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED");
383     int step = 2;
384     const int32_t canMirrorVideoAndPhoto = 2;
385     bool isMirrorEnabled = false;
386     SceneMode currentSceneMode = session->GetMode();
387     for (int i = 0; i < static_cast<int>(item.count); i += step) {
388         MEDIA_DEBUG_LOG("mode u8[%{public}d]: %{public}d, u8[%{public}d], %{public}d",
389             i, item.data.u8[i], i + 1, item.data.u8[i + 1]);
390         if (currentSceneMode == static_cast<int>(item.data.u8[i])) {
391             isMirrorEnabled = (item.data.u8[i + 1] == canMirrorVideoAndPhoto) ? true : false;
392         }
393     }
394     MEDIA_DEBUG_LOG("IsMirrorSupported isSupport: %{public}d", isMirrorEnabled);
395     return isMirrorEnabled;
396     // LCOV_EXCL_STOP
397 }
398 
GetSupportedVideoMetaTypes()399 std::vector<VideoMetaType> VideoOutput::GetSupportedVideoMetaTypes()
400 {
401     std::vector<VideoMetaType> vecto = {};
402     CHECK_EXECUTE(IsTagSupported(OHOS_ABILITY_AVAILABLE_EXTENDED_STREAM_INFO_TYPES),
403         vecto.push_back(VideoMetaType::VIDEO_META_MAKER_INFO));
404     return vecto;
405 }
406 
IsTagSupported(camera_device_metadata_tag tag)407 bool VideoOutput::IsTagSupported(camera_device_metadata_tag tag)
408 {
409     camera_metadata_item_t item;
410     sptr<CameraDevice> cameraObj;
411     auto captureSession = GetSession();
412     CHECK_RETURN_RET_ELOG(captureSession == nullptr, false,
413         "VideoOutput isTagEnabled error!, captureSession is nullptr");
414     // LCOV_EXCL_START
415     auto inputDevice = captureSession->GetInputDevice();
416     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, false,
417         "VideoOutput isTagEnabled error!, inputDevice is nullptr");
418     cameraObj = inputDevice->GetCameraDeviceInfo();
419     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, false,
420         "VideoOutput isTagEnabled error!, cameraObj is nullptr");
421     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetCachedMetadata();
422     CHECK_RETURN_RET(metadata == nullptr, false);
423     int32_t ret = Camera::FindCameraMetadataItem(metadata->get(), tag, &item);
424     CHECK_RETURN_RET_ELOG(ret != CAM_META_SUCCESS, false, "Can not find this tag");
425     MEDIA_DEBUG_LOG("This tag is Supported");
426     return true;
427     // LCOV_EXCL_STOP
428 }
429 
AttachMetaSurface(sptr<Surface> surface,VideoMetaType videoMetaType)430 void VideoOutput::AttachMetaSurface(sptr<Surface> surface, VideoMetaType videoMetaType)
431 {
432     auto stream = GetStream();
433     sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
434     int32_t errCode = CAMERA_UNKNOWN_ERROR;
435     // LCOV_EXCL_START
436     if (itemStream) {
437         errCode = itemStream->AttachMetaSurface(surface->GetProducer(), videoMetaType);
438         CHECK_PRINT_ELOG(errCode != CAMERA_OK,
439             "VideoOutput Failed to Attach Meta Surface!, errCode: %{public}d", errCode);
440     } else {
441         MEDIA_ERR_LOG("VideoOutput::AttachMetaSurface() itemStream is nullptr");
442     }
443     // LCOV_EXCL_STOP
444 }
445 
CameraServerDied(pid_t pid)446 void VideoOutput::CameraServerDied(pid_t pid)
447 {
448     MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
449     std::lock_guard<std::mutex> lock(outputCallbackMutex_);
450     if (appCallback_ != nullptr) {
451         // LCOV_EXCL_START
452         MEDIA_DEBUG_LOG("appCallback not nullptr");
453         int32_t serviceErrorType = ServiceToCameraError(CAMERA_INVALID_STATE);
454         appCallback_->OnError(serviceErrorType);
455         // LCOV_EXCL_STOP
456     }
457 }
458 
canSetFrameRateRange(int32_t minFrameRate,int32_t maxFrameRate)459 int32_t VideoOutput::canSetFrameRateRange(int32_t minFrameRate, int32_t maxFrameRate)
460 {
461     auto session = GetSession();
462     CHECK_RETURN_RET_ELOG(session == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
463         "VideoOutput canSetFrameRateRange error!, session is nullptr");
464     // LCOV_EXCL_START
465     CHECK_RETURN_RET_ELOG(!session->CanSetFrameRateRange(minFrameRate, maxFrameRate, this),
466         CameraErrorCode::UNRESOLVED_CONFLICTS_BETWEEN_STREAMS,
467         "VideoOutput canSetFrameRateRange Can not set frame rate range with wrong state of output");
468     int32_t minIndex = 0;
469     int32_t maxIndex = 1;
470     std::vector<std::vector<int32_t>> supportedFrameRange = GetSupportedFrameRates();
471     for (auto item : supportedFrameRange) {
472         CHECK_RETURN_RET(item[minIndex] <= minFrameRate && item[maxIndex] >= maxFrameRate,
473             CameraErrorCode::SUCCESS);
474     }
475     MEDIA_WARNING_LOG("VideoOutput canSetFrameRateRange Can not set frame rate range with invalid parameters");
476     return CameraErrorCode::INVALID_ARGUMENT;
477     // LCOV_EXCL_STOP
478 }
479 
GetVideoRotation(int32_t imageRotation)480 int32_t VideoOutput::GetVideoRotation(int32_t imageRotation)
481 {
482     MEDIA_DEBUG_LOG("VideoOutput GetVideoRotation is called");
483     int32_t sensorOrientation = 0;
484     CameraPosition cameraPosition;
485     ImageRotation result = ImageRotation::ROTATION_0;
486     sptr<CameraDevice> cameraObj;
487     auto session = GetSession();
488     CHECK_RETURN_RET_ELOG(session == nullptr, SERVICE_FATL_ERROR,
489         "VideoOutput GetVideoRotation error!, session is nullptr");
490     // LCOV_EXCL_START
491     auto inputDevice = session->GetInputDevice();
492     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
493         "VideoOutput GetVideoRotation error!, inputDevice is nullptr");
494     cameraObj = inputDevice->GetCameraDeviceInfo();
495     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
496         "VideoOutput GetVideoRotation error!, cameraObj is nullptr");
497     cameraPosition = cameraObj->GetPosition();
498     CHECK_RETURN_RET_ELOG(cameraPosition == CAMERA_POSITION_UNSPECIFIED, SERVICE_FATL_ERROR,
499         "VideoOutput GetVideoRotation error!, cameraPosition is unspecified");
500     sensorOrientation = static_cast<int32_t>(cameraObj->GetCameraOrientation());
501     imageRotation = (imageRotation + ROTATION_45_DEGREES) / ROTATION_90_DEGREES * ROTATION_90_DEGREES;
502     if (cameraPosition == CAMERA_POSITION_BACK) {
503         result = (ImageRotation)((imageRotation + sensorOrientation) % CAPTURE_ROTATION_BASE);
504     } else if (cameraPosition == CAMERA_POSITION_FRONT || CAMERA_POSITION_FOLD_INNER) {
505         result = (ImageRotation)((sensorOrientation - imageRotation + CAPTURE_ROTATION_BASE) % CAPTURE_ROTATION_BASE);
506     }
507     bool isMirrorEnabled = false;
508     if (result != ImageRotation::ROTATION_0 && result != ImageRotation::ROTATION_180 && IsMirrorSupported()) {
509         auto stream = GetStream();
510         sptr<IStreamRepeat> itemStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
511         if (itemStream != nullptr) {
512             int32_t ret = itemStream->GetMirror(isMirrorEnabled);
513             CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, ServiceToCameraError(ret), "VideoOutput::getMirror failed");
514             result = (isMirrorEnabled == false) ? result :
515                 (ImageRotation)((result + ImageRotation::ROTATION_180) % CAPTURE_ROTATION_BASE);
516         }
517     }
518     MEDIA_INFO_LOG("VideoOutput GetVideoRotation :result %{public}d, sensorOrientation:%{public}d, "
519         "isMirrorEnabled%{public}d", result, sensorOrientation, isMirrorEnabled);
520     return result;
521     // LCOV_EXCL_STOP
522 }
523 
IsAutoDeferredVideoEnhancementSupported()524 int32_t VideoOutput::IsAutoDeferredVideoEnhancementSupported()
525 {
526     MEDIA_INFO_LOG("IsAutoDeferredVideoEnhancementSupported");
527     sptr<CameraDevice> cameraObj;
528     auto captureSession = GetSession();
529     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
530         "VideoOutput IsAutoDeferredVideoEnhancementSupported error!, captureSession is nullptr");
531     // LCOV_EXCL_START
532     auto inputDevice = captureSession->GetInputDevice();
533     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
534         "VideoOutput IsAutoDeferredVideoEnhancementSupported error!, inputDevice is nullptr");
535     cameraObj = inputDevice->GetCameraDeviceInfo();
536     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
537         "VideoOutput IsAutoDeferredVideoEnhancementSupported error!, cameraObj is nullptr");
538 
539     int32_t curMode = captureSession->GetMode();
540     int32_t isSupported  = cameraObj->modeVideoDeferredType_[curMode];
541     MEDIA_INFO_LOG("IsAutoDeferredVideoEnhancementSupported curMode:%{public}d, modeSupportType:%{public}d",
542         curMode, isSupported);
543     return isSupported;
544     // LCOV_EXCL_STOP
545 }
546 
IsAutoDeferredVideoEnhancementEnabled()547 int32_t VideoOutput::IsAutoDeferredVideoEnhancementEnabled()
548 {
549     MEDIA_INFO_LOG("VideoOutput IsAutoDeferredVideoEnhancementEnabled");
550     auto captureSession = GetSession();
551     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
552         "VideoOutput IsAutoDeferredVideoEnhancementEnabled error!, captureSession is nullptr");
553 
554     // LCOV_EXCL_START
555     auto inputDevice = captureSession->GetInputDevice();
556     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
557         "VideoOutput IsAutoDeferredVideoEnhancementEnabled error!, inputDevice is nullptr");
558 
559     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
560     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
561         "VideoOutput IsAutoDeferredVideoEnhancementEnabled error!, cameraObj is nullptr");
562 
563     int32_t curMode = captureSession->GetMode();
564     bool isEnabled = captureSession->IsVideoDeferred();
565     MEDIA_INFO_LOG("IsAutoDeferredVideoEnhancementEnabled curMode:%{public}d, isEnabled:%{public}d",
566         curMode, isEnabled);
567     return isEnabled;
568     // LCOV_EXCL_STOP
569 }
570 
EnableAutoDeferredVideoEnhancement(bool enabled)571 int32_t VideoOutput::EnableAutoDeferredVideoEnhancement(bool enabled)
572 {
573     MEDIA_INFO_LOG("EnableAutoDeferredVideoEnhancement");
574     CAMERA_SYNC_TRACE;
575     sptr<CameraDevice> cameraObj;
576     auto captureSession = GetSession();
577     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
578         "VideoOutput EnableAutoDeferredVideoEnhancement error!, captureSession is nullptr");
579     // LCOV_EXCL_START
580     auto inputDevice = captureSession->GetInputDevice();
581     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
582         "VideoOutput EnableAutoDeferredVideoEnhancement error!, inputDevice is nullptr");
583 
584     cameraObj = inputDevice->GetCameraDeviceInfo();
585     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
586         "VideoOutput EnableAutoDeferredVideoEnhancement error!, cameraObj is nullptr");
587     captureSession->EnableAutoDeferredVideoEnhancement(enabled);
588     captureSession->SetUserId();
589     return SUCCESS;
590     // LCOV_EXCL_STOP
591 }
592 
IsVideoStarted()593 bool VideoOutput::IsVideoStarted()
594 {
595     return isVideoStarted_;
596 }
597 
GetSupportedRotations(std::vector<int32_t> & supportedRotations)598 int32_t VideoOutput::GetSupportedRotations(std::vector<int32_t> &supportedRotations)
599 {
600     MEDIA_DEBUG_LOG("VideoOutput::GetSupportedRotations is called");
601     supportedRotations.clear();
602     auto captureSession = GetSession();
603     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
604         "VideoOutput::GetSupportedRotations failed due to captureSession is nullptr");
605     // LCOV_EXCL_START
606     auto inputDevice = captureSession->GetInputDevice();
607     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
608         "VideoOutput::GetSupportedRotations failed due to inputDevice is nullptr");
609     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
610     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
611         "VideoOutput::GetSupportedRotations failed due to cameraObj is nullptr");
612     int32_t retCode = captureSession->GetSupportedVideoRotations(supportedRotations);
613     CHECK_RETURN_RET_ELOG(retCode != CameraErrorCode::SUCCESS, SERVICE_FATL_ERROR,
614         "VideoOutput::GetSupportedRotations failed, GetSupportedVideoRotations retCode: %{public}d", retCode);
615     return CameraErrorCode::SUCCESS;
616     // LCOV_EXCL_STOP
617 }
618 
IsRotationSupported(bool & isSupported)619 int32_t VideoOutput::IsRotationSupported(bool &isSupported)
620 {
621     MEDIA_DEBUG_LOG("VideoOutput::IsRotationSupported is called");
622     isSupported = false;
623     auto captureSession = GetSession();
624     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
625         "VideoOutput::IsRotationSupported failed due to captureSession is nullptr");
626     // LCOV_EXCL_START
627     auto inputDevice = captureSession->GetInputDevice();
628     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
629         "VideoOutput::IsRotationSupported failed due to inputDevice is nullptr");
630     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
631     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
632         "VideoOutput::IsRotationSupported failed due to cameraObj is nullptr");
633     int32_t retCode = captureSession->IsVideoRotationSupported(isSupported);
634     CHECK_RETURN_RET_ELOG(retCode != CameraErrorCode::SUCCESS, SERVICE_FATL_ERROR,
635         "VideoOutput::IsRotationSupported failed, IsVideoRotationSupported retCode: %{public}d", retCode);
636     return CameraErrorCode::SUCCESS;
637     // LCOV_EXCL_STOP
638 }
639 
SetRotation(int32_t rotation)640 int32_t VideoOutput::SetRotation(int32_t rotation)
641 {
642     MEDIA_DEBUG_LOG("VideoOutput::SetRotation is called, rotation: %{public}d", rotation);
643     auto captureSession = GetSession();
644     CHECK_RETURN_RET_ELOG(captureSession == nullptr, SERVICE_FATL_ERROR,
645         "VideoOutput::SetRotation failed, captureSession is nullptr");
646     // LCOV_EXCL_START
647     auto inputDevice = captureSession->GetInputDevice();
648     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, SERVICE_FATL_ERROR,
649         "VideoOutput::SetRotation failed, inputDevice is nullptr");
650     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
651     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, SERVICE_FATL_ERROR,
652         "VideoOutput::SetRotation failed, cameraObj is nullptr");
653     captureSession->LockForControl();
654     int32_t retCode = captureSession->SetVideoRotation(rotation);
655     CHECK_RETURN_RET_ELOG(retCode != CameraErrorCode::SUCCESS, SERVICE_FATL_ERROR,
656         "VideoOutput::SetRotation failed, SetVideoRotation retCode: %{public}d", retCode);
657     captureSession->UnlockForControl();
658     return CameraErrorCode::SUCCESS;
659     // LCOV_EXCL_STOP
660 }
661 
IsAutoVideoFrameRateSupported()662 bool VideoOutput::IsAutoVideoFrameRateSupported()
663 {
664     auto session = GetSession();
665     CHECK_RETURN_RET_ELOG(session == nullptr, false,
666         "VideoOutput IsAutoVideoFrameRateSupported error!, session is nullptr");
667     // LCOV_EXCL_START
668     auto inputDevice = session->GetInputDevice();
669     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, false,
670         "VideoOutput IsAutoVideoFrameRateSupported error!, inputDevice is nullptr");
671     sptr<CameraDevice> cameraObj = inputDevice->GetCameraDeviceInfo();
672     CHECK_RETURN_RET_ELOG(cameraObj == nullptr, false,
673         "VideoOutput IsAutoVideoFrameRateSupported error!, cameraObj is nullptr");
674     std::shared_ptr<Camera::CameraMetadata> metadata = cameraObj->GetCachedMetadata();
675     CHECK_RETURN_RET(metadata == nullptr, false);
676     camera_metadata_item_t item;
677     int32_t retCode = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_AUTO_VIDEO_FRAME_RATE, &item);
678     CHECK_RETURN_RET_ELOG(retCode != CAM_META_SUCCESS, false,
679         "VideoOutput Can not find OHOS_ABILITY_AUTO_VIDEO_FRAME_RATE");
680     bool isAutoVideoFrameRateSupported = false;
681     SceneMode currentSceneMode = session->GetMode();
682     for (int i = 0; i < static_cast<int>(item.count); i++) {
683         MEDIA_DEBUG_LOG("mode u8[%{public}d]: %{public}d", i, item.data.u8[i]);
684         if (currentSceneMode == static_cast<SceneMode>(item.data.u8[i])) {
685             isAutoVideoFrameRateSupported = true;
686         }
687     }
688     MEDIA_DEBUG_LOG("IsAutoVideoFrameRateSupported isSupport: %{public}d", isAutoVideoFrameRateSupported);
689     return isAutoVideoFrameRateSupported;
690     // LCOV_EXCL_STOP
691 }
692 
EnableAutoVideoFrameRate(bool enable)693 int32_t VideoOutput::EnableAutoVideoFrameRate(bool enable)
694 {
695     MEDIA_INFO_LOG("VideoOutput::EnableAutoVideoFrameRate enable: %{public}d", enable);
696     auto session = GetSession();
697     CHECK_RETURN_RET_ELOG(session == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
698         "VideoOutput IsAutoVideoFrameRateSupported error!, session is nullptr");
699     // LCOV_EXCL_START
700     auto inputDevice = session->GetInputDevice();
701     CHECK_RETURN_RET_ELOG(inputDevice == nullptr, CameraErrorCode::SESSION_NOT_CONFIG,
702         "VideoOutput IsAutoVideoFrameRateSupported error!, inputDevice is nullptr");
703     bool isSupportedAutoVideoFps = IsAutoVideoFrameRateSupported();
704     CHECK_RETURN_RET_ELOG(!isSupportedAutoVideoFps, CameraErrorCode::INVALID_ARGUMENT,
705         "VideoOutput::EnableAutoVideoFrameRate does not supported.");
706     session->LockForControl();
707     session->EnableAutoFrameRate(enable);
708     session->UnlockForControl();
709     return CameraErrorCode::SUCCESS;
710     // LCOV_EXCL_STOP
711 }
712 } // namespace CameraStandard
713 } // namespace OHOS
714