summaryrefslogtreecommitdiff
path: root/aiq/aiq_results.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'aiq/aiq_results.cpp')
-rw-r--r--aiq/aiq_results.cpp297
1 files changed, 297 insertions, 0 deletions
diff --git a/aiq/aiq_results.cpp b/aiq/aiq_results.cpp
new file mode 100644
index 0000000..9dda17c
--- /dev/null
+++ b/aiq/aiq_results.cpp
@@ -0,0 +1,297 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * aiq_results.cpp - Intel IA Imaging library C++ wrapper
+ *
+ * AIQ results container, capable of depth copies and assignments
+ * of the aiq result structures.
+ */
+
+#include "aiq/aiq_results.h"
+
+#include <algorithm>
+
+#include <libcamera/base/log.h>
+
+/* Macros used by imported code */
+#define STDCOPY(dst, src, size) std::copy((src), ((src) + (size)), (dst))
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(AIQResults)
+
+namespace ipa::ipu3::aiq {
+
+AiqResults::AiqResults()
+{
+ /* Initialise AE */
+ ae_.exposures = &aeExposureResult_;
+ ae_.exposures->exposure = &aeExposureParameters_;
+ ae_.exposures->sensor_exposure = &aeSensorParaemeters_;
+ ae_.weight_grid = &aeWeightGrid_;
+ ae_.weight_grid->weights = aeWeights_;
+ ae_.flashes = aeFlashes_;
+
+ /* GBCE */
+ gbce_.r_gamma_lut = RGammaLut_;
+ gbce_.g_gamma_lut = GGammaLut_;
+ gbce_.b_gamma_lut = BGammaLut_;
+ gbce_.gamma_lut_size = MAX_GAMMA_LUT_SIZE;
+ gbce_.tone_map_lut = toneMapLut_;
+ gbce_.tone_map_lut_size = MAX_NUM_TONE_MAP_LUTS;
+
+ /* Initialise afBracket */
+ afBracket_.distances_bracketing = &distanceBracketing_;
+ afBracket_.lens_positions_bracketing = &lensPosBracketing_;
+
+ /* Initialise PA */
+ pa_.preferred_acm = &prefAcm_;
+ pa_.preferred_acm->hue_of_sectors = &hueOfSectors_;
+ pa_.preferred_acm->advanced_color_conversion_matrices =
+ &advancedColorConversionMatrices_;
+ pa_.ir_weight = &irWeight_;
+ pa_.ir_weight->ir_weight_grid_R = &irWeightGridR_;
+ pa_.ir_weight->ir_weight_grid_G = &irWeightGridG_;
+ pa_.ir_weight->ir_weight_grid_B = &irWeightGridB_;
+
+ /* Initialise SA */
+ channelGr_.reserve(DEFAULT_LSC_SIZE);
+ channelGb_.reserve(DEFAULT_LSC_SIZE);
+ channelR_.reserve(DEFAULT_LSC_SIZE);
+ channelB_.reserve(DEFAULT_LSC_SIZE);
+ sa_.channel_gr = channelGr_.data();
+ sa_.channel_gb = channelGb_.data();
+ sa_.channel_r = channelR_.data();
+ sa_.channel_b = channelB_.data();
+}
+
+void AiqResults::setAe(ia_aiq_ae_results *ae)
+{
+ /* Todo: Potentially Requires copying
+ * ia_aiq_aperture_control *aperture_control;
+ */
+
+ ASSERT(ae);
+
+ if (!ae) {
+ LOG(AIQResults, Error) << "Invalid AE argument";
+ return;
+ }
+
+ ae_.lux_level_estimate = ae->lux_level_estimate;
+ ae_.flicker_reduction_mode = ae->flicker_reduction_mode;
+ ae_.multiframe = ae->multiframe;
+ ae_.num_flashes = ae->num_flashes;
+ ae_.num_exposures = ae->num_exposures;
+
+ ae_.exposures->converged = ae->exposures->converged;
+ ae_.exposures->distance_from_convergence = ae->exposures->distance_from_convergence;
+ ae_.exposures->exposure_index = ae->exposures->exposure_index;
+
+ if (ae_.exposures->exposure && ae->exposures->exposure) {
+ *ae_.exposures->exposure = *ae->exposures->exposure;
+ } else {
+ LOG(AIQResults, Error) << "Not copying AE Exposure";
+ }
+
+ if (ae_.exposures->sensor_exposure && ae->exposures->sensor_exposure) {
+ *ae_.exposures->sensor_exposure = *ae->exposures->sensor_exposure;
+ } else {
+ LOG(AIQResults, Error) << "Not copying AE Sensor Exposure";
+ }
+
+ // Copy weight grid
+ if (ae_.weight_grid && ae->weight_grid &&
+ ae_.weight_grid->weights && ae->weight_grid->weights) {
+ ae_.weight_grid->width = ae->weight_grid->width;
+ ae_.weight_grid->height = ae->weight_grid->height;
+
+ unsigned int gridElements = ae->weight_grid->width *
+ ae->weight_grid->height;
+ gridElements = std::clamp<unsigned int>(gridElements, 1, MAX_AE_GRID_SIZE);
+
+ STDCOPY(ae_.weight_grid->weights,
+ ae->weight_grid->weights,
+ gridElements * sizeof(char));
+ } else {
+ LOG(AIQResults, Error) << "Not copying AE Weight Grids";
+ }
+
+ // Copy the flash info structure
+ if (ae_.flashes && ae->flashes) {
+ STDCOPY((int8_t *)ae_.flashes, (int8_t *)ae->flashes,
+ NUM_FLASH_LEDS * sizeof(ia_aiq_flash_parameters));
+ } else {
+ LOG(AIQResults, Error) << "Not copying AE Flashes";
+ }
+}
+
+void AiqResults::setAf(ia_aiq_af_results *af)
+{
+ ASSERT(af);
+
+ af_.status = af->status;
+ af_.current_focus_distance = af->current_focus_distance;
+ af_.next_lens_position = af->next_lens_position;
+ af_.lens_driver_action = af->lens_driver_action;
+ af_.use_af_assist = af->use_af_assist;
+ af_.final_lens_position_reached = af->final_lens_position_reached;
+}
+
+void AiqResults::setAfBracket(ia_aiq_af_bracket_results *afBracket)
+{
+ ASSERT(afBracket);
+
+ /* todo:
+ * Distances Bracketing and lens_positions_bracketing are arrays,
+ * but it's not clear what size they are.
+ */
+ afBracket_.distances_bracketing = afBracket->distances_bracketing;
+ afBracket_.lens_positions_bracketing = afBracket->lens_positions_bracketing;
+}
+
+void AiqResults::setAwb(ia_aiq_awb_results *awb)
+{
+ ASSERT(awb);
+
+ awb_.accurate_r_per_g = awb->accurate_r_per_g;
+ awb_.accurate_b_per_g = awb->accurate_b_per_g;
+ awb_.final_r_per_g = awb->final_r_per_g;
+ awb_.final_b_per_g = awb->final_b_per_g;
+ awb_.cct_estimate = awb->cct_estimate;
+ awb_.distance_from_convergence = awb->distance_from_convergence;
+}
+
+void AiqResults::setGbce(ia_aiq_gbce_results *gbce)
+{
+ ASSERT(gbce);
+
+ if (gbce->gamma_lut_size > 0) {
+ ASSERT(gbce->gamma_lut_size <= MAX_GAMMA_LUT_SIZE);
+
+ gbce_.gamma_lut_size = gbce->gamma_lut_size;
+
+ STDCOPY((int8_t *)gbce_.r_gamma_lut, (int8_t *)gbce->r_gamma_lut,
+ gbce->gamma_lut_size * sizeof(float));
+ STDCOPY((int8_t *)gbce_.b_gamma_lut, (int8_t *)gbce->b_gamma_lut,
+ gbce->gamma_lut_size * sizeof(float));
+ STDCOPY((int8_t *)gbce_.g_gamma_lut, (int8_t *)gbce->g_gamma_lut,
+ gbce->gamma_lut_size * sizeof(float));
+ } else {
+ LOG(AIQResults, Error) << "Not copying Gamma LUT channels";
+ }
+
+ if (gbce->tone_map_lut_size > 0) {
+ gbce_.tone_map_lut_size = gbce->tone_map_lut_size;
+ STDCOPY((int8_t *)gbce_.tone_map_lut, (int8_t *)gbce->tone_map_lut,
+ gbce->tone_map_lut_size * sizeof(float));
+ } else {
+ LOG(AIQResults, Error) << "Not copying Tone Mapping Gain LUT";
+ }
+}
+
+void AiqResults::setDetectedSceneMode(ia_aiq_scene_mode dsm)
+{
+ detectedSceneMode_ = dsm;
+}
+
+void AiqResults::setPa(ia_aiq_pa_results *pa)
+{
+ ASSERT(pa);
+
+ STDCOPY(&pa_.color_conversion_matrix[0][0], &pa->color_conversion_matrix[0][0],
+ MAX_COLOR_CONVERSION_MATRIX * MAX_COLOR_CONVERSION_MATRIX *
+ sizeof(pa->color_conversion_matrix[0][0]));
+
+ if (pa_.preferred_acm && pa->preferred_acm) {
+ pa_.preferred_acm->sector_count = pa->preferred_acm->sector_count;
+
+ STDCOPY(pa_.preferred_acm->hue_of_sectors,
+ pa->preferred_acm->hue_of_sectors,
+ sizeof(*pa->preferred_acm->hue_of_sectors) * pa->preferred_acm->sector_count);
+
+ STDCOPY(pa_.preferred_acm->advanced_color_conversion_matrices[0][0],
+ pa->preferred_acm->advanced_color_conversion_matrices[0][0],
+ sizeof(*pa->preferred_acm->advanced_color_conversion_matrices) * pa->preferred_acm->sector_count);
+ } else {
+ LOG(AIQResults, Error) << "Not copying PA hue of sectors";
+ }
+
+ if (pa_.ir_weight && pa->ir_weight) {
+ pa_.ir_weight->height = pa->ir_weight->height;
+ pa_.ir_weight->width = pa->ir_weight->width;
+
+ STDCOPY(pa_.ir_weight->ir_weight_grid_R,
+ pa->ir_weight->ir_weight_grid_R,
+ sizeof(*pa->ir_weight->ir_weight_grid_R) * pa->ir_weight->height * pa->ir_weight->width);
+
+ STDCOPY(pa_.ir_weight->ir_weight_grid_G,
+ pa->ir_weight->ir_weight_grid_G,
+ sizeof(*pa->ir_weight->ir_weight_grid_G) * pa->ir_weight->height * pa->ir_weight->width);
+
+ STDCOPY(pa_.ir_weight->ir_weight_grid_B,
+ pa->ir_weight->ir_weight_grid_B,
+ sizeof(*pa->ir_weight->ir_weight_grid_B) * pa->ir_weight->height * pa->ir_weight->width);
+ } else {
+ LOG(AIQResults, Error) << "Not copying IR weight";
+ }
+
+ pa_.black_level = pa->black_level;
+ pa_.color_gains = pa->color_gains;
+ pa_.linearization = pa->linearization;
+ pa_.saturation_factor = pa->saturation_factor;
+ pa_.brightness_level = pa->brightness_level;
+}
+
+void AiqResults::setSa(ia_aiq_sa_results *sa)
+{
+ ASSERT(sa && sa->channel_r && sa->channel_gr &&
+ sa->channel_gb && sa->channel_b);
+
+ sa_.width = sa->width;
+ sa_.height = sa->height;
+ sa_.lsc_update = sa->lsc_update;
+
+ /* Check against one of the vectors but resize applicable to all. */
+ if (channelGr_.size() < (sa_.width * sa_.height)) {
+ int lscNewSize = sa_.width * sa_.height;
+ channelGr_.resize(lscNewSize);
+ channelGb_.resize(lscNewSize);
+ channelR_.resize(lscNewSize);
+ channelB_.resize(lscNewSize);
+
+ /* Update the SA data pointers to new memory locations. */
+ sa_.channel_gr = channelGr_.data();
+ sa_.channel_gb = channelGb_.data();
+ sa_.channel_r = channelR_.data();
+ sa_.channel_b = channelB_.data();
+ }
+
+ if (sa->lsc_update) {
+ uint32_t memCopySize = sa->width * sa->height * sizeof(float);
+
+ STDCOPY((int8_t *)sa_.channel_gr, (int8_t *)sa->channel_gb,
+ memCopySize);
+ STDCOPY((int8_t *)sa_.channel_gb, (int8_t *)sa->channel_gr,
+ memCopySize);
+ STDCOPY((int8_t *)sa_.channel_r, (int8_t *)sa->channel_r,
+ memCopySize);
+ STDCOPY((int8_t *)sa_.channel_b, (int8_t *)sa->channel_b,
+ memCopySize);
+ } else {
+ LOG(AIQResults, Error) << "Not copying LSC tables.";
+ }
+
+ STDCOPY(&sa_.light_source[0],
+ &sa->light_source[0],
+ CMC_NUM_LIGHTSOURCES * sizeof(sa->light_source[0]));
+ sa_.scene_difficulty = sa->scene_difficulty;
+ sa_.num_patches = sa->num_patches;
+ sa_.covered_area = sa->covered_area;
+ sa_.frame_params = sa->frame_params;
+}
+
+} /* namespace ipa::ipu3::aiq */
+
+} /* namespace libcamera */