Vadim Caen | 550634d | 2024-07-17 14:01:21 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2024 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 | */ |
| 16 | #include "VirtualCameraCaptureResult.h" |
| 17 | |
| 18 | #include <cstdint> |
| 19 | |
| 20 | #include "VirtualCameraCaptureRequest.h" |
| 21 | #include "aidl/android/hardware/camera/device/CameraMetadata.h" |
| 22 | #include "util/MetadataUtil.h" |
| 23 | |
| 24 | namespace android { |
| 25 | namespace companion { |
| 26 | namespace virtualcamera { |
| 27 | |
| 28 | using ::aidl::android::hardware::camera::device::CameraMetadata; |
| 29 | namespace { |
| 30 | // See REQUEST_PIPELINE_DEPTH in CaptureResult.java. |
| 31 | // This roughly corresponds to frame latency, we set to |
| 32 | // documented minimum of 2. |
| 33 | static constexpr uint8_t kPipelineDepth = 2; |
| 34 | |
| 35 | } // namespace |
| 36 | |
| 37 | CameraMetadata createCaptureResultMetadata( |
| 38 | const std::chrono::nanoseconds timestamp, |
| 39 | const RequestSettings& requestSettings, |
| 40 | const Resolution reportedSensorSize) { |
| 41 | // All of the keys used in the response needs to be referenced in |
| 42 | // availableResultKeys in CameraCharacteristics (see initCameraCharacteristics |
| 43 | // in VirtualCameraDevice.cc). |
| 44 | MetadataBuilder builder = |
| 45 | MetadataBuilder() |
| 46 | .setAberrationCorrectionMode( |
| 47 | ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF) |
| 48 | .setControlAeAvailableAntibandingModes( |
| 49 | {ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF}) |
| 50 | .setControlAeAntibandingMode(ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF) |
| 51 | .setControlAeExposureCompensation(0) |
| 52 | .setControlAeLockAvailable(false) |
| 53 | .setControlAeLock(ANDROID_CONTROL_AE_LOCK_OFF) |
| 54 | .setControlAeMode(ANDROID_CONTROL_AE_MODE_ON) |
| 55 | .setControlAePrecaptureTrigger( |
| 56 | // Limited devices are expected to have precapture ae enabled and |
| 57 | // respond to cancellation request. Since we don't actuall support |
| 58 | // AE at all, let's just respect the cancellation expectation in |
| 59 | // case it's requested |
| 60 | requestSettings.aePrecaptureTrigger == |
| 61 | ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL |
| 62 | ? ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL |
| 63 | : ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE) |
| 64 | .setControlAeState(ANDROID_CONTROL_AE_STATE_INACTIVE) |
| 65 | .setControlAfMode(ANDROID_CONTROL_AF_MODE_OFF) |
| 66 | .setControlAfTrigger(ANDROID_CONTROL_AF_TRIGGER_IDLE) |
| 67 | .setControlAfState(ANDROID_CONTROL_AF_STATE_INACTIVE) |
| 68 | .setControlAwbMode(ANDROID_CONTROL_AWB_MODE_AUTO) |
| 69 | .setControlAwbLock(ANDROID_CONTROL_AWB_LOCK_OFF) |
| 70 | .setControlAwbState(ANDROID_CONTROL_AWB_STATE_INACTIVE) |
| 71 | .setControlCaptureIntent(requestSettings.captureIntent) |
| 72 | .setControlEffectMode(ANDROID_CONTROL_EFFECT_MODE_OFF) |
| 73 | .setControlMode(ANDROID_CONTROL_MODE_AUTO) |
| 74 | .setControlSceneMode(ANDROID_CONTROL_SCENE_MODE_DISABLED) |
| 75 | .setControlVideoStabilizationMode( |
| 76 | ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF) |
| 77 | .setCropRegion(0, 0, reportedSensorSize.width, |
| 78 | reportedSensorSize.height) |
| 79 | .setFaceDetectMode(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) |
| 80 | .setFlashState(ANDROID_FLASH_STATE_UNAVAILABLE) |
| 81 | .setFlashMode(ANDROID_FLASH_MODE_OFF) |
| 82 | .setFocalLength(VirtualCameraDevice::kFocalLength) |
| 83 | .setJpegQuality(requestSettings.jpegQuality) |
| 84 | .setJpegOrientation(requestSettings.jpegOrientation) |
| 85 | .setJpegThumbnailSize(requestSettings.thumbnailResolution.width, |
| 86 | requestSettings.thumbnailResolution.height) |
| 87 | .setJpegThumbnailQuality(requestSettings.thumbnailJpegQuality) |
| 88 | .setLensOpticalStabilizationMode( |
| 89 | ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF) |
| 90 | .setNoiseReductionMode(ANDROID_NOISE_REDUCTION_MODE_OFF) |
| 91 | .setPipelineDepth(kPipelineDepth) |
| 92 | .setSensorTimestamp(timestamp) |
| 93 | .setStatisticsHotPixelMapMode( |
| 94 | ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF) |
| 95 | .setStatisticsLensShadingMapMode( |
| 96 | ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF) |
| 97 | .setStatisticsSceneFlicker(ANDROID_STATISTICS_SCENE_FLICKER_NONE); |
| 98 | |
| 99 | if (requestSettings.fpsRange.has_value()) { |
| 100 | builder.setControlAeTargetFpsRange(requestSettings.fpsRange.value()); |
| 101 | } |
| 102 | |
| 103 | if (requestSettings.gpsCoordinates.has_value()) { |
| 104 | const GpsCoordinates& coordinates = requestSettings.gpsCoordinates.value(); |
| 105 | builder.setJpegGpsCoordinates(coordinates); |
| 106 | } |
| 107 | |
| 108 | std::unique_ptr<CameraMetadata> metadata = builder.build(); |
| 109 | |
| 110 | if (metadata == nullptr) { |
| 111 | ALOGE("%s: Failed to build capture result metadata", __func__); |
| 112 | return CameraMetadata(); |
| 113 | } |
| 114 | return std::move(*metadata); |
| 115 | } |
| 116 | |
| 117 | } // namespace virtualcamera |
| 118 | } // namespace companion |
| 119 | } // namespace android |