blob: 557591fff3cb061c8287aec33c3dbe989d73c939 [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 Chowdhary22441f32021-12-26 18:35:41 -080026#include "device3/hidl/HidlCamera3Device.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000027#include "device3/Camera3OutputStream.h"
Emilian Peev2295df72021-11-12 18:14:10 -080028#include "system/graphics-base-v1.1.h"
Colin Crossb8a9dbb2020-08-27 04:12:26 +000029
Colin Crossb8a9dbb2020-08-27 04:12:26 +000030using android::camera3::OutputStreamInfo;
31using android::camera3::OutputStreamInfo;
32using android::hardware::camera2::ICameraDeviceUser;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080033using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
Emilian Peev2295df72021-11-12 18:14:10 -080034using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080035using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080036
37namespace android {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080038namespace camera3 {
39
40void StreamConfiguration::getStreamConfigurations(
41 const CameraMetadata &staticInfo, int configuration,
42 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
43 if (scm == nullptr) {
44 ALOGE("%s: StreamConfigurationMap nullptr", __FUNCTION__);
45 return;
46 }
47 const int STREAM_FORMAT_OFFSET = 0;
48 const int STREAM_WIDTH_OFFSET = 1;
49 const int STREAM_HEIGHT_OFFSET = 2;
50 const int STREAM_IS_INPUT_OFFSET = 3;
51
52 camera_metadata_ro_entry availableStreamConfigs = staticInfo.find(configuration);
53 for (size_t i = 0; i < availableStreamConfigs.count; i += 4) {
54 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
55 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
56 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
57 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
58 StreamConfiguration sc = {format, width, height, isInput};
59 (*scm)[format].push_back(sc);
60 }
61}
62
63void StreamConfiguration::getStreamConfigurations(
64 const CameraMetadata &staticInfo, bool maxRes,
65 std::unordered_map<int, std::vector<StreamConfiguration>> *scm) {
66 int32_t scalerKey =
67 SessionConfigurationUtils::getAppropriateModeTag(
68 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxRes);
69
70 int32_t depthKey =
71 SessionConfigurationUtils::getAppropriateModeTag(
72 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, maxRes);
73
74 int32_t dynamicDepthKey =
75 SessionConfigurationUtils::getAppropriateModeTag(
76 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
77
78 int32_t heicKey =
79 SessionConfigurationUtils::getAppropriateModeTag(
80 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
81
82 getStreamConfigurations(staticInfo, scalerKey, scm);
83 getStreamConfigurations(staticInfo, depthKey, scm);
84 getStreamConfigurations(staticInfo, dynamicDepthKey, scm);
85 getStreamConfigurations(staticInfo, heicKey, scm);
86}
87
Austin Borgerea931242021-12-13 23:10:41 +000088namespace SessionConfigurationUtils {
89
90int32_t PERF_CLASS_LEVEL =
91 property_get_int32("ro.odm.build.media_performance_class", 0);
92
93bool IS_PERF_CLASS = (PERF_CLASS_LEVEL == SDK_VERSION_S);
94
95camera3::Size getMaxJpegResolution(const CameraMetadata &metadata,
96 bool ultraHighResolution) {
97 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
98 const int STREAM_CONFIGURATION_SIZE = 4;
99 const int STREAM_FORMAT_OFFSET = 0;
100 const int STREAM_WIDTH_OFFSET = 1;
101 const int STREAM_HEIGHT_OFFSET = 2;
102 const int STREAM_IS_INPUT_OFFSET = 3;
103
104 int32_t scalerSizesTag = ultraHighResolution ?
105 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION :
106 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
107 camera_metadata_ro_entry_t availableStreamConfigs =
108 metadata.find(scalerSizesTag);
109 if (availableStreamConfigs.count == 0 ||
110 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
111 return camera3::Size(0, 0);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800112 }
Austin Borgerea931242021-12-13 23:10:41 +0000113
114 // Get max jpeg size (area-wise).
115 for (size_t i= 0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
116 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
117 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
118 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
119 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
120 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
121 && format == HAL_PIXEL_FORMAT_BLOB &&
122 (width * height > maxJpegWidth * maxJpegHeight)) {
123 maxJpegWidth = width;
124 maxJpegHeight = height;
125 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800126 }
Austin Borgerea931242021-12-13 23:10:41 +0000127
128 return camera3::Size(maxJpegWidth, maxJpegHeight);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800129}
130
Austin Borgerea931242021-12-13 23:10:41 +0000131size_t getUHRMaxJpegBufferSize(camera3::Size uhrMaxJpegSize,
132 camera3::Size defaultMaxJpegSize, size_t defaultMaxJpegBufferSize) {
133 return (uhrMaxJpegSize.width * uhrMaxJpegSize.height) /
134 (defaultMaxJpegSize.width * defaultMaxJpegSize.height) * defaultMaxJpegBufferSize;
135}
136
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800137StreamConfigurationPair
Austin Borgerea931242021-12-13 23:10:41 +0000138getStreamConfigurationPair(const CameraMetadata &staticInfo) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800139 camera3::StreamConfigurationPair streamConfigurationPair;
140 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, false,
141 &streamConfigurationPair.mDefaultStreamConfigurationMap);
142 camera3::StreamConfiguration::getStreamConfigurations(staticInfo, true,
143 &streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
144 return streamConfigurationPair;
145}
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800146
Austin Borgerea931242021-12-13 23:10:41 +0000147int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000148 int64_t d0 = x0 - x1;
149 int64_t d1 = y0 - y1;
150 return d0 * d0 + d1 * d1;
151}
152
Austin Borgerea931242021-12-13 23:10:41 +0000153bool roundBufferDimensionNearest(int32_t width, int32_t height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800154 int32_t format, android_dataspace dataSpace,
155 const CameraMetadata& info, bool maxResolution, /*out*/int32_t* outWidth,
156 /*out*/int32_t* outHeight) {
157 const int32_t depthSizesTag =
158 getAppropriateModeTag(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
159 maxResolution);
160 const int32_t scalerSizesTag =
161 getAppropriateModeTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
162 const int32_t heicSizesTag =
163 getAppropriateModeTag(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000164
165 camera_metadata_ro_entry streamConfigs =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800166 (dataSpace == HAL_DATASPACE_DEPTH) ? info.find(depthSizesTag) :
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000167 (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800168 info.find(heicSizesTag) :
169 info.find(scalerSizesTag);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000170
171 int32_t bestWidth = -1;
172 int32_t bestHeight = -1;
173
174 // Iterate through listed stream configurations and find the one with the smallest euclidean
175 // distance from the given dimensions for the given format.
176 for (size_t i = 0; i < streamConfigs.count; i += 4) {
177 int32_t fmt = streamConfigs.data.i32[i];
178 int32_t w = streamConfigs.data.i32[i + 1];
179 int32_t h = streamConfigs.data.i32[i + 2];
180
181 // Ignore input/output type for now
182 if (fmt == format) {
183 if (w == width && h == height) {
184 bestWidth = width;
185 bestHeight = height;
186 break;
187 } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 ||
188 SessionConfigurationUtils::euclidDistSquare(w, h, width, height) <
189 SessionConfigurationUtils::euclidDistSquare(bestWidth, bestHeight, width,
190 height))) {
191 bestWidth = w;
192 bestHeight = h;
193 }
194 }
195 }
196
197 if (bestWidth == -1) {
198 // Return false if no configurations for this format were listed
199 return false;
200 }
201
202 // Set the outputs to the closet width/height
203 if (outWidth != NULL) {
204 *outWidth = bestWidth;
205 }
206 if (outHeight != NULL) {
207 *outHeight = bestHeight;
208 }
209
210 // Return true if at least one configuration for this format was listed
211 return true;
212}
213
Emilian Peev2295df72021-11-12 18:14:10 -0800214//check if format is 10-bit compatible
215bool is10bitCompatibleFormat(int32_t format) {
216 switch(format) {
217 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
218 case HAL_PIXEL_FORMAT_YCBCR_P010:
219 return true;
220 default:
221 return false;
222 }
223}
224
225bool isDynamicRangeProfileSupported(int dynamicRangeProfile, const CameraMetadata& staticInfo) {
226 if (dynamicRangeProfile == ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
227 // Supported by default
228 return true;
229 }
230
231 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
232 bool is10bitDynamicRangeSupported = false;
233 for (size_t i = 0; i < entry.count; ++i) {
234 uint8_t capability = entry.data.u8[i];
235 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
236 is10bitDynamicRangeSupported = true;
237 break;
238 }
239 }
240
241 if (!is10bitDynamicRangeSupported) {
242 return false;
243 }
244
245 switch (dynamicRangeProfile) {
246 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
247 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
248 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
249 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
250 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
251 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
252 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
253 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
254 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
255 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
256 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
257 entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
258 for (size_t i = 0; i < entry.count; i += 2) {
259 if (dynamicRangeProfile == entry.data.i32[i]) {
260 return true;
261 }
262 }
263
264 return false;
265 default:
266 return false;
267 }
268
269 return false;
270}
271
272//check if format is 10-bit compatible
273bool is10bitDynamicRangeProfile(int32_t dynamicRangeProfile) {
274 switch (dynamicRangeProfile) {
275 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
276 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
277 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
278 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
279 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
280 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
281 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
282 return true;
283 default:
284 return false;
285 }
286}
287
Austin Borgerea931242021-12-13 23:10:41 +0000288bool isPublicFormat(int32_t format)
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000289{
290 switch(format) {
291 case HAL_PIXEL_FORMAT_RGBA_8888:
292 case HAL_PIXEL_FORMAT_RGBX_8888:
293 case HAL_PIXEL_FORMAT_RGB_888:
294 case HAL_PIXEL_FORMAT_RGB_565:
295 case HAL_PIXEL_FORMAT_BGRA_8888:
296 case HAL_PIXEL_FORMAT_YV12:
297 case HAL_PIXEL_FORMAT_Y8:
298 case HAL_PIXEL_FORMAT_Y16:
299 case HAL_PIXEL_FORMAT_RAW16:
300 case HAL_PIXEL_FORMAT_RAW10:
301 case HAL_PIXEL_FORMAT_RAW12:
302 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
303 case HAL_PIXEL_FORMAT_BLOB:
304 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
305 case HAL_PIXEL_FORMAT_YCbCr_420_888:
306 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
307 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
308 case HAL_PIXEL_FORMAT_YCbCr_422_I:
309 return true;
310 default:
311 return false;
312 }
313}
314
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800315bool isStreamUseCaseSupported(int streamUseCase,
316 const CameraMetadata &deviceInfo) {
317 camera_metadata_ro_entry_t availableStreamUseCases =
318 deviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES);
319
320 if (availableStreamUseCases.count == 0 &&
321 streamUseCase == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
322 return true;
323 }
324
325 for (size_t i = 0; i < availableStreamUseCases.count; i++) {
326 if (availableStreamUseCases.data.i32[i] == streamUseCase) {
327 return true;
328 }
329 }
330 return false;
331}
332
Austin Borgerea931242021-12-13 23:10:41 +0000333binder::Status createSurfaceFromGbp(
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000334 OutputStreamInfo& streamInfo, bool isStreamInfoValid,
335 sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800336 const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800337 const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
338 int streamUseCase) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000339 // bufferProducer must be non-null
340 if (gbp == nullptr) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800341 String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000342 ALOGW("%s: %s", __FUNCTION__, msg.string());
343 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
344 }
345 // HACK b/10949105
346 // Query consumer usage bits to set async operation mode for
347 // GLConsumer using controlledByApp parameter.
348 bool useAsync = false;
349 uint64_t consumerUsage = 0;
350 status_t err;
351 if ((err = gbp->getConsumerUsage(&consumerUsage)) != OK) {
352 String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800353 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000354 ALOGE("%s: %s", __FUNCTION__, msg.string());
355 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
356 }
357 if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
358 ALOGW("%s: Camera %s with consumer usage flag: %" PRIu64 ": Forcing asynchronous mode for"
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800359 "stream", __FUNCTION__, logicalCameraId.string(), consumerUsage);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000360 useAsync = true;
361 }
362
363 uint64_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
364 GRALLOC_USAGE_RENDERSCRIPT;
365 uint64_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
366 GraphicBuffer::USAGE_HW_TEXTURE |
367 GraphicBuffer::USAGE_HW_COMPOSER;
368 bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
369 (consumerUsage & allowedFlags) != 0;
370
371 surface = new Surface(gbp, useAsync);
372 ANativeWindow *anw = surface.get();
373
374 int width, height, format;
375 android_dataspace dataSpace;
376 if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
377 String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800378 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000379 ALOGE("%s: %s", __FUNCTION__, msg.string());
380 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
381 }
382 if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
383 String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800384 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000385 ALOGE("%s: %s", __FUNCTION__, msg.string());
386 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
387 }
388 if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
389 String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800390 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000391 ALOGE("%s: %s", __FUNCTION__, msg.string());
392 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
393 }
394 if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
395 reinterpret_cast<int*>(&dataSpace))) != OK) {
396 String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800397 logicalCameraId.string(), strerror(-err), err);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000398 ALOGE("%s: %s", __FUNCTION__, msg.string());
399 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
400 }
401
402 // FIXME: remove this override since the default format should be
403 // IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
404 if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
405 ((consumerUsage & GRALLOC_USAGE_HW_MASK) &&
406 ((consumerUsage & GRALLOC_USAGE_SW_READ_MASK) == 0))) {
407 ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800408 __FUNCTION__, logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000409 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
410 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800411 std::unordered_set<int32_t> overriddenSensorPixelModes;
412 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed, format, width, height,
413 physicalCameraMetadata, flexibleConsumer, &overriddenSensorPixelModes) != OK) {
414 String8 msg = String8::format("Camera %s: sensor pixel modes for stream with "
415 "format %#x are not valid",logicalCameraId.string(), format);
416 ALOGE("%s: %s", __FUNCTION__, msg.string());
417 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
418 }
419 bool foundInMaxRes = false;
420 if (overriddenSensorPixelModes.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
421 overriddenSensorPixelModes.end()) {
422 // we can use the default stream configuration map
423 foundInMaxRes = true;
424 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000425 // Round dimensions to the nearest dimensions available for this format
426 if (flexibleConsumer && isPublicFormat(format) &&
427 !SessionConfigurationUtils::roundBufferDimensionNearest(width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800428 format, dataSpace, physicalCameraMetadata, foundInMaxRes, /*out*/&width,
429 /*out*/&height)) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000430 String8 msg = String8::format("Camera %s: No supported stream configurations with "
431 "format %#x defined, failed to create output stream",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800432 logicalCameraId.string(), format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000433 ALOGE("%s: %s", __FUNCTION__, msg.string());
434 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
435 }
Emilian Peev2295df72021-11-12 18:14:10 -0800436 if (!SessionConfigurationUtils::isDynamicRangeProfileSupported(dynamicRangeProfile,
437 physicalCameraMetadata)) {
438 String8 msg = String8::format("Camera %s: Dynamic range profile 0x%x not supported,"
439 " failed to create output stream", logicalCameraId.string(), dynamicRangeProfile);
440 ALOGE("%s: %s", __FUNCTION__, msg.string());
441 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
442 }
443 if (SessionConfigurationUtils::is10bitDynamicRangeProfile(dynamicRangeProfile) &&
444 !SessionConfigurationUtils::is10bitCompatibleFormat(format)) {
445 String8 msg = String8::format("Camera %s: No 10-bit supported stream configurations with "
446 "format %#x defined and profile %#x, failed to create output stream",
447 logicalCameraId.string(), format, dynamicRangeProfile);
448 ALOGE("%s: %s", __FUNCTION__, msg.string());
449 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
450 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800451 if (!SessionConfigurationUtils::isStreamUseCaseSupported(streamUseCase,
452 physicalCameraMetadata)) {
453 String8 msg = String8::format("Camera %s: stream use case %d not supported,"
454 " failed to create output stream", logicalCameraId.string(), streamUseCase);
455 ALOGE("%s: %s", __FUNCTION__, msg.string());
456 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
457 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000458
459 if (!isStreamInfoValid) {
460 streamInfo.width = width;
461 streamInfo.height = height;
462 streamInfo.format = format;
463 streamInfo.dataSpace = dataSpace;
464 streamInfo.consumerUsage = consumerUsage;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800465 streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
Emilian Peev2295df72021-11-12 18:14:10 -0800466 streamInfo.dynamicRangeProfile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800467 streamInfo.streamUseCase = streamUseCase;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000468 return binder::Status::ok();
469 }
470 if (width != streamInfo.width) {
471 String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800472 logicalCameraId.string(), width, streamInfo.width);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000473 ALOGE("%s: %s", __FUNCTION__, msg.string());
474 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
475 }
476 if (height != streamInfo.height) {
477 String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800478 logicalCameraId.string(), height, streamInfo.height);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000479 ALOGE("%s: %s", __FUNCTION__, msg.string());
480 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
481 }
482 if (format != streamInfo.format) {
483 String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800484 logicalCameraId.string(), format, streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000485 ALOGE("%s: %s", __FUNCTION__, msg.string());
486 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
487 }
488 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
489 if (dataSpace != streamInfo.dataSpace) {
490 String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800491 logicalCameraId.string(), dataSpace, streamInfo.dataSpace);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000492 ALOGE("%s: %s", __FUNCTION__, msg.string());
493 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
494 }
495 //At the native side, there isn't a way to check whether 2 surfaces come from the same
496 //surface class type. Use usage flag to approximate the comparison.
497 if (consumerUsage != streamInfo.consumerUsage) {
498 String8 msg = String8::format(
499 "Camera %s:Surface usage flag doesn't match %" PRIu64 " vs %" PRIu64 "",
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800500 logicalCameraId.string(), consumerUsage, streamInfo.consumerUsage);
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 }
505 return binder::Status::ok();
506}
507
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000508aidl::android::hardware::graphics::common::PixelFormat mapToAidlPixelFormat(
509 int frameworkFormat) {
510 return (aidl::android::hardware::graphics::common::PixelFormat) frameworkFormat;
511}
512
513aidl::android::hardware::graphics::common::Dataspace mapToAidlDataspace(
514 android_dataspace dataSpace) {
515 return (aidl::android::hardware::graphics::common::Dataspace)dataSpace;
516}
517
518aidl::android::hardware::graphics::common::BufferUsage mapToAidlConsumerUsage(
519 uint64_t usage) {
520 return (aidl::android::hardware::graphics::common::BufferUsage)usage;
521}
522
523aidl::android::hardware::camera::device::StreamRotation
524mapToAidlStreamRotation(camera_stream_rotation_t rotation) {
525 switch (rotation) {
526 case CAMERA_STREAM_ROTATION_0:
527 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
528 case CAMERA_STREAM_ROTATION_90:
529 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_90;
530 case CAMERA_STREAM_ROTATION_180:
531 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_180;
532 case CAMERA_STREAM_ROTATION_270:
533 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_270;
534 }
535 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
536 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
537}
538
539status_t mapToAidlStreamConfigurationMode(
540 camera_stream_configuration_mode_t operationMode,
541 aidl::android::hardware::camera::device::StreamConfigurationMode *mode) {
542 using StreamConfigurationMode =
543 aidl::android::hardware::camera::device::StreamConfigurationMode;
544 if (mode == nullptr) return BAD_VALUE;
545 if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
546 switch(operationMode) {
547 case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
548 *mode = StreamConfigurationMode::NORMAL_MODE;
549 break;
550 case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
551 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
552 break;
553 default:
554 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
555 return BAD_VALUE;
556 }
557 } else {
558 *mode = static_cast<StreamConfigurationMode>(operationMode);
559 }
560 return OK;
561}
562
Austin Borgerea931242021-12-13 23:10:41 +0000563void mapStreamInfo(const OutputStreamInfo &streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700564 camera3::camera_stream_rotation_t rotation, String8 physicalId,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000565 int32_t groupId, aidl::android::hardware::camera::device::Stream *stream /*out*/) {
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000566 if (stream == nullptr) {
567 return;
568 }
569
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000570 stream->streamType = aidl::android::hardware::camera::device::StreamType::OUTPUT;
571 stream->width = streamInfo.width;
572 stream->height = streamInfo.height;
573 stream->format = mapToAidlPixelFormat(streamInfo.format);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000574 auto u = streamInfo.consumerUsage;
575 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000576 stream->usage = mapToAidlConsumerUsage(u);
577 stream->dataSpace = mapToAidlDataspace(streamInfo.dataSpace);
578 stream->rotation = mapToAidlStreamRotation(rotation);
579 stream->id = -1; // Invalid stream id
580 stream->physicalCameraId = std::string(physicalId.string());
581 stream->bufferSize = 0;
582 stream->groupId = groupId;
583 stream->sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800584 size_t idx = 0;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000585 using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800586 for (auto mode : streamInfo.sensorPixelModesUsed) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000587 stream->sensorPixelModesUsed[idx++] =
588 static_cast<SensorPixelMode>(mode);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800589 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000590 using DynamicRangeProfile =
591 aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
592 stream->dynamicRangeProfile = static_cast<DynamicRangeProfile>(streamInfo.dynamicRangeProfile);
593 using StreamUseCases =
594 aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
595 stream->useCase = static_cast<StreamUseCases>(streamInfo.streamUseCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000596}
597
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000598status_t
599convertAidlToHidl38StreamCombination(
600 const aidl::android::hardware::camera::device::StreamConfiguration &aidl,
601 hardware::camera::device::V3_8::StreamConfiguration &hidl) {
602 hidl.operationMode =
603 static_cast<hardware::camera::device::V3_2::StreamConfigurationMode>(aidl.operationMode);
604 if (aidl.streamConfigCounter < 0) {
605 return BAD_VALUE;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000606 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000607 hidl.streamConfigCounter = static_cast<uint32_t>(aidl.streamConfigCounter);
608 hidl.multiResolutionInputImage = aidl.multiResolutionInputImage;
609 hidl.sessionParams = aidl.sessionParams.metadata;
610 hidl.streams.resize(aidl.streams.size());
611 size_t i = 0;
612 for (const auto &stream : aidl.streams) {
613 //hidlv3_8
614 hidl.streams[i].dynamicRangeProfile =
615 static_cast<
616 CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
617 (stream.dynamicRangeProfile);
618 hidl.streams[i].useCase =
619 static_cast<
620 CameraMetadataEnumAndroidScalerAvailableStreamUseCases>
621 (stream.useCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000622
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000623 // hidl v3_7
624 hidl.streams[i].v3_7.groupId = stream.groupId;
625 hidl.streams[i].v3_7.sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
626 size_t j = 0;
627 for (const auto &mode : stream.sensorPixelModesUsed) {
628 hidl.streams[i].v3_7.sensorPixelModesUsed[j] =
629 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
630 j++;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000631 }
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000632
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000633 //hidl v3_4
634 hidl.streams[i].v3_7.v3_4.physicalCameraId = stream.physicalCameraId;
635
636 if (stream.bufferSize < 0) {
637 return BAD_VALUE;
638 }
639 hidl.streams[i].v3_7.v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
640
641 // hild v3_2
642 hidl.streams[i].v3_7.v3_4.v3_2.id = stream.id;
643 hidl.streams[i].v3_7.v3_4.v3_2.format =
644 static_cast<hardware::graphics::common::V1_0::PixelFormat>(stream.format);
645
646 if (stream.width < 0 || stream.height < 0) {
647 return BAD_VALUE;
648 }
649 hidl.streams[i].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
650 hidl.streams[i].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
651 hidl.streams[i].v3_7.v3_4.v3_2.usage =
652 static_cast<hardware::camera::device::V3_2::BufferUsageFlags>(stream.usage);
653 hidl.streams[i].v3_7.v3_4.v3_2.streamType =
654 static_cast<hardware::camera::device::V3_2::StreamType>(stream.streamType);
655 hidl.streams[i].v3_7.v3_4.v3_2.dataSpace =
656 static_cast<hardware::camera::device::V3_2::DataspaceFlags>(stream.dataSpace);
657 hidl.streams[i].v3_7.v3_4.v3_2.rotation =
658 static_cast<hardware::camera::device::V3_2::StreamRotation>(stream.rotation);
659 i++;
660 }
661 return OK;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000662}
663
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800664binder::Status
Austin Borgerea931242021-12-13 23:10:41 +0000665convertToHALStreamCombination(
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800666 const SessionConfiguration& sessionConfiguration,
667 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
668 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000669 aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700670 bool overrideForPerfClass, bool *earlyExit) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000671 using SensorPixelMode =
672 aidl::android::hardware::camera::metadata::SensorPixelMode;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000673 auto operatingMode = sessionConfiguration.getOperatingMode();
674 binder::Status res = checkOperatingMode(operatingMode, deviceInfo, logicalCameraId);
675 if (!res.isOk()) {
676 return res;
677 }
678
679 if (earlyExit == nullptr) {
680 String8 msg("earlyExit nullptr");
681 ALOGE("%s: %s", __FUNCTION__, msg.string());
682 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
683 }
684 *earlyExit = false;
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000685 auto ret = mapToAidlStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700686 static_cast<camera_stream_configuration_mode_t> (operatingMode),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000687 /*out*/ &streamConfiguration.operationMode);
688 if (ret != OK) {
689 String8 msg = String8::format(
690 "Camera %s: Failed mapping operating mode %d requested: %s (%d)",
691 logicalCameraId.string(), operatingMode, strerror(-ret), ret);
692 ALOGE("%s: %s", __FUNCTION__, msg.string());
693 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
694 msg.string());
695 }
696
697 bool isInputValid = (sessionConfiguration.getInputWidth() > 0) &&
698 (sessionConfiguration.getInputHeight() > 0) &&
699 (sessionConfiguration.getInputFormat() > 0);
700 auto outputConfigs = sessionConfiguration.getOutputConfigurations();
701 size_t streamCount = outputConfigs.size();
702 streamCount = isInputValid ? streamCount + 1 : streamCount;
703 streamConfiguration.streams.resize(streamCount);
704 size_t streamIdx = 0;
705 if (isInputValid) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000706 std::vector<SensorPixelMode> defaultSensorPixelModes;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800707 defaultSensorPixelModes.resize(1);
708 defaultSensorPixelModes[0] =
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000709 static_cast<SensorPixelMode>(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
710 aidl::android::hardware::camera::device::Stream stream;
711 stream.id = 0;
712 stream.streamType = aidl::android::hardware::camera::device::StreamType::INPUT;
713 stream.width = static_cast<uint32_t> (sessionConfiguration.getInputWidth());
714 stream.height = static_cast<uint32_t> (sessionConfiguration.getInputHeight());
715 stream.format = mapToAidlPixelFormat(sessionConfiguration.getInputFormat());
716 stream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(0);
717 stream.dataSpace =
718 static_cast<aidl::android::hardware::graphics::common::Dataspace>(
719 HAL_DATASPACE_UNKNOWN);
720 stream.rotation = aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
721 stream.bufferSize = 0;
722 stream.groupId = -1;
723 stream.sensorPixelModesUsed = defaultSensorPixelModes;
724 streamConfiguration.streams[streamIdx++] = stream;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800725 streamConfiguration.multiResolutionInputImage =
726 sessionConfiguration.inputIsMultiResolution();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000727 }
728
729 for (const auto &it : outputConfigs) {
730 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
731 it.getGraphicBufferProducers();
732 bool deferredConsumer = it.isDeferred();
733 String8 physicalCameraId = String8(it.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800734
Emilian Peev2295df72021-11-12 18:14:10 -0800735 int dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800736 std::vector<int32_t> sensorPixelModesUsed = it.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700737 const CameraMetadata &physicalDeviceInfo = getMetadata(physicalCameraId,
738 overrideForPerfClass);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800739 const CameraMetadata &metadataChosen =
740 physicalCameraId.size() > 0 ? physicalDeviceInfo : deviceInfo;
741
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000742 size_t numBufferProducers = bufferProducers.size();
743 bool isStreamInfoValid = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800744 int32_t groupId = it.isMultiResolution() ? it.getSurfaceSetID() : -1;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000745 OutputStreamInfo streamInfo;
746
747 res = checkSurfaceType(numBufferProducers, deferredConsumer, it.getSurfaceType());
748 if (!res.isOk()) {
749 return res;
750 }
751 res = checkPhysicalCameraId(physicalCameraIds, physicalCameraId,
752 logicalCameraId);
753 if (!res.isOk()) {
754 return res;
755 }
756
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800757 int streamUseCase = it.getStreamUseCase();
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000758 if (deferredConsumer) {
759 streamInfo.width = it.getWidth();
760 streamInfo.height = it.getHeight();
761 streamInfo.format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
762 streamInfo.dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
763 auto surfaceType = it.getSurfaceType();
764 streamInfo.consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
765 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
766 streamInfo.consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
767 }
Emilian Peev2295df72021-11-12 18:14:10 -0800768 streamInfo.dynamicRangeProfile = it.getDynamicRangeProfile();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800769 if (checkAndOverrideSensorPixelModesUsed(sensorPixelModesUsed,
770 streamInfo.format, streamInfo.width,
771 streamInfo.height, metadataChosen, false /*flexibleConsumer*/,
772 &streamInfo.sensorPixelModesUsed) != OK) {
773 ALOGE("%s: Deferred surface sensor pixel modes not valid",
774 __FUNCTION__);
775 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
776 "Deferred surface sensor pixel modes not valid");
777 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800778 streamInfo.streamUseCase = streamUseCase;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800779 mapStreamInfo(streamInfo, camera3::CAMERA_STREAM_ROTATION_0, physicalCameraId, groupId,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000780 &streamConfiguration.streams[streamIdx++]);
781 isStreamInfoValid = true;
782
783 if (numBufferProducers == 0) {
784 continue;
785 }
786 }
787
788 for (auto& bufferProducer : bufferProducers) {
789 sp<Surface> surface;
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000790 res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800791 logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
792 streamUseCase);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000793
794 if (!res.isOk())
795 return res;
796
797 if (!isStreamInfoValid) {
798 bool isDepthCompositeStream =
799 camera3::DepthCompositeStream::isDepthCompositeStream(surface);
800 bool isHeicCompositeStream =
801 camera3::HeicCompositeStream::isHeicCompositeStream(surface);
802 if (isDepthCompositeStream || isHeicCompositeStream) {
803 // We need to take in to account that composite streams can have
804 // additional internal camera streams.
805 std::vector<OutputStreamInfo> compositeStreams;
806 if (isDepthCompositeStream) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800807 // TODO: Take care of composite streams.
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000808 ret = camera3::DepthCompositeStream::getCompositeStreamInfo(streamInfo,
809 deviceInfo, &compositeStreams);
810 } else {
811 ret = camera3::HeicCompositeStream::getCompositeStreamInfo(streamInfo,
812 deviceInfo, &compositeStreams);
813 }
814 if (ret != OK) {
815 String8 msg = String8::format(
816 "Camera %s: Failed adding composite streams: %s (%d)",
817 logicalCameraId.string(), strerror(-ret), ret);
818 ALOGE("%s: %s", __FUNCTION__, msg.string());
819 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
820 }
821
822 if (compositeStreams.size() == 0) {
823 // No internal streams means composite stream not
824 // supported.
825 *earlyExit = true;
826 return binder::Status::ok();
827 } else if (compositeStreams.size() > 1) {
828 streamCount += compositeStreams.size() - 1;
829 streamConfiguration.streams.resize(streamCount);
830 }
831
832 for (const auto& compositeStream : compositeStreams) {
833 mapStreamInfo(compositeStream,
Emilian Peevf4816702020-04-03 15:44:51 -0700834 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800835 physicalCameraId, groupId,
836 &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000837 }
838 } else {
839 mapStreamInfo(streamInfo,
Emilian Peevf4816702020-04-03 15:44:51 -0700840 static_cast<camera_stream_rotation_t> (it.getRotation()),
Shuzhen Wang83bff122020-11-20 15:51:39 -0800841 physicalCameraId, groupId, &streamConfiguration.streams[streamIdx++]);
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000842 }
843 isStreamInfoValid = true;
844 }
845 }
846 }
847 return binder::Status::ok();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800848}
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000849
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000850void mapStreamInfo(const OutputStreamInfo &streamInfo,
851 camera3::camera_stream_rotation_t rotation, String8 physicalId,
852 int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
853 if (stream == nullptr) {
854 return;
855 }
856
857 stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
858 stream->v3_7.v3_4.v3_2.width = streamInfo.width;
859 stream->v3_7.v3_4.v3_2.height = streamInfo.height;
860 stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
861 auto u = streamInfo.consumerUsage;
862 camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
863 stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
864 stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
865 stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
866 stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
867 stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
868 stream->v3_7.v3_4.bufferSize = 0;
869 stream->v3_7.groupId = groupId;
870 stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
871
872 size_t idx = 0;
873 for (auto mode : streamInfo.sensorPixelModesUsed) {
874 stream->v3_7.sensorPixelModesUsed[idx++] =
875 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
876 }
877 stream->dynamicRangeProfile =
878 static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
879 streamInfo.dynamicRangeProfile);
880 stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
881 streamInfo.streamUseCase);
882}
883
884binder::Status checkPhysicalCameraId(
885 const std::vector<std::string> &physicalCameraIds, const String8 &physicalCameraId,
886 const String8 &logicalCameraId) {
887 if (physicalCameraId.size() == 0) {
888 return binder::Status::ok();
889 }
890 if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(),
891 physicalCameraId.string()) == physicalCameraIds.end()) {
892 String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
893 logicalCameraId.string(), physicalCameraId.string());
894 ALOGE("%s: %s", __FUNCTION__, msg.string());
895 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
896 }
897 return binder::Status::ok();
898}
899
900binder::Status checkSurfaceType(size_t numBufferProducers,
901 bool deferredConsumer, int surfaceType) {
902 if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
903 ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
904 __FUNCTION__, numBufferProducers, MAX_SURFACES_PER_STREAM);
905 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
906 } else if ((numBufferProducers == 0) && (!deferredConsumer)) {
907 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
908 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "No valid consumers.");
909 }
910
911 bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
912 (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
913
914 if (deferredConsumer && !validSurfaceType) {
915 ALOGE("%s: Target surface has invalid surfaceType = %d.", __FUNCTION__, surfaceType);
916 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
917 }
918
919 return binder::Status::ok();
920}
921
922binder::Status checkOperatingMode(int operatingMode,
923 const CameraMetadata &staticInfo, const String8 &cameraId) {
924 if (operatingMode < 0) {
925 String8 msg = String8::format(
926 "Camera %s: Invalid operating mode %d requested", cameraId.string(), operatingMode);
927 ALOGE("%s: %s", __FUNCTION__, msg.string());
928 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
929 msg.string());
930 }
931
932 bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
933 if (isConstrainedHighSpeed) {
934 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
935 bool isConstrainedHighSpeedSupported = false;
936 for(size_t i = 0; i < entry.count; ++i) {
937 uint8_t capability = entry.data.u8[i];
938 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
939 isConstrainedHighSpeedSupported = true;
940 break;
941 }
942 }
943 if (!isConstrainedHighSpeedSupported) {
944 String8 msg = String8::format(
945 "Camera %s: Try to create a constrained high speed configuration on a device"
946 " that doesn't support it.", cameraId.string());
947 ALOGE("%s: %s", __FUNCTION__, msg.string());
948 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
949 msg.string());
950 }
951 }
952
953 return binder::Status::ok();
954}
955
956binder::Status
957convertToHALStreamCombination(
958 const SessionConfiguration& sessionConfiguration,
959 const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
960 metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
961 hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
962 bool overrideForPerfClass, bool *earlyExit) {
963 aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
964 auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
965 getMetadata, physicalCameraIds, aidlStreamConfiguration, overrideForPerfClass,
966 earlyExit);
967 if (!ret.isOk()) {
968 return ret;
969 }
970 if (earlyExit != nullptr && *earlyExit) {
971 return binder::Status::ok();
972 }
973
974 if (convertAidlToHidl38StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
975 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
976 "Invalid AIDL->HIDL3.8 conversion");
977 }
978
979 return binder::Status::ok();
980}
981
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800982static bool inStreamConfigurationMap(int format, int width, int height,
983 const std::unordered_map<int, std::vector<camera3::StreamConfiguration>> &sm) {
984 auto scs = sm.find(format);
985 if (scs == sm.end()) {
986 return false;
987 }
988 for (auto &sc : scs->second) {
989 if (sc.width == width && sc.height == height && sc.isInput == 0) {
990 return true;
991 }
992 }
993 return false;
994}
995
996static std::unordered_set<int32_t> convertToSet(const std::vector<int32_t> &sensorPixelModesUsed) {
997 return std::unordered_set<int32_t>(sensorPixelModesUsed.begin(), sensorPixelModesUsed.end());
998}
999
Austin Borgerea931242021-12-13 23:10:41 +00001000status_t checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001001 const std::vector<int32_t> &sensorPixelModesUsed, int format, int width, int height,
1002 const CameraMetadata &staticInfo, bool flexibleConsumer,
1003 std::unordered_set<int32_t> *overriddenSensorPixelModesUsed) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -07001004
1005 const std::unordered_set<int32_t> &sensorPixelModesUsedSet =
1006 convertToSet(sensorPixelModesUsed);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001007 if (!isUltraHighResolutionSensor(staticInfo)) {
Jayant Chowdhary84df28c2021-05-26 22:32:21 -07001008 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1009 sensorPixelModesUsedSet.end()) {
1010 // invalid value for non ultra high res sensors
1011 return BAD_VALUE;
1012 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001013 overriddenSensorPixelModesUsed->clear();
1014 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
1015 return OK;
1016 }
1017
1018 StreamConfigurationPair streamConfigurationPair = getStreamConfigurationPair(staticInfo);
Jayant Chowdhary84df28c2021-05-26 22:32:21 -07001019
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001020 bool isInDefaultStreamConfigurationMap =
1021 inStreamConfigurationMap(format, width, height,
1022 streamConfigurationPair.mDefaultStreamConfigurationMap);
1023
1024 bool isInMaximumResolutionStreamConfigurationMap =
1025 inStreamConfigurationMap(format, width, height,
1026 streamConfigurationPair.mMaximumResolutionStreamConfigurationMap);
1027
1028 // Case 1: The client has not changed the sensor mode defaults. In this case, we check if the
1029 // size + format of the OutputConfiguration is found exclusively in 1.
1030 // If yes, add that sensorPixelMode to overriddenSensorPixelModes.
1031 // If no, add 'DEFAULT' to sensorPixelMode. This maintains backwards
1032 // compatibility.
1033 if (sensorPixelModesUsedSet.size() == 0) {
1034 // Ambiguous case, default to only 'DEFAULT' mode.
1035 if (isInDefaultStreamConfigurationMap && isInMaximumResolutionStreamConfigurationMap) {
1036 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
1037 return OK;
1038 }
1039 // We don't allow flexible consumer for max resolution mode.
1040 if (isInMaximumResolutionStreamConfigurationMap) {
1041 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION);
1042 return OK;
1043 }
1044 if (isInDefaultStreamConfigurationMap || (flexibleConsumer && width < ROUNDING_WIDTH_CAP)) {
1045 overriddenSensorPixelModesUsed->insert(ANDROID_SENSOR_PIXEL_MODE_DEFAULT);
1046 return OK;
1047 }
1048 return BAD_VALUE;
1049 }
1050
1051 // Case2: The app has set sensorPixelModesUsed, we need to verify that they
1052 // are valid / err out.
1053 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_DEFAULT) !=
1054 sensorPixelModesUsedSet.end() && !isInDefaultStreamConfigurationMap) {
1055 return BAD_VALUE;
1056 }
1057
1058 if (sensorPixelModesUsedSet.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1059 sensorPixelModesUsedSet.end() && !isInMaximumResolutionStreamConfigurationMap) {
1060 return BAD_VALUE;
1061 }
1062 *overriddenSensorPixelModesUsed = sensorPixelModesUsedSet;
1063 return OK;
1064}
1065
Emilian Peev2295df72021-11-12 18:14:10 -08001066bool convertHALStreamCombinationFromV38ToV37(
1067 hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
1068 const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
1069 streamConfigV37.streams.resize(streamConfigV38.streams.size());
1070 for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
1071 if (static_cast<int32_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
1072 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
1073 // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
1074 // image
1075 return false;
1076 }
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001077 if (static_cast<int32_t>(streamConfigV38.streams[i].useCase) !=
1078 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
1079 // ICameraDevice older than 3.8 doesn't support stream use case
1080 return false;
1081 }
Emilian Peev2295df72021-11-12 18:14:10 -08001082 streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
1083 }
1084 streamConfigV37.operationMode = streamConfigV38.operationMode;
1085 streamConfigV37.sessionParams = streamConfigV38.sessionParams;
1086
1087 return true;
1088}
1089
Austin Borgerea931242021-12-13 23:10:41 +00001090bool convertHALStreamCombinationFromV37ToV34(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001091 hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
1092 const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
1093 if (streamConfigV37.multiResolutionInputImage) {
1094 // ICameraDevice older than 3.7 doesn't support multi-resolution input image.
1095 return false;
1096 }
1097
1098 streamConfigV34.streams.resize(streamConfigV37.streams.size());
1099 for (size_t i = 0; i < streamConfigV37.streams.size(); i++) {
1100 if (streamConfigV37.streams[i].groupId != -1) {
1101 // ICameraDevice older than 3.7 doesn't support multi-resolution output
1102 // image
1103 return false;
1104 }
1105 streamConfigV34.streams[i] = streamConfigV37.streams[i].v3_4;
1106 }
1107 streamConfigV34.operationMode = streamConfigV37.operationMode;
1108 streamConfigV34.sessionParams = streamConfigV37.sessionParams;
1109
1110 return true;
1111}
1112
Austin Borgerea931242021-12-13 23:10:41 +00001113bool targetPerfClassPrimaryCamera(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001114 const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
1115 int targetSdkVersion) {
1116 bool isPerfClassPrimaryCamera =
1117 perfClassPrimaryCameraIds.find(cameraId) != perfClassPrimaryCameraIds.end();
1118 return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
1119}
1120
Austin Borgerea931242021-12-13 23:10:41 +00001121} // namespace SessionConfigurationUtils
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001122} // namespace camera3
1123} // namespace android