summaryrefslogtreecommitdiff
path: root/aiq/aiq_results.h
blob: 8c95852abaeae9a46ccf9ee4b5fe38f767dfbcb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* SPDX-License-Identifier: Apache-2.0 */
/*
 * Copyright (C) 2021, Google Inc.
 *
 * aiq_results.h - Intel IA Imaging library C++ wrapper
 *
 * AIQ results container, capable of depth copies and assignments
 * of the aiq result structures.
 */

#include <array>
#include <functional>
#include <vector>

#include <ia_imaging/ia_aiq.h>

#ifndef IPA_IPU3_AIQ_RESULTS_H
#define IPA_IPU3_AIQ_RESULTS_H

namespace libcamera::ipa::ipu3::aiq {

static const unsigned int NUM_FLASH_LEDS = 1; /*!> Number of leds AEC algorithm
						     provides output for */

/**
 * The result structures for 3A algorithm are full of pointers to other structs,
 * some of those depends on the RGBS grid size or LSC grid size
 * We should query those at init time and initialize the struct with the correct
 * amount of memory. This is a TODO as an optimization
 * for now we just allocate statically big values.
 */
static const unsigned int MAX_AE_GRID_SIZE = 2048; /*!> Top limit for  the RGBS grid size
							This is an upper limit to avoid dynamic allocation*/
static const unsigned int DEFAULT_LSC_SIZE = 2048;
static const unsigned int MAX_GAMMA_LUT_SIZE = 1024;
static const unsigned int MAX_NUM_TONE_MAP_LUTS = 1024;

class AiqResults
{
public:
	AiqResults();
	AiqResults(const AiqResults &other);
	AiqResults &operator=(const AiqResults &other);
	AiqResults(const AiqResults &&other) = delete;
	AiqResults &operator=(const AiqResults &&other) = delete;

	const ia_aiq_ae_results *ae() { return &ae_; }
	ia_aiq_af_results *af() { return &af_; }
	const ia_aiq_af_bracket_results *afBracket() { return &afBracket_; }
	ia_aiq_awb_results *awb() { return &awb_; }
	const ia_aiq_gbce_results *gbce() { return &gbce_; }
	const ia_aiq_pa_results *pa() { return &pa_; }
	const ia_aiq_sa_results *sa() { return &sa_; }

	void setAe(const ia_aiq_ae_results *ae);
	void setAf(const ia_aiq_af_results *af);
	void setAfBracket(const ia_aiq_af_bracket_results *afBracket);
	void setAwb(const ia_aiq_awb_results *awb);
	void setGbce(const ia_aiq_gbce_results *gbce);
	void setDetectedSceneMode(const ia_aiq_scene_mode dsm);
	void setPa(const ia_aiq_pa_results *pa);
	void setSa(const ia_aiq_sa_results *sa);

private:
	ia_aiq_ae_results ae_;
	ia_aiq_af_results af_;
	ia_aiq_af_bracket_results afBracket_;
	ia_aiq_awb_results awb_;
	ia_aiq_gbce_results gbce_;
	ia_aiq_pa_results pa_;
	ia_aiq_sa_results sa_;

	ia_aiq_scene_mode detectedSceneMode_;

	/*!< ia_aiq_ae_results pointer contents */
	ia_aiq_ae_exposure_result aeExposureResult_;
	ia_aiq_hist_weight_grid aeWeightGrid_;
	unsigned char aeWeights_[MAX_AE_GRID_SIZE];
	ia_aiq_flash_parameters aeFlashes_[NUM_FLASH_LEDS];

	/*!< ia_aiq_ae_exposure_result pointer contents */
	ia_aiq_exposure_parameters aeExposureParameters_;
	ia_aiq_exposure_sensor_parameters aeSensorParaemeters_;

	/*!< ia_aiq_gbce results */
	/* The actual size of this table can be calculated by running cold
	 * GBCE, it will provide those tables. TODO!!
	 */
	float RGammaLut_[MAX_GAMMA_LUT_SIZE];
	float GGammaLut_[MAX_GAMMA_LUT_SIZE];
	float BGammaLut_[MAX_GAMMA_LUT_SIZE];
	float toneMapLut_[MAX_NUM_TONE_MAP_LUTS];

	/*!< ia_aiq_af_bracket_results pointer contents */
	unsigned short distanceBracketing_;
	int lensPosBracketing_;

	/*!< ia_aiq_pa_results */
	ia_aiq_advanced_ccm_t prefAcm_;
	ia_aiq_ir_weight_t irWeight_;

	/*!< ia_aiq_advanced_ccm_t pointer contents */
	unsigned int hueOfSectors_;
	float advancedColorConversionMatrices_[3][3];

	/*!< ia_aiq_ir_weight_t pointer contents */
	unsigned short irWeightGridR_;
	unsigned short irWeightGridG_;
	unsigned short irWeightGridB_;

	/*!< ia_aiq_sa_results pointer contents */
	std::vector<float> channelGr_;
	std::vector<float> channelR_;
	std::vector<float> channelB_;
	std::vector<float> channelGb_;
};

static constexpr unsigned int bufferSize = 16;
class AiqResultsRingBuffer: public std::array<AiqResults, bufferSize>
{
public:
	AiqResults &operator[](unsigned int index);
	const AiqResults &operator[](unsigned int index) const;
	void reset();
	void extendOne();
	AiqResults& latest();
	unsigned int size() { return size_; }
	AiqResults& searchBackward(const std::function<bool(AiqResults&)> pred,
				   AiqResults& def);

private:
	void incrementSize();

	unsigned int start_ = 0;
	unsigned int end_ = 0;
	unsigned int size_ = 0;
};

} /* namespace libcamera::ipa::ipu3::aiq */

#endif /* IPA_IPU3_AIQ_RESULTS_H */