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