summaryrefslogtreecommitdiff
path: root/aic
diff options
context:
space:
mode:
Diffstat (limited to 'aic')
-rw-r--r--aic/aic.cpp173
-rw-r--r--aic/aic.h57
-rw-r--r--aic/meson.build1
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',
])