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