mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 01:50:58 +02:00
Merge branch 'feat/dvp_format_trans' into 'master'
feat(cam): support format conversion function See merge request espressif/esp-idf!40890
This commit is contained in:
@@ -52,6 +52,7 @@ static esp_err_t s_ctlr_csi_stop(esp_cam_ctlr_handle_t handle);
|
|||||||
static esp_err_t s_csi_ctlr_disable(esp_cam_ctlr_handle_t ctlr);
|
static esp_err_t s_csi_ctlr_disable(esp_cam_ctlr_handle_t ctlr);
|
||||||
static esp_err_t s_ctlr_csi_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
static esp_err_t s_ctlr_csi_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
||||||
static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
||||||
|
static esp_err_t s_csi_ctlr_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config);
|
||||||
|
|
||||||
static esp_err_t s_csi_claim_controller(csi_controller_t *controller)
|
static esp_err_t s_csi_claim_controller(csi_controller_t *controller)
|
||||||
{
|
{
|
||||||
@@ -227,6 +228,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_
|
|||||||
ctlr->base.get_internal_buffer = s_csi_ctlr_get_internal_buffer;
|
ctlr->base.get_internal_buffer = s_csi_ctlr_get_internal_buffer;
|
||||||
ctlr->base.get_buffer_len = s_csi_ctlr_get_buffer_length;
|
ctlr->base.get_buffer_len = s_csi_ctlr_get_buffer_length;
|
||||||
ctlr->base.alloc_buffer = s_csi_ctlr_alloc_buffer;
|
ctlr->base.alloc_buffer = s_csi_ctlr_alloc_buffer;
|
||||||
|
ctlr->base.format_conversion = s_csi_ctlr_format_conversion;
|
||||||
|
|
||||||
*ret_handle = &(ctlr->base);
|
*ret_handle = &(ctlr->base);
|
||||||
|
|
||||||
@@ -560,3 +562,10 @@ static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t s_csi_ctlr_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
// CSI controller doesn't support format conversion yet
|
||||||
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
@@ -782,6 +782,31 @@ static void *esp_cam_ctlr_dvp_cam_alloc_buffer(esp_cam_ctlr_t *handle, size_t si
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure format conversion
|
||||||
|
*
|
||||||
|
* @param cam_handle Camera controller handle
|
||||||
|
* @param src_format Source format
|
||||||
|
* @param dst_format Destination format
|
||||||
|
* @return ESP_OK on success, ESP_FAIL on failure
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_dvp_format_conversion(esp_cam_ctlr_handle_t cam_handle,
|
||||||
|
const cam_ctlr_format_conv_config_t *config)
|
||||||
|
{
|
||||||
|
if (cam_handle == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)cam_handle;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Configure format conversion: %d -> %d", config->src_format, config->dst_format);
|
||||||
|
|
||||||
|
// Configure color format conversion
|
||||||
|
cam_hal_color_format_convert(&ctlr->hal, config);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief New ESP CAM DVP controller
|
* @brief New ESP CAM DVP controller
|
||||||
*
|
*
|
||||||
@@ -876,6 +901,7 @@ esp_err_t esp_cam_new_dvp_ctlr(const esp_cam_ctlr_dvp_config_t *config, esp_cam_
|
|||||||
ctlr->base.get_internal_buffer = esp_cam_ctlr_dvp_cam_get_internal_buffer;
|
ctlr->base.get_internal_buffer = esp_cam_ctlr_dvp_cam_get_internal_buffer;
|
||||||
ctlr->base.get_buffer_len = esp_cam_ctlr_get_dvp_cam_frame_buffer_len;
|
ctlr->base.get_buffer_len = esp_cam_ctlr_get_dvp_cam_frame_buffer_len;
|
||||||
ctlr->base.alloc_buffer = esp_cam_ctlr_dvp_cam_alloc_buffer;
|
ctlr->base.alloc_buffer = esp_cam_ctlr_dvp_cam_alloc_buffer;
|
||||||
|
ctlr->base.format_conversion = esp_cam_ctlr_dvp_format_conversion;
|
||||||
|
|
||||||
*ret_handle = &ctlr->base;
|
*ret_handle = &ctlr->base;
|
||||||
|
|
||||||
|
@@ -99,3 +99,13 @@ void *esp_cam_ctlr_alloc_buffer(esp_cam_ctlr_handle_t handle, size_t size, uint3
|
|||||||
|
|
||||||
return handle->alloc_buffer(handle, size, buf_caps);
|
return handle->alloc_buffer(handle, size, buf_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_cam_ctlr_format_conversion(esp_cam_ctlr_handle_t handle,
|
||||||
|
const cam_ctlr_format_conv_config_t *conv_cfg)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
ESP_RETURN_ON_FALSE(conv_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null conv_cfg");
|
||||||
|
ESP_RETURN_ON_FALSE(handle->format_conversion, ESP_ERR_NOT_SUPPORTED, TAG, "format conversion function not supported");
|
||||||
|
|
||||||
|
return handle->format_conversion(handle, conv_cfg);
|
||||||
|
}
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "esp_cam_ctlr_types.h"
|
#include "esp_cam_ctlr_types.h"
|
||||||
|
#include "hal/cam_ctlr_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -150,6 +151,20 @@ esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t
|
|||||||
*/
|
*/
|
||||||
void *esp_cam_ctlr_alloc_buffer(esp_cam_ctlr_handle_t handle, size_t size, uint32_t buf_caps);
|
void *esp_cam_ctlr_alloc_buffer(esp_cam_ctlr_handle_t handle, size_t size, uint32_t buf_caps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure format conversion
|
||||||
|
*
|
||||||
|
* @param[in] handle ESP CAM controller handle
|
||||||
|
* @param[in] conv_cfg Color conversion configuration, contains source and destination formats
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: Format conversion not supported by this controller
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_format_conversion(esp_cam_ctlr_handle_t handle,
|
||||||
|
const cam_ctlr_format_conv_config_t *conv_cfg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_cam_ctlr_types.h"
|
#include "esp_cam_ctlr_types.h"
|
||||||
|
#include "hal/cam_ctlr_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -146,6 +147,19 @@ struct esp_cam_ctlr_t {
|
|||||||
*/
|
*/
|
||||||
void *(*alloc_buffer)(esp_cam_ctlr_t *, size_t, uint32_t);
|
void *(*alloc_buffer)(esp_cam_ctlr_t *, size_t, uint32_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure format conversion
|
||||||
|
*
|
||||||
|
* @param[in] esp_cam_ctlr_t * ESP CAM controller handle
|
||||||
|
* @param[in] const cam_ctlr_format_conv_config_t * Color conversion configuration
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: Format conversion not supported by this controller
|
||||||
|
*/
|
||||||
|
esp_err_t (*format_conversion)(esp_cam_ctlr_t *, const cam_ctlr_format_conv_config_t *);
|
||||||
|
|
||||||
void *user_data; ///< User data
|
void *user_data; ///< User data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -86,6 +86,7 @@ static esp_err_t s_isp_dvp_stop(esp_cam_ctlr_handle_t handle);
|
|||||||
static esp_err_t s_isp_dvp_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
static esp_err_t s_isp_dvp_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms);
|
||||||
static bool s_dvp_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data);
|
static bool s_dvp_dma_trans_done_callback(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data);
|
||||||
static void *s_isp_dvp_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
static void *s_isp_dvp_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps);
|
||||||
|
static esp_err_t s_isp_dvp_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config);
|
||||||
|
|
||||||
esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle)
|
esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle)
|
||||||
{
|
{
|
||||||
@@ -202,6 +203,7 @@ esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctl
|
|||||||
cam_ctlr->get_internal_buffer = s_isp_dvp_get_frame_buffer;
|
cam_ctlr->get_internal_buffer = s_isp_dvp_get_frame_buffer;
|
||||||
cam_ctlr->get_buffer_len = s_isp_dvp_get_frame_buffer_length;
|
cam_ctlr->get_buffer_len = s_isp_dvp_get_frame_buffer_length;
|
||||||
cam_ctlr->alloc_buffer = s_isp_dvp_alloc_buffer;
|
cam_ctlr->alloc_buffer = s_isp_dvp_alloc_buffer;
|
||||||
|
cam_ctlr->format_conversion = s_isp_dvp_format_conversion;
|
||||||
*ret_handle = cam_ctlr;
|
*ret_handle = cam_ctlr;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -616,3 +618,10 @@ static void *s_isp_dvp_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t s_isp_dvp_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
// ISP DVP controller doesn't support format conversion yet
|
||||||
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
@@ -1,14 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hal/cam_ll.h"
|
#include "hal/cam_ll.h"
|
||||||
#include "hal/cam_hal.h"
|
#include "hal/cam_hal.h"
|
||||||
|
#include "hal/color_types.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/cam_periph.h"
|
#include "soc/cam_periph.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default format conversion configuration
|
||||||
|
*/
|
||||||
|
#define CAM_HAL_DEFAULT_FORMAT_CONV_CONFIG { \
|
||||||
|
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601, \
|
||||||
|
.data_width = 8, \
|
||||||
|
.input_range = COLOR_RANGE_LIMIT, \
|
||||||
|
.output_range = COLOR_RANGE_LIMIT \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configure line number to trigger interrupt
|
* @brief Configure line number to trigger interrupt
|
||||||
*
|
*
|
||||||
@@ -119,3 +130,59 @@ void cam_hal_stop_streaming(cam_hal_context_t *hal)
|
|||||||
{
|
{
|
||||||
cam_ll_stop(hal->hw);
|
cam_ll_stop(hal->hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure color format conversion
|
||||||
|
*
|
||||||
|
* This function handles all types of color format conversions:
|
||||||
|
* - YUV to RGB conversion
|
||||||
|
* - RGB to YUV conversion
|
||||||
|
* - YUV to YUV conversion
|
||||||
|
*
|
||||||
|
* Color range support:
|
||||||
|
* - Full range: 0-255 for both RGB and YUV
|
||||||
|
* - Limited range: RGB 16-240, YUV Y:16-240, U-V:16-235
|
||||||
|
*
|
||||||
|
* @param hal CAM HAL context pointer
|
||||||
|
* @param config Color conversion configuration. If NULL, default config is used.
|
||||||
|
*/
|
||||||
|
void cam_hal_color_format_convert(cam_hal_context_t *hal,
|
||||||
|
const cam_ctlr_format_conv_config_t *config)
|
||||||
|
{
|
||||||
|
// Use provided config or default
|
||||||
|
const cam_ctlr_format_conv_config_t *cfg = config;
|
||||||
|
if (cfg == NULL) {
|
||||||
|
static const cam_ctlr_format_conv_config_t default_config = CAM_HAL_DEFAULT_FORMAT_CONV_CONFIG;
|
||||||
|
cfg = &default_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_ll_enable_rgb_yuv_convert(hal->hw, false);
|
||||||
|
|
||||||
|
// Extract color space from source and destination formats
|
||||||
|
color_space_t src_space = COLOR_SPACE_TYPE(cfg->src_format);
|
||||||
|
color_space_t dst_space = COLOR_SPACE_TYPE(cfg->dst_format);
|
||||||
|
|
||||||
|
// Configure conversion based on color space types
|
||||||
|
if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_RGB) {
|
||||||
|
// YUV to RGB conversion
|
||||||
|
color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format);
|
||||||
|
cam_ll_set_convert_mode_yuv_to_rgb(hal->hw, yuv_format);
|
||||||
|
} else if (src_space == COLOR_SPACE_RGB && dst_space == COLOR_SPACE_YUV) {
|
||||||
|
// RGB to YUV conversion
|
||||||
|
color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format);
|
||||||
|
cam_ll_set_convert_mode_rgb_to_yuv(hal->hw, yuv_format);
|
||||||
|
} else if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_YUV) {
|
||||||
|
// YUV to YUV conversion
|
||||||
|
color_pixel_yuv_format_t src_yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format);
|
||||||
|
color_pixel_yuv_format_t dst_yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format);
|
||||||
|
cam_ll_set_convert_mode_yuv_to_yuv(hal->hw, src_yuv_format, dst_yuv_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common configuration for all conversion types
|
||||||
|
cam_ll_set_yuv_convert_std(hal->hw, cfg->conv_std);
|
||||||
|
cam_ll_set_convert_data_width(hal->hw, cfg->data_width);
|
||||||
|
cam_ll_set_input_color_range(hal->hw, cfg->input_range);
|
||||||
|
cam_ll_set_output_color_range(hal->hw, cfg->output_range);
|
||||||
|
|
||||||
|
cam_ll_enable_rgb_yuv_convert(hal->hw, true);
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -39,6 +39,18 @@ typedef enum {
|
|||||||
CAM_CTLR_DATA_WIDTH_16 = 16, ///< 16-bit data width
|
CAM_CTLR_DATA_WIDTH_16 = 16, ///< 16-bit data width
|
||||||
} cam_ctlr_data_width_t;
|
} cam_ctlr_data_width_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Camera Controller format conversion configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
cam_ctlr_color_t src_format; /*!< Source format */
|
||||||
|
cam_ctlr_color_t dst_format; /*!< Destination format */
|
||||||
|
color_conv_std_rgb_yuv_t conv_std; /*!< Conversion standard */
|
||||||
|
uint32_t data_width; /*!< Data width in bits */
|
||||||
|
color_range_t input_range; /*!< Input color range */
|
||||||
|
color_range_t output_range; /*!< Output color range */
|
||||||
|
} cam_ctlr_format_conv_config_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +68,24 @@ void cam_hal_start_streaming(cam_hal_context_t *hal);
|
|||||||
*/
|
*/
|
||||||
void cam_hal_stop_streaming(cam_hal_context_t *hal);
|
void cam_hal_stop_streaming(cam_hal_context_t *hal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure color format conversion
|
||||||
|
*
|
||||||
|
* This function handles all types of color format conversions:
|
||||||
|
* - YUV to RGB conversion
|
||||||
|
* - RGB to YUV conversion
|
||||||
|
* - YUV to YUV conversion
|
||||||
|
*
|
||||||
|
* Color range support:
|
||||||
|
* - Full range: 0-255 for both RGB and YUV
|
||||||
|
* - Limited range: RGB 16-240, YUV Y:16-240, U-V:16-235
|
||||||
|
*
|
||||||
|
* @param hal CAM HAL context pointer
|
||||||
|
* @param config Color conversion configuration. If NULL, default config is used.
|
||||||
|
*/
|
||||||
|
void cam_hal_color_format_convert(cam_hal_context_t *hal,
|
||||||
|
const cam_ctlr_format_conv_config_t *config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -119,6 +119,16 @@ Camera controller driver can be implemented in one of following ways:
|
|||||||
|
|
||||||
After calling :cpp:func:`esp_cam_new_dvp_ctlr`, you should allocate a camera buffer that meets the alignment constraints, or call :cpp:func:`esp_cam_ctlr_alloc_buffer` to automatically allocate.
|
After calling :cpp:func:`esp_cam_new_dvp_ctlr`, you should allocate a camera buffer that meets the alignment constraints, or call :cpp:func:`esp_cam_ctlr_alloc_buffer` to automatically allocate.
|
||||||
|
|
||||||
|
You can call :cpp:func:`esp_cam_ctlr_format_conversion` to configure format conversion. The driver supports the following conversion types:
|
||||||
|
|
||||||
|
* YUV to RGB conversion
|
||||||
|
* RGB to YUV conversion
|
||||||
|
* YUV to YUV conversion
|
||||||
|
|
||||||
|
Color range support:
|
||||||
|
* Full range: 0-255 for both RGB and YUV
|
||||||
|
* Limited range: RGB 16-240, YUV Y:16-240, U-V:16-235
|
||||||
|
|
||||||
.. code:: c
|
.. code:: c
|
||||||
|
|
||||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||||
@@ -153,6 +163,16 @@ Camera controller driver can be implemented in one of following ways:
|
|||||||
|
|
||||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||||
|
|
||||||
|
const cam_ctlr_format_conv_config_t conv_cfg = {
|
||||||
|
.src_format = CAM_CTLR_COLOR_YUV422, // Source format: YUV422
|
||||||
|
.dst_format = CAM_CTLR_COLOR_RGB565, // Destination format: RGB565
|
||||||
|
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601,
|
||||||
|
.data_width = 8,
|
||||||
|
.input_range = COLOR_RANGE_LIMIT,
|
||||||
|
.output_range = COLOR_RANGE_LIMIT,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_cam_ctlr_format_conversion(cam_handle, &conv_cfg));
|
||||||
|
|
||||||
Uninstall Camera Controller Driver
|
Uninstall Camera Controller Driver
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@@ -120,6 +120,16 @@
|
|||||||
|
|
||||||
在调用 :cpp:func:`esp_cam_new_dvp_ctlr` 之后,需要分配符合对齐约束的摄像头缓冲区,或调用 :cpp:func:`esp_cam_ctlr_alloc_buffer` 来自动分配。
|
在调用 :cpp:func:`esp_cam_new_dvp_ctlr` 之后,需要分配符合对齐约束的摄像头缓冲区,或调用 :cpp:func:`esp_cam_ctlr_alloc_buffer` 来自动分配。
|
||||||
|
|
||||||
|
可以调用 :cpp:func:`esp_cam_ctlr_format_conversion` 来配置格式转换。驱动程序支持以下转换类型:
|
||||||
|
|
||||||
|
* YUV 到 RGB 转换
|
||||||
|
* RGB 到 YUV 转换
|
||||||
|
* YUV 到 YUV 转换
|
||||||
|
|
||||||
|
色彩空间范围支持:
|
||||||
|
* 全色彩空间:RGB 和 YUV 的取值范围为 0-255
|
||||||
|
* 有限色彩空间:RGB 取值范围为 16-240,YUV Y 分量取值范围为 16-240,U-V 分量取值范围为 16-235
|
||||||
|
|
||||||
.. code:: c
|
.. code:: c
|
||||||
|
|
||||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||||
@@ -154,6 +164,16 @@
|
|||||||
|
|
||||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||||
|
|
||||||
|
const cam_ctlr_format_conv_config_t conv_cfg = {
|
||||||
|
.src_format = CAM_CTLR_COLOR_YUV422, // 源格式:YUV422
|
||||||
|
.dst_format = CAM_CTLR_COLOR_RGB565, // 目标格式:RGB565
|
||||||
|
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601,
|
||||||
|
.data_width = 8,
|
||||||
|
.input_range = COLOR_RANGE_LIMIT,
|
||||||
|
.output_range = COLOR_RANGE_LIMIT,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_cam_ctlr_format_conversion(cam_handle, &conv_cfg));
|
||||||
|
|
||||||
卸载摄像头控制器驱动程序
|
卸载摄像头控制器驱动程序
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@@ -30,4 +30,15 @@ menu "Example Configuration"
|
|||||||
int
|
int
|
||||||
default 480 if EXAMPLE_CAM_VRES_480
|
default 480 if EXAMPLE_CAM_VRES_480
|
||||||
default 240 if EXAMPLE_CAM_VRES_240
|
default 240 if EXAMPLE_CAM_VRES_240
|
||||||
|
|
||||||
|
choice EXAMPLE_CAM_INPUT_FORMAT
|
||||||
|
bool "Set camera input format"
|
||||||
|
default EXAMPLE_CAM_INPUT_FORMAT_YUV422
|
||||||
|
|
||||||
|
config EXAMPLE_CAM_INPUT_FORMAT_RGB565
|
||||||
|
bool "RGB565"
|
||||||
|
config EXAMPLE_CAM_INPUT_FORMAT_YUV422
|
||||||
|
bool "YUV422"
|
||||||
|
endchoice
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@@ -146,7 +146,11 @@ void app_main(void)
|
|||||||
.clk_src = CAM_CLK_SRC_DEFAULT,
|
.clk_src = CAM_CLK_SRC_DEFAULT,
|
||||||
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
||||||
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
||||||
|
#if CONFIG_EXAMPLE_CAM_INPUT_FORMAT_YUV422
|
||||||
|
.input_data_color_type = CAM_CTLR_COLOR_YUV422,
|
||||||
|
#else
|
||||||
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
||||||
|
#endif
|
||||||
.dma_burst_size = 64,
|
.dma_burst_size = 64,
|
||||||
.pin = &pin_cfg,
|
.pin = &pin_cfg,
|
||||||
.bk_buffer_dis = 1,
|
.bk_buffer_dis = 1,
|
||||||
@@ -200,6 +204,20 @@ void app_main(void)
|
|||||||
//--------Enable and start Camera Controller----------//
|
//--------Enable and start Camera Controller----------//
|
||||||
ESP_ERROR_CHECK(esp_cam_ctlr_enable(cam_handle));
|
ESP_ERROR_CHECK(esp_cam_ctlr_enable(cam_handle));
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CAM_INPUT_FORMAT_YUV422
|
||||||
|
ESP_LOGI(TAG, "Configure format conversion: YUV422 -> RGB565");
|
||||||
|
// Configure format conversion
|
||||||
|
const cam_ctlr_format_conv_config_t conv_cfg = {
|
||||||
|
.src_format = CAM_CTLR_COLOR_YUV422, // Source format: YUV422
|
||||||
|
.dst_format = CAM_CTLR_COLOR_RGB565, // Destination format: RGB565
|
||||||
|
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601,
|
||||||
|
.data_width = 8,
|
||||||
|
.input_range = COLOR_RANGE_LIMIT,
|
||||||
|
.output_range = COLOR_RANGE_LIMIT,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_cam_ctlr_format_conversion(cam_handle, &conv_cfg));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (esp_cam_ctlr_start(cam_handle) != ESP_OK) {
|
if (esp_cam_ctlr_start(cam_handle) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Driver start fail");
|
ESP_LOGE(TAG, "Driver start fail");
|
||||||
return;
|
return;
|
||||||
|
@@ -43,7 +43,11 @@ extern "C" {
|
|||||||
#define EXAMPLE_DVP_CAM_BUF_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
|
#define EXAMPLE_DVP_CAM_BUF_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CAM_INPUT_FORMAT_YUV422
|
||||||
|
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_YUV422_240x240_25fps" // ov2640
|
||||||
|
#elif CONFIG_EXAMPLE_CAM_INPUT_FORMAT_RGB565
|
||||||
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RGB565_240x240_25fps" // ov2640
|
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RGB565_240x240_25fps" // ov2640
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef EXAMPLE_CAM_FORMAT
|
#ifndef EXAMPLE_CAM_FORMAT
|
||||||
#error "Unsupported camera format! Please adjust EXAMPLE_CAM_HRES and EXAMPLE_CAM_VRES in menuconfig"
|
#error "Unsupported camera format! Please adjust EXAMPLE_CAM_HRES and EXAMPLE_CAM_VRES in menuconfig"
|
||||||
|
Reference in New Issue
Block a user