diff --git a/common/omv_csi.c b/common/omv_csi.c index 805d0724c..beaa7cc0c 100644 --- a/common/omv_csi.c +++ b/common/omv_csi.c @@ -65,6 +65,8 @@ #define OMV_CSI_CLK_TOLERANCE (500000) #endif +#define OMV_CSI_RGB_AVG_MAX_MS (250) + #ifndef __weak #define __weak __attribute__((weak)) #endif @@ -322,6 +324,12 @@ __weak int omv_csi_reset(omv_csi_t *csi, bool hard) { NULL, NULL }; + #if defined(OMV_CSI_RGB_AVG_SIZE) + // Setup AWB moving average. + csi->awb_enabled = true; + rgb_moving_average_init(&csi->rgb_avg, OMV_CSI_RGB_AVG_MAX_MS, OMV_CSI_RGB_AVG_SIZE, csi->rgb_avg_buf); + #endif // defined(OMV_CSI_RGB_AVG_SIZE) + // Restore shutdown state on reset. if (!csi->power_on) { omv_csi_shutdown(csi, false); diff --git a/ports/alif/omv_csi.c b/ports/alif/omv_csi.c index 5907a34c7..3b392abde 100644 --- a/ports/alif/omv_csi.c +++ b/ports/alif/omv_csi.c @@ -48,6 +48,7 @@ #include "omv_gpu.h" #include "omv_i2c.h" #include "omv_csi.h" +#include "average.h" #include "unaligned_memcpy.h" // Bits missing from cpi.h @@ -230,10 +231,7 @@ static uint32_t omv_csi_get_fb_offset(omv_csi_t *csi) { int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) { CPI_Type *cpi = csi->base; framebuffer_t *fb = csi->fb; - vbuffer_t *buffer = NULL; - static uint32_t frames = 0; - static uint32_t r_stat, gb_stat, gr_stat, b_stat; // Configure and re/start the capture if it's not alrady active // and there are no pending buffers (from non-blocking capture). @@ -390,13 +388,23 @@ int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) { // Set the target pixel format before debayer. dst_image->pixfmt = fb->pixfmt; - // Update AWB stats every n frames. - if ((frames++ % 100) == 0) { - omv_csi_ioctl(csi, OMV_CSI_IOCTL_GET_RGB_STATS, &r_stat, &gb_stat, &gr_stat, &b_stat); + uint32_t r_stat, g_stat, b_stat; + if (csi->awb_enabled) { + uint32_t gb_stat, gr_stat; + int ret = omv_csi_ioctl(csi, OMV_CSI_IOCTL_GET_RGB_STATS, &r_stat, &gb_stat, &gr_stat, &b_stat); + + if (ret != 0) { + return ret; + } + + g_stat = (gb_stat + gr_stat) / 2; + rgb_moving_average_update(&csi->rgb_avg, &r_stat, &g_stat, &b_stat, mp_hal_ticks_ms()); + } else { + rgb_moving_average_get(&csi->rgb_avg, &r_stat, &g_stat, &b_stat); } // Debayer frame. - imlib_debayer_image_awb(dst_image, &src_image, false, r_stat, (gb_stat + gr_stat) / 2, b_stat); + imlib_debayer_image_awb(dst_image, &src_image, false, r_stat, g_stat, b_stat); } return 0; } diff --git a/ports/alif/omv_portconfig.h b/ports/alif/omv_portconfig.h index 122190db5..c45058675 100644 --- a/ports/alif/omv_portconfig.h +++ b/ports/alif/omv_portconfig.h @@ -34,6 +34,7 @@ #define __OMV_PORTCONFIG_H__ #include +#include "average.h" #include "clk.h" #include "i2c.h" #include "i3c.h" @@ -137,9 +138,14 @@ struct { \ uint8_t datasize; \ }; -#define OMV_CSI_PORT_BITS \ - struct { \ - CPI_Type *base; \ +#define OMV_CSI_RGB_AVG_SIZE (60) + +#define OMV_CSI_PORT_BITS \ + struct { \ + CPI_Type *base; \ + bool awb_enabled; \ + rgb_moving_average_t rgb_avg; \ + rgb_moving_average_val_t rgb_avg_buf[OMV_CSI_RGB_AVG_SIZE]; \ }; #endif // __OMV_PORTCONFIG_H__