1 /*
2 * Copyright (c) 2023-2023 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 "session/video_session.h"
17
18 #include "camera_error_code.h"
19 #include "camera_log.h"
20 #include "camera_util.h"
21 #include "input/camera_input.h"
22 #include "input/camera_manager.h"
23 #include "output/camera_output_capability.h"
24
25 namespace OHOS {
26 namespace CameraStandard {
27 namespace {
GeneratePreconfigProfiles1_1(PreconfigType preconfigType)28 std::shared_ptr<PreconfigProfiles> GeneratePreconfigProfiles1_1(PreconfigType preconfigType)
29 {
30 std::shared_ptr<PreconfigProfiles> configs = std::make_shared<PreconfigProfiles>(ColorSpace::BT709);
31 configs->photoProfile = { CameraFormat::CAMERA_FORMAT_JPEG, { .width = 0, .height = 0 } };
32 configs->photoProfile.sizeRatio_ = RATIO_1_1;
33 configs->photoProfile.sizeFollowSensorMax_ = true;
34 switch (preconfigType) {
35 case PRECONFIG_720P:
36 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 720, .height = 720 } };
37 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
38
39 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
40 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
41 break;
42 case PRECONFIG_1080P:
43 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1080, .height = 1080 } };
44 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
45
46 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
47 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
48 break;
49 case PRECONFIG_4K:
50 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1080, .height = 1080 } };
51 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
52
53 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 2160, .height = 2160 },
54 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
55 break;
56 case PRECONFIG_HIGH_QUALITY:
57 configs->colorSpace = ColorSpace::BT2020_HLG_LIMIT;
58 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 1080, .height = 1080 } };
59 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
60
61 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 2160, .height = 2160 },
62 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
63 break;
64 default:
65 MEDIA_ERR_LOG(
66 "VideoSession::GeneratePreconfigProfiles1_1 not support this config:%{public}d", preconfigType);
67 return nullptr;
68 }
69 return configs;
70 }
71
GeneratePreconfigProfiles4_3(PreconfigType preconfigType)72 std::shared_ptr<PreconfigProfiles> GeneratePreconfigProfiles4_3(PreconfigType preconfigType)
73 {
74 std::shared_ptr<PreconfigProfiles> configs = std::make_shared<PreconfigProfiles>(ColorSpace::BT709);
75 configs->photoProfile = { CameraFormat::CAMERA_FORMAT_JPEG, { .width = 0, .height = 0 } };
76 configs->photoProfile.sizeRatio_ = RATIO_4_3;
77 configs->photoProfile.sizeFollowSensorMax_ = true;
78 switch (preconfigType) {
79 case PRECONFIG_720P:
80 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 960, .height = 720 } };
81 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
82
83 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
84 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
85 break;
86 case PRECONFIG_1080P:
87 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1440, .height = 1080 } };
88 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
89
90 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
91 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
92 break;
93 case PRECONFIG_4K:
94 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1440, .height = 1080 } };
95 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
96
97 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 2880, .height = 2160 },
98 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
99 break;
100 case PRECONFIG_HIGH_QUALITY:
101 configs->colorSpace = ColorSpace::BT2020_HLG_LIMIT;
102 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 1440, .height = 1080 } };
103 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
104
105 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 2880, .height = 2160 },
106 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
107 break;
108 default:
109 MEDIA_ERR_LOG(
110 "VideoSession::GeneratePreconfigProfiles4_3 not support this config:%{public}d", preconfigType);
111 return nullptr;
112 }
113 return configs;
114 }
115
GeneratePreconfigProfiles16_9(PreconfigType preconfigType)116 std::shared_ptr<PreconfigProfiles> GeneratePreconfigProfiles16_9(PreconfigType preconfigType)
117 {
118 std::shared_ptr<PreconfigProfiles> configs = std::make_shared<PreconfigProfiles>(ColorSpace::BT709);
119 configs->photoProfile = { CameraFormat::CAMERA_FORMAT_JPEG, { .width = 0, .height = 0 } };
120 configs->photoProfile.sizeRatio_ = RATIO_16_9;
121 configs->photoProfile.sizeFollowSensorMax_ = true;
122 switch (preconfigType) {
123 case PRECONFIG_720P:
124 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1280, .height = 720 } };
125 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
126
127 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
128 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
129 break;
130 case PRECONFIG_1080P:
131 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1920, .height = 1080 } };
132 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
133
134 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, configs->previewProfile.size_,
135 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
136 break;
137 case PRECONFIG_4K:
138 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 1920, .height = 1080 } };
139 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
140
141 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YUV_420_SP, { .width = 3840, .height = 2160 },
142 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
143 break;
144 case PRECONFIG_HIGH_QUALITY:
145 configs->colorSpace = ColorSpace::BT2020_HLG_LIMIT;
146 configs->previewProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 1920, .height = 1080 } };
147 configs->previewProfile.fps_ = { .fixedFps = 30, .minFps = 24, .maxFps = 30 };
148
149 configs->videoProfile = { CameraFormat::CAMERA_FORMAT_YCRCB_P010, { .width = 3840, .height = 2160 },
150 { configs->previewProfile.fps_.minFps, configs->previewProfile.fps_.maxFps } };
151 break;
152 default:
153 MEDIA_ERR_LOG(
154 "VideoSession::GeneratePreconfigProfiles4_3 not support this config:%{public}d", preconfigType);
155 return nullptr;
156 }
157 return configs;
158 }
159 } // namespace
160
CanAddOutput(sptr<CaptureOutput> & output)161 bool VideoSession::CanAddOutput(sptr<CaptureOutput>& output)
162 {
163 MEDIA_DEBUG_LOG("Enter Into VideoSession::CanAddOutput");
164 CHECK_ERROR_RETURN_RET_LOG(
165 !IsSessionConfiged() || output == nullptr, false, "VideoSession::CanAddOutput operation is Not allowed!");
166 return CaptureSession::CanAddOutput(output);
167 }
168
GeneratePreconfigProfiles(PreconfigType preconfigType,ProfileSizeRatio preconfigRatio)169 std::shared_ptr<PreconfigProfiles> VideoSession::GeneratePreconfigProfiles(
170 PreconfigType preconfigType, ProfileSizeRatio preconfigRatio)
171 {
172 switch (preconfigRatio) {
173 case RATIO_1_1:
174 return GeneratePreconfigProfiles1_1(preconfigType);
175 case RATIO_4_3:
176 return GeneratePreconfigProfiles4_3(preconfigType);
177 case UNSPECIFIED:
178 // Fall through
179 case RATIO_16_9:
180 return GeneratePreconfigProfiles16_9(preconfigType);
181 default:
182 MEDIA_ERR_LOG("VideoSession::GeneratePreconfigProfiles unknow profile size ratio.");
183 break;
184 }
185 return nullptr;
186 }
187
IsPreconfigProfilesLegal(std::shared_ptr<PreconfigProfiles> configs)188 bool VideoSession::IsPreconfigProfilesLegal(std::shared_ptr<PreconfigProfiles> configs)
189 {
190 auto cameraList = CameraManager::GetInstance()->GetSupportedCameras();
191 int32_t supportedCameraNum = 0;
192 for (auto& device : cameraList) {
193 MEDIA_INFO_LOG("VideoSession::IsPreconfigProfilesLegal check camera:%{public}s type:%{public}d",
194 device->GetID().c_str(), device->GetCameraType());
195 if (device->GetCameraType() != CAMERA_TYPE_DEFAULT) {
196 continue;
197 }
198 // Check photo
199 bool isPhotoCanPreconfig = IsPhotoProfileLegal(device, configs->photoProfile);
200 CHECK_ERROR_RETURN_RET_LOG(!isPhotoCanPreconfig, false,
201 "VideoSession::IsPreconfigProfilesLegal check photo profile fail, no matched photo profiles:%{public}d "
202 "%{public}dx%{public}d",
203 configs->photoProfile.format_, configs->photoProfile.size_.width, configs->photoProfile.size_.height);
204
205 // Check preview
206 bool isPreviewCanPreconfig = IsPreviewProfileLegal(device, configs->previewProfile);
207 CHECK_ERROR_RETURN_RET_LOG(!isPreviewCanPreconfig, false,
208 "VideoSession::IsPreconfigProfilesLegal check preview profile fail, no matched preview profiles:%{public}d "
209 "%{public}dx%{public}d",
210 configs->previewProfile.format_, configs->previewProfile.size_.width, configs->previewProfile.size_.height);
211
212 // Check video
213 auto isVideoCanPreconfig = IsVideoProfileLegal(device, configs->videoProfile);
214 CHECK_ERROR_RETURN_RET_LOG(!isVideoCanPreconfig, false,
215 "VideoSession::IsPreconfigProfilesLegal check video profile fail, no matched video profiles:%{public}d "
216 "%{public}dx%{public}d",
217 configs->videoProfile.format_, configs->videoProfile.size_.width, configs->videoProfile.size_.height);
218 supportedCameraNum++;
219 }
220 MEDIA_INFO_LOG(
221 "VideoSession::IsPreconfigProfilesLegal check pass, supportedCameraNum is%{public}d", supportedCameraNum);
222 return supportedCameraNum > 0;
223 }
224
IsPhotoProfileLegal(sptr<CameraDevice> & device,Profile & photoProfile)225 bool VideoSession::IsPhotoProfileLegal(sptr<CameraDevice>& device, Profile& photoProfile)
226 {
227 auto photoProfilesIt = device->modePhotoProfiles_.find(SceneMode::VIDEO);
228 CHECK_ERROR_RETURN_RET_LOG(photoProfilesIt == device->modePhotoProfiles_.end(), false,
229 "VideoSession::CanPreconfig check photo profile fail, empty photo profiles");
230 auto photoProfiles = photoProfilesIt->second;
231 return std::any_of(photoProfiles.begin(), photoProfiles.end(), [&photoProfile](auto& profile) {
232 if (!photoProfile.sizeFollowSensorMax_) {
233 return profile == photoProfile;
234 }
235 return IsProfileSameRatio(profile, photoProfile.sizeRatio_, RATIO_VALUE_16_9);
236 });
237 }
238
IsPreviewProfileLegal(sptr<CameraDevice> & device,Profile & previewProfile)239 bool VideoSession::IsPreviewProfileLegal(sptr<CameraDevice>& device, Profile& previewProfile)
240 {
241 auto previewProfilesIt = device->modePreviewProfiles_.find(SceneMode::VIDEO);
242 CHECK_ERROR_RETURN_RET_LOG(previewProfilesIt == device->modePreviewProfiles_.end(), false,
243 "VideoSession::CanPreconfig check preview profile fail, empty preview profiles");
244 auto previewProfiles = previewProfilesIt->second;
245 return std::any_of(previewProfiles.begin(), previewProfiles.end(),
246 [&previewProfile](auto& profile) { return profile == previewProfile; });
247 }
248
IsVideoProfileLegal(sptr<CameraDevice> & device,VideoProfile & videoProfile)249 bool VideoSession::IsVideoProfileLegal(sptr<CameraDevice>& device, VideoProfile& videoProfile)
250 {
251 auto videoProfilesIt = device->modeVideoProfiles_.find(SceneMode::VIDEO);
252 CHECK_ERROR_RETURN_RET_LOG(videoProfilesIt == device->modeVideoProfiles_.end(), false,
253 "VideoSession::CanPreconfig check video profile fail, empty video profiles");
254 auto videoProfiles = videoProfilesIt->second;
255 return std::any_of(videoProfiles.begin(), videoProfiles.end(),
256 [&videoProfile](auto& profile) { return profile.IsContains(videoProfile); });
257 }
258
CanPreconfig(PreconfigType preconfigType,ProfileSizeRatio preconfigRatio)259 bool VideoSession::CanPreconfig(PreconfigType preconfigType, ProfileSizeRatio preconfigRatio)
260 {
261 MEDIA_INFO_LOG(
262 "VideoSession::CanPreconfig check type:%{public}d, check ratio:%{public}d", preconfigType, preconfigRatio);
263 std::shared_ptr<PreconfigProfiles> configs = GeneratePreconfigProfiles(preconfigType, preconfigRatio);
264 CHECK_ERROR_RETURN_RET_LOG(configs == nullptr, false, "VideoSession::CanPreconfig get configs fail.");
265 return IsPreconfigProfilesLegal(configs);
266 }
267
Preconfig(PreconfigType preconfigType,ProfileSizeRatio preconfigRatio)268 int32_t VideoSession::Preconfig(PreconfigType preconfigType, ProfileSizeRatio preconfigRatio)
269 {
270 MEDIA_INFO_LOG("VideoSession::Preconfig type:%{public}d ratio:%{public}d", preconfigType, preconfigRatio);
271 std::shared_ptr<PreconfigProfiles> configs = GeneratePreconfigProfiles(preconfigType, preconfigRatio);
272 CHECK_ERROR_RETURN_RET_LOG(configs == nullptr, SERVICE_FATL_ERROR,
273 "VideoSession::Preconfig not support this type:%{public}d ratio:%{public}d", preconfigType, preconfigRatio);
274 CHECK_ERROR_RETURN_RET_LOG(
275 !IsPreconfigProfilesLegal(configs), SERVICE_FATL_ERROR, "VideoSession::Preconfig preconfigProfile is illegal.");
276 SetPreconfigProfiles(configs);
277 MEDIA_INFO_LOG("VideoSession::Preconfig %s", configs->ToString().c_str());
278 return SUCCESS;
279 }
280
CanSetFrameRateRange(int32_t minFps,int32_t maxFps,CaptureOutput * curOutput)281 bool VideoSession::CanSetFrameRateRange(int32_t minFps, int32_t maxFps, CaptureOutput* curOutput)
282 {
283 return CanSetFrameRateRangeForOutput(minFps, maxFps, curOutput) ? true : false;
284 }
285 } // namespace CameraStandard
286 } // namespace OHOS