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