Loading services/camera/virtualcamera/VirtualCameraDevice.cc +36 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ #include <chrono> #include <cstdint> #include <iterator> #include <numeric> #include <optional> #include <string> #include <vector> #include "VirtualCameraSession.h" #include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h" Loading Loading @@ -81,6 +83,17 @@ bool isSupportedOutputFormat(const PixelFormat pixelFormat) { kOutputFormats.end(); } std::vector<MetadataBuilder::FpsRange> fpsRangesForInputConfig( const std::vector<SupportedStreamConfiguration>& configs) { std::set<MetadataBuilder::FpsRange> availableRanges; for (const SupportedStreamConfiguration& config : configs) { availableRanges.insert({.minFps = config.maxFps, .maxFps = config.maxFps}); } return std::vector<MetadataBuilder::FpsRange>(availableRanges.begin(), availableRanges.end()); } std::optional<Resolution> getMaxResolution( const std::vector<SupportedStreamConfiguration>& configs) { auto itMax = std::max_element(configs.begin(), configs.end(), Loading Loading @@ -151,12 +164,16 @@ std::optional<CameraMetadata> initCameraCharacteristics( .setControlAfAvailableModes({ANDROID_CONTROL_AF_MODE_OFF}) .setControlAvailableSceneModes({ANDROID_CONTROL_SCENE_MODE_DISABLED}) .setControlAvailableEffects({ANDROID_CONTROL_EFFECT_MODE_OFF}) .setControlAeAvailableFpsRange(10, 30) .setControlAeAvailableModes({ANDROID_CONTROL_AE_MODE_ON}) .setControlAeAvailableAntibandingModes( {ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}) .setControlAeAvailableFpsRanges( fpsRangesForInputConfig(supportedInputConfig)) .setControlMaxRegions(0, 0, 0) .setControlAfRegions({kDefaultEmptyControlRegion}) .setControlAeRegions({kDefaultEmptyControlRegion}) .setControlAwbRegions({kDefaultEmptyControlRegion}) .setControlAeCompensationRange(0, 1) .setControlAeCompensationRange(0, 0) .setControlAeCompensationStep(camera_metadata_rational_t{0, 1}) .setControlAwbLockAvailable(false) .setControlAeLockAvailable(false) Loading @@ -170,9 +187,18 @@ std::optional<CameraMetadata> initCameraCharacteristics( VirtualCameraDevice::kMaxNumberOfProcessedStreams, VirtualCameraDevice::kMaxNumberOfStallStreams) .setSyncMaxLatency(ANDROID_SYNC_MAX_LATENCY_UNKNOWN) .setAvailableRequestKeys({}) .setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE}) .setAvailableResultKeys({ANDROID_CONTROL_AF_MODE}) .setAvailableRequestKeys( {ANDROID_CONTROL_CAPTURE_INTENT, ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_TRIGGER, ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AWB_MODE, ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_FLASH_MODE}) .setAvailableResultKeys( {ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AWB_MODE, ANDROID_FLASH_STATE, ANDROID_SENSOR_TIMESTAMP}) .setAvailableCapabilities( {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}); Loading Loading @@ -394,6 +420,11 @@ std::string VirtualCameraDevice::getCameraName() const { return std::string(kDevicePathPrefix) + std::to_string(mCameraId); } const std::vector<SupportedStreamConfiguration>& VirtualCameraDevice::getInputConfigs() const { return mSupportedInputConfigurations; } std::shared_ptr<VirtualCameraDevice> VirtualCameraDevice::sharedFromThis() { // SharedRefBase which BnCameraDevice inherits from breaks // std::enable_shared_from_this. This is recommended replacement for Loading services/camera/virtualcamera/VirtualCameraDevice.h +4 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,10 @@ class VirtualCameraDevice uint32_t getCameraId() const { return mCameraId; } const std::vector< aidl::android::companion::virtualcamera::SupportedStreamConfiguration>& getInputConfigs() const; // Maximal number of RAW streams - virtual camera doesn't support RAW streams. static const int32_t kMaxNumberOfRawStreams = 0; Loading services/camera/virtualcamera/VirtualCameraRenderThread.cc +9 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,15 @@ static constexpr std::chrono::milliseconds kAcquireFenceTimeout = 500ms; CameraMetadata createCaptureResultMetadata( const std::chrono::nanoseconds timestamp) { std::unique_ptr<CameraMetadata> metadata = MetadataBuilder().setSensorTimestamp(timestamp).build(); MetadataBuilder() .setControlAeMode(ANDROID_CONTROL_AE_MODE_ON) .setControlAePrecaptureTrigger( ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE) .setControlAfMode(ANDROID_CONTROL_AF_MODE_AUTO) .setControlAwbMode(ANDROID_CONTROL_AWB_MODE_AUTO) .setFlashState(ANDROID_FLASH_STATE_UNAVAILABLE) .setSensorTimestamp(timestamp) .build(); if (metadata == nullptr) { ALOGE("%s: Failed to build capture result metadata", __func__); return CameraMetadata(); Loading services/camera/virtualcamera/VirtualCameraSession.cc +59 −18 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <map> #include <memory> #include <mutex> #include <numeric> #include <optional> #include <tuple> #include <unordered_set> Loading @@ -44,6 +45,7 @@ #include "aidl/android/hardware/camera/device/CaptureRequest.h" #include "aidl/android/hardware/camera/device/HalStream.h" #include "aidl/android/hardware/camera/device/NotifyMsg.h" #include "aidl/android/hardware/camera/device/RequestTemplate.h" #include "aidl/android/hardware/camera/device/ShutterMsg.h" #include "aidl/android/hardware/camera/device/StreamBuffer.h" #include "aidl/android/hardware/camera/device/StreamConfiguration.h" Loading @@ -69,6 +71,7 @@ namespace virtualcamera { using ::aidl::android::companion::virtualcamera::Format; using ::aidl::android::companion::virtualcamera::IVirtualCameraCallback; using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration; using ::aidl::android::hardware::camera::common::Status; using ::aidl::android::hardware::camera::device::BufferCache; using ::aidl::android::hardware::camera::device::CameraMetadata; Loading Loading @@ -102,31 +105,59 @@ static constexpr size_t kMetadataMsgQueueSize = 0; // Maximum number of buffers to use per single stream. static constexpr size_t kMaxStreamBuffers = 2; CameraMetadata createDefaultRequestSettings(RequestTemplate type) { hardware::camera::common::V1_0::helper::CameraMetadata metadataHelper; camera_metadata_enum_android_control_capture_intent_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; camera_metadata_enum_android_control_capture_intent_t requestTemplateToIntent( const RequestTemplate type) { switch (type) { case RequestTemplate::PREVIEW: intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; break; return ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; case RequestTemplate::STILL_CAPTURE: intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; break; return ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; case RequestTemplate::VIDEO_RECORD: intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; break; return ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; case RequestTemplate::VIDEO_SNAPSHOT: intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; break; return ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; default: // Leave default. break; // Return PREVIEW by default return ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; } } int getMaxFps(const std::vector<SupportedStreamConfiguration>& configs) { return std::transform_reduce( configs.begin(), configs.end(), 0, [](const int a, const int b) { return std::max(a, b); }, [](const SupportedStreamConfiguration& config) { return config.maxFps; }); } CameraMetadata createDefaultRequestSettings( const RequestTemplate type, const std::vector<SupportedStreamConfiguration>& inputConfigs) { int maxFps = getMaxFps(inputConfigs); auto metadata = MetadataBuilder() .setControlCaptureIntent(requestTemplateToIntent(type)) .setControlMode(ANDROID_CONTROL_MODE_AUTO) .setControlAeMode(ANDROID_CONTROL_AE_MODE_ON) .setControlAeExposureCompensation(0) .setControlAeTargetFpsRange(maxFps, maxFps) .setControlAeAntibandingMode(ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO) .setControlAePrecaptureTrigger( ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE) .setControlAfTrigger(ANDROID_CONTROL_AF_TRIGGER_IDLE) .setControlAfMode(ANDROID_CONTROL_AF_MODE_AUTO) .setControlAwbMode(ANDROID_CONTROL_AWB_MODE_AUTO) .setFaceDetectMode(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) .setFlashMode(ANDROID_FLASH_MODE_OFF) .build(); if (metadata == nullptr) { ALOGE("%s: Failed to construct metadata for default request type %s", __func__, toString(type).c_str()); return CameraMetadata(); } else { ALOGV("%s: Successfully created metadata for request type %s", __func__, toString(type).c_str()); } auto metadata = MetadataBuilder().setControlCaptureIntent(intent).build(); return (metadata != nullptr) ? std::move(*metadata) : CameraMetadata(); return *metadata; } HalStream getHalStream(const Stream& stream) { Loading Loading @@ -272,12 +303,22 @@ ndk::ScopedAStatus VirtualCameraSession::constructDefaultRequestSettings( RequestTemplate in_type, CameraMetadata* _aidl_return) { ALOGV("%s: type %d", __func__, static_cast<int32_t>(in_type)); std::shared_ptr<VirtualCameraDevice> camera = mCameraDevice.lock(); if (camera == nullptr) { ALOGW( "%s: constructDefaultRequestSettings called on already unregistered " "camera", __func__); return cameraStatus(Status::CAMERA_DISCONNECTED); } switch (in_type) { case RequestTemplate::PREVIEW: case RequestTemplate::STILL_CAPTURE: case RequestTemplate::VIDEO_RECORD: case RequestTemplate::VIDEO_SNAPSHOT: { *_aidl_return = createDefaultRequestSettings(in_type); *_aidl_return = createDefaultRequestSettings(in_type, camera->getInputConfigs()); return ndk::ScopedAStatus::ok(); } case RequestTemplate::MANUAL: Loading services/camera/virtualcamera/util/MetadataBuilder.cc +119 −26 Original line number Diff line number Diff line Loading @@ -51,12 +51,17 @@ std::vector<To> convertTo(const std::vector<From>& from) { return to; } template <typename To, typename From> std::vector<To> asVectorOf(const From from) { return std::vector<To>({static_cast<To>(from)}); } } // namespace MetadataBuilder& MetadataBuilder::setSupportedHardwareLevel( camera_metadata_enum_android_info_supported_hardware_level_t hwLevel) { mEntryMap[ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL] = std::vector<uint8_t>({static_cast<uint8_t>(hwLevel)}); asVectorOf<uint8_t>(hwLevel); return *this; } Loading @@ -64,14 +69,25 @@ MetadataBuilder& MetadataBuilder::setFlashAvailable(bool flashAvailable) { const uint8_t metadataVal = flashAvailable ? ANDROID_FLASH_INFO_AVAILABLE_TRUE : ANDROID_FLASH_INFO_AVAILABLE_FALSE; mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = std::vector<uint8_t>({metadataVal}); mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = asVectorOf<uint8_t>(metadataVal); return *this; } MetadataBuilder& MetadataBuilder::setFlashState( const camera_metadata_enum_android_flash_state_t flashState) { mEntryMap[ANDROID_FLASH_STATE] = asVectorOf<uint8_t>(flashState); return *this; } MetadataBuilder& MetadataBuilder::setFlashMode( const camera_metadata_enum_android_flash_mode_t flashMode) { mEntryMap[ANDROID_FLASH_MODE] = asVectorOf<uint8_t>(flashMode); return *this; } MetadataBuilder& MetadataBuilder::setLensFacing( camera_metadata_enum_android_lens_facing lensFacing) { mEntryMap[ANDROID_LENS_FACING] = std::vector<uint8_t>({static_cast<uint8_t>(lensFacing)}); mEntryMap[ANDROID_LENS_FACING] = asVectorOf<uint8_t>(lensFacing); return *this; } Loading @@ -79,7 +95,7 @@ MetadataBuilder& MetadataBuilder::setSensorReadoutTimestamp( const camera_metadata_enum_android_sensor_readout_timestamp_t sensorReadoutTimestamp) { mEntryMap[ANDROID_SENSOR_READOUT_TIMESTAMP] = std::vector<uint8_t>({static_cast<uint8_t>(sensorReadoutTimestamp)}); asVectorOf<uint8_t>(sensorReadoutTimestamp); return *this; } Loading @@ -91,8 +107,7 @@ MetadataBuilder& MetadataBuilder::setFocalLength(float focalLength) { } MetadataBuilder& MetadataBuilder::setSensorOrientation(int32_t sensorOrientation) { mEntryMap[ANDROID_SENSOR_ORIENTATION] = std::vector<int32_t>({sensorOrientation}); mEntryMap[ANDROID_SENSOR_ORIENTATION] = asVectorOf<int32_t>(sensorOrientation); return *this; } Loading @@ -100,14 +115,13 @@ MetadataBuilder& MetadataBuilder::setSensorTimestampSource( const camera_metadata_enum_android_sensor_info_timestamp_source_t timestampSource) { mEntryMap[ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE] = std::vector<uint8_t>({static_cast<uint8_t>(timestampSource)}); asVectorOf<uint8_t>(timestampSource); return *this; } MetadataBuilder& MetadataBuilder::setSensorTimestamp( std::chrono::nanoseconds timestamp) { mEntryMap[ANDROID_SENSOR_TIMESTAMP] = std::vector<int64_t>({timestamp.count()}); mEntryMap[ANDROID_SENSOR_TIMESTAMP] = asVectorOf<int64_t>(timestamp.count()); return *this; } Loading @@ -119,6 +133,14 @@ MetadataBuilder& MetadataBuilder::setAvailableFaceDetectModes( return *this; } MetadataBuilder& MetadataBuilder::setFaceDetectMode( const camera_metadata_enum_android_statistics_face_detect_mode_t faceDetectMode) { mEntryMap[ANDROID_STATISTICS_FACE_DETECT_MODE] = asVectorOf<uint8_t>(faceDetectMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAvailableModes( const std::vector<camera_metadata_enum_android_control_mode_t>& availableModes) { Loading @@ -127,6 +149,12 @@ MetadataBuilder& MetadataBuilder::setControlAvailableModes( return *this; } MetadataBuilder& MetadataBuilder::setControlMode( const camera_metadata_enum_android_control_mode_t mode) { mEntryMap[ANDROID_CONTROL_MODE] = asVectorOf<uint8_t>(mode); return *this; } MetadataBuilder& MetadataBuilder::setControlAvailableSceneModes( const std::vector<camera_metadata_enum_android_control_scene_mode>& availableSceneModes) { Loading @@ -153,18 +181,55 @@ MetadataBuilder& MetadataBuilder::setControlAfAvailableModes( MetadataBuilder& MetadataBuilder::setControlAfMode( const camera_metadata_enum_android_control_af_mode_t mode) { mEntryMap[ANDROID_CONTROL_AF_MODE] = std::vector<uint8_t>({static_cast<uint8_t>(mode)}); mEntryMap[ANDROID_CONTROL_AF_MODE] = asVectorOf<uint8_t>(mode); return *this; } // See ANDROID_CONTROL_AF_TRIGGER_MODE in CameraMetadataTag.aidl. MetadataBuilder& MetadataBuilder::setControlAfTrigger( const camera_metadata_enum_android_control_af_trigger_t trigger) { mEntryMap[ANDROID_CONTROL_AF_TRIGGER] = asVectorOf<uint8_t>(trigger); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRanges( const std::vector<FpsRange>& fpsRanges) { std::vector<int32_t> ranges; ranges.resize(2 * fpsRanges.size()); for (const FpsRange fpsRange : fpsRanges) { ranges.push_back(fpsRange.minFps); ranges.push_back(fpsRange.maxFps); } mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] = std::move(ranges); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRange( MetadataBuilder& MetadataBuilder::setControlAeTargetFpsRange( const int32_t minFps, const int32_t maxFps) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] = mEntryMap[ANDROID_CONTROL_AE_TARGET_FPS_RANGE] = std::vector<int32_t>({minFps, maxFps}); return *this; } MetadataBuilder& MetadataBuilder::setControlAeMode( camera_metadata_enum_android_control_ae_mode_t mode) { mEntryMap[ANDROID_CONTROL_AE_MODE] = asVectorOf<uint8_t>(mode); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableModes( const std::vector<camera_metadata_enum_android_control_ae_mode_t>& modes) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_MODES] = convertTo<uint8_t>(modes); return *this; } MetadataBuilder& MetadataBuilder::setControlAePrecaptureTrigger( const camera_metadata_enum_android_control_ae_precapture_trigger_t trigger) { mEntryMap[ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER] = asVectorOf<uint8_t>(trigger); return *this; } MetadataBuilder& MetadataBuilder::setControlMaxRegions(int32_t maxAeRegions, int32_t maxAwbRegions, int32_t maxAfRegions) { Loading @@ -179,6 +244,12 @@ MetadataBuilder& MetadataBuilder::setControlAvailableAwbModes( return *this; } MetadataBuilder& MetadataBuilder::setControlAwbMode( const camera_metadata_enum_android_control_awb_mode awbMode) { mEntryMap[ANDROID_CONTROL_AWB_MODE] = asVectorOf<uint8_t>(awbMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable( const bool awbLockAvailable) { const uint8_t lockAvailable = awbLockAvailable Loading @@ -189,13 +260,29 @@ MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable( return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableAntibandingModes( const std::vector<camera_metadata_enum_android_control_ae_antibanding_mode_t>& antibandingModes) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES] = convertTo<uint8_t>(antibandingModes); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAntibandingMode( const camera_metadata_enum_android_control_ae_antibanding_mode_t antibandingMode) { mEntryMap[ANDROID_CONTROL_AE_ANTIBANDING_MODE] = asVectorOf<uint8_t>(antibandingMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAeLockAvailable( const bool aeLockAvailable) { const uint8_t lockAvailable = aeLockAvailable ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE; mEntryMap[ANDROID_CONTROL_AE_LOCK_AVAILABLE] = std::vector<uint8_t>({lockAvailable}); asVectorOf<uint8_t>(lockAvailable); return *this; } Loading Loading @@ -246,13 +333,12 @@ MetadataBuilder& MetadataBuilder::setControlAwbRegions( MetadataBuilder& MetadataBuilder::setControlCaptureIntent( const camera_metadata_enum_android_control_capture_intent_t intent) { mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] = std::vector<uint8_t>({static_cast<uint8_t>(intent)}); mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] = asVectorOf<uint8_t>(intent); return *this; } MetadataBuilder& MetadataBuilder::setMaxJpegSize(const int32_t size) { mEntryMap[ANDROID_JPEG_MAX_SIZE] = std::vector<int32_t>({size}); mEntryMap[ANDROID_JPEG_MAX_SIZE] = asVectorOf<int32_t>(size); return *this; } Loading @@ -264,7 +350,7 @@ MetadataBuilder& MetadataBuilder::setJpegAvailableThumbnailSizes( sizes.push_back(resolution.width); sizes.push_back(resolution.height); } mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = sizes; mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = std::move(sizes); return *this; } Loading @@ -278,8 +364,7 @@ MetadataBuilder& MetadataBuilder::setMaxNumberOutputStreams( MetadataBuilder& MetadataBuilder::setSyncMaxLatency( camera_metadata_enum_android_sync_max_latency latency) { mEntryMap[ANDROID_SYNC_MAX_LATENCY] = std::vector<int32_t>({static_cast<int32_t>(latency)}); mEntryMap[ANDROID_SYNC_MAX_LATENCY] = asVectorOf<int32_t>(latency); return *this; } Loading Loading @@ -319,17 +404,18 @@ MetadataBuilder& MetadataBuilder::setAvailableOutputStreamConfigurations( } mEntryMap[ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS] = metadataStreamConfigs; std::move(metadataStreamConfigs); mEntryMap[ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS] = metadataMinFrameDurations; mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] = metadataStallDurations; std::move(metadataMinFrameDurations); mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] = std::move(metadataStallDurations); return *this; } MetadataBuilder& MetadataBuilder::setAvailableMaxDigitalZoom(const float maxZoom) { mEntryMap[ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] = std::vector<float>({maxZoom}); asVectorOf<float>(maxZoom); return *this; } Loading Loading @@ -370,7 +456,14 @@ MetadataBuilder& MetadataBuilder::setControlAeCompensationRange(int32_t min, MetadataBuilder& MetadataBuilder::setControlAeCompensationStep( const camera_metadata_rational step) { mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_STEP] = std::vector<camera_metadata_rational>({step}); asVectorOf<camera_metadata_rational>(step); return *this; } MetadataBuilder& MetadataBuilder::setControlAeExposureCompensation( const int32_t exposureCompensation) { mEntryMap[ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION] = asVectorOf<int32_t>(exposureCompensation); return *this; } Loading Loading
services/camera/virtualcamera/VirtualCameraDevice.cc +36 −5 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ #include <chrono> #include <cstdint> #include <iterator> #include <numeric> #include <optional> #include <string> #include <vector> #include "VirtualCameraSession.h" #include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h" Loading Loading @@ -81,6 +83,17 @@ bool isSupportedOutputFormat(const PixelFormat pixelFormat) { kOutputFormats.end(); } std::vector<MetadataBuilder::FpsRange> fpsRangesForInputConfig( const std::vector<SupportedStreamConfiguration>& configs) { std::set<MetadataBuilder::FpsRange> availableRanges; for (const SupportedStreamConfiguration& config : configs) { availableRanges.insert({.minFps = config.maxFps, .maxFps = config.maxFps}); } return std::vector<MetadataBuilder::FpsRange>(availableRanges.begin(), availableRanges.end()); } std::optional<Resolution> getMaxResolution( const std::vector<SupportedStreamConfiguration>& configs) { auto itMax = std::max_element(configs.begin(), configs.end(), Loading Loading @@ -151,12 +164,16 @@ std::optional<CameraMetadata> initCameraCharacteristics( .setControlAfAvailableModes({ANDROID_CONTROL_AF_MODE_OFF}) .setControlAvailableSceneModes({ANDROID_CONTROL_SCENE_MODE_DISABLED}) .setControlAvailableEffects({ANDROID_CONTROL_EFFECT_MODE_OFF}) .setControlAeAvailableFpsRange(10, 30) .setControlAeAvailableModes({ANDROID_CONTROL_AE_MODE_ON}) .setControlAeAvailableAntibandingModes( {ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}) .setControlAeAvailableFpsRanges( fpsRangesForInputConfig(supportedInputConfig)) .setControlMaxRegions(0, 0, 0) .setControlAfRegions({kDefaultEmptyControlRegion}) .setControlAeRegions({kDefaultEmptyControlRegion}) .setControlAwbRegions({kDefaultEmptyControlRegion}) .setControlAeCompensationRange(0, 1) .setControlAeCompensationRange(0, 0) .setControlAeCompensationStep(camera_metadata_rational_t{0, 1}) .setControlAwbLockAvailable(false) .setControlAeLockAvailable(false) Loading @@ -170,9 +187,18 @@ std::optional<CameraMetadata> initCameraCharacteristics( VirtualCameraDevice::kMaxNumberOfProcessedStreams, VirtualCameraDevice::kMaxNumberOfStallStreams) .setSyncMaxLatency(ANDROID_SYNC_MAX_LATENCY_UNKNOWN) .setAvailableRequestKeys({}) .setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE}) .setAvailableResultKeys({ANDROID_CONTROL_AF_MODE}) .setAvailableRequestKeys( {ANDROID_CONTROL_CAPTURE_INTENT, ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_TRIGGER, ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AWB_MODE, ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_FLASH_MODE}) .setAvailableResultKeys( {ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AWB_MODE, ANDROID_FLASH_STATE, ANDROID_SENSOR_TIMESTAMP}) .setAvailableCapabilities( {ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}); Loading Loading @@ -394,6 +420,11 @@ std::string VirtualCameraDevice::getCameraName() const { return std::string(kDevicePathPrefix) + std::to_string(mCameraId); } const std::vector<SupportedStreamConfiguration>& VirtualCameraDevice::getInputConfigs() const { return mSupportedInputConfigurations; } std::shared_ptr<VirtualCameraDevice> VirtualCameraDevice::sharedFromThis() { // SharedRefBase which BnCameraDevice inherits from breaks // std::enable_shared_from_this. This is recommended replacement for Loading
services/camera/virtualcamera/VirtualCameraDevice.h +4 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,10 @@ class VirtualCameraDevice uint32_t getCameraId() const { return mCameraId; } const std::vector< aidl::android::companion::virtualcamera::SupportedStreamConfiguration>& getInputConfigs() const; // Maximal number of RAW streams - virtual camera doesn't support RAW streams. static const int32_t kMaxNumberOfRawStreams = 0; Loading
services/camera/virtualcamera/VirtualCameraRenderThread.cc +9 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,15 @@ static constexpr std::chrono::milliseconds kAcquireFenceTimeout = 500ms; CameraMetadata createCaptureResultMetadata( const std::chrono::nanoseconds timestamp) { std::unique_ptr<CameraMetadata> metadata = MetadataBuilder().setSensorTimestamp(timestamp).build(); MetadataBuilder() .setControlAeMode(ANDROID_CONTROL_AE_MODE_ON) .setControlAePrecaptureTrigger( ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE) .setControlAfMode(ANDROID_CONTROL_AF_MODE_AUTO) .setControlAwbMode(ANDROID_CONTROL_AWB_MODE_AUTO) .setFlashState(ANDROID_FLASH_STATE_UNAVAILABLE) .setSensorTimestamp(timestamp) .build(); if (metadata == nullptr) { ALOGE("%s: Failed to build capture result metadata", __func__); return CameraMetadata(); Loading
services/camera/virtualcamera/VirtualCameraSession.cc +59 −18 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <map> #include <memory> #include <mutex> #include <numeric> #include <optional> #include <tuple> #include <unordered_set> Loading @@ -44,6 +45,7 @@ #include "aidl/android/hardware/camera/device/CaptureRequest.h" #include "aidl/android/hardware/camera/device/HalStream.h" #include "aidl/android/hardware/camera/device/NotifyMsg.h" #include "aidl/android/hardware/camera/device/RequestTemplate.h" #include "aidl/android/hardware/camera/device/ShutterMsg.h" #include "aidl/android/hardware/camera/device/StreamBuffer.h" #include "aidl/android/hardware/camera/device/StreamConfiguration.h" Loading @@ -69,6 +71,7 @@ namespace virtualcamera { using ::aidl::android::companion::virtualcamera::Format; using ::aidl::android::companion::virtualcamera::IVirtualCameraCallback; using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration; using ::aidl::android::hardware::camera::common::Status; using ::aidl::android::hardware::camera::device::BufferCache; using ::aidl::android::hardware::camera::device::CameraMetadata; Loading Loading @@ -102,31 +105,59 @@ static constexpr size_t kMetadataMsgQueueSize = 0; // Maximum number of buffers to use per single stream. static constexpr size_t kMaxStreamBuffers = 2; CameraMetadata createDefaultRequestSettings(RequestTemplate type) { hardware::camera::common::V1_0::helper::CameraMetadata metadataHelper; camera_metadata_enum_android_control_capture_intent_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; camera_metadata_enum_android_control_capture_intent_t requestTemplateToIntent( const RequestTemplate type) { switch (type) { case RequestTemplate::PREVIEW: intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; break; return ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; case RequestTemplate::STILL_CAPTURE: intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; break; return ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; case RequestTemplate::VIDEO_RECORD: intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; break; return ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; case RequestTemplate::VIDEO_SNAPSHOT: intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; break; return ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; default: // Leave default. break; // Return PREVIEW by default return ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; } } int getMaxFps(const std::vector<SupportedStreamConfiguration>& configs) { return std::transform_reduce( configs.begin(), configs.end(), 0, [](const int a, const int b) { return std::max(a, b); }, [](const SupportedStreamConfiguration& config) { return config.maxFps; }); } CameraMetadata createDefaultRequestSettings( const RequestTemplate type, const std::vector<SupportedStreamConfiguration>& inputConfigs) { int maxFps = getMaxFps(inputConfigs); auto metadata = MetadataBuilder() .setControlCaptureIntent(requestTemplateToIntent(type)) .setControlMode(ANDROID_CONTROL_MODE_AUTO) .setControlAeMode(ANDROID_CONTROL_AE_MODE_ON) .setControlAeExposureCompensation(0) .setControlAeTargetFpsRange(maxFps, maxFps) .setControlAeAntibandingMode(ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO) .setControlAePrecaptureTrigger( ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE) .setControlAfTrigger(ANDROID_CONTROL_AF_TRIGGER_IDLE) .setControlAfMode(ANDROID_CONTROL_AF_MODE_AUTO) .setControlAwbMode(ANDROID_CONTROL_AWB_MODE_AUTO) .setFaceDetectMode(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) .setFlashMode(ANDROID_FLASH_MODE_OFF) .build(); if (metadata == nullptr) { ALOGE("%s: Failed to construct metadata for default request type %s", __func__, toString(type).c_str()); return CameraMetadata(); } else { ALOGV("%s: Successfully created metadata for request type %s", __func__, toString(type).c_str()); } auto metadata = MetadataBuilder().setControlCaptureIntent(intent).build(); return (metadata != nullptr) ? std::move(*metadata) : CameraMetadata(); return *metadata; } HalStream getHalStream(const Stream& stream) { Loading Loading @@ -272,12 +303,22 @@ ndk::ScopedAStatus VirtualCameraSession::constructDefaultRequestSettings( RequestTemplate in_type, CameraMetadata* _aidl_return) { ALOGV("%s: type %d", __func__, static_cast<int32_t>(in_type)); std::shared_ptr<VirtualCameraDevice> camera = mCameraDevice.lock(); if (camera == nullptr) { ALOGW( "%s: constructDefaultRequestSettings called on already unregistered " "camera", __func__); return cameraStatus(Status::CAMERA_DISCONNECTED); } switch (in_type) { case RequestTemplate::PREVIEW: case RequestTemplate::STILL_CAPTURE: case RequestTemplate::VIDEO_RECORD: case RequestTemplate::VIDEO_SNAPSHOT: { *_aidl_return = createDefaultRequestSettings(in_type); *_aidl_return = createDefaultRequestSettings(in_type, camera->getInputConfigs()); return ndk::ScopedAStatus::ok(); } case RequestTemplate::MANUAL: Loading
services/camera/virtualcamera/util/MetadataBuilder.cc +119 −26 Original line number Diff line number Diff line Loading @@ -51,12 +51,17 @@ std::vector<To> convertTo(const std::vector<From>& from) { return to; } template <typename To, typename From> std::vector<To> asVectorOf(const From from) { return std::vector<To>({static_cast<To>(from)}); } } // namespace MetadataBuilder& MetadataBuilder::setSupportedHardwareLevel( camera_metadata_enum_android_info_supported_hardware_level_t hwLevel) { mEntryMap[ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL] = std::vector<uint8_t>({static_cast<uint8_t>(hwLevel)}); asVectorOf<uint8_t>(hwLevel); return *this; } Loading @@ -64,14 +69,25 @@ MetadataBuilder& MetadataBuilder::setFlashAvailable(bool flashAvailable) { const uint8_t metadataVal = flashAvailable ? ANDROID_FLASH_INFO_AVAILABLE_TRUE : ANDROID_FLASH_INFO_AVAILABLE_FALSE; mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = std::vector<uint8_t>({metadataVal}); mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = asVectorOf<uint8_t>(metadataVal); return *this; } MetadataBuilder& MetadataBuilder::setFlashState( const camera_metadata_enum_android_flash_state_t flashState) { mEntryMap[ANDROID_FLASH_STATE] = asVectorOf<uint8_t>(flashState); return *this; } MetadataBuilder& MetadataBuilder::setFlashMode( const camera_metadata_enum_android_flash_mode_t flashMode) { mEntryMap[ANDROID_FLASH_MODE] = asVectorOf<uint8_t>(flashMode); return *this; } MetadataBuilder& MetadataBuilder::setLensFacing( camera_metadata_enum_android_lens_facing lensFacing) { mEntryMap[ANDROID_LENS_FACING] = std::vector<uint8_t>({static_cast<uint8_t>(lensFacing)}); mEntryMap[ANDROID_LENS_FACING] = asVectorOf<uint8_t>(lensFacing); return *this; } Loading @@ -79,7 +95,7 @@ MetadataBuilder& MetadataBuilder::setSensorReadoutTimestamp( const camera_metadata_enum_android_sensor_readout_timestamp_t sensorReadoutTimestamp) { mEntryMap[ANDROID_SENSOR_READOUT_TIMESTAMP] = std::vector<uint8_t>({static_cast<uint8_t>(sensorReadoutTimestamp)}); asVectorOf<uint8_t>(sensorReadoutTimestamp); return *this; } Loading @@ -91,8 +107,7 @@ MetadataBuilder& MetadataBuilder::setFocalLength(float focalLength) { } MetadataBuilder& MetadataBuilder::setSensorOrientation(int32_t sensorOrientation) { mEntryMap[ANDROID_SENSOR_ORIENTATION] = std::vector<int32_t>({sensorOrientation}); mEntryMap[ANDROID_SENSOR_ORIENTATION] = asVectorOf<int32_t>(sensorOrientation); return *this; } Loading @@ -100,14 +115,13 @@ MetadataBuilder& MetadataBuilder::setSensorTimestampSource( const camera_metadata_enum_android_sensor_info_timestamp_source_t timestampSource) { mEntryMap[ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE] = std::vector<uint8_t>({static_cast<uint8_t>(timestampSource)}); asVectorOf<uint8_t>(timestampSource); return *this; } MetadataBuilder& MetadataBuilder::setSensorTimestamp( std::chrono::nanoseconds timestamp) { mEntryMap[ANDROID_SENSOR_TIMESTAMP] = std::vector<int64_t>({timestamp.count()}); mEntryMap[ANDROID_SENSOR_TIMESTAMP] = asVectorOf<int64_t>(timestamp.count()); return *this; } Loading @@ -119,6 +133,14 @@ MetadataBuilder& MetadataBuilder::setAvailableFaceDetectModes( return *this; } MetadataBuilder& MetadataBuilder::setFaceDetectMode( const camera_metadata_enum_android_statistics_face_detect_mode_t faceDetectMode) { mEntryMap[ANDROID_STATISTICS_FACE_DETECT_MODE] = asVectorOf<uint8_t>(faceDetectMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAvailableModes( const std::vector<camera_metadata_enum_android_control_mode_t>& availableModes) { Loading @@ -127,6 +149,12 @@ MetadataBuilder& MetadataBuilder::setControlAvailableModes( return *this; } MetadataBuilder& MetadataBuilder::setControlMode( const camera_metadata_enum_android_control_mode_t mode) { mEntryMap[ANDROID_CONTROL_MODE] = asVectorOf<uint8_t>(mode); return *this; } MetadataBuilder& MetadataBuilder::setControlAvailableSceneModes( const std::vector<camera_metadata_enum_android_control_scene_mode>& availableSceneModes) { Loading @@ -153,18 +181,55 @@ MetadataBuilder& MetadataBuilder::setControlAfAvailableModes( MetadataBuilder& MetadataBuilder::setControlAfMode( const camera_metadata_enum_android_control_af_mode_t mode) { mEntryMap[ANDROID_CONTROL_AF_MODE] = std::vector<uint8_t>({static_cast<uint8_t>(mode)}); mEntryMap[ANDROID_CONTROL_AF_MODE] = asVectorOf<uint8_t>(mode); return *this; } // See ANDROID_CONTROL_AF_TRIGGER_MODE in CameraMetadataTag.aidl. MetadataBuilder& MetadataBuilder::setControlAfTrigger( const camera_metadata_enum_android_control_af_trigger_t trigger) { mEntryMap[ANDROID_CONTROL_AF_TRIGGER] = asVectorOf<uint8_t>(trigger); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRanges( const std::vector<FpsRange>& fpsRanges) { std::vector<int32_t> ranges; ranges.resize(2 * fpsRanges.size()); for (const FpsRange fpsRange : fpsRanges) { ranges.push_back(fpsRange.minFps); ranges.push_back(fpsRange.maxFps); } mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] = std::move(ranges); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRange( MetadataBuilder& MetadataBuilder::setControlAeTargetFpsRange( const int32_t minFps, const int32_t maxFps) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] = mEntryMap[ANDROID_CONTROL_AE_TARGET_FPS_RANGE] = std::vector<int32_t>({minFps, maxFps}); return *this; } MetadataBuilder& MetadataBuilder::setControlAeMode( camera_metadata_enum_android_control_ae_mode_t mode) { mEntryMap[ANDROID_CONTROL_AE_MODE] = asVectorOf<uint8_t>(mode); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableModes( const std::vector<camera_metadata_enum_android_control_ae_mode_t>& modes) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_MODES] = convertTo<uint8_t>(modes); return *this; } MetadataBuilder& MetadataBuilder::setControlAePrecaptureTrigger( const camera_metadata_enum_android_control_ae_precapture_trigger_t trigger) { mEntryMap[ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER] = asVectorOf<uint8_t>(trigger); return *this; } MetadataBuilder& MetadataBuilder::setControlMaxRegions(int32_t maxAeRegions, int32_t maxAwbRegions, int32_t maxAfRegions) { Loading @@ -179,6 +244,12 @@ MetadataBuilder& MetadataBuilder::setControlAvailableAwbModes( return *this; } MetadataBuilder& MetadataBuilder::setControlAwbMode( const camera_metadata_enum_android_control_awb_mode awbMode) { mEntryMap[ANDROID_CONTROL_AWB_MODE] = asVectorOf<uint8_t>(awbMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable( const bool awbLockAvailable) { const uint8_t lockAvailable = awbLockAvailable Loading @@ -189,13 +260,29 @@ MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable( return *this; } MetadataBuilder& MetadataBuilder::setControlAeAvailableAntibandingModes( const std::vector<camera_metadata_enum_android_control_ae_antibanding_mode_t>& antibandingModes) { mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES] = convertTo<uint8_t>(antibandingModes); return *this; } MetadataBuilder& MetadataBuilder::setControlAeAntibandingMode( const camera_metadata_enum_android_control_ae_antibanding_mode_t antibandingMode) { mEntryMap[ANDROID_CONTROL_AE_ANTIBANDING_MODE] = asVectorOf<uint8_t>(antibandingMode); return *this; } MetadataBuilder& MetadataBuilder::setControlAeLockAvailable( const bool aeLockAvailable) { const uint8_t lockAvailable = aeLockAvailable ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE; mEntryMap[ANDROID_CONTROL_AE_LOCK_AVAILABLE] = std::vector<uint8_t>({lockAvailable}); asVectorOf<uint8_t>(lockAvailable); return *this; } Loading Loading @@ -246,13 +333,12 @@ MetadataBuilder& MetadataBuilder::setControlAwbRegions( MetadataBuilder& MetadataBuilder::setControlCaptureIntent( const camera_metadata_enum_android_control_capture_intent_t intent) { mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] = std::vector<uint8_t>({static_cast<uint8_t>(intent)}); mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] = asVectorOf<uint8_t>(intent); return *this; } MetadataBuilder& MetadataBuilder::setMaxJpegSize(const int32_t size) { mEntryMap[ANDROID_JPEG_MAX_SIZE] = std::vector<int32_t>({size}); mEntryMap[ANDROID_JPEG_MAX_SIZE] = asVectorOf<int32_t>(size); return *this; } Loading @@ -264,7 +350,7 @@ MetadataBuilder& MetadataBuilder::setJpegAvailableThumbnailSizes( sizes.push_back(resolution.width); sizes.push_back(resolution.height); } mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = sizes; mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = std::move(sizes); return *this; } Loading @@ -278,8 +364,7 @@ MetadataBuilder& MetadataBuilder::setMaxNumberOutputStreams( MetadataBuilder& MetadataBuilder::setSyncMaxLatency( camera_metadata_enum_android_sync_max_latency latency) { mEntryMap[ANDROID_SYNC_MAX_LATENCY] = std::vector<int32_t>({static_cast<int32_t>(latency)}); mEntryMap[ANDROID_SYNC_MAX_LATENCY] = asVectorOf<int32_t>(latency); return *this; } Loading Loading @@ -319,17 +404,18 @@ MetadataBuilder& MetadataBuilder::setAvailableOutputStreamConfigurations( } mEntryMap[ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS] = metadataStreamConfigs; std::move(metadataStreamConfigs); mEntryMap[ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS] = metadataMinFrameDurations; mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] = metadataStallDurations; std::move(metadataMinFrameDurations); mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] = std::move(metadataStallDurations); return *this; } MetadataBuilder& MetadataBuilder::setAvailableMaxDigitalZoom(const float maxZoom) { mEntryMap[ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] = std::vector<float>({maxZoom}); asVectorOf<float>(maxZoom); return *this; } Loading Loading @@ -370,7 +456,14 @@ MetadataBuilder& MetadataBuilder::setControlAeCompensationRange(int32_t min, MetadataBuilder& MetadataBuilder::setControlAeCompensationStep( const camera_metadata_rational step) { mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_STEP] = std::vector<camera_metadata_rational>({step}); asVectorOf<camera_metadata_rational>(step); return *this; } MetadataBuilder& MetadataBuilder::setControlAeExposureCompensation( const int32_t exposureCompensation) { mEntryMap[ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION] = asVectorOf<int32_t>(exposureCompensation); return *this; } Loading