blob: c9520d502b29783815f77cc2a206ece091b11d43 [file] [log] [blame]
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Austin Borgerea931242021-12-13 23:10:41 +000016
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070017#include <cutils/properties.h>
18
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080019#include "SessionConfigurationUtils.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000020#include "../api2/DepthCompositeStream.h"
21#include "../api2/HeicCompositeStream.h"
22#include "common/CameraDeviceBase.h"
Jayant Chowdharya04055f2022-01-03 02:07:49 +000023#include "common/HalConversionsTemplated.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000024#include "../CameraService.h"
Jayant Chowdhary35642f22022-01-08 00:39:39 +000025#include "device3/aidl/AidlCamera3Device.h"
Jayant Chowdhary22441f32021-12-26 18:35:41 -080026#include "device3/hidl/HidlCamera3Device.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000027#include "device3/Camera3OutputStream.h"
Emilian Peev2295df72021-11-12 18:14:10 -080028#include "system/graphics-base-v1.1.h"
Austin Borger0fb3ad92023-06-01 16:51:35 -070029#include <camera/StringUtils.h>
Colin Crossb8a9dbb2020-08-27 04:12:26 +000030
Colin Crossb8a9dbb2020-08-27 04:12:26 +000031using android::camera3::OutputStreamInfo;
32using android::camera3::OutputStreamInfo;
33using android::hardware::camera2::ICameraDeviceUser;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080034
35namespace android {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080036namespace camera3 {
37
38void StreamConfiguration::getStreamConfigurations(
39 const CameraMetadata &staticInfo, int configuration,
40 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
41 if (scm == nullptr) {
42 ALOGE("%s: StreamConfigurationMap nullptr", __FUNCTION__);
43 return;
44 }
45 const int STREAM_FORMAT_OFFSET = 0;
46 const int STREAM_WIDTH_OFFSET = 1;
47 const int STREAM_HEIGHT_OFFSET = 2;
48 const int STREAM_IS_INPUT_OFFSET = 3;
49
50 camera_metadata_ro_entry availableStreamConfigs = staticInfo.find(configuration);
51 for (size_t i = 0; i < availableStreamConfigs.count; i += 4) {
52 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
53 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
54 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
55 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
56 StreamConfiguration sc = {format, width, height, isInput};
57 (*scm)[format].push_back(sc);
58 }
59}
60
61void StreamConfiguration::getStreamConfigurations(
62 const CameraMetadata &staticInfo, bool maxRes,
63 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
64 int32_t scalerKey =
65 SessionConfigurationUtils::getAppropriateModeTag(
66 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxRes);
67
68 int32_t depthKey =
69 SessionConfigurationUtils::getAppropriateModeTag(
70 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, maxRes);
71
72 int32_t dynamicDepthKey =
73 SessionConfigurationUtils::getAppropriateModeTag(
74 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
75
76 int32_t heicKey =
77 SessionConfigurationUtils::getAppropriateModeTag(
78 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
79
80 getStreamConfigurations(staticInfo, scalerKey, scm);
81 getStreamConfigurations(staticInfo, depthKey, scm);
82 getStreamConfigurations(staticInfo, dynamicDepthKey, scm);
83 getStreamConfigurations(staticInfo, heicKey, scm);
84}
85
Austin Borgerea931242021-12-13 23:10:41 +000086namespace SessionConfigurationUtils {
87
88int32_t PERF_CLASS_LEVEL =
89 property_get_int32("ro.odm.build.media_performance_class", 0);
90
Shuzhen Wangf18887c2022-05-31 10:24:02 -070091bool IS_PERF_CLASS = (PERF_CLASS_LEVEL >= SDK_VERSION_S);
Austin Borgerea931242021-12-13 23:10:41 +000092
93camera3::Size getMaxJpegResolution(const CameraMetadata &metadata,
94 bool ultraHighResolution) {
95 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
96 const int STREAM_CONFIGURATION_SIZE = 4;
97 const int STREAM_FORMAT_OFFSET = 0;
98 const int STREAM_WIDTH_OFFSET = 1;
99 const int STREAM_HEIGHT_OFFSET = 2;
100 const int STREAM_IS_INPUT_OFFSET = 3;
101
102 int32_t scalerSizesTag = ultraHighResolution ?
103 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION :
104 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
105 camera_metadata_ro_entry_t availableStreamConfigs =
106 metadata.find(scalerSizesTag);
107 if (availableStreamConfigs.count == 0 ||
108 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
109 return camera3::Size(0, 0);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800110 }
Austin Borgerea931242021-12-13 23:10:41 +0000111
112 // Get max jpeg size (area-wise).
113 for (size_t i= 0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
114 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
115 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
116 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
117 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
118 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
119 && format == HAL_PIXEL_FORMAT_BLOB &&
120 (width * height > maxJpegWidth * maxJpegHeight)) {
121 maxJpegWidth = width;
122 maxJpegHeight = height;
123 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800124 }
Austin Borgerea931242021-12-13 23:10:41 +0000125
126 return camera3::Size(maxJpegWidth, maxJpegHeight);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800127}
128
Austin Borgerea931242021-12-13 23:10:41 +0000129size_t getUHRMaxJpegBufferSize(camera3::Size uhrMaxJpegSize,
130 camera3::Size defaultMaxJpegSize, size_t defaultMaxJpegBufferSize) {
Jayant Chowdhary2fd93aa2022-07-12 23:22:53 +0000131 return ((float)uhrMaxJpegSize.width * uhrMaxJpegSize.height) /
Austin Borgerea931242021-12-13 23:10:41 +0000132 (defaultMaxJpegSize.width * defaultMaxJpegSize.height) * defaultMaxJpegBufferSize;
133}
134
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800135StreamConfigurationPair
Austin Borgerea931242021-12-13 23:10:41 +0000136getStreamConfigurationPair(const CameraMetadata &staticInfo) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800137 camera3::StreamConfigurationPair streamConfigurationPair;
138 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, false,
139 &streamConfigurationPair.mDefaultStreamConfigurationMap);
140 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, true,
141 &streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
142 return streamConfigurationPair;
143}
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800144
Austin Borgerea931242021-12-13 23:10:41 +0000145int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000146 int64_t d0 = x0 - x1;
147 int64_t d1 = y0 - y1;
148 return d0 * d0 + d1 * d1;
149}
150
Austin Borgerea931242021-12-13 23:10:41 +0000151bool roundBufferDimensionNearest(int32_t width, int32_t height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800152 int32_t format, android_dataspace dataSpace,
153 const CameraMetadata& info, bool maxResolution, /*out*/int32_t* outWidth,
154 /*out*/int32_t* outHeight) {
155 const int32_t depthSizesTag =
156 getAppropriateModeTag(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
157 maxResolution);
158 const int32_t scalerSizesTag =
159 getAppropriateModeTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
160 const int32_t heicSizesTag =
161 getAppropriateModeTag(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000162
163 camera_metadata_ro_entry streamConfigs =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800164 (dataSpace == HAL_DATASPACE_DEPTH) ? info.find(depthSizesTag) :
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000165 (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800166 info.find(heicSizesTag) :
167 info.find(scalerSizesTag);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000168
169 int32_t bestWidth = -1;
170 int32_t bestHeight = -1;
171
172 // Iterate through listed stream configurations and find the one with the smallest euclidean
173 // distance from the given dimensions for the given format.
174 for (size_t i = 0; i < streamConfigs.count; i += 4) {
175 int32_t fmt = streamConfigs.data.i32[i];
176 int32_t w = streamConfigs.data.i32[i + 1];
177 int32_t h = streamConfigs.data.i32[i + 2];
178
179 // Ignore input/output type for now
180 if (fmt == format) {
181 if (w == width && h == height) {
182 bestWidth = width;
183 bestHeight = height;
184 break;
185 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
186 SessionConfigurationUtils::euclidDistSquare(w, h, width, height) <
187 SessionConfigurationUtils::euclidDistSquare(bestWidth, bestHeight, width,
188 height))) {
189 bestWidth = w;
190 bestHeight = h;
191 }
192 }
193 }
194
195 if (bestWidth == -1) {
196 // Return false if no configurations for this format were listed
197 return false;
198 }
199
200 // Set the outputs to the closet width/height
201 if (outWidth != NULL) {
202 *outWidth = bestWidth;
203 }
204 if (outHeight != NULL) {
205 *outHeight = bestHeight;
206 }
207
208 // Return true if at least one configuration for this format was listed
209 return true;
210}
211
Emilian Peev2295df72021-11-12 18:14:10 -0800212//check if format is 10-bit compatible
213bool is10bitCompatibleFormat(int32_t format) {
214 switch(format) {
215 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
216 case HAL_PIXEL_FORMAT_YCBCR_P010:
217 return true;
218 default:
219 return false;
220 }
221}
222
Emilian Peevc81a7592022-02-14 17:38:18 -0800223bool isDynamicRangeProfileSupported(int64_t dynamicRangeProfile, const CameraMetadata& staticInfo) {
Emilian Peev2295df72021-11-12 18:14:10 -0800224 if (dynamicRangeProfile == ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
225 // Supported by default
226 return true;
227 }
228
229 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
230 bool is10bitDynamicRangeSupported = false;
231 for (size_t i = 0; i < entry.count; ++i) {
232 uint8_t capability = entry.data.u8[i];
233 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
234 is10bitDynamicRangeSupported = true;
235 break;
236 }
237 }
238
239 if (!is10bitDynamicRangeSupported) {
240 return false;
241 }
242
243 switch (dynamicRangeProfile) {
244 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
245 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
246 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
247 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
248 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
249 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
250 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
251 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
252 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
253 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
254 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
255 entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
Emilian Peevc81a7592022-02-14 17:38:18 -0800256 for (size_t i = 0; i < entry.count; i += 3) {
257 if (dynamicRangeProfile == entry.data.i64[i]) {
Emilian Peev2295df72021-11-12 18:14:10 -0800258 return true;
259 }
260 }
261
262 return false;
263 default:
264 return false;
265 }
266
267 return false;
268}
269
270//check if format is 10-bit compatible
Emilian Peevc81a7592022-02-14 17:38:18 -0800271bool is10bitDynamicRangeProfile(int64_t dynamicRangeProfile) {
Emilian Peev2295df72021-11-12 18:14:10 -0800272 switch (dynamicRangeProfile) {
273 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
274 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
275 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
276 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
277 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
278 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
279 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
280 return true;
281 default:
282 return false;
283 }
284}
285
Austin Borgerea931242021-12-13 23:10:41 +0000286bool isPublicFormat(int32_t format)
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000287{
288 switch(format) {
289 case HAL_PIXEL_FORMAT_RGBA_8888:
290 case HAL_PIXEL_FORMAT_RGBX_8888:
291 case HAL_PIXEL_FORMAT_RGB_888:
292 case HAL_PIXEL_FORMAT_RGB_565:
293 case HAL_PIXEL_FORMAT_BGRA_8888:
294 case HAL_PIXEL_FORMAT_YV12:
295 case HAL_PIXEL_FORMAT_Y8:
296 case HAL_PIXEL_FORMAT_Y16:
297 case HAL_PIXEL_FORMAT_RAW16:
298 case HAL_PIXEL_FORMAT_RAW10:
299 case HAL_PIXEL_FORMAT_RAW12:
300 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
301 case HAL_PIXEL_FORMAT_BLOB:
302 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
303 case HAL_PIXEL_FORMAT_YCbCr_420_888:
304 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
305 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
306 case HAL_PIXEL_FORMAT_YCbCr_422_I:
307 return true;
308 default:
309 return false;
310 }
311}
312
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800313bool isStreamUseCaseSupported(int64_t streamUseCase,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800314 const CameraMetadata &deviceInfo) {
315 camera_metadata_ro_entry_t availableStreamUseCases =
316 deviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES);
317
318 if (availableStreamUseCases.count == 0 &&
319 streamUseCase == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
320 return true;
321 }
Shuzhen Wangb77131a2022-04-27 15:34:33 -0700322 // Allow vendor stream use case unconditionally.
323 if (streamUseCase >= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START) {
324 return true;
325 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800326
327 for (size_t i = 0; i < availableStreamUseCases.count; i++) {
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800328 if (availableStreamUseCases.data.i64[i] == streamUseCase) {
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800329 return true;
330 }
331 }
332 return false;
333}
334
Austin Borgerea931242021-12-13 23:10:41 +0000335binder::Status createSurfaceFromGbp(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000336 OutputStreamInfo& streamInfo, bool isStreamInfoValid,
337 sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700338 const std::string &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
Emilian Peevc81a7592022-02-14 17:38:18 -0800339 const std::vector<int32_t> &sensorPixelModesUsed, int64_t dynamicRangeProfile,
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800340 int64_t streamUseCase, int timestampBase, int mirrorMode) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000341 // bufferProducer must be non-null
342 if (gbp == nullptr) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700343 std::string msg = fmt::sprintf("Camera %s: Surface is NULL", logicalCameraId.c_str());
344 ALOGW("%s: %s", __FUNCTION__, msg.c_str());
345 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000346 }
347 // HACK b/10949105
348 // Query consumer usage bits to set async operation mode for
349 // GLConsumer using controlledByApp parameter.
350 bool useAsync = false;
351 uint64_t consumerUsage = 0;
352 status_t err;
353 if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700354 std::string msg = fmt::sprintf("Camera %s: Failed to query Surface consumer usage: %s (%d)",
355 logicalCameraId.c_str(), strerror(-err), err);
356 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
357 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000358 }
359 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
360 ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
Austin Borger0fb3ad92023-06-01 16:51:35 -0700361 "stream", __FUNCTION__, logicalCameraId.c_str(), consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000362 useAsync = true;
363 }
364
365 uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
366 GRALLOC_USAGE_RENDERSCRIPT;
367 uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
368 GraphicBuffer::USAGE_HW_TEXTURE |
369 GraphicBuffer::USAGE_HW_COMPOSER;
370 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
371 (consumerUsage & allowedFlags) != 0;
372
373 surface = new Surface(gbp, useAsync);
374 ANativeWindow *anw = surface.get();
375
376 int width, height, format;
377 android_dataspace dataSpace;
378 if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700379 std::string msg = fmt::sprintf("Camera %s: Failed to query Surface width: %s (%d)",
380 logicalCameraId.c_str(), strerror(-err), err);
381 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
382 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000383 }
384 if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700385 std::string msg = fmt::sprintf("Camera %s: Failed to query Surface height: %s (%d)",
386 logicalCameraId.c_str(), strerror(-err), err);
387 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
388 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000389 }
390 if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700391 std::string msg = fmt::sprintf("Camera %s: Failed to query Surface format: %s (%d)",
392 logicalCameraId.c_str(), strerror(-err), err);
393 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
394 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000395 }
396 if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
397 reinterpret_cast<int*>(&dataSpace))) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700398 std::string msg = fmt::sprintf("Camera %s: Failed to query Surface dataspace: %s (%d)",
399 logicalCameraId.c_str(), strerror(-err), err);
400 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
401 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000402 }
403
404 // FIXME: remove this override since the default format should be
405 // IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
406 if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
407 ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
408 ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
409 ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700410 __FUNCTION__, logicalCameraId.c_str(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000411 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
412 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800413 std::unordered_set<int32_t> overriddenSensorPixelModes;
414 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
415 physicalCameraMetadata, flexibleConsumer, &overriddenSensorPixelModes) != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700416 std::string msg = fmt::sprintf("Camera %s: sensor pixel modes for stream with "
417 "format %#x are not valid",logicalCameraId.c_str(), format);
418 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
419 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800420 }
421 bool foundInMaxRes = false;
422 if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
423 overriddenSensorPixelModes.end()) {
424 // we can use the default stream configuration map
425 foundInMaxRes = true;
426 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000427 // Round dimensions to the nearest dimensions available for this format
428 if (flexibleConsumer && isPublicFormat(format) &&
429 !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800430 format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
431 /*out*/&height)) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700432 std::string msg = fmt::sprintf("Camera %s: No supported stream configurations with "
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000433 "format %#x defined, failed to create output stream",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700434 logicalCameraId.c_str(), format);
435 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
436 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000437 }
Emilian Peev2295df72021-11-12 18:14:10 -0800438 if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
439 physicalCameraMetadata)) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700440 std::string msg = fmt::sprintf("Camera %s: Dynamic range profile 0x%" PRIx64
441 " not supported,failed to create output stream", logicalCameraId.c_str(),
Emilian Peevc81a7592022-02-14 17:38:18 -0800442 dynamicRangeProfile);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700443 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
444 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Emilian Peev2295df72021-11-12 18:14:10 -0800445 }
446 if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
447 !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700448 std::string msg = fmt::sprintf("Camera %s: No 10-bit supported stream configurations with "
Emilian Peevc81a7592022-02-14 17:38:18 -0800449 "format %#x defined and profile %" PRIx64 ", failed to create output stream",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700450 logicalCameraId.c_str(), format, dynamicRangeProfile);
451 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
452 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Emilian Peev2295df72021-11-12 18:14:10 -0800453 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800454 if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
455 physicalCameraMetadata)) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700456 std::string msg = fmt::sprintf("Camera %s: stream use case %" PRId64 " not supported,"
457 " failed to create output stream", logicalCameraId.c_str(), streamUseCase);
458 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
459 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800460 }
Shuzhen Wange4208922022-02-01 16:52:48 -0800461 if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
Shuzhen Wangffc4c012022-04-20 15:55:46 -0700462 timestampBase > OutputConfiguration::TIMESTAMP_BASE_MAX) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700463 std::string msg = fmt::sprintf("Camera %s: invalid timestamp base %d",
464 logicalCameraId.c_str(), timestampBase);
465 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
466 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Shuzhen Wange4208922022-02-01 16:52:48 -0800467 }
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800468 if (mirrorMode < OutputConfiguration::MIRROR_MODE_AUTO ||
469 mirrorMode > OutputConfiguration::MIRROR_MODE_V) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700470 std::string msg = fmt::sprintf("Camera %s: invalid mirroring mode %d",
471 logicalCameraId.c_str(), mirrorMode);
472 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
473 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800474 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000475
476 if (!isStreamInfoValid) {
477 streamInfo.width = width;
478 streamInfo.height = height;
479 streamInfo.format = format;
480 streamInfo.dataSpace = dataSpace;
481 streamInfo.consumerUsage = consumerUsage;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800482 streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
Emilian Peev2295df72021-11-12 18:14:10 -0800483 streamInfo.dynamicRangeProfile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800484 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wange4208922022-02-01 16:52:48 -0800485 streamInfo.timestampBase = timestampBase;
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800486 streamInfo.mirrorMode = mirrorMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000487 return binder::Status::ok();
488 }
489 if (width != streamInfo.width) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700490 std::string msg = fmt::sprintf("Camera %s:Surface width doesn't match: %d vs %d",
491 logicalCameraId.c_str(), width, streamInfo.width);
492 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
493 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000494 }
495 if (height != streamInfo.height) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700496 std::string msg = fmt::sprintf("Camera %s:Surface height doesn't match: %d vs %d",
497 logicalCameraId.c_str(), height, streamInfo.height);
498 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
499 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000500 }
501 if (format != streamInfo.format) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700502 std::string msg = fmt::sprintf("Camera %s:Surface format doesn't match: %d vs %d",
503 logicalCameraId.c_str(), format, streamInfo.format);
504 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
505 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000506 }
507 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
508 if (dataSpace != streamInfo.dataSpace) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700509 std::string msg = fmt::sprintf("Camera %s:Surface dataSpace doesn't match: %d vs %d",
510 logicalCameraId.c_str(), dataSpace, streamInfo.dataSpace);
511 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
512 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000513 }
514 //At the native side, there isn't a way to check whether 2 surfaces come from the same
515 //surface class type. Use usage flag to approximate the comparison.
516 if (consumerUsage != streamInfo.consumerUsage) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700517 std::string msg = fmt::sprintf(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000518 "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700519 logicalCameraId.c_str(), consumerUsage, streamInfo.consumerUsage);
520 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
521 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000522 }
523 }
524 return binder::Status::ok();
525}
526
Austin Borgerea931242021-12-13 23:10:41 +0000527void mapStreamInfo(const OutputStreamInfo &streamInfo,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700528 camera3::camera_stream_rotation_t rotation, const std::string &physicalId,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000529 int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000530 if (stream == nullptr) {
531 return;
532 }
533
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000534 stream->streamType = aidl::android::hardware::camera::device::StreamType::OUTPUT;
535 stream->width = streamInfo.width;
536 stream->height = streamInfo.height;
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000537 stream->format = AidlCamera3Device::mapToAidlPixelFormat(streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000538 auto u = streamInfo.consumerUsage;
539 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000540 stream->usage = AidlCamera3Device::mapToAidlConsumerUsage(u);
541 stream->dataSpace = AidlCamera3Device::mapToAidlDataspace(streamInfo.dataSpace);
542 stream->rotation = AidlCamera3Device::mapToAidlStreamRotation(rotation);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000543 stream->id = -1; // Invalid stream id
Austin Borger0fb3ad92023-06-01 16:51:35 -0700544 stream->physicalCameraId = physicalId;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000545 stream->bufferSize = 0;
546 stream->groupId = groupId;
547 stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800548 size_t idx = 0;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000549 using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800550 for (auto mode : streamInfo.sensorPixelModesUsed) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000551 stream->sensorPixelModesUsed[idx++] =
552 static_cast<SensorPixelMode>(mode);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800553 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000554 using DynamicRangeProfile =
555 aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
556 stream->dynamicRangeProfile = static_cast<DynamicRangeProfile>(streamInfo.dynamicRangeProfile);
557 using StreamUseCases =
558 aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
559 stream->useCase = static_cast<StreamUseCases>(streamInfo.streamUseCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000560}
561
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800562binder::Status
Austin Borgerea931242021-12-13 23:10:41 +0000563convertToHALStreamCombination(
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800564 const SessionConfiguration& sessionConfiguration,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700565 const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800566 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000567 aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700568 bool overrideForPerfClass, bool *earlyExit) {
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000569 using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000570 auto operatingMode = sessionConfiguration.getOperatingMode();
Austin Borger0fb3ad92023-06-01 16:51:35 -0700571 binder::Status res = checkOperatingMode(operatingMode, deviceInfo,
572 logicalCameraId);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000573 if (!res.isOk()) {
574 return res;
575 }
576
577 if (earlyExit == nullptr) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700578 std::string msg("earlyExit nullptr");
579 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
580 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000581 }
582 *earlyExit = false;
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000583 auto ret = AidlCamera3Device::mapToAidlStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700584 static_cast<camera_stream_configuration_mode_t> (operatingMode),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000585 /*out*/ &streamConfiguration.operationMode);
586 if (ret != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700587 std::string msg = fmt::sprintf(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000588 "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700589 logicalCameraId.c_str(), operatingMode, strerror(-ret), ret);
590 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000591 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700592 msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000593 }
594
595 bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
596 (sessionConfiguration.getInputHeight() > 0) &&
597 (sessionConfiguration.getInputFormat() > 0);
598 auto outputConfigs = sessionConfiguration.getOutputConfigurations();
599 size_t streamCount = outputConfigs.size();
600 streamCount = isInputValid ? streamCount + 1 : streamCount;
601 streamConfiguration.streams.resize(streamCount);
602 size_t streamIdx = 0;
603 if (isInputValid) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000604 std::vector<SensorPixelMode> defaultSensorPixelModes;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800605 defaultSensorPixelModes.resize(1);
606 defaultSensorPixelModes[0] =
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000607 static_cast<SensorPixelMode>(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
608 aidl::android::hardware::camera::device::Stream stream;
609 stream.id = 0;
610 stream.streamType = aidl::android::hardware::camera::device::StreamType::INPUT;
611 stream.width = static_cast<uint32_t> (sessionConfiguration.getInputWidth());
612 stream.height = static_cast<uint32_t> (sessionConfiguration.getInputHeight());
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000613 stream.format =
614 AidlCamera3Device::AidlCamera3Device::mapToAidlPixelFormat(
615 sessionConfiguration.getInputFormat());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000616 stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0);
617 stream.dataSpace =
618 static_cast<aidl::android::hardware::graphics::common::Dataspace>(
619 HAL_DATASPACE_UNKNOWN);
620 stream.rotation = aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
621 stream.bufferSize = 0;
622 stream.groupId = -1;
623 stream.sensorPixelModesUsed = defaultSensorPixelModes;
Emilian Peev065fb0f2022-05-16 15:37:16 -0700624 using DynamicRangeProfile =
625 aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
626 stream.dynamicRangeProfile =
627 DynamicRangeProfile::ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000628 streamConfiguration.streams[streamIdx++] = stream;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800629 streamConfiguration.multiResolutionInputImage =
630 sessionConfiguration.inputIsMultiResolution();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000631 }
632
633 for (const auto &it : outputConfigs) {
634 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
635 it.getGraphicBufferProducers();
636 bool deferredConsumer = it.isDeferred();
Austin Borger0fb3ad92023-06-01 16:51:35 -0700637 const std::string &physicalCameraId = it.getPhysicalCameraId();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800638
Emilian Peevc81a7592022-02-14 17:38:18 -0800639 int64_t dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800640 std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700641 const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
642 overrideForPerfClass);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800643 const CameraMetadata &metadataChosen =
644 physicalCameraId.size() > 0 ? physicalDeviceInfo : deviceInfo;
645
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000646 size_t numBufferProducers = bufferProducers.size();
647 bool isStreamInfoValid = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800648 int32_t groupId = it.isMultiResolution() ? it.getSurfaceSetID() : -1;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000649 OutputStreamInfo streamInfo;
650
651 res = checkSurfaceType(numBufferProducers, deferredConsumer, it.getSurfaceType());
652 if (!res.isOk()) {
653 return res;
654 }
655 res = checkPhysicalCameraId(physicalCameraIds, physicalCameraId,
656 logicalCameraId);
657 if (!res.isOk()) {
658 return res;
659 }
660
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800661 int64_t streamUseCase = it.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -0800662 int timestampBase = it.getTimestampBase();
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800663 int mirrorMode = it.getMirrorMode();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000664 if (deferredConsumer) {
665 streamInfo.width = it.getWidth();
666 streamInfo.height = it.getHeight();
667 streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
668 streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
669 auto surfaceType = it.getSurfaceType();
670 streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
671 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
672 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
673 }
Emilian Peev2295df72021-11-12 18:14:10 -0800674 streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800675 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
676 streamInfo.format, streamInfo.width,
677 streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
678 &streamInfo.sensorPixelModesUsed) != OK) {
679 ALOGE("%s: Deferred surface sensor pixel modes not valid",
680 __FUNCTION__);
681 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
682 "Deferred surface sensor pixel modes not valid");
683 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800684 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800685 mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000686 &streamConfiguration.streams[streamIdx++]);
687 isStreamInfoValid = true;
688
689 if (numBufferProducers == 0) {
690 continue;
691 }
692 }
693
694 for (auto& bufferProducer : bufferProducers) {
695 sp<Surface> surface;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000696 res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800697 logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800698 streamUseCase, timestampBase, mirrorMode);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000699
700 if (!res.isOk())
701 return res;
702
703 if (!isStreamInfoValid) {
704 bool isDepthCompositeStream =
705 camera3::DepthCompositeStream::isDepthCompositeStream(surface);
706 bool isHeicCompositeStream =
707 camera3::HeicCompositeStream::isHeicCompositeStream(surface);
708 if (isDepthCompositeStream || isHeicCompositeStream) {
709 // We need to take in to account that composite streams can have
710 // additional internal camera streams.
711 std::vector<OutputStreamInfo> compositeStreams;
712 if (isDepthCompositeStream) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800713 // TODO: Take care of composite streams.
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000714 ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
715 deviceInfo, &compositeStreams);
716 } else {
717 ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
718 deviceInfo, &compositeStreams);
719 }
720 if (ret != OK) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700721 std::string msg = fmt::sprintf(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000722 "Camera %s: Failed adding composite streams: %s (%d)",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700723 logicalCameraId.c_str(), strerror(-ret), ret);
724 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
725 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000726 }
727
728 if (compositeStreams.size() == 0) {
729 // No internal streams means composite stream not
730 // supported.
731 *earlyExit = true;
732 return binder::Status::ok();
733 } else if (compositeStreams.size() > 1) {
734 streamCount += compositeStreams.size() - 1;
735 streamConfiguration.streams.resize(streamCount);
736 }
737
738 for (const auto& compositeStream : compositeStreams) {
739 mapStreamInfo(compositeStream,
Emilian Peevf4816702020-04-03 15:44:51 -0700740 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800741 physicalCameraId, groupId,
742 &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000743 }
744 } else {
745 mapStreamInfo(streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700746 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800747 physicalCameraId, groupId, &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000748 }
749 isStreamInfoValid = true;
750 }
751 }
752 }
753 return binder::Status::ok();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800754}
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000755
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000756binder::Status checkPhysicalCameraId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700757 const std::vector<std::string> &physicalCameraIds, const std::string &physicalCameraId,
758 const std::string &logicalCameraId) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000759 if (physicalCameraId.size() == 0) {
760 return binder::Status::ok();
761 }
762 if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
Austin Borger0fb3ad92023-06-01 16:51:35 -0700763 physicalCameraId) == physicalCameraIds.end()) {
764 std::string msg = fmt::sprintf("Camera %s: Camera doesn't support physicalCameraId %s.",
765 logicalCameraId.c_str(), physicalCameraId.c_str());
766 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
767 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000768 }
769 return binder::Status::ok();
770}
771
772binder::Status checkSurfaceType(size_t numBufferProducers,
773 bool deferredConsumer, int surfaceType) {
774 if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
775 ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
776 __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
777 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
778 } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
779 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
780 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
781 }
782
783 bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
784 (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
785
786 if (deferredConsumer && !validSurfaceType) {
787 ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
788 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
789 }
790
791 return binder::Status::ok();
792}
793
794binder::Status checkOperatingMode(int operatingMode,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700795 const CameraMetadata &staticInfo, const std::string &cameraId) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000796 if (operatingMode < 0) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700797 std::string msg = fmt::sprintf(
798 "Camera %s: Invalid operating mode %d requested", cameraId.c_str(), operatingMode);
799 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000800 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700801 msg.c_str());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000802 }
803
804 bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
805 if (isConstrainedHighSpeed) {
806 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
807 bool isConstrainedHighSpeedSupported = false;
808 for(size_t i = 0; i < entry.count; ++i) {
809 uint8_t capability = entry.data.u8[i];
810 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
811 isConstrainedHighSpeedSupported = true;
812 break;
813 }
814 }
815 if (!isConstrainedHighSpeedSupported) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700816 std::string msg = fmt::sprintf(
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000817 "Camera %s: Try to create a constrained high speed configuration on a device"
Austin Borger0fb3ad92023-06-01 16:51:35 -0700818 " that doesn't support it.", cameraId.c_str());
819 ALOGE("%s: %s", __FUNCTION__, msg.c_str());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000820 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
Austin Borger0fb3ad92023-06-01 16:51:35 -0700821 msg.c_str());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000822 }
823 }
824
825 return binder::Status::ok();
826}
827
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800828static bool inStreamConfigurationMap(int format, int width, int height,
829 const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
830 auto scs = sm.find(format);
831 if (scs == sm.end()) {
832 return false;
833 }
834 for (auto &sc : scs->second) {
835 if (sc.width == width && sc.height == height && sc.isInput == 0) {
836 return true;
837 }
838 }
839 return false;
840}
841
842static std::unordered_set<int32_t> convertToSet(const std::vector<int32_t> &sensorPixelModesUsed) {
843 return std::unordered_set<int32_t>(sensorPixelModesUsed.begin(), sensorPixelModesUsed.end());
844}
845
Austin Borgerea931242021-12-13 23:10:41 +0000846status_t checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800847 const std::vector<int32_t> &sensorPixelModesUsed, int format, int width, int height,
848 const CameraMetadata &staticInfo, bool flexibleConsumer,
849 std::unordered_set<int32_t> *overriddenSensorPixelModesUsed) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700850
851 const std::unordered_set<int32_t> &sensorPixelModesUsedSet =
852 convertToSet(sensorPixelModesUsed);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800853 if (!isUltraHighResolutionSensor(staticInfo)) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700854 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
855 sensorPixelModesUsedSet.end()) {
856 // invalid value for non ultra high res sensors
857 return BAD_VALUE;
858 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800859 overriddenSensorPixelModesUsed->clear();
860 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
861 return OK;
862 }
863
864 StreamConfigurationPair streamConfigurationPair = getStreamConfigurationPair(staticInfo);
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700865
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800866 bool isInDefaultStreamConfigurationMap =
867 inStreamConfigurationMap(format, width, height,
868 streamConfigurationPair.mDefaultStreamConfigurationMap);
869
870 bool isInMaximumResolutionStreamConfigurationMap =
871 inStreamConfigurationMap(format, width, height,
872 streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
873
874 // Case 1: The client has not changed the sensor mode defaults. In this case, we check if the
875 // size + format of the OutputConfiguration is found exclusively in 1.
876 // If yes, add that sensorPixelMode to overriddenSensorPixelModes.
877 // If no, add 'DEFAULT' to sensorPixelMode. This maintains backwards
878 // compatibility.
879 if (sensorPixelModesUsedSet.size() == 0) {
880 // Ambiguous case, default to only 'DEFAULT' mode.
881 if (isInDefaultStreamConfigurationMap && isInMaximumResolutionStreamConfigurationMap) {
882 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
883 return OK;
884 }
885 // We don't allow flexible consumer for max resolution mode.
886 if (isInMaximumResolutionStreamConfigurationMap) {
887 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
888 return OK;
889 }
890 if (isInDefaultStreamConfigurationMap || (flexibleConsumer && width < ROUNDING_WIDTH_CAP)) {
891 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
892 return OK;
893 }
894 return BAD_VALUE;
895 }
896
897 // Case2: The app has set sensorPixelModesUsed, we need to verify that they
898 // are valid / err out.
899 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_DEFAULT) !=
900 sensorPixelModesUsedSet.end() && !isInDefaultStreamConfigurationMap) {
901 return BAD_VALUE;
902 }
903
904 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
905 sensorPixelModesUsedSet.end() && !isInMaximumResolutionStreamConfigurationMap) {
906 return BAD_VALUE;
907 }
908 *overriddenSensorPixelModesUsed = sensorPixelModesUsedSet;
909 return OK;
910}
911
Austin Borgerea931242021-12-13 23:10:41 +0000912bool targetPerfClassPrimaryCamera(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700913 const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
914 int targetSdkVersion) {
915 bool isPerfClassPrimaryCamera =
916 perfClassPrimaryCameraIds.find(cameraId) != perfClassPrimaryCameraIds.end();
917 return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
918}
919
Austin Borgerea931242021-12-13 23:10:41 +0000920} // namespace SessionConfigurationUtils
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800921} // namespace camera3
922} // namespace android