blob: e38140bd07168e3731875e46177e20cbb0268981 [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"
Emilian Peev2295df72021-11-12 18:14:10 -080022#include "android/hardware/camera/metadata/3.8/types.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000023#include "common/CameraDeviceBase.h"
24#include "../CameraService.h"
Jayant Chowdhary22441f32021-12-26 18:35:41 -080025#include "device3/hidl/HidlCamera3Device.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000026#include "device3/Camera3OutputStream.h"
Emilian Peev2295df72021-11-12 18:14:10 -080027#include "system/graphics-base-v1.1.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000028
Colin Crossb8a9dbb2020-08-27 04:12:26 +000029using android::camera3::OutputStreamInfo;
30using android::camera3::OutputStreamInfo;
31using android::hardware::camera2::ICameraDeviceUser;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080032using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
Emilian Peev2295df72021-11-12 18:14:10 -080033using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080034using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080035
36namespace android {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080037namespace camera3 {
38
39void StreamConfiguration::getStreamConfigurations(
40 const CameraMetadata &staticInfo, int configuration,
41 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
42 if (scm == nullptr) {
43 ALOGE("%s: StreamConfigurationMap nullptr", __FUNCTION__);
44 return;
45 }
46 const int STREAM_FORMAT_OFFSET = 0;
47 const int STREAM_WIDTH_OFFSET = 1;
48 const int STREAM_HEIGHT_OFFSET = 2;
49 const int STREAM_IS_INPUT_OFFSET = 3;
50
51 camera_metadata_ro_entry availableStreamConfigs = staticInfo.find(configuration);
52 for (size_t i = 0; i < availableStreamConfigs.count; i += 4) {
53 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
54 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
55 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
56 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
57 StreamConfiguration sc = {format, width, height, isInput};
58 (*scm)[format].push_back(sc);
59 }
60}
61
62void StreamConfiguration::getStreamConfigurations(
63 const CameraMetadata &staticInfo, bool maxRes,
64 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
65 int32_t scalerKey =
66 SessionConfigurationUtils::getAppropriateModeTag(
67 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxRes);
68
69 int32_t depthKey =
70 SessionConfigurationUtils::getAppropriateModeTag(
71 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, maxRes);
72
73 int32_t dynamicDepthKey =
74 SessionConfigurationUtils::getAppropriateModeTag(
75 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
76
77 int32_t heicKey =
78 SessionConfigurationUtils::getAppropriateModeTag(
79 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
80
81 getStreamConfigurations(staticInfo, scalerKey, scm);
82 getStreamConfigurations(staticInfo, depthKey, scm);
83 getStreamConfigurations(staticInfo, dynamicDepthKey, scm);
84 getStreamConfigurations(staticInfo, heicKey, scm);
85}
86
Austin Borgerea931242021-12-13 23:10:41 +000087namespace SessionConfigurationUtils {
88
89int32_t PERF_CLASS_LEVEL =
90 property_get_int32("ro.odm.build.media_performance_class", 0);
91
92bool IS_PERF_CLASS = (PERF_CLASS_LEVEL == SDK_VERSION_S);
93
94camera3::Size getMaxJpegResolution(const CameraMetadata &metadata,
95 bool ultraHighResolution) {
96 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
97 const int STREAM_CONFIGURATION_SIZE = 4;
98 const int STREAM_FORMAT_OFFSET = 0;
99 const int STREAM_WIDTH_OFFSET = 1;
100 const int STREAM_HEIGHT_OFFSET = 2;
101 const int STREAM_IS_INPUT_OFFSET = 3;
102
103 int32_t scalerSizesTag = ultraHighResolution ?
104 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION :
105 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
106 camera_metadata_ro_entry_t availableStreamConfigs =
107 metadata.find(scalerSizesTag);
108 if (availableStreamConfigs.count == 0 ||
109 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
110 return camera3::Size(0, 0);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800111 }
Austin Borgerea931242021-12-13 23:10:41 +0000112
113 // Get max jpeg size (area-wise).
114 for (size_t i= 0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
115 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
116 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
117 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
118 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
119 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
120 && format == HAL_PIXEL_FORMAT_BLOB &&
121 (width * height > maxJpegWidth * maxJpegHeight)) {
122 maxJpegWidth = width;
123 maxJpegHeight = height;
124 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800125 }
Austin Borgerea931242021-12-13 23:10:41 +0000126
127 return camera3::Size(maxJpegWidth, maxJpegHeight);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800128}
129
Austin Borgerea931242021-12-13 23:10:41 +0000130size_t getUHRMaxJpegBufferSize(camera3::Size uhrMaxJpegSize,
131 camera3::Size defaultMaxJpegSize, size_t defaultMaxJpegBufferSize) {
132 return (uhrMaxJpegSize.width * uhrMaxJpegSize.height) /
133 (defaultMaxJpegSize.width * defaultMaxJpegSize.height) * defaultMaxJpegBufferSize;
134}
135
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800136StreamConfigurationPair
Austin Borgerea931242021-12-13 23:10:41 +0000137getStreamConfigurationPair(const CameraMetadata &staticInfo) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800138 camera3::StreamConfigurationPair streamConfigurationPair;
139 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, false,
140 &streamConfigurationPair.mDefaultStreamConfigurationMap);
141 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, true,
142 &streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
143 return streamConfigurationPair;
144}
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800145
Austin Borgerea931242021-12-13 23:10:41 +0000146int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000147 int64_t d0 = x0 - x1;
148 int64_t d1 = y0 - y1;
149 return d0 * d0 + d1 * d1;
150}
151
Austin Borgerea931242021-12-13 23:10:41 +0000152bool roundBufferDimensionNearest(int32_t width, int32_t height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800153 int32_t format, android_dataspace dataSpace,
154 const CameraMetadata& info, bool maxResolution, /*out*/int32_t* outWidth,
155 /*out*/int32_t* outHeight) {
156 const int32_t depthSizesTag =
157 getAppropriateModeTag(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
158 maxResolution);
159 const int32_t scalerSizesTag =
160 getAppropriateModeTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
161 const int32_t heicSizesTag =
162 getAppropriateModeTag(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000163
164 camera_metadata_ro_entry streamConfigs =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800165 (dataSpace == HAL_DATASPACE_DEPTH) ? info.find(depthSizesTag) :
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000166 (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800167 info.find(heicSizesTag) :
168 info.find(scalerSizesTag);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000169
170 int32_t bestWidth = -1;
171 int32_t bestHeight = -1;
172
173 // Iterate through listed stream configurations and find the one with the smallest euclidean
174 // distance from the given dimensions for the given format.
175 for (size_t i = 0; i < streamConfigs.count; i += 4) {
176 int32_t fmt = streamConfigs.data.i32[i];
177 int32_t w = streamConfigs.data.i32[i + 1];
178 int32_t h = streamConfigs.data.i32[i + 2];
179
180 // Ignore input/output type for now
181 if (fmt == format) {
182 if (w == width && h == height) {
183 bestWidth = width;
184 bestHeight = height;
185 break;
186 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
187 SessionConfigurationUtils::euclidDistSquare(w, h, width, height) <
188 SessionConfigurationUtils::euclidDistSquare(bestWidth, bestHeight, width,
189 height))) {
190 bestWidth = w;
191 bestHeight = h;
192 }
193 }
194 }
195
196 if (bestWidth == -1) {
197 // Return false if no configurations for this format were listed
198 return false;
199 }
200
201 // Set the outputs to the closet width/height
202 if (outWidth != NULL) {
203 *outWidth = bestWidth;
204 }
205 if (outHeight != NULL) {
206 *outHeight = bestHeight;
207 }
208
209 // Return true if at least one configuration for this format was listed
210 return true;
211}
212
Emilian Peev2295df72021-11-12 18:14:10 -0800213//check if format is 10-bit compatible
214bool is10bitCompatibleFormat(int32_t format) {
215 switch(format) {
216 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
217 case HAL_PIXEL_FORMAT_YCBCR_P010:
218 return true;
219 default:
220 return false;
221 }
222}
223
224bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticInfo) {
225 if (dynamicRangeProfile == ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
226 // Supported by default
227 return true;
228 }
229
230 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
231 bool is10bitDynamicRangeSupported = false;
232 for (size_t i = 0; i < entry.count; ++i) {
233 uint8_t capability = entry.data.u8[i];
234 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
235 is10bitDynamicRangeSupported = true;
236 break;
237 }
238 }
239
240 if (!is10bitDynamicRangeSupported) {
241 return false;
242 }
243
244 switch (dynamicRangeProfile) {
245 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
246 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
247 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
248 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
249 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
250 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
251 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
252 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
253 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
254 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
255 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
256 entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
257 for (size_t i = 0; i < entry.count; i += 2) {
258 if (dynamicRangeProfile == entry.data.i32[i]) {
259 return true;
260 }
261 }
262
263 return false;
264 default:
265 return false;
266 }
267
268 return false;
269}
270
271//check if format is 10-bit compatible
272bool is10bitDynamicRangeProfile(int32_t dynamicRangeProfile) {
273 switch (dynamicRangeProfile) {
274 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
275 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
276 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
277 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
278 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
279 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
280 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
281 return true;
282 default:
283 return false;
284 }
285}
286
Austin Borgerea931242021-12-13 23:10:41 +0000287bool isPublicFormat(int32_t format)
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000288{
289 switch(format) {
290 case HAL_PIXEL_FORMAT_RGBA_8888:
291 case HAL_PIXEL_FORMAT_RGBX_8888:
292 case HAL_PIXEL_FORMAT_RGB_888:
293 case HAL_PIXEL_FORMAT_RGB_565:
294 case HAL_PIXEL_FORMAT_BGRA_8888:
295 case HAL_PIXEL_FORMAT_YV12:
296 case HAL_PIXEL_FORMAT_Y8:
297 case HAL_PIXEL_FORMAT_Y16:
298 case HAL_PIXEL_FORMAT_RAW16:
299 case HAL_PIXEL_FORMAT_RAW10:
300 case HAL_PIXEL_FORMAT_RAW12:
301 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
302 case HAL_PIXEL_FORMAT_BLOB:
303 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
304 case HAL_PIXEL_FORMAT_YCbCr_420_888:
305 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
306 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
307 case HAL_PIXEL_FORMAT_YCbCr_422_I:
308 return true;
309 default:
310 return false;
311 }
312}
313
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800314bool isStreamUseCaseSupported(int streamUseCase,
315 const CameraMetadata &deviceInfo) {
316 camera_metadata_ro_entry_t availableStreamUseCases =
317 deviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES);
318
319 if (availableStreamUseCases.count == 0 &&
320 streamUseCase == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
321 return true;
322 }
323
324 for (size_t i = 0; i < availableStreamUseCases.count; i++) {
325 if (availableStreamUseCases.data.i32[i] == streamUseCase) {
326 return true;
327 }
328 }
329 return false;
330}
331
Austin Borgerea931242021-12-13 23:10:41 +0000332binder::Status createSurfaceFromGbp(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000333 OutputStreamInfo& streamInfo, bool isStreamInfoValid,
334 sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800335 const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800336 const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800337 int streamUseCase, int timestampBase, int mirrorMode) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000338 // bufferProducer must be non-null
339 if (gbp == nullptr) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800340 String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000341 ALOGW("%s: %s", __FUNCTION__, msg.string());
342 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
343 }
344 // HACK b/10949105
345 // Query consumer usage bits to set async operation mode for
346 // GLConsumer using controlledByApp parameter.
347 bool useAsync = false;
348 uint64_t consumerUsage = 0;
349 status_t err;
350 if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
351 String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800352 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000353 ALOGE("%s: %s", __FUNCTION__, msg.string());
354 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
355 }
356 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
357 ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800358 "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000359 useAsync = true;
360 }
361
362 uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
363 GRALLOC_USAGE_RENDERSCRIPT;
364 uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
365 GraphicBuffer::USAGE_HW_TEXTURE |
366 GraphicBuffer::USAGE_HW_COMPOSER;
367 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
368 (consumerUsage & allowedFlags) != 0;
369
370 surface = new Surface(gbp, useAsync);
371 ANativeWindow *anw = surface.get();
372
373 int width, height, format;
374 android_dataspace dataSpace;
375 if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
376 String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800377 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000378 ALOGE("%s: %s", __FUNCTION__, msg.string());
379 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
380 }
381 if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
382 String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800383 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000384 ALOGE("%s: %s", __FUNCTION__, msg.string());
385 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
386 }
387 if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
388 String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800389 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000390 ALOGE("%s: %s", __FUNCTION__, msg.string());
391 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
392 }
393 if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
394 reinterpret_cast<int*>(&dataSpace))) != OK) {
395 String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800396 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000397 ALOGE("%s: %s", __FUNCTION__, msg.string());
398 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
399 }
400
401 // FIXME: remove this override since the default format should be
402 // IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
403 if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
404 ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
405 ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
406 ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800407 __FUNCTION__, logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000408 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
409 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800410 std::unordered_set<int32_t> overriddenSensorPixelModes;
411 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
412 physicalCameraMetadata, flexibleConsumer, &overriddenSensorPixelModes) != OK) {
413 String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
414 "format %#x are not valid",logicalCameraId.string(), format);
415 ALOGE("%s: %s", __FUNCTION__, msg.string());
416 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
417 }
418 bool foundInMaxRes = false;
419 if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
420 overriddenSensorPixelModes.end()) {
421 // we can use the default stream configuration map
422 foundInMaxRes = true;
423 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000424 // Round dimensions to the nearest dimensions available for this format
425 if (flexibleConsumer && isPublicFormat(format) &&
426 !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800427 format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
428 /*out*/&height)) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000429 String8 msg = String8::format("Camera %s: No supported stream configurations with "
430 "format %#x defined, failed to create output stream",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800431 logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000432 ALOGE("%s: %s", __FUNCTION__, msg.string());
433 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
434 }
Emilian Peev2295df72021-11-12 18:14:10 -0800435 if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
436 physicalCameraMetadata)) {
437 String8 msg = String8::format("Camera %s: Dynamic range profile 0x%x not supported,"
438 " failed to create output stream", logicalCameraId.string(), dynamicRangeProfile);
439 ALOGE("%s: %s", __FUNCTION__, msg.string());
440 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
441 }
442 if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
443 !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
444 String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
445 "format %#x defined and profile %#x, failed to create output stream",
446 logicalCameraId.string(), format, dynamicRangeProfile);
447 ALOGE("%s: %s", __FUNCTION__, msg.string());
448 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
449 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800450 if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
451 physicalCameraMetadata)) {
452 String8 msg = String8::format("Camera %s: stream use case %d not supported,"
453 " failed to create output stream", logicalCameraId.string(), streamUseCase);
454 ALOGE("%s: %s", __FUNCTION__, msg.string());
455 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
456 }
Shuzhen Wange4208922022-02-01 16:52:48 -0800457 if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
458 timestampBase > OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
459 String8 msg = String8::format("Camera %s: invalid timestamp base %d",
460 logicalCameraId.string(), timestampBase);
461 ALOGE("%s: %s", __FUNCTION__, msg.string());
462 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
463 }
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800464 if (mirrorMode < OutputConfiguration::MIRROR_MODE_AUTO ||
465 mirrorMode > OutputConfiguration::MIRROR_MODE_V) {
466 String8 msg = String8::format("Camera %s: invalid mirroring mode %d",
467 logicalCameraId.string(), mirrorMode);
468 ALOGE("%s: %s", __FUNCTION__, msg.string());
469 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
470 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000471
472 if (!isStreamInfoValid) {
473 streamInfo.width = width;
474 streamInfo.height = height;
475 streamInfo.format = format;
476 streamInfo.dataSpace = dataSpace;
477 streamInfo.consumerUsage = consumerUsage;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800478 streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
Emilian Peev2295df72021-11-12 18:14:10 -0800479 streamInfo.dynamicRangeProfile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800480 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wange4208922022-02-01 16:52:48 -0800481 streamInfo.timestampBase = timestampBase;
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800482 streamInfo.mirrorMode = mirrorMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000483 return binder::Status::ok();
484 }
485 if (width != streamInfo.width) {
486 String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800487 logicalCameraId.string(), width, streamInfo.width);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000488 ALOGE("%s: %s", __FUNCTION__, msg.string());
489 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
490 }
491 if (height != streamInfo.height) {
492 String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800493 logicalCameraId.string(), height, streamInfo.height);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000494 ALOGE("%s: %s", __FUNCTION__, msg.string());
495 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
496 }
497 if (format != streamInfo.format) {
498 String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800499 logicalCameraId.string(), format, streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000500 ALOGE("%s: %s", __FUNCTION__, msg.string());
501 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
502 }
503 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
504 if (dataSpace != streamInfo.dataSpace) {
505 String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800506 logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000507 ALOGE("%s: %s", __FUNCTION__, msg.string());
508 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
509 }
510 //At the native side, there isn't a way to check whether 2 surfaces come from the same
511 //surface class type. Use usage flag to approximate the comparison.
512 if (consumerUsage != streamInfo.consumerUsage) {
513 String8 msg = String8::format(
514 "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800515 logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000516 ALOGE("%s: %s", __FUNCTION__, msg.string());
517 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
518 }
519 }
520 return binder::Status::ok();
521}
522
Austin Borgerea931242021-12-13 23:10:41 +0000523void mapStreamInfo(const OutputStreamInfo &streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700524 camera3::camera_stream_rotation_t rotation, String8 physicalId,
Emilian Peev2295df72021-11-12 18:14:10 -0800525 int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000526 if (stream == nullptr) {
527 return;
528 }
529
Emilian Peev2295df72021-11-12 18:14:10 -0800530 stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
531 stream->v3_7.v3_4.v3_2.width = streamInfo.width;
532 stream->v3_7.v3_4.v3_2.height = streamInfo.height;
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800533 stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000534 auto u = streamInfo.consumerUsage;
535 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800536 stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
537 stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
538 stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
Emilian Peev2295df72021-11-12 18:14:10 -0800539 stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
540 stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
541 stream->v3_7.v3_4.bufferSize = 0;
542 stream->v3_7.groupId = groupId;
543 stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800544
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800545 size_t idx = 0;
546 for (auto mode : streamInfo.sensorPixelModesUsed) {
Emilian Peev2295df72021-11-12 18:14:10 -0800547 stream->v3_7.sensorPixelModesUsed[idx++] =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800548 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
549 }
Emilian Peev2295df72021-11-12 18:14:10 -0800550 stream->dynamicRangeProfile =
551 static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
552 streamInfo.dynamicRangeProfile);
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800553 stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
554 streamInfo.streamUseCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000555}
556
Austin Borgerea931242021-12-13 23:10:41 +0000557binder::Status checkPhysicalCameraId(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000558 const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
559 const String8 &logicalCameraId) {
560 if (physicalCameraId.size() == 0) {
561 return binder::Status::ok();
562 }
563 if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
564 physicalCameraId.string()) == physicalCameraIds.end()) {
565 String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
566 logicalCameraId.string(), physicalCameraId.string());
567 ALOGE("%s: %s", __FUNCTION__, msg.string());
568 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
569 }
570 return binder::Status::ok();
571}
572
Austin Borgerea931242021-12-13 23:10:41 +0000573binder::Status checkSurfaceType(size_t numBufferProducers,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000574 bool deferredConsumer, int surfaceType) {
575 if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
576 ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
577 __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
578 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
579 } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
580 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
581 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
582 }
583
584 bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
585 (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
586
587 if (deferredConsumer && !validSurfaceType) {
588 ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
589 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
590 }
591
592 return binder::Status::ok();
593}
594
Austin Borgerea931242021-12-13 23:10:41 +0000595binder::Status checkOperatingMode(int operatingMode,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000596 const CameraMetadata &staticInfo, const String8 &cameraId) {
597 if (operatingMode < 0) {
598 String8 msg = String8::format(
599 "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
600 ALOGE("%s: %s", __FUNCTION__, msg.string());
601 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
602 msg.string());
603 }
604
605 bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
606 if (isConstrainedHighSpeed) {
607 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
608 bool isConstrainedHighSpeedSupported = false;
609 for(size_t i = 0; i < entry.count; ++i) {
610 uint8_t capability = entry.data.u8[i];
611 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
612 isConstrainedHighSpeedSupported = true;
613 break;
614 }
615 }
616 if (!isConstrainedHighSpeedSupported) {
617 String8 msg = String8::format(
618 "Camera %s: Try to create a constrained high speed configuration on a device"
619 " that doesn't support it.", cameraId.string());
620 ALOGE("%s: %s", __FUNCTION__, msg.string());
621 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
622 msg.string());
623 }
624 }
625
626 return binder::Status::ok();
627}
628
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800629binder::Status
Austin Borgerea931242021-12-13 23:10:41 +0000630convertToHALStreamCombination(
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800631 const SessionConfiguration& sessionConfiguration,
632 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
633 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
Emilian Peev2295df72021-11-12 18:14:10 -0800634 hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700635 bool overrideForPerfClass, bool *earlyExit) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000636
637 auto operatingMode = sessionConfiguration.getOperatingMode();
638 binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
639 if (!res.isOk()) {
640 return res;
641 }
642
643 if (earlyExit == nullptr) {
644 String8 msg("earlyExit nullptr");
645 ALOGE("%s: %s", __FUNCTION__, msg.string());
646 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
647 }
648 *earlyExit = false;
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800649 auto ret = HidlCamera3Device::mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700650 static_cast<camera_stream_configuration_mode_t> (operatingMode),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000651 /*out*/ &streamConfiguration.operationMode);
652 if (ret != OK) {
653 String8 msg = String8::format(
654 "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
655 logicalCameraId.string(), operatingMode, strerror(-ret), ret);
656 ALOGE("%s: %s", __FUNCTION__, msg.string());
657 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
658 msg.string());
659 }
660
661 bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
662 (sessionConfiguration.getInputHeight() > 0) &&
663 (sessionConfiguration.getInputFormat() > 0);
664 auto outputConfigs = sessionConfiguration.getOutputConfigurations();
665 size_t streamCount = outputConfigs.size();
666 streamCount = isInputValid ? streamCount + 1 : streamCount;
667 streamConfiguration.streams.resize(streamCount);
668 size_t streamIdx = 0;
669 if (isInputValid) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800670 hardware::hidl_vec<CameraMetadataEnumAndroidSensorPixelMode> defaultSensorPixelModes;
671 defaultSensorPixelModes.resize(1);
672 defaultSensorPixelModes[0] =
673 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(
674 ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
Emilian Peev2295df72021-11-12 18:14:10 -0800675 streamConfiguration.streams[streamIdx++].v3_7 = {{{/*streamId*/0,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000676 hardware::camera::device::V3_2::StreamType::INPUT,
677 static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
678 static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800679 HidlCamera3Device::mapToPixelFormat(sessionConfiguration.getInputFormat()),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000680 /*usage*/ 0, HAL_DATASPACE_UNKNOWN,
681 hardware::camera::device::V3_2::StreamRotation::ROTATION_0},
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800682 /*physicalId*/ nullptr, /*bufferSize*/0}, /*groupId*/-1, defaultSensorPixelModes};
Shuzhen Wang83bff122020-11-20 15:51:39 -0800683 streamConfiguration.multiResolutionInputImage =
684 sessionConfiguration.inputIsMultiResolution();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000685 }
686
687 for (const auto &it : outputConfigs) {
688 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
689 it.getGraphicBufferProducers();
690 bool deferredConsumer = it.isDeferred();
691 String8 physicalCameraId = String8(it.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800692
Emilian Peev2295df72021-11-12 18:14:10 -0800693 int dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800694 std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700695 const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
696 overrideForPerfClass);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800697 const CameraMetadata &metadataChosen =
698 physicalCameraId.size() > 0 ? physicalDeviceInfo : deviceInfo;
699
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000700 size_t numBufferProducers = bufferProducers.size();
701 bool isStreamInfoValid = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800702 int32_t groupId = it.isMultiResolution() ? it.getSurfaceSetID() : -1;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000703 OutputStreamInfo streamInfo;
704
705 res = checkSurfaceType(numBufferProducers, deferredConsumer, it.getSurfaceType());
706 if (!res.isOk()) {
707 return res;
708 }
709 res = checkPhysicalCameraId(physicalCameraIds, physicalCameraId,
710 logicalCameraId);
711 if (!res.isOk()) {
712 return res;
713 }
714
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800715 int streamUseCase = it.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -0800716 int timestampBase = it.getTimestampBase();
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800717 int mirrorMode = it.getMirrorMode();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000718 if (deferredConsumer) {
719 streamInfo.width = it.getWidth();
720 streamInfo.height = it.getHeight();
721 streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
722 streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
723 auto surfaceType = it.getSurfaceType();
724 streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
725 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
726 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
727 }
Emilian Peev2295df72021-11-12 18:14:10 -0800728 streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800729 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
730 streamInfo.format, streamInfo.width,
731 streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
732 &streamInfo.sensorPixelModesUsed) != OK) {
733 ALOGE("%s: Deferred surface sensor pixel modes not valid",
734 __FUNCTION__);
735 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
736 "Deferred surface sensor pixel modes not valid");
737 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800738 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800739 mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000740 &streamConfiguration.streams[streamIdx++]);
741 isStreamInfoValid = true;
742
743 if (numBufferProducers == 0) {
744 continue;
745 }
746 }
747
748 for (auto& bufferProducer : bufferProducers) {
749 sp<Surface> surface;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000750 res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800751 logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800752 streamUseCase, timestampBase, mirrorMode);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000753
754 if (!res.isOk())
755 return res;
756
757 if (!isStreamInfoValid) {
758 bool isDepthCompositeStream =
759 camera3::DepthCompositeStream::isDepthCompositeStream(surface);
760 bool isHeicCompositeStream =
761 camera3::HeicCompositeStream::isHeicCompositeStream(surface);
762 if (isDepthCompositeStream || isHeicCompositeStream) {
763 // We need to take in to account that composite streams can have
764 // additional internal camera streams.
765 std::vector<OutputStreamInfo> compositeStreams;
766 if (isDepthCompositeStream) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800767 // TODO: Take care of composite streams.
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000768 ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
769 deviceInfo, &compositeStreams);
770 } else {
771 ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
772 deviceInfo, &compositeStreams);
773 }
774 if (ret != OK) {
775 String8 msg = String8::format(
776 "Camera %s: Failed adding composite streams: %s (%d)",
777 logicalCameraId.string(), strerror(-ret), ret);
778 ALOGE("%s: %s", __FUNCTION__, msg.string());
779 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
780 }
781
782 if (compositeStreams.size() == 0) {
783 // No internal streams means composite stream not
784 // supported.
785 *earlyExit = true;
786 return binder::Status::ok();
787 } else if (compositeStreams.size() > 1) {
788 streamCount += compositeStreams.size() - 1;
789 streamConfiguration.streams.resize(streamCount);
790 }
791
792 for (const auto& compositeStream : compositeStreams) {
793 mapStreamInfo(compositeStream,
Emilian Peevf4816702020-04-03 15:44:51 -0700794 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800795 physicalCameraId, groupId,
796 &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000797 }
798 } else {
799 mapStreamInfo(streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700800 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800801 physicalCameraId, groupId, &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000802 }
803 isStreamInfoValid = true;
804 }
805 }
806 }
807 return binder::Status::ok();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800808}
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000809
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800810static bool inStreamConfigurationMap(int format, int width, int height,
811 const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
812 auto scs = sm.find(format);
813 if (scs == sm.end()) {
814 return false;
815 }
816 for (auto &sc : scs->second) {
817 if (sc.width == width && sc.height == height && sc.isInput == 0) {
818 return true;
819 }
820 }
821 return false;
822}
823
824static std::unordered_set<int32_t> convertToSet(const std::vector<int32_t> &sensorPixelModesUsed) {
825 return std::unordered_set<int32_t>(sensorPixelModesUsed.begin(), sensorPixelModesUsed.end());
826}
827
Austin Borgerea931242021-12-13 23:10:41 +0000828status_t checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800829 const std::vector<int32_t> &sensorPixelModesUsed, int format, int width, int height,
830 const CameraMetadata &staticInfo, bool flexibleConsumer,
831 std::unordered_set<int32_t> *overriddenSensorPixelModesUsed) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700832
833 const std::unordered_set<int32_t> &sensorPixelModesUsedSet =
834 convertToSet(sensorPixelModesUsed);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800835 if (!isUltraHighResolutionSensor(staticInfo)) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700836 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
837 sensorPixelModesUsedSet.end()) {
838 // invalid value for non ultra high res sensors
839 return BAD_VALUE;
840 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800841 overriddenSensorPixelModesUsed->clear();
842 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
843 return OK;
844 }
845
846 StreamConfigurationPair streamConfigurationPair = getStreamConfigurationPair(staticInfo);
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700847
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800848 bool isInDefaultStreamConfigurationMap =
849 inStreamConfigurationMap(format, width, height,
850 streamConfigurationPair.mDefaultStreamConfigurationMap);
851
852 bool isInMaximumResolutionStreamConfigurationMap =
853 inStreamConfigurationMap(format, width, height,
854 streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
855
856 // Case 1: The client has not changed the sensor mode defaults. In this case, we check if the
857 // size + format of the OutputConfiguration is found exclusively in 1.
858 // If yes, add that sensorPixelMode to overriddenSensorPixelModes.
859 // If no, add 'DEFAULT' to sensorPixelMode. This maintains backwards
860 // compatibility.
861 if (sensorPixelModesUsedSet.size() == 0) {
862 // Ambiguous case, default to only 'DEFAULT' mode.
863 if (isInDefaultStreamConfigurationMap && isInMaximumResolutionStreamConfigurationMap) {
864 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
865 return OK;
866 }
867 // We don't allow flexible consumer for max resolution mode.
868 if (isInMaximumResolutionStreamConfigurationMap) {
869 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
870 return OK;
871 }
872 if (isInDefaultStreamConfigurationMap || (flexibleConsumer && width < ROUNDING_WIDTH_CAP)) {
873 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
874 return OK;
875 }
876 return BAD_VALUE;
877 }
878
879 // Case2: The app has set sensorPixelModesUsed, we need to verify that they
880 // are valid / err out.
881 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_DEFAULT) !=
882 sensorPixelModesUsedSet.end() && !isInDefaultStreamConfigurationMap) {
883 return BAD_VALUE;
884 }
885
886 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
887 sensorPixelModesUsedSet.end() && !isInMaximumResolutionStreamConfigurationMap) {
888 return BAD_VALUE;
889 }
890 *overriddenSensorPixelModesUsed = sensorPixelModesUsedSet;
891 return OK;
892}
893
Emilian Peev2295df72021-11-12 18:14:10 -0800894bool convertHALStreamCombinationFromV38ToV37(
895 hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
896 const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
897 streamConfigV37.streams.resize(streamConfigV38.streams.size());
898 for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
899 if (static_cast<int32_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
900 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
901 // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
902 // image
903 return false;
904 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800905 if (static_cast<int32_t>(streamConfigV38.streams[i].useCase) !=
906 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
907 // ICameraDevice older than 3.8 doesn't support stream use case
908 return false;
909 }
Emilian Peev2295df72021-11-12 18:14:10 -0800910 streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
911 }
912 streamConfigV37.operationMode = streamConfigV38.operationMode;
913 streamConfigV37.sessionParams = streamConfigV38.sessionParams;
914
915 return true;
916}
917
Austin Borgerea931242021-12-13 23:10:41 +0000918bool convertHALStreamCombinationFromV37ToV34(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800919 hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
920 const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
921 if (streamConfigV37.multiResolutionInputImage) {
922 // ICameraDevice older than 3.7 doesn't support multi-resolution input image.
923 return false;
924 }
925
926 streamConfigV34.streams.resize(streamConfigV37.streams.size());
927 for (size_t i = 0; i < streamConfigV37.streams.size(); i++) {
928 if (streamConfigV37.streams[i].groupId != -1) {
929 // ICameraDevice older than 3.7 doesn't support multi-resolution output
930 // image
931 return false;
932 }
933 streamConfigV34.streams[i] = streamConfigV37.streams[i].v3_4;
934 }
935 streamConfigV34.operationMode = streamConfigV37.operationMode;
936 streamConfigV34.sessionParams = streamConfigV37.sessionParams;
937
938 return true;
939}
940
Austin Borgerea931242021-12-13 23:10:41 +0000941bool targetPerfClassPrimaryCamera(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700942 const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
943 int targetSdkVersion) {
944 bool isPerfClassPrimaryCamera =
945 perfClassPrimaryCameraIds.find(cameraId) != perfClassPrimaryCameraIds.end();
946 return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
947}
948
Austin Borgerea931242021-12-13 23:10:41 +0000949} // namespace SessionConfigurationUtils
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800950} // namespace camera3
951} // namespace android