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