kopia lustrzana https://github.com/espressif/esp-idf
827 wiersze
34 KiB
ReStructuredText
827 wiersze
34 KiB
ReStructuredText
图像信号处理器 (ISP)
|
||
====================
|
||
|
||
:link_to_translation:`en:[English]`
|
||
|
||
简介
|
||
----
|
||
|
||
{IDF_TARGET_NAME} 内含图像信号处理器 (ISP),是由众多图像处理算法组成的流水线。ISP 从 DVP 摄像头、MIPI-CSI 摄像头或系统存储处接收图像数据,并通过 DMA 将处理后的图像数据写入系统存储。ISP 需要与其他摄像头控制器模块协同工作,无法独立工作。
|
||
|
||
术语表
|
||
------
|
||
|
||
.. list::
|
||
|
||
- MIPI-CSI:符合 MIPI 规范的高速串行摄像头接口
|
||
- DVP:数字视频并行接口,通常由 vsync、hsync、de 和 data 信号组成
|
||
- RAW:直接从图像传感器输出的未处理数据,通常分为 R、Gr、Gb 和 B 四个通道,按位宽分为 RAW8、RAW10、RAW12 等不同格式
|
||
- RGB:由红、绿、蓝三种颜色组成的彩色图像格式,按每种颜色的位宽分为 RGB888、RGB565 等格式
|
||
- YUV:由亮度和色度组成的彩色图像格式,按数据排列方式分为 YUV444、YUV422、YUV420 等格式
|
||
- AF:自动对焦
|
||
- AWB:自动白平衡
|
||
- AE:自动曝光
|
||
- HIST:直方图
|
||
- BF:拜耳域降噪
|
||
- CCM:色彩校正矩阵
|
||
|
||
ISP 流水线
|
||
----------
|
||
|
||
.. blockdiag::
|
||
:scale: 100%
|
||
:caption: ISP 流水线
|
||
:align: center
|
||
|
||
blockdiag isp_pipeline {
|
||
orientation = portrait;
|
||
node_height = 30;
|
||
node_width = 120;
|
||
span_width = 100;
|
||
default_fontsize = 16;
|
||
|
||
isp_header [label = "ISP Header"];
|
||
isp_tail [label = "ISP Tail"];
|
||
isp_chs [label = "对比度 &\n 色调 & 饱和度", width = 150, height = 70];
|
||
isp_yuv [label = "YUV 限制\n YUB2RGB", width = 120, height = 70];
|
||
|
||
isp_header -> BF -> 去马赛克 -> CCM -> gamma 校正 -> RGB 转 YUV -> 锐化 -> isp_chs -> isp_yuv -> isp_tail;
|
||
|
||
BF -> HIST
|
||
去马赛克 -> AWB
|
||
去马赛克 -> AE
|
||
去马赛克 -> HIST
|
||
CCM -> AWB
|
||
gamma 校正 -> AE
|
||
RGB 转 YUV -> HIST
|
||
RGB 转 YUV -> AF
|
||
}
|
||
|
||
功能概述
|
||
--------
|
||
|
||
ISP 驱动程序提供以下服务:
|
||
|
||
- :ref:`isp-resource-allocation` - 涵盖如何通过正确的配置来分配 ISP 资源,以及完成工作后如何回收资源。
|
||
- :ref:`isp-enable-disable` - 涵盖如何启用和禁用 ISP 处理器。
|
||
- :ref:`isp-af-statistics` - 涵盖如何单次或连续获取 AF 统计信息。
|
||
- :ref:`isp-awb-statistics` - 涵盖如何单次或连续获取 AWB 白块统计信息。
|
||
- :ref:`isp-ae-statistics` - 涵盖如何单次或连续获取 AE 统计信息。
|
||
- :ref:`isp-hist-statistics` - 涵盖如何单次或连续获取直方图统计信息。
|
||
- :ref:`isp-bf` - 涵盖如何启用和配置 BF 功能。
|
||
- :ref:`isp-ccm-config` - 涵盖如何配置 CCM。
|
||
- :ref:`isp-demosaic` - 涵盖如何配置去马赛克功能。
|
||
- :ref:`isp-gamma-correction` - 涵盖如何启用和配置 gamma 校正。
|
||
- :ref:`isp-sharpen` - 涵盖如何配置锐化功能。
|
||
- :ref:`isp-callback` - 涵盖如何将用户特定代码挂接到 ISP 驱动事件回调。
|
||
- :ref:`isp-thread-safety` - 列出了驱动程序中线程安全的 API。
|
||
- :ref:`isp-kconfig-options` - 列出了支持的 Kconfig 选项,这些选项可以对驱动程序产生不同影响。
|
||
- :ref:`isp-iram-safe` - 描述了当 cache 被禁用时,如何使 ISP 中断和控制功能正常工作。
|
||
|
||
.. _isp-resource-allocation:
|
||
|
||
资源分配
|
||
^^^^^^^^
|
||
|
||
安装 ISP 驱动程序
|
||
~~~~~~~~~~~~~~~~~
|
||
|
||
ISP 驱动程序需要由 :cpp:type:`esp_isp_processor_cfg_t` 指定配置。
|
||
|
||
指定 :cpp:type:`esp_isp_processor_cfg_t` 中的配置后,可以调用 :cpp:func:`esp_isp_new_processor` 来分配和初始化 ISP 处理器。如果函数运行正常,将返回一个 ISP 处理器句柄。请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_processor_cfg_t isp_config = {
|
||
.clk_src = ISP_CLK_SRC_DEFAULT,
|
||
...
|
||
};
|
||
|
||
isp_proc_handle_t isp_proc = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||
|
||
使用上述句柄,可以启用/禁用 ISP 驱动程序,也可以安装其他 ISP 模块。
|
||
|
||
|
||
安装 ISP 自动对焦 (AF) 驱动程序
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP 自动对焦 (AF) 驱动程序需要由 :cpp:type:`esp_isp_af_config_t` 指定配置。
|
||
|
||
指定 :cpp:type:`esp_isp_af_config_t` 中的配置后,可以调用 :cpp:func:`esp_isp_new_af_controller` 来分配和初始化 ISP AF 控制器。如果函数运行正常,将返回一个 ISP AF 控制器句柄。请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_af_config_t af_config = {
|
||
.edge_thresh = 128,
|
||
};
|
||
isp_af_ctlr_t af_ctrlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr));
|
||
|
||
使用上述句柄,可以启用/禁用 ISP AF 驱动程序,也可以安装 ISP AF 环境检测模块。
|
||
|
||
安装 ISP 自动白平衡 (AWB) 驱动程序
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP 自动白平衡 (AWB) 驱动程序需要由 :cpp:type:`esp_isp_awb_config_t` 指定配置。
|
||
|
||
指定 :cpp:type:`esp_isp_awb_config_t` 中的配置后,可以调用 :cpp:func:`esp_isp_new_awb_controller` 来分配和初始化 ISP AWB 控制器。如果函数运行正常,将返回一个 ISP AWB 控制器句柄。请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
isp_awb_ctlr_t awb_ctlr = NULL;
|
||
uint32_t image_width = 800;
|
||
uint32_t image_height = 600;
|
||
/* AWB 配置,请参考 API 注释来调整参数 */
|
||
esp_isp_awb_config_t awb_config = {
|
||
.sample_point = ISP_AWB_SAMPLE_POINT_AFTER_CCM,
|
||
...
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_new_awb_controller(isp_proc, &awb_config, &awb_ctlr));
|
||
|
||
其他 AWB API 和 AWB 方案也需要此步骤中创建的 AWB 句柄。
|
||
|
||
安装 ISP 自动曝光 (AE) 驱动程序
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP 自动曝光 (AE) 驱动程序需要由 :cpp:type:`esp_isp_ae_config_t` 指定配置。
|
||
|
||
指定 :cpp:type:`esp_isp_ae_config_t` 中的配置后,可以调用 :cpp:func:`esp_isp_new_ae_controller` 来分配和初始化 ISP AE 控制器。如果函数运行正常,将返回一个 ISP AE 控制器句柄。请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_ae_config_t ae_config = {
|
||
.sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
||
...
|
||
};
|
||
isp_ae_ctlr_t ae_ctlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_ae_controller(isp_proc, &ae_config, &ae_ctlr));
|
||
|
||
使用上述句柄,可以启用/禁用 ISP AE 驱动程序,也可以设置 ISP AE 环境检测器。
|
||
|
||
安装 ISP 直方图 (HIST) 驱动程序
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP 直方图 (HIST) 驱动程序需要由 :cpp:type:`esp_isp_hist_config_t` 指定配置。
|
||
|
||
指定 :cpp:type:`esp_isp_hist_config_t` 中的配置后,可以调用 :cpp:func:`esp_isp_new_hist_controller` 来分配和初始化 ISP 直方图控制器。如果此函数运行正常,将返回一个 ISP HIST 控制器句柄。请参考以下代码。
|
||
|
||
.. list::
|
||
|
||
- 所有子窗口权重的十进制值之和应为 256,否则统计数据将较小,并且整数值应为 0。
|
||
- 所有 RGB 系数的十进制值之和应为 256,否则统计数据将较小,并且整数值应为 0。
|
||
- segment_threshold 必须在 0~255 之间且按顺序排列。
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_hist_config_t hist_cfg = {
|
||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||
.rgb_coefficient.coeff_r = {
|
||
.integer = 0,
|
||
.decimal = 86,
|
||
},
|
||
.rgb_coefficient.coeff_g = {
|
||
.integer = 0,
|
||
.decimal = 85,
|
||
},
|
||
.rgb_coefficient.coeff_b = {
|
||
.integer = 0,
|
||
.decimal = 85,
|
||
},
|
||
.window_weight = {
|
||
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||
},
|
||
};
|
||
isp_hist_ctlr_t hist_ctlr_ctlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
||
|
||
使用上述句柄,可以启用/禁用 ISP HIST 驱动程序的设置。
|
||
|
||
卸载 ISP 驱动程序
|
||
~~~~~~~~~~~~~~~~~
|
||
|
||
如果不再需要先前安装的 ISP 驱动程序,建议通过调用 API 来回收资源,并释放底层硬件:
|
||
|
||
.. list::
|
||
|
||
- :cpp:func:`esp_isp_del_processor`,用于 ISP 核心处理器。
|
||
- :cpp:func:`esp_isp_del_af_controller`,用于 ISP AF 控制器。
|
||
- :cpp:func:`esp_isp_del_awb_controller`,用于 ISP AWB 控制器。
|
||
- :cpp:func:`esp_isp_del_ae_controller`,用于 ISP AE 控制器。
|
||
- :cpp:func:`esp_isp_del_hist_controller`,用于 ISP 直方图控制器。
|
||
|
||
.. _isp-enable-disable:
|
||
|
||
启用和禁用 ISP
|
||
^^^^^^^^^^^^^^
|
||
|
||
ISP
|
||
~~~
|
||
|
||
在进行 ISP 流水线操作之前,需要先调用 :cpp:func:`esp_isp_enable` 函数来启用 ISP 处理器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
ISP AF 控制器
|
||
~~~~~~~~~~~~~
|
||
|
||
在进行 ISP AF 操作之前,需要先调用 :cpp:func:`esp_isp_af_controller_enable` 函数来启用 ISP AF 控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_af_controller_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-af-statistics:
|
||
|
||
单次与连续 AF 数据统计
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_af_controller_get_oneshot_statistics` 可获取单次 AF 统计结果,请参考以下代码。
|
||
|
||
除此之外,ISP AF 驱动程序还可以连续获取 AF 统计信息。调用 :cpp:func:`esp_isp_af_controller_start_continuous_statistics` 可启动连续统计,调用 :cpp:func:`esp_isp_af_controller_stop_continuous_statistics` 可停止统计。
|
||
|
||
若想启用连续统计,需要先注册回调函数 :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_statistics_done` 或 :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_change` 以获取统计数据。有关如何注册回调函数,请参见 :ref:`isp-callback`。
|
||
|
||
.. note::
|
||
|
||
使用连续统计时,AF 环境检测器将失效。
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_af_config_t af_config = {
|
||
.edge_thresh = 128,
|
||
};
|
||
isp_af_ctlr_t af_ctrlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr));
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_enable(af_ctrlr));
|
||
isp_af_result_t result = {};
|
||
/* 触发单次 AF 统计并获取结果,超时时长为 2000 ms */
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_get_oneshot_statistics(af_ctrlr, 2000, &result));
|
||
|
||
/* 启动连续 AF 数据统计 */
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_start_continuous_statistics(af_ctrlr));
|
||
// 可在此进行其他操作,统计结果可从回调函数中获取
|
||
// ......
|
||
// vTaskDelay(pdMS_TO_TICKS(1000));
|
||
/* 停止连续 AF 数据统计 */
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_stop_continuous_statistics(af_ctrlr));
|
||
|
||
/* 禁用 AF 控制器 */
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_disable(af_ctrlr));
|
||
/* 删除 AF 控制器并释放资源 */
|
||
ESP_ERROR_CHECK(esp_isp_del_af_controller(af_ctrlr));
|
||
|
||
设置 AF 环境检测器
|
||
^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_af_controller_set_env_detector` 来设置 ISP AF 环境检测器,请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_af_env_config_t env_config = {
|
||
.interval = 10,
|
||
};
|
||
isp_af_ctlr_t af_ctrlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_af_controller(isp_proc, &af_config, &af_ctrlr));
|
||
ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector(af_ctrlr, &env_config));
|
||
|
||
设置 AF 环境检测器阈值
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_af_controller_set_env_detector_threshold` 来设置 ISP AF 环境检测器的阈值。
|
||
|
||
.. code-block:: c
|
||
|
||
int definition_thresh = 0;
|
||
int luminance_thresh = 0;
|
||
ESP_ERROR_CHECK(esp_isp_af_env_detector_set_threshold(env_detector, definition_thresh, luminance_thresh));
|
||
|
||
ISP AWB 控制器
|
||
~~~~~~~~~~~~~~
|
||
|
||
在进行 ISP AWB 操作之前,需要先调用 :cpp:func:`esp_isp_awb_controller_enable` 以启用 ISP AWB 控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_awb_controller_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-awb-statistics:
|
||
|
||
单次与连续 AWB 数据统计
|
||
^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_awb_controller_get_oneshot_statistics` 可获取单次 AWB 白块统计结果,请参考以下代码。
|
||
|
||
除此之外,ISP AWB 驱动程序还可以连续获取 AWB 统计信息。调用 :cpp:func:`esp_isp_awb_controller_start_continuous_statistics` 可启动连续统计,调用 :cpp:func:`esp_isp_awb_controller_stop_continuous_statistics` 可停止统计。
|
||
|
||
若想启用连续统计,需要先注册回调函数 :cpp:member:`esp_isp_awb_cbs_t::on_statistics_done` 以获取统计结果。有关如何注册回调函数,请参见 :ref:`isp-callback`。
|
||
|
||
.. code-block:: c
|
||
|
||
bool example_isp_awb_on_statistics_done_cb(isp_awb_ctlr_t awb_ctlr, const esp_isp_awb_evt_data_t *edata, void *user_data);
|
||
// ...
|
||
isp_awb_ctlr_t awb_ctlr = NULL;
|
||
uint32_t image_width = 800;
|
||
uint32_t image_height = 600;
|
||
/* AWB 配置,请参考 API 注释来调整参数 */
|
||
esp_isp_awb_config_t awb_config = {
|
||
.sample_point = ISP_AWB_SAMPLE_POINT_AFTER_CCM,
|
||
...
|
||
};
|
||
isp_awb_stat_result_t stat_res = {};
|
||
/* 创建 AWB 控制器 */
|
||
ESP_ERROR_CHECK(esp_isp_new_awb_controller(isp_proc, &awb_config, &awb_ctlr));
|
||
/* 注册 AWB 回调函数 */
|
||
esp_isp_awb_cbs_t awb_cb = {
|
||
.on_statistics_done = example_isp_awb_on_statistics_done_cb,
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_awb_register_event_callbacks(awb_ctlr, &awb_cb, NULL));
|
||
/* 启用 AWB 控制器 */
|
||
ESP_ERROR_CHECK(esp_isp_awb_controller_enable(awb_ctlr));
|
||
|
||
/* 获取单次 AWB 统计结果 */
|
||
ESP_ERROR_CHECK(esp_isp_awb_controller_get_oneshot_statistics(awb_ctlr, -1, &stat_res));
|
||
|
||
/* 启动连续 AWB 数据统计,注意在此之前需要先注册 `on_statistics_done` 回调函数 */
|
||
ESP_ERROR_CHECK(esp_isp_awb_controller_start_continuous_statistics(awb_ctlr));
|
||
// 可在此进行其他操作,统计结果可从回调函数中获取
|
||
// ......
|
||
// vTaskDelay(pdMS_TO_TICKS(1000));
|
||
/* 停止连续 AWB 数据统计 */
|
||
ESP_ERROR_CHECK(esp_isp_awb_controller_stop_continuous_statistics(awb_ctlr));
|
||
|
||
/* 禁用 AWB 控制器 */
|
||
ESP_ERROR_CHECK(esp_isp_awb_controller_disable(awb_ctlr));
|
||
/* 删除 AWB 控制器并释放资源 */
|
||
ESP_ERROR_CHECK(esp_isp_del_awb_controller(awb_ctlr));
|
||
|
||
ISP AE 控制器
|
||
~~~~~~~~~~~~~
|
||
|
||
在进行 ISP AE 操作之前,需要先调用 :cpp:func:`esp_isp_ae_controller_enable` 来启用 ISP AE 控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_ae_controller_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-ae-statistics:
|
||
|
||
单次与连续 AE 数据统计
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_ae_controller_get_oneshot_statistics` 可获取单次 AE 统计结果,请参考以下代码。
|
||
|
||
使用单次 AE 数据统计时,需要禁用连续 AE 模式,否则结果可能会被环境检测器覆盖。完成单次操作后,请重新启动连续模式。
|
||
|
||
除了上述单次统计 API 外,ISP AE 驱动程序还可以连续获取 AE 统计信息。调用 :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_statistics_done` 可启动连续统计,调用 :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_change` 可停止统计。
|
||
|
||
若想启用连续统计,需要先注册回调函数 :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_statistics_done` 或 :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_change` 以获取统计数据。有关如何注册回调函数,请参见 :ref:`isp-callback`。
|
||
|
||
.. note::
|
||
|
||
使用单次统计时,AE 环境检测器将暂时失效,并在完成单次操作后自动恢复。
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_ae_config_t ae_config = {
|
||
.sample_point = ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC,
|
||
};
|
||
isp_ae_ctlr_t ae_ctlr = NULL;
|
||
ESP_ERROR_CHECK(esp_isp_new_ae_controller(isp_proc, &ae_config, &ae_ctlr));
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_enable(ae_ctlr));
|
||
isp_ae_result_t result = {};
|
||
/* 触发单次 AE 统计并获取结果,超时时长为 2000 ms */
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_get_oneshot_statistics(ae_ctlr, 2000, &result));
|
||
|
||
/* 启动连续 AE 数据统计 */
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_start_continuous_statistics(ae_ctlr));
|
||
// 可在此进行其他操作,统计结果可从回调函数中获取
|
||
// ......
|
||
// vTaskDelay(pdMS_TO_TICKS(1000));
|
||
/* 停止连续 AE 数据统计 */
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_stop_continuous_statistics(ae_ctlr));
|
||
|
||
/* 禁用 AE 控制器 */
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_disable(ae_ctlr));
|
||
/* 删除 AE 控制器并释放资源 */
|
||
ESP_ERROR_CHECK(esp_isp_del_ae_controller(ae_ctlr));
|
||
|
||
设置 AE 环境检测器
|
||
^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_ae_controller_set_env_detector` 来设置 ISP AE 环境检测器,请参考以下代码:
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_ae_env_config_t env_config = {
|
||
.interval = 10,
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_set_env_detector(ae_ctlr, &env_config));
|
||
|
||
设置 AE 环境检测器阈值
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_ae_controller_set_env_detector_threshold` 来设置 ISP AE 环境检测器的阈值 (1-255)。
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_ae_env_thresh_t env_thresh = {
|
||
.low_thresh = 110,
|
||
.high_thresh = 130,
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_ae_controller_set_env_detector_threshold(ae_ctlr, env_thresh));
|
||
|
||
.. _isp-hist:
|
||
|
||
ISP 直方图控制器
|
||
~~~~~~~~~~~~~~~~
|
||
|
||
在进行 ISP 直方图统计之前,需要先调用 :cpp:func:`esp_isp_hist_controller_enable` 以启用 ISP 直方图控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_hist_controller_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-hist-statistics:
|
||
|
||
单次与连续直方图数据统计
|
||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
调用 :cpp:func:`esp_isp_hist_controller_get_oneshot_statistics` 可获取单次直方图统计结果,请参考以下代码。
|
||
|
||
除此之外,ISP 直方图驱动程序还可以连续获取直方图统计信息。调用 :cpp:func:`esp_isp_hist_controller_start_continuous_statistics` 可启动连续统计,调用 :cpp:func:`esp_isp_hist_controller_stop_continuous_statistics` 可停止连续统计。
|
||
|
||
若想启用连续统计,需要先注册回调函数 :cpp:member:`esp_isp_hist_cbs_t::on_statistics_done` 以获取统计结果。有关如何注册回调函数,请参见 :ref:`isp-callback`。
|
||
|
||
.. code:: c
|
||
|
||
static bool s_hist_scheme_on_statistics_done_callback(isp_hist_ctlr_t awb_ctrlr, const esp_isp_hist_evt_data_t *edata, void *user_data)
|
||
{
|
||
for(int i = 0; i < 16; i++) {
|
||
esp_rom_printf(DRAM_STR("val %d is %x\n"), i, edata->hist_result.hist_value[i]); // 获取直方图统计值
|
||
}
|
||
return true;
|
||
}
|
||
|
||
esp_isp_hist_cbs_t hist_cbs = {
|
||
.on_statistics_done = s_hist_scheme_on_statistics_done_callback,
|
||
};
|
||
|
||
esp_isp_hist_register_event_callbacks(hist_ctlr, &hist_cbs, hist_ctlr);
|
||
esp_isp_hist_controller_enable(hist_ctlr);
|
||
|
||
|
||
.. _isp-bf:
|
||
|
||
ISP BF 控制器
|
||
~~~~~~~~~~~~~
|
||
|
||
此流水线用于在拜耳模式下进行图像输入降噪。
|
||
|
||
可调用 :cpp:func:`esp_isp_bf_configure` 函数配置 BF 功能,请参考以下代码:
|
||
|
||
.. code-block:: c
|
||
|
||
esp_isp_bf_config_t bf_config = {
|
||
.denoising_level = 5,
|
||
.bf_template = {
|
||
{1, 2, 1},
|
||
{2, 4, 2},
|
||
{1, 2, 1},
|
||
},
|
||
...
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_bf_configure(isp_proc, &bf_config));
|
||
ESP_ERROR_CHECK(esp_isp_bf_enable(isp_proc));
|
||
|
||
:cpp:member:`esp_isp_bf_config_t::bf_template` 用于拜耳域降噪。可以通过高斯滤波器模板或均值滤波器模板来设置 :cpp:member:`esp_isp_bf_config_t::bf_template`。
|
||
|
||
调用 :cpp:func:`esp_isp_bf_configure` 后,需要通过调用 :cpp:func:`esp_isp_bf_enable` 来启用 ISP BF 控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_bf_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-color:
|
||
|
||
ISP 色彩控制器
|
||
~~~~~~~~~~~~~~
|
||
|
||
该流水线用于调整图像的对比度、饱和度、色调和亮度。
|
||
|
||
可调用 :cpp:func:`esp_isp_color_configure` 函数配置色彩功能,请参考以下代码。
|
||
|
||
{IDF_TARGET_SOC_ISP_COLOR_CONTRAST_MAX:default="1.0", esp32p4="1.0"}
|
||
{IDF_TARGET_SOC_ISP_COLOR_CONTRAST_DEFAULT:default="1.0", esp32p4="1.0"}
|
||
|
||
{IDF_TARGET_SOC_ISP_COLOR_SATURATION_MAX:default="1.0", esp32p4="1.0"}
|
||
{IDF_TARGET_SOC_ISP_COLOR_SATURATION_DEFAULT:default="1.0", esp32p4="1.0"}
|
||
|
||
{IDF_TARGET_SOC_ISP_COLOR_HUE_MAX:default="360", esp32p4="360"}
|
||
{IDF_TARGET_SOC_ISP_COLOR_HUE_DEFAULT:default="0", esp32p4="0"}
|
||
|
||
{IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_MIN:default="-127", esp32p4="-127"}
|
||
{IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_MAX:default="128", esp32p4="128"}
|
||
{IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_DEFAULT:default="0", esp32p4="0"}
|
||
|
||
.. list::
|
||
|
||
- 对比度应为 0 ~ {IDF_TARGET_SOC_ISP_COLOR_CONTRAST_MAX},默认值为 {IDF_TARGET_SOC_ISP_COLOR_CONTRAST_DEFAULT}
|
||
- 饱和度应为 0 ~ {IDF_TARGET_SOC_ISP_COLOR_SATURATION_MAX},默认值为 {IDF_TARGET_SOC_ISP_COLOR_SATURATION_DEFAULT}
|
||
- 色调应为 0 ~ {IDF_TARGET_SOC_ISP_COLOR_HUE_MAX},默认值为 {IDF_TARGET_SOC_ISP_COLOR_HUE_DEFAULT}
|
||
- 亮度应为 {IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_MIN} ~ {IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_MAX},默认值为 {IDF_TARGET_SOC_ISP_COLOR_BRIGHTNESS_DEFAULT}
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_color_config_t color_config = {
|
||
.color_contrast = {
|
||
.integer = 1,
|
||
.decimal = 0,
|
||
},
|
||
.color_saturation = {
|
||
.integer = 1,
|
||
.decimal = 0,
|
||
},
|
||
.color_hue = 0,
|
||
.color_brightness = 0,
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_color_configure(isp_proc, &color_config));
|
||
ESP_ERROR_CHECK(esp_isp_color_enable(isp_proc));
|
||
|
||
调用 :cpp:func:`esp_isp_color_configure` 后,需要通过调用 :cpp:func:`esp_isp_color_enable` 来启用 ISP 色彩控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换为 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_color_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
.. _isp-ccm-config:
|
||
|
||
配置 CCM
|
||
^^^^^^^^
|
||
|
||
色彩校正矩阵可以调整 RGB888 像素格式的颜色比例,可用于通过算法调整图像颜色(例如,使用 AWB 计算结果进行白平衡),或者通过滤波算法用作过滤器。
|
||
|
||
调整色彩校正矩阵的公式如下:
|
||
|
||
.. code-block:: none
|
||
|
||
[ R' ] [ RR RG RB ] [ R ]
|
||
[ G' ] = [ GR GG GB ] * [ G ]
|
||
[ B' ] [ BR BG BB ] [ B ]
|
||
|
||
可以参考以下代码进行配置:
|
||
|
||
.. code-block:: c
|
||
|
||
// ...
|
||
// 配置 CCM
|
||
esp_isp_ccm_config_t ccm_cfg = {
|
||
.matrix = {
|
||
1.0, 0.0, 0.0,
|
||
0.0, 1.0, 0.0,
|
||
0.0, 0.0, 1.0
|
||
},
|
||
.saturation = false,
|
||
...
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_ccm_configure(isp_proc, &ccm_cfg));
|
||
// 启用 CCM 模块后,配置好的 CCM 将应用到图像上
|
||
ESP_ERROR_CHECK(esp_isp_ccm_enable(isp_proc));
|
||
// CCM 也可以在启用后进行配置
|
||
ccm_cfg.matrix[0][0] = 2.0;
|
||
ESP_ERROR_CHECK(esp_isp_ccm_configure(isp_proc, &ccm_cfg));
|
||
// 如果不再需要 CCM,则禁用它
|
||
ESP_ERROR_CHECK(esp_isp_ccm_disable(isp_proc));
|
||
|
||
.. _isp-demosaic:
|
||
|
||
ISP 去马赛克控制器
|
||
~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
此流水线用于执行图像去马赛克算法,将 RAW 图像转换为 RGB 模式。
|
||
|
||
可调用 :cpp:func:`esp_isp_demosaic_configure` 来配置去马赛克功能,请参考以下代码:
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_demosaic_config_t demosaic_config = {
|
||
.grad_ratio = {
|
||
.integer = 2,
|
||
.decimal = 5,
|
||
},
|
||
...
|
||
};
|
||
|
||
ESP_ERROR_CHECK(esp_isp_demosaic_configure(isp_proc, &sharpen_config));
|
||
ESP_ERROR_CHECK(esp_isp_demosaic_enable(isp_proc));
|
||
|
||
调用 :cpp:func:`esp_isp_demosaic_configure` 后,需要通过调用 :cpp:func:`esp_isp_demosaic_enable` 来启用 ISP 去马赛克控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_demosaic_disable` 会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
即使驱动程序处于 **init** 状态,也可以调用 :cpp:func:`esp_isp_demosaic_configure`,但去马赛克配置只有在 **enable** 状态下才会生效。
|
||
|
||
.. _isp-gamma-correction:
|
||
|
||
启用 gamma 校正
|
||
^^^^^^^^^^^^^^^
|
||
|
||
人眼的视觉系统对物理亮度的感知是非线性的。将 gamma 校正添加到 ISP 流水线中,可以将 RGB 坐标转换为坐标与主观亮度成正比的空间。
|
||
|
||
驱动程序提供了帮助函数 :cpp:func:`esp_isp_gamma_fill_curve_points`,用于填充 :cpp:type:`isp_gamma_curve_points_t`,这是描述 gamma 校正曲线的点集合。也可以通过手动声明点来获得期望的 gamma 校正曲线。每个 R/G/B 分量有自己的 gamma 校正曲线,可以通过调用 :cpp:func:`esp_isp_gamma_configure` 来配置。
|
||
|
||
以下是一个典型的代码示例:
|
||
|
||
.. code:: c
|
||
|
||
#include <math.h>
|
||
|
||
// 设置相机 gamma 为 0.7,gamma 校正曲线为 y = 256 * (x / 256) ^ 0.7
|
||
static uint32_t s_gamma_curve(uint32_t x)
|
||
{
|
||
return pow((double)x / 256, 0.7) * 256;
|
||
}
|
||
|
||
isp_gamma_curve_points_t pts = {};
|
||
ESP_ERROR_CHECK(esp_isp_gamma_fill_curve_points(s_gamma_curve, &pts));
|
||
ESP_ERROR_CHECK(esp_isp_gamma_configure(isp_proc, COLOR_COMPONENT_R, &pts));
|
||
ESP_ERROR_CHECK(esp_isp_gamma_configure(isp_proc, COLOR_COMPONENT_G, &pts));
|
||
ESP_ERROR_CHECK(esp_isp_gamma_configure(isp_proc, COLOR_COMPONENT_B, &pts));
|
||
|
||
// 配置完曲线参数后启用 gamma 模块
|
||
ESP_ERROR_CHECK(esp_isp_gamma_enable(isp_proc));
|
||
|
||
// 如果不再需要,则禁用 gamma
|
||
ESP_ERROR_CHECK(esp_isp_gamma_disable(isp_proc));
|
||
|
||
.. _isp-sharpen:
|
||
|
||
ISP 锐化控制器
|
||
~~~~~~~~~~~~~~
|
||
|
||
此流水线用于在 YUV 模式下锐化输入图像。
|
||
|
||
调用 :cpp:func:`esp_isp_sharpen_configure` 来配置锐化功能,请参考以下代码。
|
||
|
||
.. code:: c
|
||
|
||
esp_isp_sharpen_config_t sharpen_config = {
|
||
.h_thresh = 255,
|
||
.sharpen_template = {
|
||
{1, 2, 1},
|
||
{2, 4, 2},
|
||
{1, 2, 1},
|
||
},
|
||
...
|
||
};
|
||
ESP_ERROR_CHECK(esp_isp_sharpen_configure(isp_proc, &sharpen_config));
|
||
ESP_ERROR_CHECK(esp_isp_sharpen_enable(isp_proc));
|
||
|
||
调用 :cpp:member:`esp_isp_sharpen_config_t::sharpen_template` 进行锐化。可以通过高斯滤波器模板或均值滤波器模板来设置 :cpp:member:`esp_isp_sharpen_config_t::sharpen_template`。
|
||
|
||
调用 :cpp:func:`esp_isp_sharpen_configure` 后,需要通过调用 :cpp:func:`esp_isp_sharpen_enable` 以启用 ISP 锐化控制器。此函数:
|
||
|
||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||
|
||
调用 :cpp:func:`esp_isp_sharpen_disable` 函数会执行相反的操作,即将驱动程序恢复到 **init** 状态。
|
||
|
||
即使驱动程序处于 **init** 状态,也可以调用 :cpp:func:`esp_isp_sharpen_configure`,但锐化配置只有在 **enable** 状态下才会生效。
|
||
|
||
|
||
.. _isp-callback:
|
||
|
||
注册事件回调函数
|
||
^^^^^^^^^^^^^^^^
|
||
|
||
ISP 模块启动后,会动态生成特定事件。
|
||
|
||
你也可以通过参数 ``user_data`` 将自己的上下文保存到回调函数中,用户数据将直接传递给回调函数。
|
||
|
||
.. note::
|
||
|
||
下文中提到的回调函数在 ISR 上下文中被调用,必须确保这些函数不会尝试阻塞(例如,确保只从函数中调用带有 ``ISR`` 后缀的 FreeRTOS API)。
|
||
|
||
注册 ISP 处理器事件回调函数
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
启用 ISP 处理器后,会动态生成多个 ISP 子模块的事件。可以通过调用 :cpp:func:`esp_isp_register_event_callbacks` 将函数挂接到中断服务例程。所有支持的事件回调函数可参见 :cpp:type:`esp_isp_evt_cbs_t`:
|
||
|
||
- :cpp:member:`esp_isp_evt_cbs_t::on_sharpen_frame_done` 在完成锐化帧后设置回调函数。ISP 锐化子模块完成一帧的操作后会调用此函数。函数原型在 :cpp:type:`esp_isp_sharpen_callback_t` 中声明。
|
||
|
||
注册 ISP AF 环境检测器事件回调函数
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP AF 环境检测器启动后,将动态生成特定事件。若想在事件发生时调用某些函数,请通过调用 :cpp:func:`esp_isp_af_env_detector_register_event_callbacks` 将目标函数挂接到中断服务程序中。所有支持的事件回调函数可参见 :cpp:type:`esp_isp_af_env_detector_evt_cbs_t`:
|
||
|
||
- :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_statistics_done` 为环境统计完成事件设置回调函数。该函数原型在 :cpp:type:`esp_isp_af_env_detector_callback_t` 中声明。
|
||
- :cpp:member:`esp_isp_af_env_detector_evt_cbs_t::on_env_change` 为环境变化事件设置回调函数。该函数原型在 :cpp:type:`esp_isp_af_env_detector_callback_t` 中声明。
|
||
|
||
注册 ISP AWB 统计完成事件回调函数
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP AWB 控制器完成白块数据统计后,将动态生成特定事件。若想在统计完成时收到通知,请通过调用 :cpp:func:`esp_isp_awb_register_event_callbacks` 将目标函数挂接到中断服务程序中。所有支持的事件回调函数可参见 :cpp:type:`esp_isp_awb_cbs_t`:
|
||
|
||
- :cpp:member:`esp_isp_awb_cbs_t::on_statistics_done` 在白块数据统计完成后设置回调函数。该函数原型在 :cpp:type:`esp_isp_awb_callback_t` 中声明。
|
||
|
||
|
||
注册 ISP AE 环境检测器事件回调函数
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP AE 环境检测器启动后,将动态生成特定事件。若想在事件发生时调用某些函数,请通过调用 :cpp:func:`esp_isp_ae_env_detector_register_event_callbacks` 将目标函数挂接到中断服务程序中。所有支持的事件回调函数可参见 :cpp:type:`esp_isp_ae_env_detector_evt_cbs_t`:
|
||
|
||
- :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_statistics_done` 为环境统计完成事件设置回调函数。该函数原型在 :cpp:type:`esp_isp_ae_env_detector_callback_t` 中声明。
|
||
- :cpp:member:`esp_isp_ae_env_detector_evt_cbs_t::on_env_change` 为环境变化事件设置回调函数。该函数原型在 :cpp:type:`esp_isp_ae_env_detector_callback_t` 中声明。
|
||
|
||
|
||
注册 ISP HIST 统计完成事件回调函数
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ISP HIST 控制器完成亮度统计后,将动态生成特定事件。若想在统计完成时收到通知,请通过调用 :cpp:func:`esp_isp_hist_register_event_callbacks` 将目标函数挂挂接到中断服务程序。所有支持的事件回调函数可参见 :cpp:type:`esp_isp_hist_cbs_t`:
|
||
|
||
- :cpp:member:`esp_isp_hist_cbs_t::on_statistics_done` 在完成亮度统计时设置回调函数。该函数原型在 :cpp:type:`esp_isp_hist_callback_t` 中声明。
|
||
|
||
.. _isp-thread-safety:
|
||
|
||
线程安全
|
||
^^^^^^^^
|
||
|
||
驱动程序会确保以下工厂函数的线程安全:
|
||
|
||
.. list::
|
||
|
||
- :cpp:func:`esp_isp_new_processor`
|
||
- :cpp:func:`esp_isp_del_processor`
|
||
- :cpp:func:`esp_isp_new_af_controller`
|
||
- :cpp:func:`esp_isp_del_af_controller`
|
||
- :cpp:func:`esp_isp_new_awb_controller`
|
||
- :cpp:func:`esp_isp_del_awb_controller`
|
||
- :cpp:func:`esp_isp_new_ae_controller`
|
||
- :cpp:func:`esp_isp_del_ae_controller`
|
||
- :cpp:func:`esp_isp_new_hist_controller`
|
||
- :cpp:func:`esp_isp_del_hist_controller`
|
||
|
||
使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。其他 API 无法确保线程安全。
|
||
|
||
.. _isp-kconfig-options:
|
||
|
||
Kconfig 选项
|
||
^^^^^^^^^^^^
|
||
|
||
- :ref:`CONFIG_ISP_ISR_IRAM_SAFE` 控制默认的 ISR 句柄在 cache 被禁用时是否可以正常工作。
|
||
|
||
.. _isp-iram-safe:
|
||
|
||
IRAM 安全
|
||
^^^^^^^^^
|
||
|
||
默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,ISP 的中断将会延迟。
|
||
|
||
Kconfig 选项 :ref:`CONFIG_ISP_ISR_IRAM_SAFE` 支持:
|
||
|
||
- 即使 cache 被禁用也能启用中断
|
||
- 将 ISR 使用的所有函数放入 IRAM
|
||
- 将驱动程序对象放入 DRAM(以防意外映射到 PSRAM)
|
||
|
||
启用上述 Kconfig 选项,保证 cache 被禁用时中断可以正常运行,但这会增加 IRAM 使用量。启用此选项后,当 cache 被禁用时,ISR 回调函数将继续运行。因此,必须确保回调函数及其上下文也是 IRAM 安全的。
|
||
|
||
Kconfig 选项 :ref:`CONFIG_ISP_CTRL_FUNC_IN_IRAM` 支持:
|
||
|
||
- 将一些 ISP 控制函数放入 IRAM,函数列表请参见:
|
||
|
||
.. list::
|
||
|
||
- :cpp:func:`esp_isp_sharpen_configure`
|
||
- :cpp:func:`esp_isp_demosaic_configure`
|
||
|
||
应用示例
|
||
--------
|
||
|
||
* :example:`peripherals/isp/multi_pipelines` 演示了如何使用 ISP 流水线处理来自摄像头传感器的图像信号,并通过 DSI 外设在 LCD 屏幕上显示视频。
|
||
|
||
API 参考
|
||
--------
|
||
|
||
.. include-build-file:: inc/isp.inc
|
||
.. include-build-file:: inc/isp_af.inc
|
||
.. include-build-file:: inc/isp_ae.inc
|
||
.. include-build-file:: inc/isp_awb.inc
|
||
.. include-build-file:: inc/isp_bf.inc
|
||
.. include-build-file:: inc/isp_ccm.inc
|
||
.. include-build-file:: inc/isp_demosaic.inc
|
||
.. include-build-file:: inc/isp_sharpen.inc
|
||
.. include-build-file:: inc/isp_gamma.inc
|
||
.. include-build-file:: inc/isp_hist.inc
|
||
.. include-build-file:: inc/isp_color.inc
|
||
.. include-build-file:: inc/isp_core.inc
|
||
.. include-build-file:: inc/components/esp_driver_isp/include/driver/isp_types.inc
|
||
.. include-build-file:: inc/components/hal/include/hal/isp_types.inc
|