blob: f826d83f5bec3140679ccb20f691559880d92f41 [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;
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
91bool IS_PERF_CLASS = (PERF_CLASS_LEVEL == SDK_VERSION_S);
92
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) {
131 return (uhrMaxJpegSize.width * uhrMaxJpegSize.height) /
132 (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
223bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticInfo) {
224 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);
256 for (size_t i = 0; i < entry.count; i += 2) {
257 if (dynamicRangeProfile == entry.data.i32[i]) {
258 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
271bool is10bitDynamicRangeProfile(int32_t dynamicRangeProfile) {
272 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
Austin Borgerea931242021-12-13 23:10:41 +0000313binder::Status createSurfaceFromGbp(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000314 OutputStreamInfo& streamInfo, bool isStreamInfoValid,
315 sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800316 const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
Emilian Peev2295df72021-11-12 18:14:10 -0800317 const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile){
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000318 // bufferProducer must be non-null
319 if (gbp == nullptr) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800320 String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000321 ALOGW("%s: %s", __FUNCTION__, msg.string());
322 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
323 }
324 // HACK b/10949105
325 // Query consumer usage bits to set async operation mode for
326 // GLConsumer using controlledByApp parameter.
327 bool useAsync = false;
328 uint64_t consumerUsage = 0;
329 status_t err;
330 if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
331 String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800332 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000333 ALOGE("%s: %s", __FUNCTION__, msg.string());
334 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
335 }
336 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
337 ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800338 "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000339 useAsync = true;
340 }
341
342 uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
343 GRALLOC_USAGE_RENDERSCRIPT;
344 uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
345 GraphicBuffer::USAGE_HW_TEXTURE |
346 GraphicBuffer::USAGE_HW_COMPOSER;
347 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
348 (consumerUsage & allowedFlags) != 0;
349
350 surface = new Surface(gbp, useAsync);
351 ANativeWindow *anw = surface.get();
352
353 int width, height, format;
354 android_dataspace dataSpace;
355 if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
356 String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800357 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000358 ALOGE("%s: %s", __FUNCTION__, msg.string());
359 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
360 }
361 if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
362 String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800363 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000364 ALOGE("%s: %s", __FUNCTION__, msg.string());
365 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
366 }
367 if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
368 String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800369 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000370 ALOGE("%s: %s", __FUNCTION__, msg.string());
371 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
372 }
373 if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
374 reinterpret_cast<int*>(&dataSpace))) != OK) {
375 String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800376 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000377 ALOGE("%s: %s", __FUNCTION__, msg.string());
378 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
379 }
380
381 // FIXME: remove this override since the default format should be
382 // IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
383 if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
384 ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
385 ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
386 ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800387 __FUNCTION__, logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000388 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
389 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800390 std::unordered_set<int32_t> overriddenSensorPixelModes;
391 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
392 physicalCameraMetadata, flexibleConsumer, &overriddenSensorPixelModes) != OK) {
393 String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
394 "format %#x are not valid",logicalCameraId.string(), format);
395 ALOGE("%s: %s", __FUNCTION__, msg.string());
396 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
397 }
398 bool foundInMaxRes = false;
399 if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
400 overriddenSensorPixelModes.end()) {
401 // we can use the default stream configuration map
402 foundInMaxRes = true;
403 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000404 // Round dimensions to the nearest dimensions available for this format
405 if (flexibleConsumer && isPublicFormat(format) &&
406 !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800407 format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
408 /*out*/&height)) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000409 String8 msg = String8::format("Camera %s: No supported stream configurations with "
410 "format %#x defined, failed to create output stream",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800411 logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000412 ALOGE("%s: %s", __FUNCTION__, msg.string());
413 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
414 }
Emilian Peev2295df72021-11-12 18:14:10 -0800415 if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
416 physicalCameraMetadata)) {
417 String8 msg = String8::format("Camera %s: Dynamic range profile 0x%x not supported,"
418 " failed to create output stream", logicalCameraId.string(), dynamicRangeProfile);
419 ALOGE("%s: %s", __FUNCTION__, msg.string());
420 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
421 }
422 if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
423 !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
424 String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
425 "format %#x defined and profile %#x, failed to create output stream",
426 logicalCameraId.string(), format, dynamicRangeProfile);
427 ALOGE("%s: %s", __FUNCTION__, msg.string());
428 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
429 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000430
431 if (!isStreamInfoValid) {
432 streamInfo.width = width;
433 streamInfo.height = height;
434 streamInfo.format = format;
435 streamInfo.dataSpace = dataSpace;
436 streamInfo.consumerUsage = consumerUsage;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800437 streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
Emilian Peev2295df72021-11-12 18:14:10 -0800438 streamInfo.dynamicRangeProfile = dynamicRangeProfile;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000439 return binder::Status::ok();
440 }
441 if (width != streamInfo.width) {
442 String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800443 logicalCameraId.string(), width, streamInfo.width);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000444 ALOGE("%s: %s", __FUNCTION__, msg.string());
445 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
446 }
447 if (height != streamInfo.height) {
448 String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800449 logicalCameraId.string(), height, streamInfo.height);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000450 ALOGE("%s: %s", __FUNCTION__, msg.string());
451 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
452 }
453 if (format != streamInfo.format) {
454 String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800455 logicalCameraId.string(), format, streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000456 ALOGE("%s: %s", __FUNCTION__, msg.string());
457 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
458 }
459 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
460 if (dataSpace != streamInfo.dataSpace) {
461 String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800462 logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000463 ALOGE("%s: %s", __FUNCTION__, msg.string());
464 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
465 }
466 //At the native side, there isn't a way to check whether 2 surfaces come from the same
467 //surface class type. Use usage flag to approximate the comparison.
468 if (consumerUsage != streamInfo.consumerUsage) {
469 String8 msg = String8::format(
470 "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800471 logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000472 ALOGE("%s: %s", __FUNCTION__, msg.string());
473 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
474 }
475 }
476 return binder::Status::ok();
477}
478
Austin Borgerea931242021-12-13 23:10:41 +0000479void mapStreamInfo(const OutputStreamInfo &streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700480 camera3::camera_stream_rotation_t rotation, String8 physicalId,
Emilian Peev2295df72021-11-12 18:14:10 -0800481 int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000482 if (stream == nullptr) {
483 return;
484 }
485
Emilian Peev2295df72021-11-12 18:14:10 -0800486 stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
487 stream->v3_7.v3_4.v3_2.width = streamInfo.width;
488 stream->v3_7.v3_4.v3_2.height = streamInfo.height;
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800489 stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000490 auto u = streamInfo.consumerUsage;
491 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800492 stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
493 stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
494 stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
Emilian Peev2295df72021-11-12 18:14:10 -0800495 stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
496 stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
497 stream->v3_7.v3_4.bufferSize = 0;
498 stream->v3_7.groupId = groupId;
499 stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800500
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800501 size_t idx = 0;
502 for (auto mode : streamInfo.sensorPixelModesUsed) {
Emilian Peev2295df72021-11-12 18:14:10 -0800503 stream->v3_7.sensorPixelModesUsed[idx++] =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800504 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
505 }
Emilian Peev2295df72021-11-12 18:14:10 -0800506 stream->dynamicRangeProfile =
507 static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
508 streamInfo.dynamicRangeProfile);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000509}
510
Austin Borgerea931242021-12-13 23:10:41 +0000511binder::Status checkPhysicalCameraId(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000512 const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
513 const String8 &logicalCameraId) {
514 if (physicalCameraId.size() == 0) {
515 return binder::Status::ok();
516 }
517 if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
518 physicalCameraId.string()) == physicalCameraIds.end()) {
519 String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
520 logicalCameraId.string(), physicalCameraId.string());
521 ALOGE("%s: %s", __FUNCTION__, msg.string());
522 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
523 }
524 return binder::Status::ok();
525}
526
Austin Borgerea931242021-12-13 23:10:41 +0000527binder::Status checkSurfaceType(size_t numBufferProducers,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000528 bool deferredConsumer, int surfaceType) {
529 if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
530 ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
531 __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
532 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
533 } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
534 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
535 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
536 }
537
538 bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
539 (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
540
541 if (deferredConsumer && !validSurfaceType) {
542 ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
543 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
544 }
545
546 return binder::Status::ok();
547}
548
Austin Borgerea931242021-12-13 23:10:41 +0000549binder::Status checkOperatingMode(int operatingMode,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000550 const CameraMetadata &staticInfo, const String8 &cameraId) {
551 if (operatingMode < 0) {
552 String8 msg = String8::format(
553 "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
554 ALOGE("%s: %s", __FUNCTION__, msg.string());
555 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
556 msg.string());
557 }
558
559 bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
560 if (isConstrainedHighSpeed) {
561 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
562 bool isConstrainedHighSpeedSupported = false;
563 for(size_t i = 0; i < entry.count; ++i) {
564 uint8_t capability = entry.data.u8[i];
565 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
566 isConstrainedHighSpeedSupported = true;
567 break;
568 }
569 }
570 if (!isConstrainedHighSpeedSupported) {
571 String8 msg = String8::format(
572 "Camera %s: Try to create a constrained high speed configuration on a device"
573 " that doesn't support it.", cameraId.string());
574 ALOGE("%s: %s", __FUNCTION__, msg.string());
575 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
576 msg.string());
577 }
578 }
579
580 return binder::Status::ok();
581}
582
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800583binder::Status
Austin Borgerea931242021-12-13 23:10:41 +0000584convertToHALStreamCombination(
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800585 const SessionConfiguration& sessionConfiguration,
586 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
587 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
Emilian Peev2295df72021-11-12 18:14:10 -0800588 hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700589 bool overrideForPerfClass, bool *earlyExit) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000590
591 auto operatingMode = sessionConfiguration.getOperatingMode();
592 binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
593 if (!res.isOk()) {
594 return res;
595 }
596
597 if (earlyExit == nullptr) {
598 String8 msg("earlyExit nullptr");
599 ALOGE("%s: %s", __FUNCTION__, msg.string());
600 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
601 }
602 *earlyExit = false;
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800603 auto ret = HidlCamera3Device::mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700604 static_cast<camera_stream_configuration_mode_t> (operatingMode),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000605 /*out*/ &streamConfiguration.operationMode);
606 if (ret != OK) {
607 String8 msg = String8::format(
608 "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
609 logicalCameraId.string(), operatingMode, strerror(-ret), ret);
610 ALOGE("%s: %s", __FUNCTION__, msg.string());
611 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
612 msg.string());
613 }
614
615 bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
616 (sessionConfiguration.getInputHeight() > 0) &&
617 (sessionConfiguration.getInputFormat() > 0);
618 auto outputConfigs = sessionConfiguration.getOutputConfigurations();
619 size_t streamCount = outputConfigs.size();
620 streamCount = isInputValid ? streamCount + 1 : streamCount;
621 streamConfiguration.streams.resize(streamCount);
622 size_t streamIdx = 0;
623 if (isInputValid) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800624 hardware::hidl_vec<CameraMetadataEnumAndroidSensorPixelMode> defaultSensorPixelModes;
625 defaultSensorPixelModes.resize(1);
626 defaultSensorPixelModes[0] =
627 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(
628 ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
Emilian Peev2295df72021-11-12 18:14:10 -0800629 streamConfiguration.streams[streamIdx++].v3_7 = {{{/*streamId*/0,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000630 hardware::camera::device::V3_2::StreamType::INPUT,
631 static_cast<uint32_t> (sessionConfiguration.getInputWidth()),
632 static_cast<uint32_t> (sessionConfiguration.getInputHeight()),
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800633 HidlCamera3Device::mapToPixelFormat(sessionConfiguration.getInputFormat()),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000634 /*usage*/ 0, HAL_DATASPACE_UNKNOWN,
635 hardware::camera::device::V3_2::StreamRotation::ROTATION_0},
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800636 /*physicalId*/ nullptr, /*bufferSize*/0}, /*groupId*/-1, defaultSensorPixelModes};
Shuzhen Wang83bff122020-11-20 15:51:39 -0800637 streamConfiguration.multiResolutionInputImage =
638 sessionConfiguration.inputIsMultiResolution();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000639 }
640
641 for (const auto &it : outputConfigs) {
642 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
643 it.getGraphicBufferProducers();
644 bool deferredConsumer = it.isDeferred();
645 String8 physicalCameraId = String8(it.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800646
Emilian Peev2295df72021-11-12 18:14:10 -0800647 int dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800648 std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700649 const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
650 overrideForPerfClass);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800651 const CameraMetadata &metadataChosen =
652 physicalCameraId.size() > 0 ? physicalDeviceInfo : deviceInfo;
653
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000654 size_t numBufferProducers = bufferProducers.size();
655 bool isStreamInfoValid = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800656 int32_t groupId = it.isMultiResolution() ? it.getSurfaceSetID() : -1;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000657 OutputStreamInfo streamInfo;
658
659 res = checkSurfaceType(numBufferProducers, deferredConsumer, it.getSurfaceType());
660 if (!res.isOk()) {
661 return res;
662 }
663 res = checkPhysicalCameraId(physicalCameraIds, physicalCameraId,
664 logicalCameraId);
665 if (!res.isOk()) {
666 return res;
667 }
668
669 if (deferredConsumer) {
670 streamInfo.width = it.getWidth();
671 streamInfo.height = it.getHeight();
672 streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
673 streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
674 auto surfaceType = it.getSurfaceType();
675 streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
676 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
677 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
678 }
Emilian Peev2295df72021-11-12 18:14:10 -0800679 streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800680 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
681 streamInfo.format, streamInfo.width,
682 streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
683 &streamInfo.sensorPixelModesUsed) != OK) {
684 ALOGE("%s: Deferred surface sensor pixel modes not valid",
685 __FUNCTION__);
686 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
687 "Deferred surface sensor pixel modes not valid");
688 }
Shuzhen Wang83bff122020-11-20 15:51:39 -0800689 mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000690 &streamConfiguration.streams[streamIdx++]);
691 isStreamInfoValid = true;
692
693 if (numBufferProducers == 0) {
694 continue;
695 }
696 }
697
698 for (auto& bufferProducer : bufferProducers) {
699 sp<Surface> surface;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000700 res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
Emilian Peev2295df72021-11-12 18:14:10 -0800701 logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000702
703 if (!res.isOk())
704 return res;
705
706 if (!isStreamInfoValid) {
707 bool isDepthCompositeStream =
708 camera3::DepthCompositeStream::isDepthCompositeStream(surface);
709 bool isHeicCompositeStream =
710 camera3::HeicCompositeStream::isHeicCompositeStream(surface);
711 if (isDepthCompositeStream || isHeicCompositeStream) {
712 // We need to take in to account that composite streams can have
713 // additional internal camera streams.
714 std::vector<OutputStreamInfo> compositeStreams;
715 if (isDepthCompositeStream) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800716 // TODO: Take care of composite streams.
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000717 ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
718 deviceInfo, &compositeStreams);
719 } else {
720 ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
721 deviceInfo, &compositeStreams);
722 }
723 if (ret != OK) {
724 String8 msg = String8::format(
725 "Camera %s: Failed adding composite streams: %s (%d)",
726 logicalCameraId.string(), strerror(-ret), ret);
727 ALOGE("%s: %s", __FUNCTION__, msg.string());
728 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
729 }
730
731 if (compositeStreams.size() == 0) {
732 // No internal streams means composite stream not
733 // supported.
734 *earlyExit = true;
735 return binder::Status::ok();
736 } else if (compositeStreams.size() > 1) {
737 streamCount += compositeStreams.size() - 1;
738 streamConfiguration.streams.resize(streamCount);
739 }
740
741 for (const auto& compositeStream : compositeStreams) {
742 mapStreamInfo(compositeStream,
Emilian Peevf4816702020-04-03 15:44:51 -0700743 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800744 physicalCameraId, groupId,
745 &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000746 }
747 } else {
748 mapStreamInfo(streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700749 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800750 physicalCameraId, groupId, &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000751 }
752 isStreamInfoValid = true;
753 }
754 }
755 }
756 return binder::Status::ok();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800757}
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000758
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800759static bool inStreamConfigurationMap(int format, int width, int height,
760 const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
761 auto scs = sm.find(format);
762 if (scs == sm.end()) {
763 return false;
764 }
765 for (auto &sc : scs->second) {
766 if (sc.width == width && sc.height == height && sc.isInput == 0) {
767 return true;
768 }
769 }
770 return false;
771}
772
773static std::unordered_set<int32_t> convertToSet(const std::vector<int32_t> &sensorPixelModesUsed) {
774 return std::unordered_set<int32_t>(sensorPixelModesUsed.begin(), sensorPixelModesUsed.end());
775}
776
Austin Borgerea931242021-12-13 23:10:41 +0000777status_t checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800778 const std::vector<int32_t> &sensorPixelModesUsed, int format, int width, int height,
779 const CameraMetadata &staticInfo, bool flexibleConsumer,
780 std::unordered_set<int32_t> *overriddenSensorPixelModesUsed) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700781
782 const std::unordered_set<int32_t> &sensorPixelModesUsedSet =
783 convertToSet(sensorPixelModesUsed);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800784 if (!isUltraHighResolutionSensor(staticInfo)) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700785 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
786 sensorPixelModesUsedSet.end()) {
787 // invalid value for non ultra high res sensors
788 return BAD_VALUE;
789 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800790 overriddenSensorPixelModesUsed->clear();
791 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
792 return OK;
793 }
794
795 StreamConfigurationPair streamConfigurationPair = getStreamConfigurationPair(staticInfo);
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700796
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800797 bool isInDefaultStreamConfigurationMap =
798 inStreamConfigurationMap(format, width, height,
799 streamConfigurationPair.mDefaultStreamConfigurationMap);
800
801 bool isInMaximumResolutionStreamConfigurationMap =
802 inStreamConfigurationMap(format, width, height,
803 streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
804
805 // Case 1: The client has not changed the sensor mode defaults. In this case, we check if the
806 // size + format of the OutputConfiguration is found exclusively in 1.
807 // If yes, add that sensorPixelMode to overriddenSensorPixelModes.
808 // If no, add 'DEFAULT' to sensorPixelMode. This maintains backwards
809 // compatibility.
810 if (sensorPixelModesUsedSet.size() == 0) {
811 // Ambiguous case, default to only 'DEFAULT' mode.
812 if (isInDefaultStreamConfigurationMap && isInMaximumResolutionStreamConfigurationMap) {
813 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
814 return OK;
815 }
816 // We don't allow flexible consumer for max resolution mode.
817 if (isInMaximumResolutionStreamConfigurationMap) {
818 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
819 return OK;
820 }
821 if (isInDefaultStreamConfigurationMap || (flexibleConsumer && width < ROUNDING_WIDTH_CAP)) {
822 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
823 return OK;
824 }
825 return BAD_VALUE;
826 }
827
828 // Case2: The app has set sensorPixelModesUsed, we need to verify that they
829 // are valid / err out.
830 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_DEFAULT) !=
831 sensorPixelModesUsedSet.end() && !isInDefaultStreamConfigurationMap) {
832 return BAD_VALUE;
833 }
834
835 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
836 sensorPixelModesUsedSet.end() && !isInMaximumResolutionStreamConfigurationMap) {
837 return BAD_VALUE;
838 }
839 *overriddenSensorPixelModesUsed = sensorPixelModesUsedSet;
840 return OK;
841}
842
Emilian Peev2295df72021-11-12 18:14:10 -0800843bool convertHALStreamCombinationFromV38ToV37(
844 hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
845 const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
846 streamConfigV37.streams.resize(streamConfigV38.streams.size());
847 for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
848 if (static_cast<int32_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
849 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
850 // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
851 // image
852 return false;
853 }
854 streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
855 }
856 streamConfigV37.operationMode = streamConfigV38.operationMode;
857 streamConfigV37.sessionParams = streamConfigV38.sessionParams;
858
859 return true;
860}
861
Austin Borgerea931242021-12-13 23:10:41 +0000862bool convertHALStreamCombinationFromV37ToV34(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800863 hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
864 const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
865 if (streamConfigV37.multiResolutionInputImage) {
866 // ICameraDevice older than 3.7 doesn't support multi-resolution input image.
867 return false;
868 }
869
870 streamConfigV34.streams.resize(streamConfigV37.streams.size());
871 for (size_t i = 0; i < streamConfigV37.streams.size(); i++) {
872 if (streamConfigV37.streams[i].groupId != -1) {
873 // ICameraDevice older than 3.7 doesn't support multi-resolution output
874 // image
875 return false;
876 }
877 streamConfigV34.streams[i] = streamConfigV37.streams[i].v3_4;
878 }
879 streamConfigV34.operationMode = streamConfigV37.operationMode;
880 streamConfigV34.sessionParams = streamConfigV37.sessionParams;
881
882 return true;
883}
884
Austin Borgerea931242021-12-13 23:10:41 +0000885bool targetPerfClassPrimaryCamera(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700886 const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
887 int targetSdkVersion) {
888 bool isPerfClassPrimaryCamera =
889 perfClassPrimaryCameraIds.find(cameraId) != perfClassPrimaryCameraIds.end();
890 return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
891}
892
Austin Borgerea931242021-12-13 23:10:41 +0000893} // namespace SessionConfigurationUtils
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800894} // namespace camera3
895} // namespace android