/* SPDX-License-Identifier: Apache-2.0 */ /* * Copyright (C) 2021, Google Inc. * * aiq_input_parameters.cpp - Intel IA Imaging library C++ wrapper * * AIQ Input Parameters container, manages the parameters and state for each * algorithm. */ #include "aiq/aiq_input_parameters.h" #include #include namespace libcamera { LOG_DEFINE_CATEGORY(AIQInputParameters) namespace ipa::ipu3::aiq { void AiqInputParameters::init() { aeInputParams = {}; afParams = {}; afBracketParams = {}; awbParams = {}; gbceParams = {}; paParams = {}; saParams = {}; sensorDescriptor = {}; exposureWindow = {}; exposureCoordinate = {}; aeFeatures = {}; aeManualLimits = {}; manualFocusParams = {}; focusRect = {}; manualCctRange = {}; manualWhiteCoordinate = {}; awbResults = {}; colorGains = {}; exposureParams = {}; sensorFrameParams = {}; aeLock = false; awbLock = false; blackLevelLock = false; /* \todo: afRegion.reset(); */ reset(); } void AiqInputParameters::reset() { aeInputParams.sensor_descriptor = &sensorDescriptor; aeInputParams.exposure_window = &exposureWindow; aeInputParams.exposure_coordinate = &exposureCoordinate; aeInputParams.aec_features = &aeFeatures; aeInputParams.manual_limits = &aeManualLimits; aeInputParams.manual_exposure_time_us = &manual_exposure_time_us[0]; aeInputParams.manual_analog_gain = &manual_analog_gain[0]; aeInputParams.manual_iso = &manual_iso[0]; aeInputParams.manual_convergence_time = -1; afParams.focus_rect = &focusRect; afParams.manual_focus_parameters = &manualFocusParams; awbParams.manual_cct_range = &manualCctRange; awbParams.manual_white_coordinate = &manualWhiteCoordinate; paParams.awb_results = &awbResults; paParams.color_gains = &colorGains; paParams.exposure_params = &exposureParams; saParams.awb_results = &awbResults; saParams.sensor_frame_params = &sensorFrameParams; } int AiqInputParameters::configure(const IPAConfigInfo &configInfo) { sensorDescriptor.pixel_clock_freq_mhz = configInfo.sensorInfo.pixelRate / 1000000; sensorDescriptor.pixel_periods_per_line = configInfo.sensorInfo.minLineLength; sensorDescriptor.line_periods_per_field = configInfo.sensorInfo.minFrameLength; sensorDescriptor.line_periods_vertical_blanking = 106; /* default */ //INFO: fine integration is not supported by v4l2 sensorDescriptor.fine_integration_time_min = 0; sensorDescriptor.fine_integration_time_max_margin = sensorDescriptor.pixel_periods_per_line; sensorDescriptor.coarse_integration_time_min = 4; /* min VBLANK */ /* Guess from hal-configs-nautilus/files/camera3_profiles.xml#263 */ sensorDescriptor.coarse_integration_time_max_margin = 10; sensorFrameParams.horizontal_crop_offset = 0; sensorFrameParams.vertical_crop_offset = 0; sensorFrameParams.cropped_image_width = configInfo.sensorInfo.analogCrop.width; sensorFrameParams.cropped_image_height = configInfo.sensorInfo.analogCrop.height; sensorFrameParams.horizontal_scaling_numerator = 1; sensorFrameParams.horizontal_scaling_denominator = 1; sensorFrameParams.vertical_scaling_numerator = 1; sensorFrameParams.vertical_scaling_denominator = 1; return 0; } AiqInputParameters &AiqInputParameters::operator=(const AiqInputParameters &other) { if (this == &other) return *this; memcpy(this, &other, sizeof(AiqInputParameters)); reset(); /* Exposure coordinate is nullptr in other than SPOT mode. */ if (other.aeInputParams.exposure_coordinate == nullptr) aeInputParams.exposure_coordinate = nullptr; /* focus_rect and manual_focus_parameters may be nullptr */ if (other.afParams.focus_rect == nullptr) afParams.focus_rect = nullptr; if (other.afParams.manual_focus_parameters == nullptr) afParams.manual_focus_parameters = nullptr; /* manual_cct_range and manual_white_coordinate may be nullptr */ if (other.awbParams.manual_cct_range == nullptr) awbParams.manual_cct_range = nullptr; if (other.awbParams.manual_white_coordinate == nullptr) awbParams.manual_white_coordinate = nullptr; return *this; } void AiqInputParameters::setAeAwbAfDefaults() { /* Ae Params */ aeInputParams.num_exposures = NUM_EXPOSURES; aeInputParams.frame_use = ia_aiq_frame_use_preview; aeInputParams.flash_mode = ia_aiq_flash_mode_off; aeInputParams.operation_mode = ia_aiq_ae_operation_mode_automatic; aeInputParams.metering_mode = ia_aiq_ae_metering_mode_evaluative; aeInputParams.priority_mode = ia_aiq_ae_priority_mode_normal; aeInputParams.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_off; aeInputParams.exposure_window = nullptr; aeInputParams.exposure_coordinate = nullptr; aeInputParams.ev_shift = 0; aeInputParams.sensor_descriptor = &sensorDescriptor; aeInputParams.manual_exposure_time_us = nullptr; aeInputParams.manual_analog_gain = nullptr; aeInputParams.manual_iso = nullptr; aeInputParams.aec_features = nullptr; aeInputParams.manual_limits = nullptr; aeInputParams.manual_aperture_fn = -1; aeInputParams.manual_dc_iris_command = ia_aiq_aperture_control_dc_iris_auto; aeInputParams.exposure_distribution_priority = ia_aiq_ae_exposure_distribution_shutter; aeInputParams.manual_convergence_time = -1; /* AWB Params */ awbParams.frame_use = ia_aiq_frame_use_preview; awbParams.scene_mode = ia_aiq_awb_operation_mode_auto; awbParams.manual_convergence_time = -1.0; awbParams.manual_cct_range = nullptr; awbParams.manual_white_coordinate = nullptr; /* AF Params */ afParams = { ia_aiq_frame_use_preview, 0, 1500, ia_aiq_af_operation_mode_auto, ia_aiq_af_range_normal, ia_aiq_af_metering_mode_auto, ia_aiq_flash_mode_off, &focusRect, &manualFocusParams, false }; /* GBCE Params */ gbceParams.gbce_level = ia_aiq_gbce_level_use_tuning; gbceParams.tone_map_level = ia_aiq_tone_map_level_use_tuning; gbceParams.frame_use = ia_aiq_frame_use_preview; gbceParams.ev_shift = 0; /* SA Params */ saParams.frame_use = ia_aiq_frame_use_preview; } } /* namespace ipa::ipu3::aiq */ } /* namespace libcamera */