diff options
author | Umang Jain <umang.jain@ideasonboard.com> | 2021-05-10 17:27:04 +0530 |
---|---|---|
committer | Umang Jain <umang.jain@ideasonboard.com> | 2021-06-28 14:12:06 +0530 |
commit | 2ed7faa7cb7e7b164a75bc249fa24bde1006db38 (patch) | |
tree | f759b4a3ce93a229968c98c5f54c477b7f46ec52 /aiq/aiq_results.cpp | |
parent | 249b42db7cd39d7ec20094242cd7a8c41ea3b442 (diff) |
aiq: Provide managed AIQ Results structures
The AIQ results structures returned from the AIQ library has many
complex and deeply nested data structures which must be copied out.
This class handles the correct initialisation of a full set of AIQ
results, along with the allocations required, and the ability to copy
data into those structures correctly.
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'aiq/aiq_results.cpp')
-rw-r--r-- | aiq/aiq_results.cpp | 297 |
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 */ |