|
1 | 1 | /* |
2 | | - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD |
| 2 | + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD |
3 | 3 | * |
4 | 4 | * SPDX-License-Identifier: Apache-2.0 |
5 | 5 | */ |
6 | 6 |
|
7 | 7 | #include "hal/cam_ll.h" |
8 | 8 | #include "hal/cam_hal.h" |
| 9 | +#include "hal/color_types.h" |
9 | 10 | #include "soc/soc_caps.h" |
10 | 11 | #include "soc/cam_periph.h" |
11 | 12 |
|
| 13 | +/** |
| 14 | + * @brief Default format conversion configuration |
| 15 | + */ |
| 16 | +#define CAM_HAL_DEFAULT_FORMAT_CONV_CONFIG { \ |
| 17 | + .conv_std = COLOR_CONV_STD_RGB_YUV_BT601, \ |
| 18 | + .data_width = 8, \ |
| 19 | + .input_range = COLOR_RANGE_LIMIT, \ |
| 20 | + .output_range = COLOR_RANGE_LIMIT \ |
| 21 | +} |
| 22 | + |
12 | 23 | /** |
13 | 24 | * @brief Configure line number to trigger interrupt |
14 | 25 | * |
@@ -119,3 +130,59 @@ void cam_hal_stop_streaming(cam_hal_context_t *hal) |
119 | 130 | { |
120 | 131 | cam_ll_stop(hal->hw); |
121 | 132 | } |
| 133 | + |
| 134 | +/** |
| 135 | + * @brief Configure color format conversion |
| 136 | + * |
| 137 | + * This function handles all types of color format conversions: |
| 138 | + * - YUV to RGB conversion |
| 139 | + * - RGB to YUV conversion |
| 140 | + * - YUV to YUV conversion |
| 141 | + * |
| 142 | + * Color range support: |
| 143 | + * - Full range: 0-255 for both RGB and YUV |
| 144 | + * - Limited range: RGB 16-240, YUV Y:16-240, U-V:16-235 |
| 145 | + * |
| 146 | + * @param hal CAM HAL context pointer |
| 147 | + * @param config Color conversion configuration. If NULL, default config is used. |
| 148 | + */ |
| 149 | +void cam_hal_color_format_convert(cam_hal_context_t *hal, |
| 150 | + const cam_ctlr_format_conv_config_t *config) |
| 151 | +{ |
| 152 | + // Use provided config or default |
| 153 | + const cam_ctlr_format_conv_config_t *cfg = config; |
| 154 | + if (cfg == NULL) { |
| 155 | + static const cam_ctlr_format_conv_config_t default_config = CAM_HAL_DEFAULT_FORMAT_CONV_CONFIG; |
| 156 | + cfg = &default_config; |
| 157 | + } |
| 158 | + |
| 159 | + cam_ll_enable_rgb_yuv_convert(hal->hw, false); |
| 160 | + |
| 161 | + // Extract color space from source and destination formats |
| 162 | + color_space_t src_space = COLOR_SPACE_TYPE(cfg->src_format); |
| 163 | + color_space_t dst_space = COLOR_SPACE_TYPE(cfg->dst_format); |
| 164 | + |
| 165 | + // Configure conversion based on color space types |
| 166 | + if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_RGB) { |
| 167 | + // YUV to RGB conversion |
| 168 | + color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format); |
| 169 | + cam_ll_set_convert_mode_yuv_to_rgb(hal->hw, yuv_format); |
| 170 | + } else if (src_space == COLOR_SPACE_RGB && dst_space == COLOR_SPACE_YUV) { |
| 171 | + // RGB to YUV conversion |
| 172 | + color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format); |
| 173 | + cam_ll_set_convert_mode_rgb_to_yuv(hal->hw, yuv_format); |
| 174 | + } else if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_YUV) { |
| 175 | + // YUV to YUV conversion |
| 176 | + color_pixel_yuv_format_t src_yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format); |
| 177 | + color_pixel_yuv_format_t dst_yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format); |
| 178 | + cam_ll_set_convert_mode_yuv_to_yuv(hal->hw, src_yuv_format, dst_yuv_format); |
| 179 | + } |
| 180 | + |
| 181 | + // Common configuration for all conversion types |
| 182 | + cam_ll_set_yuv_convert_std(hal->hw, cfg->conv_std); |
| 183 | + cam_ll_set_convert_data_width(hal->hw, cfg->data_width); |
| 184 | + cam_ll_set_input_color_range(hal->hw, cfg->input_range); |
| 185 | + cam_ll_set_output_color_range(hal->hw, cfg->output_range); |
| 186 | + |
| 187 | + cam_ll_enable_rgb_yuv_convert(hal->hw, true); |
| 188 | +} |
0 commit comments