Skip to content

Commit 53fd6cb

Browse files
committed
Merge branch 'feature/support_isp_awb_v5.3' into 'release/v5.3'
feat(isp): Support ISP Auto White Balance (AWB) (v5.3) See merge request espressif/esp-idf!31605
2 parents d4ac547 + 4189c54 commit 53fd6cb

File tree

18 files changed

+1306
-59
lines changed

18 files changed

+1306
-59
lines changed

components/esp_driver_isp/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ set(requires)
1010

1111
if(CONFIG_SOC_ISP_SUPPORTED)
1212
list(APPEND srcs "src/isp_core.c"
13-
"src/isp_af.c")
13+
"src/isp_af.c"
14+
"src/isp_awb.c")
1415
endif()
1516

1617
if(CONFIG_SOC_ISP_BF_SUPPORTED)

components/esp_driver_isp/include/driver/isp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313

1414
#include "driver/isp_core.h"
1515
#include "driver/isp_af.h"
16+
#include "driver/isp_awb.h"
1617
#include "driver/isp_bf.h"

components/esp_driver_isp/include/driver/isp_af.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ typedef struct {
178178
/**
179179
* @brief Prototype of ISP AF Env detector event callback
180180
*
181-
* @param[in] handle ISP AF controller handle
181+
* @param[in] af_ctrlr ISP AF controller handle
182182
* @param[in] edata ISP AF Env detector event data
183183
* @param[in] user_data User registered context, registered when in `esp_isp_af_env_detector_register_event_callbacks()`
184184
*
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdint.h>
10+
#include <stdbool.h>
11+
#include "esp_err.h"
12+
#include "driver/isp_types.h"
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
/**
19+
* @brief AWB controller config
20+
*/
21+
typedef struct {
22+
isp_awb_sample_point_t sample_point; /*!< AWB sample point of the ISP pipeline.
23+
* ISP_AWB_SAMPLE_POINT_BEFORE_CCM: sample before Color Correction Matrix(CCM).
24+
* ISP_AWB_SAMPLE_POINT_AFTER_CCM: sample after Color Correction Matrix(CCM).
25+
* If your camera support to set the manual gain to the RGB channels,
26+
* then you can choose to sample before CCM, and set the gain to the camera registers.
27+
* If your camera doesn't support the manual gain or don't want to change the camera configuration,
28+
* then you can choose to sample after CCM, and set the calculated gain to the CCM
29+
*/
30+
isp_window_t window; /*!< Statistic window of AWB.
31+
* Suggest to set it at the middle of the image and a little smaller than the whole image.
32+
* It will be more reliable because the edges of image are easily to be overexposure,
33+
* the overexposure pixels are almost at maximum luminance,
34+
* which are not good references to calculate the gain for white balance.
35+
*/
36+
struct {
37+
isp_u32_range_t luminance; /*!< Luminance range of the white patch. Range [0, 255 * 3]
38+
* Not suggest to set the max value to 255 * 3,
39+
* because these pixels are too bright, very possible to be overexposure.
40+
* So the pixels that too bright should not be the reference of the white balance.
41+
* And the minimum value better to be 0 to allow the white balance work under low luminance environment.
42+
*/
43+
isp_float_range_t red_green_ratio; /*!< Red to green ratio of the white patch. Range [0, 4.0).
44+
* The ratio could be as wider as possible,
45+
* so that all the distorted pixels will be counted for the reference of white balance.
46+
*/
47+
isp_float_range_t blue_green_ratio; /*!< Blue to green ratio of the white patch. Range [0, 4.0)
48+
* The ratio could be as wider as possible,
49+
* so that all the distorted pixels will be counted for the reference of white balance.
50+
*/
51+
} white_patch; /*!< white patch configuration */
52+
int intr_priority; /*!< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with
53+
* a relative low priority (1,2,3)
54+
*/
55+
} esp_isp_awb_config_t;
56+
57+
/**
58+
* @brief New an ISP AWB controller
59+
*
60+
* @param[in] isp_proc ISP Processor handle
61+
* @param[in] awb_cfg Pointer to AWB config. Refer to ``esp_isp_awb_config_t``.
62+
* @param[out] ret_hdl AWB controller handle
63+
*
64+
* @return
65+
* - ESP_OK On success
66+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
67+
* - ESP_ERR_INVALID_STATE Invalid state
68+
* - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
69+
* - ESP_ERR_NO_MEM If out of memory
70+
*/
71+
esp_err_t esp_isp_new_awb_controller(isp_proc_handle_t isp_proc, const esp_isp_awb_config_t *awb_cfg, isp_awb_ctlr_t *ret_hdl);
72+
73+
/**
74+
* @brief Delete an ISP AWB controller
75+
*
76+
* @param[in] awb_ctlr AWB controller handle
77+
*
78+
* @return
79+
* - ESP_OK On success
80+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
81+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
82+
*/
83+
esp_err_t esp_isp_del_awb_controller(isp_awb_ctlr_t awb_ctlr);
84+
85+
/**
86+
* @brief Reconfigure the ISP AWB controller
87+
* @note This function is allowed to be called no matter the awb controller is enabled or not.
88+
*
89+
* @param[in] awb_ctlr AWB controller handle
90+
* @param[in] awb_cfg Pointer to AWB config. Refer to ``esp_isp_awb_config_t``
91+
*
92+
* @return
93+
* - ESP_OK On success
94+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
95+
*/
96+
esp_err_t esp_isp_awb_controller_reconfig(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_config_t *awb_cfg);
97+
98+
/**
99+
* @brief Enable an ISP AWB controller
100+
*
101+
* @param[in] awb_ctlr AWB controller handle
102+
*
103+
* @return
104+
* - ESP_OK On success
105+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
106+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
107+
*/
108+
esp_err_t esp_isp_awb_controller_enable(isp_awb_ctlr_t awb_ctlr);
109+
110+
/**
111+
* @brief Disable an ISP AWB controller
112+
*
113+
* @param[in] awb_ctlr AWB controller handle
114+
*
115+
* @return
116+
* - ESP_OK On success
117+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
118+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
119+
*/
120+
esp_err_t esp_isp_awb_controller_disable(isp_awb_ctlr_t awb_ctlr);
121+
122+
/**
123+
* @brief Trigger AWB white patch statistics for one time and get the result
124+
* @note This function is a synchronous and block function,
125+
* it only returns when AWB white patch statistics is done or timeout.
126+
* It's a simple method to get the result directly for one time.
127+
*
128+
* @param[in] awb_ctlr AWB controller handle
129+
* @param[in] timeout_ms Timeout in millisecond
130+
* - timeout_ms < 0: Won't return until finished
131+
* - timeout_ms = 0: No timeout, trigger one time statistics and return immediately,
132+
* in this case, the result won't be assigned in this function,
133+
* but you can get the result in the callback `esp_isp_awb_cbs_t::on_statistics_done`
134+
* - timeout_ms > 0: Wait for specified milliseconds, if not finished, then return timeout error
135+
* @param[out] out_res AWB white patch statistics result
136+
*
137+
* @return
138+
* - ESP_OK On success
139+
* - ESP_ERR_TIMEOUT Wait for the result timeout
140+
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
141+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
142+
*/
143+
esp_err_t esp_isp_awb_controller_get_oneshot_statistics(isp_awb_ctlr_t awb_ctlr, int timeout_ms, isp_awb_stat_result_t *out_res);
144+
145+
/**
146+
* @brief Start AWB continuous statistics of the white patch in the window
147+
* @note This function is an asynchronous and non-block function,
148+
* it will start the continuous statistics and return immediately.
149+
* You have to register the AWB callback and get the result from the callback event data.
150+
*
151+
* @param[in] awb_ctlr AWB controller handle
152+
* @return
153+
* - ESP_OK On success
154+
* - ESP_ERR_INVALID_ARG Null pointer
155+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
156+
*/
157+
esp_err_t esp_isp_awb_controller_start_continuous_statistics(isp_awb_ctlr_t awb_ctlr);
158+
159+
/**
160+
* @brief Stop AWB continuous statistics of the white patch in the window
161+
*
162+
* @param[in] awb_ctlr AWB controller handle
163+
* @return
164+
* - ESP_OK On success
165+
* - ESP_ERR_INVALID_ARG Null pointer
166+
* - ESP_ERR_INVALID_STATE Driver state is invalid.
167+
*/
168+
esp_err_t esp_isp_awb_controller_stop_continuous_statistics(isp_awb_ctlr_t awb_ctlr);
169+
170+
/**
171+
* @brief Event data of callbacks
172+
*/
173+
typedef struct {
174+
isp_awb_stat_result_t awb_result; /*!< The AWB white patch statistics result */
175+
} esp_isp_awb_evt_data_t;
176+
177+
/**
178+
* @brief Prototype of ISP AWB event callback
179+
*
180+
* @param[in] handle ISP AWB controller handle
181+
* @param[in] edata ISP AWB event data
182+
* @param[in] user_data User registered context, registered when in `esp_isp_awb_env_detector_register_event_callbacks()`
183+
*
184+
* @return Whether a high priority task is woken up by this function
185+
*/
186+
typedef bool (*esp_isp_awb_callback_t)(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_evt_data_t *edata, void *user_data);
187+
188+
/**
189+
* @brief Group of ISP AWB callbacks
190+
*
191+
* @note These callbacks are all running in an ISR environment.
192+
* @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
193+
* Involved variables should be in internal RAM as well.
194+
*/
195+
typedef struct {
196+
esp_isp_awb_callback_t on_statistics_done; ///< Event callback, invoked when white patches statistic done.
197+
} esp_isp_awb_cbs_t;
198+
199+
/**
200+
* @brief Register AWB event callbacks
201+
*
202+
* @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member in
203+
* the `cbs` structure to NULL.
204+
* @note When CONFIG_ISP_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
205+
* Involved variables (including `user_data`) should be in internal RAM as well.
206+
*
207+
* @param[in] awb_ctlr AWB controller handle
208+
* @param[in] cbs Group of callback functions
209+
* @param[in] user_data User data, which will be delivered to the callback functions directly
210+
*
211+
* @return
212+
* - ESP_OK: On success
213+
* - ESP_ERR_INVALID_ARG: Invalid arguments
214+
* - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment
215+
*/
216+
esp_err_t esp_isp_awb_register_event_callbacks(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_cbs_t *cbs, void *user_data);
217+
218+
#ifdef __cplusplus
219+
}
220+
#endif

