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