diff options
Diffstat (limited to 'aic')
-rw-r--r-- | aic/aic.cpp | 173 | ||||
-rw-r--r-- | aic/aic.h | 57 | ||||
-rw-r--r-- | aic/meson.build | 1 |
3 files changed, 231 insertions, 0 deletions
diff --git a/aic/aic.cpp b/aic/aic.cpp new file mode 100644 index 0000000..0184b85 --- /dev/null +++ b/aic/aic.cpp @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright (C) 2021, Google Inc. + * + * aic.cpp - Intel IA Imaging library C++ wrapper + * + * Automatic IPU Configuration + */ + +#include <ia_imaging/ia_cmc_parser.h> + +#include "aic.h" + +#include <libcamera/base/log.h> + +#include "binary_data.h" +#include "parameter_encoder.h" + +#define CLEAR(x) memset(&(x), 0, sizeof(x)) +#define ALIGN128(x) (((x) + 127) & ~127) + +namespace libcamera { + +LOG_DEFINE_CATEGORY(AIC) + +namespace ipa::ipu3::aic { + +/* + * Only a Single Pipeline instance of the AIC is currently supported. + * The CrOS implementation defines a set of AIC to run for both STILL and VIDEO + * allowing improved perfomance on preview streams while taking an image + * capture. + */ + +AIC::~AIC() +{ + if (iaCmc_) + ia_cmc_parser_deinit(iaCmc_); +} + +int AIC::init(BinaryData &aiqb) +{ + LOG(AIC, Debug) << "Initialising IA AIC Wrapper"; + + pipe_ = std::make_unique<IPU3ISPPipe>(); + + CLEAR(runtimeOutFrameParams_); + CLEAR(runtimeResCfgParams_); + CLEAR(runtimeInFrameParams_); + CLEAR(runtimeParamsRec_); + CLEAR(runtimeParams_); + + runtimeParams_.output_frame_params = &runtimeOutFrameParams_; + runtimeParams_.frame_resolution_parameters = &runtimeResCfgParams_; + runtimeParams_.input_frame_params = &runtimeInFrameParams_; + runtimeParams_.focus_rect = &runtimeParamsRec_; + + /* + * \todo: Both the AIC and the AIQ use the iaCmc_. + * Can this be the same instance or do they need their own instances? + */ + iaCmc_ = ia_cmc_parser_init(aiqb.data()); + if (iaCmc_ == nullptr) { + LOG(AIC, Error) << "Failed to initialise CMC Parser"; + return -EINVAL; + } + + /* \todo: Initialise the mRuntimeParams with ia_aiq_frame_params before + * constructing the KBL_AIC. + * In CrOS, GraphConfig::getSensorFrameParams provides all these + * details. Start looking from ParameterWorker::configure() + */ + ISPPipe *pipe = static_cast<ISPPipe *>(pipe_.get()); + skyCam_ = std::make_unique<KBL_AIC>(&pipe, 1, iaCmc_, aiqb.data(), + runtimeParams_, 0, 0); + + return 0; +} + +int AIC::configure(const struct IPAConfigInfo &configInfo) +{ + LOG(AIC, Debug) << "IA AIC configure(): " + << " bds: " << configInfo.bdsOutputSize.width << "x" << configInfo.bdsOutputSize.height + << " ifSize: " << configInfo.iif.width << "x" << configInfo.iif.height + << " cropRegion: " << configInfo.sensorInfo.analogCrop.width + << "x" << configInfo.sensorInfo.analogCrop.height; + + //Fill AIC input frame params + runtimeParams_.frame_use = ia_aiq_frame_use_still; + runtimeParams_.mode_index = AIC_MODE_STILL; + runtimeInFrameParams_.sensor_frame_params.horizontal_crop_offset = 0; + runtimeInFrameParams_.sensor_frame_params.vertical_crop_offset = 0; + runtimeInFrameParams_.sensor_frame_params.cropped_image_width = configInfo.sensorInfo.analogCrop.width; + runtimeInFrameParams_.sensor_frame_params.cropped_image_height = configInfo.sensorInfo.analogCrop.height; + runtimeInFrameParams_.sensor_frame_params.horizontal_scaling_numerator = 1; + runtimeInFrameParams_.sensor_frame_params.horizontal_scaling_denominator = 1; + runtimeInFrameParams_.sensor_frame_params.vertical_scaling_numerator = 1; + runtimeInFrameParams_.sensor_frame_params.vertical_scaling_denominator = 1; + runtimeInFrameParams_.fix_flip_x = 0; + runtimeInFrameParams_.fix_flip_y = 0; + + runtimeOutFrameParams_.width = configInfo.sensorInfo.analogCrop.width; + runtimeOutFrameParams_.height = configInfo.sensorInfo.analogCrop.height; + + runtimeResCfgParams_.BDSin_img_width = configInfo.iif.width; + runtimeResCfgParams_.BDSin_img_height = configInfo.iif.height; + runtimeResCfgParams_.BDSout_img_width = configInfo.bdsOutputSize.width; + runtimeResCfgParams_.BDSout_img_height = configInfo.bdsOutputSize.height; + + runtimeResCfgParams_.horizontal_IF_crop = + (configInfo.sensorInfo.outputSize.width - configInfo.iif.width) / 2; + runtimeResCfgParams_.vertical_IF_crop = + (configInfo.sensorInfo.outputSize.height - configInfo.iif.height) / 2; + runtimeResCfgParams_.BDS_horizontal_padding = + static_cast<uint16_t>(ALIGN128(configInfo.bdsOutputSize.width) - configInfo.bdsOutputSize.width); + + return 0; +} + +void AIC::reset() +{ +} + +int AIC::run(ipu3_uapi_params *params) +{ + skyCam_->Run(&runtimeParams_, 1); + + /* IPU3 firmware specific encoding for ISP controls. */ + ParameterEncoder::encode(GetAicConfig(), params); + + return 0; +} + +std::string AIC::version() +{ + if (skyCam_) + return skyCam_->GetAICVersion(); + else + return ""; +} + +aic_config_t *AIC::GetAicConfig() +{ + //pipe_->dump(); + return pipe_->GetAicConfig(); +} + +void AIC::updateRuntimeParams(aiq::AiqResults &results) +{ + runtimeParams_.pa_results = results.pa(); + runtimeParams_.sa_results = results.sa(); + + const ia_aiq_ae_results *ae = results.ae(); + runtimeParams_.exposure_results = ae->exposures->exposure; + runtimeParams_.weight_grid = ae->weight_grid; + + runtimeParams_.isp_vamem_type = 0; + runtimeParams_.awb_results = results.awb(); + runtimeParams_.gbce_results = results.gbce(); + + /* \todo: Set below parameters from capture settings + params->time_stamp = 0; //microsecond unit + params->manual_brightness = settings->ispSettings.manualSettings.manualBrightness; + params->manual_contrast = settings->ispSettings.manualSettings.manualContrast; + params->manual_hue = settings->ispSettings.manualSettings.manualHue; + params->manual_saturation = settings->ispSettings.manualSettings.manualSaturation; + params->manual_sharpness = settings->ispSettings.manualSettings.manualSharpness; + */ +} + +} /* namespace ipa::ipu3::aic */ + +} /* namespace libcamera */ diff --git a/aic/aic.h b/aic/aic.h new file mode 100644 index 0000000..d7b9e10 --- /dev/null +++ b/aic/aic.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Incorporate equivalent structures for the AIC algorithms without requiring + * all of the header based implementation provided by the IA AIQ library + * headers. + */ + +#include <string> + +#include <libcamera/geometry.h> +#include <libcamera/ipa/ipu3_ipa_interface.h> + +#include <linux/intel-ipu3.h> + +#include "kbl_aic.h" + +#include "aiq/aiq_results.h" +#include "binary_data.h" +#include "ipu3_isp_pipe.h" + +#ifndef IPA_IPU3_AIC_H +#define IPA_IPU3_AIC_H + +namespace libcamera::ipa::ipu3::aic { + +class AIC +{ +public: + ~AIC(); + + int init(BinaryData &aiqb); + void reset(); + int run(ipu3_uapi_params *params); + aic_config_t *GetAicConfig(); + void updateRuntimeParams(aiq::AiqResults &results); + std::string version(); + int configure(const struct IPAConfigInfo &configInfo); + +private: + /** \todo: Only a single AIC_MODE is supported currently. */ + std::unique_ptr<KBL_AIC> skyCam_; + std::unique_ptr<IPU3ISPPipe> pipe_; + + ia_cmc_t *iaCmc_; + + /* IPU3AICRuntimeParams pointer contents */ + ia_aiq_output_frame_parameters_t runtimeOutFrameParams_; + aic_resolution_config_parameters_t runtimeResCfgParams_; + aic_input_frame_parameters_t runtimeInFrameParams_; + ia_rectangle runtimeParamsRec_; + IPU3AICRuntimeParams runtimeParams_; +}; + +} /* namespace libcamera::ipa::ipu3::aic */ + +#endif /* IPA_IPU3_AIC_H */ + diff --git a/aic/meson.build b/aic/meson.build index 361d8b2..d6b8997 100644 --- a/aic/meson.build +++ b/aic/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_files += files([ + 'aic.cpp', 'ipu3_isp_pipe.cpp', 'parameter_encoder.cpp', ]) |