components/esp_driver_isp/include/driver/isp_types.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,42 @@
1212
extern "C" {
1313
#endif
1414

15+
/**
16+
* @brief ISP unsigned integer range type
17+
* @note Whether the edge value are included depends on the variable itself
18+
*/
19+
typedef struct {
20+
uint32_t min; ///< Minimum unsigned int value
21+
uint32_t max; ///< Maximum unsigned int value
22+
} isp_u32_range_t;
23+
24+
/**
25+
* @brief ISP float range type
26+
* @note Whether the edge value are included depends on the variable itself
27+
*/
28+
typedef struct {
29+
float min; ///< Minimum float value
30+
float max; ///< Maximum float value
31+
} isp_float_range_t;
32+
33+
/**
34+
* @brief ISP AF result
35+
*/
36+
typedef struct {
37+
int definition[ISP_AF_WINDOW_NUM]; ///< Definition, it refers how clear and sharp an image is
38+
int luminance[ISP_AF_WINDOW_NUM]; ///< Luminance, it refers how luminant an image is
39+
} isp_af_result_t;
40+
41+
/**
42+
* @brief ISP AWB result
43+
*/
44+
typedef struct {
45+
uint32_t white_patch_num; ///< white patch number that counted by AWB in the window
46+
uint32_t sum_r; ///< The sum of R channel of these white patches
47+
uint32_t sum_g; ///< The sum of G channel of these white patches
48+
uint32_t sum_b; ///< The sum of B channel of these white patches
49+
} isp_awb_stat_result_t;
50+
1551
/**
1652
* @brief Type of ISP processor handle
1753
*/
@@ -22,6 +58,11 @@ typedef struct isp_processor_t *isp_proc_handle_t;
2258
*/
2359
typedef struct isp_af_controller_t *isp_af_ctlr_t;
2460

61+
/**
62+
* @brief Type of ISP AWB controller handle
63+
*/
64+
typedef struct isp_awb_controller_t *isp_awb_ctlr_t;
65+
2566
#ifdef __cplusplus
2667
}
2768
#endif

components/esp_driver_isp/include/esp_private/isp_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct isp_processor_t {
6464
uint32_t v_res;
6565
/* sub module contexts */
6666
isp_af_ctlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS];
67+
isp_awb_ctlr_t awb_ctlr;
6768
isp_fsm_t bf_fsm;
6869
} isp_processor_t;
6970
#endif

0 commit comments

Comments
 (0)