blob: a46266ea43cc95c89554843eb4745eb90b8ea0fa [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"
Jayant Chowdharya04055f2022-01-03 02:07:49 +000024#include "common/HalConversionsTemplated.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000025#include "../CameraService.h"
Jayant Chowdhary35642f22022-01-08 00:39:39 +000026#include "device3/aidl/AidlCamera3Device.h"
Jayant Chowdhary22441f32021-12-26 18:35:41 -080027#include "device3/hidl/HidlCamera3Device.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000028#include "device3/Camera3OutputStream.h"
Emilian Peev2295df72021-11-12 18:14:10 -080029#include "system/graphics-base-v1.1.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000030
Colin Crossb8a9dbb2020-08-27 04:12:26 +000031using android::camera3::OutputStreamInfo;
32using android::camera3::OutputStreamInfo;
33using android::hardware::camera2::ICameraDeviceUser;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080034using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
Emilian Peev2295df72021-11-12 18:14:10 -080035using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080036using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080037
38namespace android {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080039namespace camera3 {
40
41void StreamConfiguration::getStreamConfigurations(
42 const CameraMetadata &staticInfo, int configuration,
43 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
44 if (scm == nullptr) {
45 ALOGE("%s: StreamConfigurationMap nullptr", __FUNCTION__);
46 return;
47 }
48 const int STREAM_FORMAT_OFFSET = 0;
49 const int STREAM_WIDTH_OFFSET = 1;
50 const int STREAM_HEIGHT_OFFSET = 2;
51 const int STREAM_IS_INPUT_OFFSET = 3;
52
53 camera_metadata_ro_entry availableStreamConfigs = staticInfo.find(configuration);
54 for (size_t i = 0; i < availableStreamConfigs.count; i += 4) {
55 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
56 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
57 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
58 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
59 StreamConfiguration sc = {format, width, height, isInput};
60 (*scm)[format].push_back(sc);
61 }
62}
63
64void StreamConfiguration::getStreamConfigurations(
65 const CameraMetadata &staticInfo, bool maxRes,
66 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
67 int32_t scalerKey =
68 SessionConfigurationUtils::getAppropriateModeTag(
69 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxRes);
70
71 int32_t depthKey =
72 SessionConfigurationUtils::getAppropriateModeTag(
73 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, maxRes);
74
75 int32_t dynamicDepthKey =
76 SessionConfigurationUtils::getAppropriateModeTag(
77 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
78
79 int32_t heicKey =
80 SessionConfigurationUtils::getAppropriateModeTag(
81 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
82
83 getStreamConfigurations(staticInfo, scalerKey, scm);
84 getStreamConfigurations(staticInfo, depthKey, scm);
85 getStreamConfigurations(staticInfo, dynamicDepthKey, scm);
86 getStreamConfigurations(staticInfo, heicKey, scm);
87}
88
Austin Borgerea931242021-12-13 23:10:41 +000089namespace SessionConfigurationUtils {
90
91int32_t PERF_CLASS_LEVEL =
92 property_get_int32("ro.odm.build.media_performance_class", 0);
93
94bool IS_PERF_CLASS = (PERF_CLASS_LEVEL == SDK_VERSION_S);
95
96camera3::Size getMaxJpegResolution(const CameraMetadata &metadata,
97 bool ultraHighResolution) {
98 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
99 const int STREAM_CONFIGURATION_SIZE = 4;
100 const int STREAM_FORMAT_OFFSET = 0;
101 const int STREAM_WIDTH_OFFSET = 1;
102 const int STREAM_HEIGHT_OFFSET = 2;
103 const int STREAM_IS_INPUT_OFFSET = 3;
104
105 int32_t scalerSizesTag = ultraHighResolution ?
106 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION :
107 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
108 camera_metadata_ro_entry_t availableStreamConfigs =
109 metadata.find(scalerSizesTag);
110 if (availableStreamConfigs.count == 0 ||
111 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
112 return camera3::Size(0, 0);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800113 }
Austin Borgerea931242021-12-13 23:10:41 +0000114
115 // Get max jpeg size (area-wise).
116 for (size_t i= 0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
117 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
118 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
119 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
120 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
121 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
122 && format == HAL_PIXEL_FORMAT_BLOB &&
123 (width * height > maxJpegWidth * maxJpegHeight)) {
124 maxJpegWidth = width;
125 maxJpegHeight = height;
126 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800127 }
Austin Borgerea931242021-12-13 23:10:41 +0000128
129 return camera3::Size(maxJpegWidth, maxJpegHeight);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800130}
131
Austin Borgerea931242021-12-13 23:10:41 +0000132size_t getUHRMaxJpegBufferSize(camera3::Size uhrMaxJpegSize,
133 camera3::Size defaultMaxJpegSize, size_t defaultMaxJpegBufferSize) {
134 return (uhrMaxJpegSize.width * uhrMaxJpegSize.height) /
135 (defaultMaxJpegSize.width * defaultMaxJpegSize.height) * defaultMaxJpegBufferSize;
136}
137
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800138StreamConfigurationPair
Austin Borgerea931242021-12-13 23:10:41 +0000139getStreamConfigurationPair(const CameraMetadata &staticInfo) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800140 camera3::StreamConfigurationPair streamConfigurationPair;
141 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, false,
142 &streamConfigurationPair.mDefaultStreamConfigurationMap);
143 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, true,
144 &streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
145 return streamConfigurationPair;
146}
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800147
Austin Borgerea931242021-12-13 23:10:41 +0000148int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000149 int64_t d0 = x0 - x1;
150 int64_t d1 = y0 - y1;
151 return d0 * d0 + d1 * d1;
152}
153
Austin Borgerea931242021-12-13 23:10:41 +0000154bool roundBufferDimensionNearest(int32_t width, int32_t height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800155 int32_t format, android_dataspace dataSpace,
156 const CameraMetadata& info, bool maxResolution, /*out*/int32_t* outWidth,
157 /*out*/int32_t* outHeight) {
158 const int32_t depthSizesTag =
159 getAppropriateModeTag(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
160 maxResolution);
161 const int32_t scalerSizesTag =
162 getAppropriateModeTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
163 const int32_t heicSizesTag =
164 getAppropriateModeTag(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000165
166 camera_metadata_ro_entry streamConfigs =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800167 (dataSpace == HAL_DATASPACE_DEPTH) ? info.find(depthSizesTag) :
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000168 (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800169 info.find(heicSizesTag) :
170 info.find(scalerSizesTag);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000171
172 int32_t bestWidth = -1;
173 int32_t bestHeight = -1;
174
175 // Iterate through listed stream configurations and find the one with the smallest euclidean
176 // distance from the given dimensions for the given format.
177 for (size_t i = 0; i < streamConfigs.count; i += 4) {
178 int32_t fmt = streamConfigs.data.i32[i];
179 int32_t w = streamConfigs.data.i32[i + 1];
180 int32_t h = streamConfigs.data.i32[i + 2];
181
182 // Ignore input/output type for now
183 if (fmt == format) {
184 if (w == width && h == height) {
185 bestWidth = width;
186 bestHeight = height;
187 break;
188 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
189 SessionConfigurationUtils::euclidDistSquare(w, h, width, height) <
190 SessionConfigurationUtils::euclidDistSquare(bestWidth, bestHeight, width,
191 height))) {
192 bestWidth = w;
193 bestHeight = h;
194 }
195 }
196 }
197
198 if (bestWidth == -1) {
199 // Return false if no configurations for this format were listed
200 return false;
201 }
202
203 // Set the outputs to the closet width/height
204 if (outWidth != NULL) {
205 *outWidth = bestWidth;
206 }
207 if (outHeight != NULL) {
208 *outHeight = bestHeight;
209 }
210
211 // Return true if at least one configuration for this format was listed
212 return true;
213}
214
Emilian Peev2295df72021-11-12 18:14:10 -0800215//check if format is 10-bit compatible
216bool is10bitCompatibleFormat(int32_t format) {
217 switch(format) {
218 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
219 case HAL_PIXEL_FORMAT_YCBCR_P010:
220 return true;
221 default:
222 return false;
223 }
224}
225
Emilian Peevc81a7592022-02-14 17:38:18 -0800226bool isDynamicRangeProfileSupported(int64_t dynamicRangeProfile, const CameraMetadata& staticInfo) {
Emilian Peev2295df72021-11-12 18:14:10 -0800227 if (dynamicRangeProfile == ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
228 // Supported by default
229 return true;
230 }
231
232 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
233 bool is10bitDynamicRangeSupported = false;
234 for (size_t i = 0; i < entry.count; ++i) {
235 uint8_t capability = entry.data.u8[i];
236 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
237 is10bitDynamicRangeSupported = true;
238 break;
239 }
240 }
241
242 if (!is10bitDynamicRangeSupported) {
243 return false;
244 }
245
246 switch (dynamicRangeProfile) {
247 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
248 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
249 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
250 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
251 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
252 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
253 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
254 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
255 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
256 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
257 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
258 entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
Emilian Peevc81a7592022-02-14 17:38:18 -0800259 for (size_t i = 0; i < entry.count; i += 3) {
260 if (dynamicRangeProfile == entry.data.i64[i]) {
Emilian Peev2295df72021-11-12 18:14:10 -0800261 return true;
262 }
263 }
264
265 return false;
266 default:
267 return false;
268 }
269
270 return false;
271}
272
273//check if format is 10-bit compatible
Emilian Peevc81a7592022-02-14 17:38:18 -0800274bool is10bitDynamicRangeProfile(int64_t dynamicRangeProfile) {
Emilian Peev2295df72021-11-12 18:14:10 -0800275 switch (dynamicRangeProfile) {
276 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
277 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
278 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
279 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
280 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
281 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
282 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
283 return true;
284 default:
285 return false;
286 }
287}
288
Austin Borgerea931242021-12-13 23:10:41 +0000289bool isPublicFormat(int32_t format)
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000290{
291 switch(format) {
292 case HAL_PIXEL_FORMAT_RGBA_8888:
293 case HAL_PIXEL_FORMAT_RGBX_8888:
294 case HAL_PIXEL_FORMAT_RGB_888:
295 case HAL_PIXEL_FORMAT_RGB_565:
296 case HAL_PIXEL_FORMAT_BGRA_8888:
297 case HAL_PIXEL_FORMAT_YV12:
298 case HAL_PIXEL_FORMAT_Y8:
299 case HAL_PIXEL_FORMAT_Y16:
300 case HAL_PIXEL_FORMAT_RAW16:
301 case HAL_PIXEL_FORMAT_RAW10:
302 case HAL_PIXEL_FORMAT_RAW12:
303 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
304 case HAL_PIXEL_FORMAT_BLOB:
305 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
306 case HAL_PIXEL_FORMAT_YCbCr_420_888:
307 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
308 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
309 case HAL_PIXEL_FORMAT_YCbCr_422_I:
310 return true;
311 default:
312 return false;
313 }
314}
315
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800316bool isStreamUseCaseSupported(int64_t streamUseCase,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800317 const CameraMetadata &deviceInfo) {
318 camera_metadata_ro_entry_t availableStreamUseCases =
319 deviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES);
320
321 if (availableStreamUseCases.count == 0 &&
322 streamUseCase == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
323 return true;
324 }
Shuzhen Wangb77131a2022-04-27 15:34:33 -0700325 // Allow vendor stream use case unconditionally.
326 if (streamUseCase >= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START) {
327 return true;
328 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800329
330 for (size_t i = 0; i < availableStreamUseCases.count; i++) {
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800331 if (availableStreamUseCases.data.i64[i] == streamUseCase) {
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800332 return true;
333 }
334 }
335 return false;
336}
337
Austin Borgerea931242021-12-13 23:10:41 +0000338binder::Status createSurfaceFromGbp(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000339 OutputStreamInfo& streamInfo, bool isStreamInfoValid,
340 sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800341 const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
Emilian Peevc81a7592022-02-14 17:38:18 -0800342 const std::vector<int32_t> &sensorPixelModesUsed, int64_t dynamicRangeProfile,
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800343 int64_t streamUseCase, int timestampBase, int mirrorMode) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000344 // bufferProducer must be non-null
345 if (gbp == nullptr) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800346 String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000347 ALOGW("%s: %s", __FUNCTION__, msg.string());
348 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
349 }
350 // HACK b/10949105
351 // Query consumer usage bits to set async operation mode for
352 // GLConsumer using controlledByApp parameter.
353 bool useAsync = false;
354 uint64_t consumerUsage = 0;
355 status_t err;
356 if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
357 String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800358 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000359 ALOGE("%s: %s", __FUNCTION__, msg.string());
360 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
361 }
362 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
363 ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800364 "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000365 useAsync = true;
366 }
367
368 uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
369 GRALLOC_USAGE_RENDERSCRIPT;
370 uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
371 GraphicBuffer::USAGE_HW_TEXTURE |
372 GraphicBuffer::USAGE_HW_COMPOSER;
373 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
374 (consumerUsage & allowedFlags) != 0;
375
376 surface = new Surface(gbp, useAsync);
377 ANativeWindow *anw = surface.get();
378
379 int width, height, format;
380 android_dataspace dataSpace;
381 if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
382 String8 msg = String8::format("Camera %s: Failed to query Surface width: %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_HEIGHT, &height)) != OK) {
388 String8 msg = String8::format("Camera %s: Failed to query Surface height: %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_FORMAT, &format)) != OK) {
394 String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800395 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000396 ALOGE("%s: %s", __FUNCTION__, msg.string());
397 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
398 }
399 if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
400 reinterpret_cast<int*>(&dataSpace))) != OK) {
401 String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800402 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000403 ALOGE("%s: %s", __FUNCTION__, msg.string());
404 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
405 }
406
407 // FIXME: remove this override since the default format should be
408 // IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
409 if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
410 ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
411 ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
412 ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800413 __FUNCTION__, logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000414 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
415 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800416 std::unordered_set<int32_t> overriddenSensorPixelModes;
417 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
418 physicalCameraMetadata, flexibleConsumer, &overriddenSensorPixelModes) != OK) {
419 String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
420 "format %#x are not valid",logicalCameraId.string(), format);
421 ALOGE("%s: %s", __FUNCTION__, msg.string());
422 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
423 }
424 bool foundInMaxRes = false;
425 if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
426 overriddenSensorPixelModes.end()) {
427 // we can use the default stream configuration map
428 foundInMaxRes = true;
429 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000430 // Round dimensions to the nearest dimensions available for this format
431 if (flexibleConsumer && isPublicFormat(format) &&
432 !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800433 format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
434 /*out*/&height)) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000435 String8 msg = String8::format("Camera %s: No supported stream configurations with "
436 "format %#x defined, failed to create output stream",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800437 logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000438 ALOGE("%s: %s", __FUNCTION__, msg.string());
439 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
440 }
Emilian Peev2295df72021-11-12 18:14:10 -0800441 if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
442 physicalCameraMetadata)) {
Emilian Peevc81a7592022-02-14 17:38:18 -0800443 String8 msg = String8::format("Camera %s: Dynamic range profile 0x%" PRIx64
444 " not supported,failed to create output stream", logicalCameraId.string(),
445 dynamicRangeProfile);
Emilian Peev2295df72021-11-12 18:14:10 -0800446 ALOGE("%s: %s", __FUNCTION__, msg.string());
447 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
448 }
449 if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
450 !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
451 String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
Emilian Peevc81a7592022-02-14 17:38:18 -0800452 "format %#x defined and profile %" PRIx64 ", failed to create output stream",
Emilian Peev2295df72021-11-12 18:14:10 -0800453 logicalCameraId.string(), format, dynamicRangeProfile);
454 ALOGE("%s: %s", __FUNCTION__, msg.string());
455 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
456 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800457 if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
458 physicalCameraMetadata)) {
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800459 String8 msg = String8::format("Camera %s: stream use case %" PRId64 " not supported,"
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800460 " failed to create output stream", logicalCameraId.string(), streamUseCase);
461 ALOGE("%s: %s", __FUNCTION__, msg.string());
462 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
463 }
Shuzhen Wange4208922022-02-01 16:52:48 -0800464 if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
465 timestampBase > OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
466 String8 msg = String8::format("Camera %s: invalid timestamp base %d",
467 logicalCameraId.string(), timestampBase);
468 ALOGE("%s: %s", __FUNCTION__, msg.string());
469 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
470 }
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800471 if (mirrorMode < OutputConfiguration::MIRROR_MODE_AUTO ||
472 mirrorMode > OutputConfiguration::MIRROR_MODE_V) {
473 String8 msg = String8::format("Camera %s: invalid mirroring mode %d",
474 logicalCameraId.string(), mirrorMode);
475 ALOGE("%s: %s", __FUNCTION__, msg.string());
476 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
477 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000478
479 if (!isStreamInfoValid) {
480 streamInfo.width = width;
481 streamInfo.height = height;
482 streamInfo.format = format;
483 streamInfo.dataSpace = dataSpace;
484 streamInfo.consumerUsage = consumerUsage;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800485 streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
Emilian Peev2295df72021-11-12 18:14:10 -0800486 streamInfo.dynamicRangeProfile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800487 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wange4208922022-02-01 16:52:48 -0800488 streamInfo.timestampBase = timestampBase;
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800489 streamInfo.mirrorMode = mirrorMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000490 return binder::Status::ok();
491 }
492 if (width != streamInfo.width) {
493 String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800494 logicalCameraId.string(), width, streamInfo.width);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000495 ALOGE("%s: %s", __FUNCTION__, msg.string());
496 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
497 }
498 if (height != streamInfo.height) {
499 String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800500 logicalCameraId.string(), height, streamInfo.height);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000501 ALOGE("%s: %s", __FUNCTION__, msg.string());
502 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
503 }
504 if (format != streamInfo.format) {
505 String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800506 logicalCameraId.string(), format, streamInfo.format);
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 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
511 if (dataSpace != streamInfo.dataSpace) {
512 String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800513 logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000514 ALOGE("%s: %s", __FUNCTION__, msg.string());
515 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
516 }
517 //At the native side, there isn't a way to check whether 2 surfaces come from the same
518 //surface class type. Use usage flag to approximate the comparison.
519 if (consumerUsage != streamInfo.consumerUsage) {
520 String8 msg = String8::format(
521 "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800522 logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000523 ALOGE("%s: %s", __FUNCTION__, msg.string());
524 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
525 }
526 }
527 return binder::Status::ok();
528}
529
Austin Borgerea931242021-12-13 23:10:41 +0000530void mapStreamInfo(const OutputStreamInfo &streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700531 camera3::camera_stream_rotation_t rotation, String8 physicalId,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000532 int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000533 if (stream == nullptr) {
534 return;
535 }
536
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000537 stream->streamType = aidl::android::hardware::camera::device::StreamType::OUTPUT;
538 stream->width = streamInfo.width;
539 stream->height = streamInfo.height;
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000540 stream->format = AidlCamera3Device::mapToAidlPixelFormat(streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000541 auto u = streamInfo.consumerUsage;
542 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000543 stream->usage = AidlCamera3Device::mapToAidlConsumerUsage(u);
544 stream->dataSpace = AidlCamera3Device::mapToAidlDataspace(streamInfo.dataSpace);
545 stream->rotation = AidlCamera3Device::mapToAidlStreamRotation(rotation);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000546 stream->id = -1; // Invalid stream id
547 stream->physicalCameraId = std::string(physicalId.string());
548 stream->bufferSize = 0;
549 stream->groupId = groupId;
550 stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800551 size_t idx = 0;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000552 using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800553 for (auto mode : streamInfo.sensorPixelModesUsed) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000554 stream->sensorPixelModesUsed[idx++] =
555 static_cast<SensorPixelMode>(mode);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800556 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000557 using DynamicRangeProfile =
558 aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
559 stream->dynamicRangeProfile = static_cast<DynamicRangeProfile>(streamInfo.dynamicRangeProfile);
560 using StreamUseCases =
561 aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
562 stream->useCase = static_cast<StreamUseCases>(streamInfo.streamUseCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000563}
564
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000565status_t
566convertAidlToHidl38StreamCombination(
567 const aidl::android::hardware::camera::device::StreamConfiguration &aidl,
568 hardware::camera::device::V3_8::StreamConfiguration &hidl) {
569 hidl.operationMode =
570 static_cast<hardware::camera::device::V3_2::StreamConfigurationMode>(aidl.operationMode);
571 if (aidl.streamConfigCounter < 0) {
572 return BAD_VALUE;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000573 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000574 hidl.streamConfigCounter = static_cast<uint32_t>(aidl.streamConfigCounter);
575 hidl.multiResolutionInputImage = aidl.multiResolutionInputImage;
576 hidl.sessionParams = aidl.sessionParams.metadata;
577 hidl.streams.resize(aidl.streams.size());
578 size_t i = 0;
579 for (const auto &stream : aidl.streams) {
580 //hidlv3_8
581 hidl.streams[i].dynamicRangeProfile =
582 static_cast<
583 CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
584 (stream.dynamicRangeProfile);
585 hidl.streams[i].useCase =
586 static_cast<
587 CameraMetadataEnumAndroidScalerAvailableStreamUseCases>
588 (stream.useCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000589
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000590 // hidl v3_7
591 hidl.streams[i].v3_7.groupId = stream.groupId;
592 hidl.streams[i].v3_7.sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
593 size_t j = 0;
594 for (const auto &mode : stream.sensorPixelModesUsed) {
595 hidl.streams[i].v3_7.sensorPixelModesUsed[j] =
596 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
597 j++;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000598 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000599
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000600 //hidl v3_4
601 hidl.streams[i].v3_7.v3_4.physicalCameraId = stream.physicalCameraId;
602
603 if (stream.bufferSize < 0) {
604 return BAD_VALUE;
605 }
606 hidl.streams[i].v3_7.v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
607
608 // hild v3_2
609 hidl.streams[i].v3_7.v3_4.v3_2.id = stream.id;
610 hidl.streams[i].v3_7.v3_4.v3_2.format =
611 static_cast<hardware::graphics::common::V1_0::PixelFormat>(stream.format);
612
613 if (stream.width < 0 || stream.height < 0) {
614 return BAD_VALUE;
615 }
616 hidl.streams[i].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
617 hidl.streams[i].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
618 hidl.streams[i].v3_7.v3_4.v3_2.usage =
619 static_cast<hardware::camera::device::V3_2::BufferUsageFlags>(stream.usage);
620 hidl.streams[i].v3_7.v3_4.v3_2.streamType =
621 static_cast<hardware::camera::device::V3_2::StreamType>(stream.streamType);
622 hidl.streams[i].v3_7.v3_4.v3_2.dataSpace =
623 static_cast<hardware::camera::device::V3_2::DataspaceFlags>(stream.dataSpace);
624 hidl.streams[i].v3_7.v3_4.v3_2.rotation =
625 static_cast<hardware::camera::device::V3_2::StreamRotation>(stream.rotation);
626 i++;
627 }
628 return OK;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000629}
630
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800631binder::Status
Austin Borgerea931242021-12-13 23:10:41 +0000632convertToHALStreamCombination(
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800633 const SessionConfiguration& sessionConfiguration,
634 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
635 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000636 aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700637 bool overrideForPerfClass, bool *earlyExit) {
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000638 using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000639 auto operatingMode = sessionConfiguration.getOperatingMode();
640 binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
641 if (!res.isOk()) {
642 return res;
643 }
644
645 if (earlyExit == nullptr) {
646 String8 msg("earlyExit nullptr");
647 ALOGE("%s: %s", __FUNCTION__, msg.string());
648 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
649 }
650 *earlyExit = false;
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000651 auto ret = AidlCamera3Device::mapToAidlStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700652 static_cast<camera_stream_configuration_mode_t> (operatingMode),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000653 /*out*/ &streamConfiguration.operationMode);
654 if (ret != OK) {
655 String8 msg = String8::format(
656 "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
657 logicalCameraId.string(), operatingMode, strerror(-ret), ret);
658 ALOGE("%s: %s", __FUNCTION__, msg.string());
659 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
660 msg.string());
661 }
662
663 bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
664 (sessionConfiguration.getInputHeight() > 0) &&
665 (sessionConfiguration.getInputFormat() > 0);
666 auto outputConfigs = sessionConfiguration.getOutputConfigurations();
667 size_t streamCount = outputConfigs.size();
668 streamCount = isInputValid ? streamCount + 1 : streamCount;
669 streamConfiguration.streams.resize(streamCount);
670 size_t streamIdx = 0;
671 if (isInputValid) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000672 std::vector<SensorPixelMode> defaultSensorPixelModes;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800673 defaultSensorPixelModes.resize(1);
674 defaultSensorPixelModes[0] =
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000675 static_cast<SensorPixelMode>(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
676 aidl::android::hardware::camera::device::Stream stream;
677 stream.id = 0;
678 stream.streamType = aidl::android::hardware::camera::device::StreamType::INPUT;
679 stream.width = static_cast<uint32_t> (sessionConfiguration.getInputWidth());
680 stream.height = static_cast<uint32_t> (sessionConfiguration.getInputHeight());
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000681 stream.format =
682 AidlCamera3Device::AidlCamera3Device::mapToAidlPixelFormat(
683 sessionConfiguration.getInputFormat());
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000684 stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0);
685 stream.dataSpace =
686 static_cast<aidl::android::hardware::graphics::common::Dataspace>(
687 HAL_DATASPACE_UNKNOWN);
688 stream.rotation = aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
689 stream.bufferSize = 0;
690 stream.groupId = -1;
691 stream.sensorPixelModesUsed = defaultSensorPixelModes;
692 streamConfiguration.streams[streamIdx++] = stream;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800693 streamConfiguration.multiResolutionInputImage =
694 sessionConfiguration.inputIsMultiResolution();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000695 }
696
697 for (const auto &it : outputConfigs) {
698 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
699 it.getGraphicBufferProducers();
700 bool deferredConsumer = it.isDeferred();
701 String8 physicalCameraId = String8(it.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800702
Emilian Peevc81a7592022-02-14 17:38:18 -0800703 int64_t dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800704 std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700705 const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
706 overrideForPerfClass);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800707 const CameraMetadata &metadataChosen =
708 physicalCameraId.size() > 0 ? physicalDeviceInfo : deviceInfo;
709
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000710 size_t numBufferProducers = bufferProducers.size();
711 bool isStreamInfoValid = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800712 int32_t groupId = it.isMultiResolution() ? it.getSurfaceSetID() : -1;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000713 OutputStreamInfo streamInfo;
714
715 res = checkSurfaceType(numBufferProducers, deferredConsumer, it.getSurfaceType());
716 if (!res.isOk()) {
717 return res;
718 }
719 res = checkPhysicalCameraId(physicalCameraIds, physicalCameraId,
720 logicalCameraId);
721 if (!res.isOk()) {
722 return res;
723 }
724
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800725 int64_t streamUseCase = it.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -0800726 int timestampBase = it.getTimestampBase();
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800727 int mirrorMode = it.getMirrorMode();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000728 if (deferredConsumer) {
729 streamInfo.width = it.getWidth();
730 streamInfo.height = it.getHeight();
731 streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
732 streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
733 auto surfaceType = it.getSurfaceType();
734 streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
735 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
736 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
737 }
Emilian Peev2295df72021-11-12 18:14:10 -0800738 streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800739 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
740 streamInfo.format, streamInfo.width,
741 streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
742 &streamInfo.sensorPixelModesUsed) != OK) {
743 ALOGE("%s: Deferred surface sensor pixel modes not valid",
744 __FUNCTION__);
745 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
746 "Deferred surface sensor pixel modes not valid");
747 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800748 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800749 mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000750 &streamConfiguration.streams[streamIdx++]);
751 isStreamInfoValid = true;
752
753 if (numBufferProducers == 0) {
754 continue;
755 }
756 }
757
758 for (auto& bufferProducer : bufferProducers) {
759 sp<Surface> surface;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000760 res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800761 logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800762 streamUseCase, timestampBase, mirrorMode);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000763
764 if (!res.isOk())
765 return res;
766
767 if (!isStreamInfoValid) {
768 bool isDepthCompositeStream =
769 camera3::DepthCompositeStream::isDepthCompositeStream(surface);
770 bool isHeicCompositeStream =
771 camera3::HeicCompositeStream::isHeicCompositeStream(surface);
772 if (isDepthCompositeStream || isHeicCompositeStream) {
773 // We need to take in to account that composite streams can have
774 // additional internal camera streams.
775 std::vector<OutputStreamInfo> compositeStreams;
776 if (isDepthCompositeStream) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800777 // TODO: Take care of composite streams.
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000778 ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
779 deviceInfo, &compositeStreams);
780 } else {
781 ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
782 deviceInfo, &compositeStreams);
783 }
784 if (ret != OK) {
785 String8 msg = String8::format(
786 "Camera %s: Failed adding composite streams: %s (%d)",
787 logicalCameraId.string(), strerror(-ret), ret);
788 ALOGE("%s: %s", __FUNCTION__, msg.string());
789 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
790 }
791
792 if (compositeStreams.size() == 0) {
793 // No internal streams means composite stream not
794 // supported.
795 *earlyExit = true;
796 return binder::Status::ok();
797 } else if (compositeStreams.size() > 1) {
798 streamCount += compositeStreams.size() - 1;
799 streamConfiguration.streams.resize(streamCount);
800 }
801
802 for (const auto& compositeStream : compositeStreams) {
803 mapStreamInfo(compositeStream,
Emilian Peevf4816702020-04-03 15:44:51 -0700804 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800805 physicalCameraId, groupId,
806 &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000807 }
808 } else {
809 mapStreamInfo(streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700810 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800811 physicalCameraId, groupId, &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000812 }
813 isStreamInfoValid = true;
814 }
815 }
816 }
817 return binder::Status::ok();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800818}
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000819
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000820void mapStreamInfo(const OutputStreamInfo &streamInfo,
821 camera3::camera_stream_rotation_t rotation, String8 physicalId,
822 int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
823 if (stream == nullptr) {
824 return;
825 }
826
827 stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
828 stream->v3_7.v3_4.v3_2.width = streamInfo.width;
829 stream->v3_7.v3_4.v3_2.height = streamInfo.height;
830 stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
831 auto u = streamInfo.consumerUsage;
832 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
833 stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
834 stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
835 stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
836 stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
837 stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
838 stream->v3_7.v3_4.bufferSize = 0;
839 stream->v3_7.groupId = groupId;
840 stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
841
842 size_t idx = 0;
843 for (auto mode : streamInfo.sensorPixelModesUsed) {
844 stream->v3_7.sensorPixelModesUsed[idx++] =
845 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
846 }
847 stream->dynamicRangeProfile =
848 static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
849 streamInfo.dynamicRangeProfile);
850 stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
851 streamInfo.streamUseCase);
852}
853
854binder::Status checkPhysicalCameraId(
855 const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
856 const String8 &logicalCameraId) {
857 if (physicalCameraId.size() == 0) {
858 return binder::Status::ok();
859 }
860 if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
861 physicalCameraId.string()) == physicalCameraIds.end()) {
862 String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
863 logicalCameraId.string(), physicalCameraId.string());
864 ALOGE("%s: %s", __FUNCTION__, msg.string());
865 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
866 }
867 return binder::Status::ok();
868}
869
870binder::Status checkSurfaceType(size_t numBufferProducers,
871 bool deferredConsumer, int surfaceType) {
872 if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
873 ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
874 __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
875 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
876 } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
877 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
878 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
879 }
880
881 bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
882 (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
883
884 if (deferredConsumer && !validSurfaceType) {
885 ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
886 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
887 }
888
889 return binder::Status::ok();
890}
891
892binder::Status checkOperatingMode(int operatingMode,
893 const CameraMetadata &staticInfo, const String8 &cameraId) {
894 if (operatingMode < 0) {
895 String8 msg = String8::format(
896 "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
897 ALOGE("%s: %s", __FUNCTION__, msg.string());
898 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
899 msg.string());
900 }
901
902 bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
903 if (isConstrainedHighSpeed) {
904 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
905 bool isConstrainedHighSpeedSupported = false;
906 for(size_t i = 0; i < entry.count; ++i) {
907 uint8_t capability = entry.data.u8[i];
908 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
909 isConstrainedHighSpeedSupported = true;
910 break;
911 }
912 }
913 if (!isConstrainedHighSpeedSupported) {
914 String8 msg = String8::format(
915 "Camera %s: Try to create a constrained high speed configuration on a device"
916 " that doesn't support it.", cameraId.string());
917 ALOGE("%s: %s", __FUNCTION__, msg.string());
918 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
919 msg.string());
920 }
921 }
922
923 return binder::Status::ok();
924}
925
926binder::Status
927convertToHALStreamCombination(
928 const SessionConfiguration& sessionConfiguration,
929 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
930 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
931 hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
932 bool overrideForPerfClass, bool *earlyExit) {
933 aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
934 auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
935 getMetadata, physicalCameraIds, aidlStreamConfiguration, overrideForPerfClass,
936 earlyExit);
937 if (!ret.isOk()) {
938 return ret;
939 }
940 if (earlyExit != nullptr && *earlyExit) {
941 return binder::Status::ok();
942 }
943
944 if (convertAidlToHidl38StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
945 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
946 "Invalid AIDL->HIDL3.8 conversion");
947 }
948
949 return binder::Status::ok();
950}
951
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800952static bool inStreamConfigurationMap(int format, int width, int height,
953 const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
954 auto scs = sm.find(format);
955 if (scs == sm.end()) {
956 return false;
957 }
958 for (auto &sc : scs->second) {
959 if (sc.width == width && sc.height == height && sc.isInput == 0) {
960 return true;
961 }
962 }
963 return false;
964}
965
966static std::unordered_set<int32_t> convertToSet(const std::vector<int32_t> &sensorPixelModesUsed) {
967 return std::unordered_set<int32_t>(sensorPixelModesUsed.begin(), sensorPixelModesUsed.end());
968}
969
Austin Borgerea931242021-12-13 23:10:41 +0000970status_t checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800971 const std::vector<int32_t> &sensorPixelModesUsed, int format, int width, int height,
972 const CameraMetadata &staticInfo, bool flexibleConsumer,
973 std::unordered_set<int32_t> *overriddenSensorPixelModesUsed) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700974
975 const std::unordered_set<int32_t> &sensorPixelModesUsedSet =
976 convertToSet(sensorPixelModesUsed);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800977 if (!isUltraHighResolutionSensor(staticInfo)) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700978 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
979 sensorPixelModesUsedSet.end()) {
980 // invalid value for non ultra high res sensors
981 return BAD_VALUE;
982 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800983 overriddenSensorPixelModesUsed->clear();
984 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
985 return OK;
986 }
987
988 StreamConfigurationPair streamConfigurationPair = getStreamConfigurationPair(staticInfo);
Jayant Chowdhary84df28c2021-05-26 22:32:21 -0700989
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800990 bool isInDefaultStreamConfigurationMap =
991 inStreamConfigurationMap(format, width, height,
992 streamConfigurationPair.mDefaultStreamConfigurationMap);
993
994 bool isInMaximumResolutionStreamConfigurationMap =
995 inStreamConfigurationMap(format, width, height,
996 streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
997
998 // Case 1: The client has not changed the sensor mode defaults. In this case, we check if the
999 // size + format of the OutputConfiguration is found exclusively in 1.
1000 // If yes, add that sensorPixelMode to overriddenSensorPixelModes.
1001 // If no, add 'DEFAULT' to sensorPixelMode. This maintains backwards
1002 // compatibility.
1003 if (sensorPixelModesUsedSet.size() == 0) {
1004 // Ambiguous case, default to only 'DEFAULT' mode.
1005 if (isInDefaultStreamConfigurationMap && isInMaximumResolutionStreamConfigurationMap) {
1006 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
1007 return OK;
1008 }
1009 // We don't allow flexible consumer for max resolution mode.
1010 if (isInMaximumResolutionStreamConfigurationMap) {
1011 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
1012 return OK;
1013 }
1014 if (isInDefaultStreamConfigurationMap || (flexibleConsumer && width < ROUNDING_WIDTH_CAP)) {
1015 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
1016 return OK;
1017 }
1018 return BAD_VALUE;
1019 }
1020
1021 // Case2: The app has set sensorPixelModesUsed, we need to verify that they
1022 // are valid / err out.
1023 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_DEFAULT) !=
1024 sensorPixelModesUsedSet.end() && !isInDefaultStreamConfigurationMap) {
1025 return BAD_VALUE;
1026 }
1027
1028 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1029 sensorPixelModesUsedSet.end() && !isInMaximumResolutionStreamConfigurationMap) {
1030 return BAD_VALUE;
1031 }
1032 *overriddenSensorPixelModesUsed = sensorPixelModesUsedSet;
1033 return OK;
1034}
1035
Emilian Peev2295df72021-11-12 18:14:10 -08001036bool convertHALStreamCombinationFromV38ToV37(
1037 hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
1038 const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
1039 streamConfigV37.streams.resize(streamConfigV38.streams.size());
1040 for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
Emilian Peevc81a7592022-02-14 17:38:18 -08001041 if (static_cast<int64_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
Emilian Peev2295df72021-11-12 18:14:10 -08001042 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
1043 // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
1044 // image
1045 return false;
1046 }
Shuzhen Wang8ed1e872022-03-08 16:34:33 -08001047 if (static_cast<int64_t>(streamConfigV38.streams[i].useCase) !=
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001048 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
1049 // ICameraDevice older than 3.8 doesn't support stream use case
1050 return false;
1051 }
Emilian Peev2295df72021-11-12 18:14:10 -08001052 streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
1053 }
1054 streamConfigV37.operationMode = streamConfigV38.operationMode;
1055 streamConfigV37.sessionParams = streamConfigV38.sessionParams;
1056
1057 return true;
1058}
1059
Austin Borgerea931242021-12-13 23:10:41 +00001060bool convertHALStreamCombinationFromV37ToV34(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001061 hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
1062 const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
1063 if (streamConfigV37.multiResolutionInputImage) {
1064 // ICameraDevice older than 3.7 doesn't support multi-resolution input image.
1065 return false;
1066 }
1067
1068 streamConfigV34.streams.resize(streamConfigV37.streams.size());
1069 for (size_t i = 0; i < streamConfigV37.streams.size(); i++) {
1070 if (streamConfigV37.streams[i].groupId != -1) {
1071 // ICameraDevice older than 3.7 doesn't support multi-resolution output
1072 // image
1073 return false;
1074 }
1075 streamConfigV34.streams[i] = streamConfigV37.streams[i].v3_4;
1076 }
1077 streamConfigV34.operationMode = streamConfigV37.operationMode;
1078 streamConfigV34.sessionParams = streamConfigV37.sessionParams;
1079
1080 return true;
1081}
1082
Austin Borgerea931242021-12-13 23:10:41 +00001083bool targetPerfClassPrimaryCamera(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001084 const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
1085 int targetSdkVersion) {
1086 bool isPerfClassPrimaryCamera =
1087 perfClassPrimaryCameraIds.find(cameraId) != perfClassPrimaryCameraIds.end();
1088 return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
1089}
1090
Austin Borgerea931242021-12-13 23:10:41 +00001091} // namespace SessionConfigurationUtils
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001092} // namespace camera3
1093} // namespace android