docs: Provide translation for jpeg&override_driver&arch in peripherals

This commit is contained in:
shenmengjing 2024-04-07 12:03:56 +08:00 committed by BOT
parent f375125e28
commit 2dc3068a21
6 changed files with 774 additions and 111 deletions

View File

@ -1,10 +1,12 @@
JPEG Encoder and Decoder
========================
:link_to_translation:`zh_CN:[中文]`
Introduction
------------
JPEG is a commonly used method of lossy compression for digital images, particularly for those images produced by digital photography. The degree of compression can be adjusted, allowing a selectable tradeoff between storage size and image quality. JPEG typically achieves 10:1 compression with little perceptible loss in image quality.
JPEG is a commonly used method of lossy compression for digital images, particularly for those images produced by digital photography. The compression level varies with changes in image size and compression quality. JPEG typically achieves 10:1 compression with little perceptible loss in image quality.
JPEG codec on {IDF_TARGET_NAME} is an image codec, which is based on the JPEG baseline standard, for compressing and decompressing images to reduce the bandwidth required to transmit images or the space required to store images, making it possible to process large-resolution images. But please note, at one time, the codec engine can only work as either encoder or decoder.
@ -20,7 +22,7 @@ This document covers the following sections:
- `Performance Overview <#performance-overview>`__ - covers encoder and decoder performance.
- `Pixel Storage Layout for Different Color Formats <#pixel-storage-layout-for-different-color-formats>`__ - covers color space order overview required in this JPEG decoder and encoder.
- `Thread Safety <#thread-safety>`__ - lists which APIs are guaranteed to be thread safe by the driver.
- `Power Management <#power-management>`__ - describes how jpeg driver would be affected by power consumption.
- `Power Management <#power-management>`__ - describes how JPEG driver would be affected by power consumption.
- `Kconfig Options <#kconfig-options>`__ - lists the supported Kconfig options that can bring different effects to the driver.
Resource Allocation
@ -97,37 +99,25 @@ JPEG Decoder Engine
After installing the JPEG decoder driver by :cpp:func:`jpeg_new_decoder_engine`, {IDF_TARGET_NAME} is ready to decode JPEG pictures by :cpp:func:`jpeg_decoder_process`. :cpp:func:`jpeg_decoder_process` is flexible for decoding different types of pictures by a configurable parameter called :cpp:type:`jpeg_decode_cfg_t`.
Moreover, our jpeg decoder api provides a helper function which helps you get the basic information of your given image. Calling :cpp:func:`jpeg_decoder_get_info` would return the picture information structure called :cpp:func:`jpeg_decoder_get_info`. If you already know the picture basic information, this functions is unnecessary to be called.
Moreover, our JPEG decoder API provides a helper function which helps you get the basic information of your given image. Calling :cpp:func:`jpeg_decoder_get_info` would return the picture information structure called :cpp:func:`jpeg_decoder_get_info`. If you already know the picture basic information, this functions is unnecessary to be called.
The format conversions supported by this driver are listed in the table below:
+----------------------------------------+-----------------------------------+
| Format of the already compressed image | Format after decompressing |
+========================================+===================================+
| | RGB565 |
| YUV444 +-----------------------------------+
| | RGB888 |
| +-----------------------------------+
| | YUV444 |
+----------------------------------------+-----------------------------------+
| | RGB565 |
| +-----------------------------------+
| | RGB888 |
| YUV422 +-----------------------------------+
| | YUV444 |
| +-----------------------------------+
| | YUV422 |
+----------------------------------------+-----------------------------------+
| | RGB565 |
| +-----------------------------------+
| | RGB888 |
| YUV420 +-----------------------------------+
| | YUV444 |
| +-----------------------------------+
| | YUV420 |
+----------------------------------------+-----------------------------------+
| GRAY | GRAY |
+----------------------------------------+-----------------------------------+
.. list-table::
:header-rows: 1
:widths: 50 50
:align: center
* - Format of the already compressed image
- Format after decompressing
* - YUV444
- RGB565/RGB888
* - YUV422
- RGB565/RGB888
* - YUV420
- RGB565/RGB888
* - GRAY
- GRAY
Overall, You can take following code as reference, the code is going to decode a 1080*1920 picture.
@ -158,34 +148,32 @@ Overall, You can take following code as reference, the code is going to decode a
ESP_ERROR_CHECK(jpeg_decoder_process(decoder_engine, &decode_cfg_rgb, bit_stream, bit_stream_size, out_buf, &out_size));
There are some Tips that can help you use this driver more accurately:
There are some tips that can help you use this driver more accurately:
1. In above code, you should make sure the `bit_stream` and `out_buf` should be aligned by certain rules. We provide a helper function :cpp:func:`jpeg_alloc_decoder_mem` to help you malloc a buffer which is aligned in both size and address.
2. The content of `bit_stream` buffer should not be changed until :cpp:func:`jpeg_decoder_process` returns.
3. The width and height of output picture would be 16 bytes aligned if original picture is formatted by YUV420 or YUV422. For example, if the input picture is 1080*1920, the output picture will be 1088*1920. That is the restriction of jpeg protocol. Please provide sufficient output buffer memory.
3. The width and height of output picture would be 16 bytes aligned if original picture is compressed by YUV420 or YUV422. For example, if the input picture is 1080*1920, the output picture will be 1088*1920. That is the restriction of jpeg protocol. Please provide sufficient output buffer memory.
JPEG Encoder Engine
^^^^^^^^^^^^^^^^^^^
After installing the JPEG encoder driver by :cpp:func:`jpeg_new_encoder_engine`, {IDF_TARGET_NAME} is ready to decode JPEG pictures by :cpp:func:`jpeg_encoder_process`. :cpp:func:`jpeg_encoder_process` is flexible for decoding different types of pictures by a configurable parameter called :cpp:type:`jpeg_encode_cfg_t`.
After installing the JPEG encoder driver by :cpp:func:`jpeg_new_encoder_engine`, {IDF_TARGET_NAME} is ready to encode JPEG pictures by :cpp:func:`jpeg_encoder_process`. :cpp:func:`jpeg_encoder_process` is flexible for decoding different types of pictures by a configurable parameter called :cpp:type:`jpeg_encode_cfg_t`.
The format conversions supported by this driver are listed in the table below:
+--------------------------+--------------------------------------+
| Format of Original Image | Down sampling method |
+==========================+======================================+
| | YUV444 |
| +--------------------------------------+
| RGB565/RGB888 | YUV422 |
| +--------------------------------------+
| | YUV420 |
+--------------------------+--------------------------------------+
| GRAY | GRAY |
+--------------------------+--------------------------------------+
| YUV422 | YUV422 |
+--------------------------+--------------------------------------+
.. list-table::
:header-rows: 1
:widths: 50 50
:align: center
* - Format of Original Image
- Down sampling method
* - RGB565/RGB888
- YUV444/YUV422/YUV420
* - GRAY
- GRAY
Below is the example of code that encodes a 1080*1920 picture:
@ -214,7 +202,7 @@ Below is the example of code that encodes a 1080*1920 picture:
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, &jpg_size_1080p););
There are some Tips that can help you use this driver more accurately:
There are some tips that can help you use this driver more accurately:
1. In above code, you should make sure the `raw_buf_1080p` and `jpg_buf_1080p` should aligned by calling :cpp:func:`jpeg_alloc_encoder_mem`.
@ -225,72 +213,133 @@ There are some Tips that can help you use this driver more accurately:
Performance Overview
^^^^^^^^^^^^^^^^^^^^
This section provides some measurements of the decoder and encoder performance. The data presented in the tables below gives the average values of decoding or encoding a randomly chosen picture fragments for 50 times. All tests were performed at a CPU frequency of 360MHz and a SPIRAM clock frequency of 200MHz. Only JPEG related code is run in this test, no other modules are involved (e.g. USB Camera, etc.).
This section provides some measurements of the decoder and encoder performance. The data presented in the tables below gives the average values of decoding or encoding a randomly chosen picture fragments for 50 times. All tests were performed at a CPU frequency of 360MHz and a SPI RAM clock frequency of 200MHz. Only JPEG related code is run in this test, no other modules are involved (e.g. USB Camera, etc.).
Both decoder and encoder are not cause too much CPU involvement. Only header parse causes CPU source. Calculations related to JPEG compression, such as DCT, quantization, huffman encoding/decoding, etc., are done entirely in hardware.
JPEG decoder performance
~~~~~~~~~~~~~~~~~~~~~~~~
+----------------+-------------------------------------------------------------------------------------+------------------+
| JPEG Size | Pixel Format | |
+--------+-------+--------------------------------------------+----------------------------------------+ Performance(fps) +
| Height | Width | in(Format of the already compressed image) | out(Format after decompressing) | |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 1080 | 1920 | YUV422 | RGB888/RGB565 | 48 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 720 | 1280 | YUV422 | RGB888/RGB565 | 109 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 800 | YUV422 | RGB888/RGB565 | 253 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 640 | YUV422 | RGB888/RGB565 | 307 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 320 | YUV422 | RGB888/RGB565 | 571 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 720 | 1280 | GRAY | GRAY | 161 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 800 | YUV444 | YUV444 | 129 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 800 | YUV422 | YUV444/YUV422 | 190 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
| 480 | 800 | YUV420 | YUV444/YUV420 | 253 |
+--------+-------+--------------------------------------------+----------------------------------------+------------------+
.. list-table::
:header-rows: 1
:widths: 25 25 25 25 25
:align: center
* - JPEG Height
- JPEG Width
- Pixel Format in [#]_
- Pixel Format out [#]_
- Performance (fps)
* - 1080
- 1920
- YUV422
- RGB888/RGB565
- 48
* - 720
- 1280
- YUV422
- RGB888/RGB565
- 109
* - 480
- 800
- YUV422
- RGB888/RGB565
- 253
* - 480
- 640
- YUV422
- RGB888/RGB565
- 307
* - 480
- 320
- YUV422
- RGB888/RGB565
- 571
* - 720
- 1280
- GRAY
- GRAY
- 161
.. [#] Format of the already compressed image
.. [#] Format after decompressing
JPEG encoder performance
~~~~~~~~~~~~~~~~~~~~~~~~
+----------------+-------------------------------------------------------------------------------------+------------------+
| JPEG Size | Pixel Format | |
+--------+-------+-----------------------------------------+-------------------------------------------+ Performance(fps) +
| Height | Width | in(Format of Original Image) | out(Down sampling method) | |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 1080 | 1920 | RGB888 | YUV422 | 26 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 1080 | 1920 | RGB565 | YUV422 | 36 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 1080 | 1920 | RGB565 | YUV420 | 40 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 1080 | 1920 | RGB565 | YUV444 | 24 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 1080 | 1920 | RGB888 | YUV422 | 26 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 720 | 1280 | RGB565 | YUV420 | 88 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 720 | 1280 | RGB565 | YUV444 | 55 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 720 | 1280 | RGB565 | YUV422 | 81 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 480 | 800 | RGB888 | YUV420 | 142 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 480 | 640 | RGB888 | YUV420 | 174 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 480 | 320 | RGB888 | YUV420 | 315 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 720 | 1280 | GRAY | GRAY | 163 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
| 480 | 800 | YUV422 | YUV422 | 146 |
+--------+-------+-----------------------------------------+-------------------------------------------+------------------+
.. list-table::
:header-rows: 1
:widths: 25 25 25 25 25
:align: center
* - JPEG Height
- JPEG Width
- Pixel Format in [#]_
- Pixel Format out [#]_
- Performance (fps)
* - 1080
- 1920
- RGB888
- YUV422
- 26
* - 1080
- 1920
- RGB565
- YUV422
- 36
* - 1080
- 1920
- RGB565
- YUV420
- 40
* - 1080
- 1920
- RGB565
- YUV444
- 24
* - 1080
- 1920
- RGB888
- YUV422
- 26
* - 720
- 1280
- RGB565
- YUV420
- 88
* - 720
- 1280
- RGB565
- YUV444
- 55
* - 720
- 1280
- RGB565
- YUV422
- 81
* - 480
- 800
- RGB888
- YUV420
- 142
* - 640
- 800
- RGB888
- YUV420
- 174
* - 480
- 320
- RGB888
- YUV420
- 315
* - 720
- 1280
- GRAY
- GRAY
- 163
.. [#] Format of Original Image
.. [#] Down sampling method
Pixel Storage Layout for Different Color Formats
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -376,9 +425,9 @@ The factory function :cpp:func:`jpeg_new_decoder_engine`, :cpp:func:`jpeg_decode
Power Management
^^^^^^^^^^^^^^^^
When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is set), the system needs to adjust or stop the source clock of JPEG to enter Light-sleep, thus potentially changing the JPEG decoder or encoder process. This might lead to unexpected behavior in hardware calculation. To prevent such issues, entering light sleep is disabled for the time when JPEG encoder or decoder is working.
When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is set), the system needs to adjust or stop the source clock of JPEG to enter Light-sleep, thus potentially changing the JPEG decoder or encoder process. This might lead to unexpected behavior in hardware calculation. To prevent such issues, entering Light-sleep is disabled for the time when JPEG encoder or decoder is working.
Whenever the user is decoding or encoding via JPEG (i.e., calling :cpp:func:`jpeg_encoder_process` or :cpp:func:`jpeg_decoder_process`), the driver guarantees that the power management lock is acquired by setting it to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_NO_LIGHT_SLEEP`. Once the encoding or decoding is finished, the driver releases the lock and the system can enter light sleep.
Whenever the user is decoding or encoding via JPEG (i.e., calling :cpp:func:`jpeg_encoder_process` or :cpp:func:`jpeg_decoder_process`), the driver guarantees that the power management lock is acquired by setting it to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_CPU_FREQ_MAX`. Once the encoding or decoding is finished, the driver releases the lock and the system can enter Light-sleep.
Kconfig Options
^^^^^^^^^^^^^^^
@ -388,7 +437,7 @@ Kconfig Options
Maintainers' Notes
------------------
The JPEG driver usage of hardware resources and its process workflow are shown in the following graph:
The JPEG driver usage of hardware resources and its dependency status are shown in the following graph:
.. figure:: ../../../_static/diagrams/jpeg/jpeg_drv_file_structure.png
:align: center

View File

@ -1,6 +1,8 @@
Overriding Default Chip Drivers
===============================
:link_to_translation:`zh_CN:[中文]`
.. warning::
Customizing SPI Flash Chip Drivers is considered an "expert" feature. Users should only do so at their own risk. (See the notes below)
@ -39,7 +41,7 @@ Steps For Creating Custom Chip Drivers and Overriding the ESP-IDF Default Driver
- When writing your own flash chip driver, you can set your flash chip capabilities through ``spi_flash_chip_***(vendor)_get_caps`` and points the function pointer ``get_chip_caps`` for protection to the ``spi_flash_chip_***_get_caps`` function. The steps are as follows.
1. Please check whether your flash chip have the capabilities listed in ``spi_flash_caps_t`` by checking the flash datasheet.
2. Write a function named ``spi_flash_chip_***(vendor)_get_caps``. Take the example below as a reference. (if the flash support ``suspend`` and ``read unique id``).
2. Write a function named ``spi_flash_chip_***(vendor)_get_caps``. Take the example below as a reference (if the flash support ``suspend`` and ``read unique id``).
3. Points the pointer ``get_chip_caps`` (in ``spi_flash_chip_t``) to the function mentioned above.
.. code-block:: c

View File

@ -1,6 +1,8 @@
USB Host Maintainers Notes (Architecture)
=========================================
:link_to_translation:`zh_CN:[中文]`
The Host Stack is roughly split into multiple layers of abstraction, with each layer representing different USB concepts and a different level of USB Host operation. For example, a higher layer may present an abstraction of devices and application data transfers, whereas a lower layer may present an abstraction of endpoints and USB transfers.
Layer Descriptions
@ -45,9 +47,9 @@ Layer Dependencies
The Host Stack roughly follows a top to bottom hierarchy with inter-layer dependencies. Given layers A (highest), B, and C (lowest), the Host Stack has the following inter-layer dependency rules:
- a particular layer can use the API of any layer directly below (Layer A using layer B is allowed)
- a particular layer can use the API of any layer directly below (Layer A using layer B is allowed).
- a particular layer can use the API of any layer indirectly below (Layer A using layer C is allowed) i.e., skipping layers.
- a particular layer must not use the API of any layer above (Layer C using layer A/B is forbidden)
- a particular layer must not use the API of any layer above (Layer C using layer A/B is forbidden).
.. note::

View File

@ -1 +1,466 @@
.. include:: ../../../en/api-reference/peripherals/jpeg.rst
JPEG 图像编解码器
===================
:link_to_translation:`en:[English]`
简介
----
JPEG 常用于数字图像尤其是数码摄影图像的有损压缩。压缩程度会随图片大小和压缩质量的变化而改变。JPEG 通常能保证图像质量损失肉眼不可见,并实现 10:1 的压缩。
{IDF_TARGET_NAME} 的 JPEG 编解码器是一种基于 JPEG 基线标准的图像编解码器,可以压缩和解压缩图像,从而降低传输图像所需的带宽或存储图像所需的空间,可以处理高分辨率的图像。但请注意,编解码器引擎不能同时作为编码器和解码器工作。
功能概述
--------
本文档包含以下几部分内容:
- `资源分配 <#resource-allocation>`__,包括如何正确地设置配置来分配 JPEG 资源、如何在完成工作时回收资源。
- `有限状态机 <#finite-state-machine>`__,涵盖了 JPEG 的工作流程,介绍了 JPEG 驱动程序的软件流程,以及是如何使用内部资源的。
- `JPEG 解码器引擎 <#jpeg_decoder_engine>`__,包括 JPEG 解码器引擎的行为。介绍了如何使用解码器引擎函数为图像解码(从 jpg 格式到 raw 格式)。
- `JPEG 编码器引擎 <#jpeg_encoder_engine>`__,包括 JPEG 编码器引擎的行为。介绍了如何使用编码器引擎函数为图像编码(从 raw 格式到 jpg 格式)。
- `性能概览 <#performance-overview>`__,介绍了编码器和解码器的性能。
- `不同颜色格式的像素存储布局 <#pixel-storage-layout-for-different-color-formats>`__,涵盖了 JPEG 解码器和编码器所需的颜色空间顺序。
- `线程安全性 <#thread-safety>`__ 列出了驱动程序能保证线程安全的 API。
- `电源管理 <#power-management>`__,描述了影响 JPEG 驱动程序功耗的因素。
- `Kconfig 选项 <#kconfig-options>`__,列出了支持的 Kconfig 选项,可以为驱动程序带来不同的效果。
资源分配
^^^^^^^^
安装 JPEG 解码器引擎
~~~~~~~~~~~~~~~~~~~~
JPEG 解码器引擎的配置需要由 :cpp:type:`jpeg_decode_engine_cfg_t` 指定:
如果在 :cpp:type:`jpeg_decode_engine_cfg_t` 中指定了配置,则可以调用 :cpp:func:`jpeg_new_decoder_engine` 来分配和初始化 JPEG 解码器引擎。如果该函数运行正确,则会返回一个 JPEG 解码器句柄。请参考以下代码:
.. code:: c
jpeg_decoder_handle_t decoder_engine;
jpeg_decode_engine_cfg_t decode_eng_cfg = {
.intr_priority = 0,
.timeout_ms = 40,
};
ESP_ERROR_CHECK(jpeg_new_decoder_engine(&decode_eng_cfg, &decoder_engine));
卸载 JPEG 解码器引擎
~~~~~~~~~~~~~~~~~~~~
如果不再需要先前安装的 JPEG 引擎,建议通过调用 :cpp:func:`jpeg_del_decoder_engine` 回收资源,从而释放底层硬件。
.. code:: c
ESP_ERROR_CHECK(jpeg_del_decoder_engine(decoder_engine));
安装 JPEG 编码器引擎
~~~~~~~~~~~~~~~~~~~~
JPEG 编码器引擎的配置需要由 :cpp:type:`jpeg_encode_engine_cfg_t` 指定。
如果在 :cpp:type:`jpeg_encode_engine_cfg_t` 中指定了配置,则可以调用 :cpp:func:`jpeg_new_encoder_engine` 来分配和初始化 JPEG 编码器引擎。如果该函数运行正确,则会返回一个 JPEG 编码器句柄。请参考以下代码:
.. code:: c
jpeg_encoder_handle_t encoder_engine;
jpeg_encode_engine_cfg_t encode_eng_cfg = {
.intr_priority = 0,
.timeout_ms = 40,
};
ESP_ERROR_CHECK(jpeg_new_encoder_engine(&encode_eng_cfg, &encoder_engine));
卸载 JPEG 编码器引擎
~~~~~~~~~~~~~~~~~~~~
如果不再需要先前安装的 JPEG 引擎,建议通过调用 :cpp:func:`jpeg_del_encoder_engine` 回收资源,从而释放底层硬件。
.. code:: c
ESP_ERROR_CHECK(jpeg_del_encoder_engine(encoder_engine));
有限状态机
^^^^^^^^^^
JPEG 驱动程序对硬件资源的使用情况及其处理流程如下图所示:
.. figure:: ../../../_static/diagrams/jpeg/jpeg_workflow.png
:align: center
:alt: JPEG 有限状态机
JPEG 有限状态机
JPEG 解码器引擎
^^^^^^^^^^^^^^^
通过 :cpp:func:`jpeg_new_decoder_engine` 安装好 JPEG 解码器驱动程序后,{IDF_TARGET_NAME} 就可以用 :cpp:func:`jpeg_decoder_process` 解码 JPEG 图片。通过配置参数 :cpp:type:`jpeg_decode_cfg_t` :cpp:func:`jpeg_decoder_process` 能灵活地解码不同类型的图片:
此外,我们的 JPEG 解码器 API 提供了 helper 函数,可以帮助获取给定图像的基本信息。调用 :cpp:func:`jpeg_decoder_get_info`,将返回名为 :cpp:func:`jpeg_decoder_get_info` 的图片信息结构。如果图片的基本信息已知,则不需要调用此函数。
该驱动程序支持的格式转换如下表所示:
.. list-table::
:header-rows: 1
:widths: 50 50
:align: center
* - 已压缩图像的格式
- 解压后的格式
* - YUV444
- RGB565/RGB888
* - YUV422
- RGB565/RGB888
* - YUV420
- RGB565/RGB888
* - GRAY
- GRAY
可参考以下代码,为 1080*1920 大小的图片解码:
.. code:: c
jpeg_decode_cfg_t decode_cfg_rgb = {
.output_format = JPEG_DECODE_OUT_FORMAT_RGB888,
.rgb_order = JPEG_DEC_RGB_ELEMENT_ORDER_BGR,
};
size_t tx_buffer_size;
size_t rx_buffer_size;
jpeg_decode_memory_alloc_cfg_t rx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_OUTPUT_BUFFER,
};
jpeg_decode_memory_alloc_cfg_t tx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_INPUT_BUFFER,
};
uint8_t *bit_stream = (uint8_t*)jpeg_alloc_decoder_mem(jpeg_size, &tx_mem_cfg, &tx_buffer_size);
uint8_t *out_buf = (uint8_t*)jpeg_alloc_decoder_mem(1920 * 1088 * 3, &rx_mem_cfg, &rx_buffer_size);
jpeg_decode_picture_info_t header_info;
ESP_ERROR_CHECK(jpeg_decoder_get_info(bit_stream, bit_stream_size, &header_info));
uint32_t out_size = 0;
ESP_ERROR_CHECK(jpeg_decoder_process(decoder_engine, &decode_cfg_rgb, bit_stream, bit_stream_size, out_buf, &out_size));
参考以下提示,可以更准确地使用该驱动程序:
1. 在上述代码中,应确保 `bit_stream``out_buf` 按照一定的规则对齐。可以通过 :cpp:func:`jpeg_alloc_decoder_mem` 函数来分配一个在大小和地址上都对齐的缓冲区。
2. 在 :cpp:func:`jpeg_decoder_process` 返回前, `bit_stream` 缓冲区的内容不应有更改。
3. 如果原始图片以 YUV420 或 YUV422 格式压缩,则输出图片的宽度和高度将会以 16 字节对齐。例如,如果输入图片大小为 1080*1920则输出图片大小为 1088*1920。这是 jpeg 协议的限制,所以请准备足够的输出缓冲区内存。
JPEG 编码器引擎
^^^^^^^^^^^^^^^
通过 :cpp:func:`jpeg_new_encoder_engine` 安装好 JPEG 编码器驱动程序后,{IDF_TARGET_NAME} 就可以用 :cpp:func:`jpeg_encoder_process` 编码 JPEG 图片。借由可配置参数 :cpp:type:`jpeg_encode_cfg_t` :cpp:func:`jpeg_encoder_process` 能灵活地编码不同类型的图片:
该驱动程序支持的格式转换如下表所示:
.. list-table::
:header-rows: 1
:widths: 50 50
:align: center
* - 原图格式
- 下采样法
* - RGB565/RGB888
- YUV444/YUV422/YUV420
* - GRAY
- GRAY
可参考以下代码,为 1080*1920 大小的图片编码:
.. code:: c
int raw_size_1080p = 0;/* Your raw image size */
jpeg_encode_cfg_t enc_config = {
.src_type = JPEG_ENCODE_IN_FORMAT_RGB888,
.sub_sample = JPEG_DOWN_SAMPLING_YUV422,
.image_quality = 80,
.width = 1920,
.height = 1080,
};
uint8_t *raw_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p);
if (raw_buf_1080p == NULL) {
ESP_LOGE(TAG, "alloc 1080p tx buffer error");
return;
}
uint8_t *jpg_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p / 10); // Assume that compression ratio of 10 to 1
if (jpg_buf_1080p == NULL) {
ESP_LOGE(TAG, "alloc jpg_buf_1080p error");
return;
}
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, &jpg_size_1080p););
参考以下提示,可以更准确地使用该驱动程序:
1. 在上述代码中,应调用 :cpp:func:`jpeg_alloc_encoder_mem` 函数,确保 `raw_buf_1080p``jpg_buf_1080p` 对齐。
2. 在 :cpp:func:`jpeg_encoder_process` 返回前, `raw_buf_1080p` 缓冲区的内容不应有更改。
3. 压缩比取决于所选择的 `image_quality` 和图像本身的内容。一般来说, `image_quality` 值越高,图像质量越好,相应的压缩比就越小。至于图像内容,则很难给出具体的指导方针,因此本文也就不再讨论。基准 JPEG 压缩比通常从 40:1 到 10:1 不等,请依实际情况而定。
性能概述
^^^^^^^^
本节提供了解码器和编码器性能的一些测量数据。下表中呈现的数据是对随机选择的图片片段进行 50 次解码或编码的平均值。所有测试都在 360 MHz 的 CPU 频率以及 200 MHz 的 SPI RAM 时钟频率下进行。在此测试中,仅运行与 JPEG 相关的代码,不涉及其他模块(例如 USB 摄像头等)。
解码器和编码器都不会占用过多的 CPU仅头部解析会消耗一定 CPU。与 JPEG 压缩相关的计算,如 DCT、量化、哈夫曼编码/解码等,完全由硬件完成。
JPEG 解码器性能
~~~~~~~~~~~~~~~
.. list-table::
:header-rows: 1
:widths: 25 25 25 25 25
:align: center
* - JPEG 高度
- JPEG 宽度
- 像素输入格式 [#]_
- 像素输出格式 [#]_
- 性能 (fps)
* - 1080
- 1920
- YUV422
- RGB888/RGB565
- 48
* - 720
- 1280
- YUV422
- RGB888/RGB565
- 109
* - 480
- 800
- YUV422
- RGB888/RGB565
- 253
* - 480
- 640
- YUV422
- RGB888/RGB565
- 307
* - 480
- 320
- YUV422
- RGB888/RGB565
- 571
* - 720
- 1280
- GRAY
- GRAY
- 161
.. [#] 已压缩图像格式
.. [#] 解压后图像格式
JPEG 编码器性能
~~~~~~~~~~~~~~~
.. list-table::
:header-rows: 1
:widths: 25 25 25 25 25
:align: center
* - JPEG 高度
- JPEG 宽度
- 像素输入格式 [#]_
- 像素输出格式 [#]_
- 性能 (fps)
* - 1080
- 1920
- RGB888
- YUV422
- 26
* - 1080
- 1920
- RGB565
- YUV422
- 36
* - 1080
- 1920
- RGB565
- YUV420
- 40
* - 1080
- 1920
- RGB565
- YUV444
- 24
* - 1080
- 1920
- RGB888
- YUV422
- 26
* - 720
- 1280
- RGB565
- YUV420
- 88
* - 720
- 1280
- RGB565
- YUV444
- 55
* - 720
- 1280
- RGB565
- YUV422
- 81
* - 480
- 800
- RGB888
- YUV420
- 142
* - 640
- 800
- RGB888
- YUV420
- 174
* - 480
- 320
- RGB888
- YUV420
- 315
* - 720
- 1280
- GRAY
- GRAY
- 163
.. [#] 原图格式
.. [#] 下采样法
不同颜色格式的像素存储布局
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
本指南中提到的编码器和解码器使用相同的未压缩原始图像格式 (RGB, YUV)。因此,本节中编码器和解码器不做单独讨论。以下格式的像素布局适用于编码器的输入方向和解码器的输出方向(如果支持)。具体的像素布局如图所示:
RGB888
~~~~~~
下图中的每个小块表示一位。
.. figure:: ../../../_static/diagrams/jpeg/rgb888.png
:align: center
:alt: RGB888 像素顺序
RGB888 像素顺序
对于 RGB888可以通过 :cpp:member:`jpeg_decode_cfg_t::rgb_order` 将像素设置为 `RGB` 顺序。
.. figure:: ../../../_static/diagrams/jpeg/rgb888_bigendian.png
:align: center
:alt: RGB888 大端像素顺序
RGB888 大端像素顺序
RGB565
~~~~~~
下图中的每个小块表示一位。
.. figure:: ../../../_static/diagrams/jpeg/rgb565.png
:align: center
:alt: RGB565 像素顺序
RGB565 像素顺序
对于 RGB565可以通过 :cpp:member:`jpeg_decode_cfg_t::rgb_order` 将像素设置为 `RGB` 顺序。
.. figure:: ../../../_static/diagrams/jpeg/rgb565_bigendian.png
:align: center
:alt: RGB565 大端像素顺序
RGB565 大端像素顺序
YUV444
~~~~~~
下图中的每个小块表示一位。
.. figure:: ../../../_static/diagrams/jpeg/yuv444.png
:align: center
:alt: YUV444 像素顺序
YUV444 像素顺序
YUV422
~~~~~~
下图中的每个小块表示一位。
.. figure:: ../../../_static/diagrams/jpeg/yuv422.png
:align: center
:alt: YUV422 像素顺序
YUV422 像素顺序
YUV420
~~~~~~
下图中的每个小块表示一位。
.. figure:: ../../../_static/diagrams/jpeg/yuv420.png
:align: center
:alt: YUV420 像素顺序
YUV420 像素顺序
线程安全性
^^^^^^^^^^
驱动程序能保证工厂函数 :cpp:func:`jpeg_new_decoder_engine` :cpp:func:`jpeg_decoder_get_info` :cpp:func:`jpeg_decoder_process`,以及 :cpp:func:`jpeg_del_decoder_engine` 是线程安全的,这意味着无需额外的锁保护,也可以从不同的 RTOS 任务中调用这些函数。
电源管理
^^^^^^^^
当启用电源管理(即设置了 :ref:`CONFIG_PM_ENABLE`)时,系统需要调整或停止 JPEG 的源时钟以进入 Light-sleep 模式,这可能会改变 JPEG 解码器/编码器的处理过程,也可能会导致硬件计算出现意外。为防止以上问题出现,当 JPEG 编码器/解码器工作时,无法进入 Light-sleep 模式。
每当用户通过 JPEG 进行解码或编码(即调用 :cpp:func:`jpeg_encoder_process`:cpp:func:`jpeg_decoder_process`)时,驱动程序会将电源管理设定为 :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_CPU_FREQ_MAX`,确保获取电源管理锁。一旦编码或解码完成,驱动程序将释放锁,则系统可以进入 Light-sleep 模式。
Kconfig 选项
^^^^^^^^^^^^
- :ref:`CONFIG_JPEG_ENABLE_DEBUG_LOG` 可启用调试日志,但会增加固件二进制大小。
维护者须知
----------
驱动程序对硬件资源的使用情况及其依赖状况如下图所示:
.. figure:: ../../../_static/diagrams/jpeg/jpeg_drv_file_structure.png
:align: center
:alt: JPEG 驱动程序文件结构
JPEG 驱动程序文件结构
应用程序示例
------------
* JPEG 编码器应用程序示例: :example:`peripherals/jpeg/jpeg_decode`
* JPEG 解码器应用程序示例: :example:`peripherals/jpeg/jpeg_encode`
API 参考
--------
.. only:: SOC_JPEG_DECODE_SUPPORTED
.. include-build-file:: inc/jpeg_decode.inc
.. only:: SOC_JPEG_ENCODE_SUPPORTED
.. include-build-file:: inc/jpeg_encode.inc
.. include-build-file:: inc/components/esp_driver_jpeg/include/driver/jpeg_types.inc
.. include-build-file:: inc/components/hal/include/hal/jpeg_types.inc

View File

@ -1 +1,87 @@
.. include:: ../../../../en/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst
覆盖默认芯片驱动程序
====================
:link_to_translation:`en:[English]`
.. warning::
自定义 SPI Flash 芯片驱动程序是一项高级功能,进行此操作时应自担风险。(请参阅下面的注意事项)
在初始化 SPI Flash 驱动程序时(即,:cpp:func:`esp_flash_init`),驱动程序会在芯片检测步骤中遍历默认芯片驱动程序列表,并找到可以支持当前连接的 Flash 芯片的驱动程序。默认芯片驱动程序由 ESP-IDF 提供,因此会随着 ESP-IDF 的版本一起更新。当然ESP-IDF 也允许自定义芯片驱动程序。
在自定义芯片驱动程序时,应注意以下事项:
1. 自定义芯片驱动可能会用到非公开的 ESP-IDF 函数。ESP-IDF 版本不同,这些函数也有极小的可能会随之变化,有的会修复驱动程序中的错误,也有可能会破坏代码。
2. 针对某些芯片驱动程序的 ESP-IDF 错误修复并不会自动应用到自定义的芯片驱动程序中。
3. 如果未能正确处理针对 flash 的保护,可能会出现一些随机的可靠性问题。
4. 如果升级到支持更多芯片的新 ESP-IDF 版本,则必须手动将这些新的芯片驱动程序添加到自定义芯片驱动程序列表中。否则,驱动程序将仅搜索自定义列表中已有的驱动程序。
创建自定义芯片驱动程序并覆盖 ESP-IDF 默认驱动程序列表的步骤
-----------------------------------------------------------
.. highlight: cmake
1. 启用 :ref:`CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST` 配置选项,确保不会编译和链接 ESP-IDF 的默认芯片驱动列表 (default_registered_chips),而链接器会搜索用户自定义的同名结构体 (default_registered_chips)。
2. 在项目中添加一个新组件,例如 ``custom_chip_driver``
3. 从 ESP-IDF 的 ``spi_flash`` 组件中复制必要的芯片驱动程序文件。这可能包括:
- ``spi_flash_chip_drivers.c`` (该文件中定义了 ``default_registered_chips`` 结构体)
- 与你的 flash 型号最匹配的任何 ``spi_flash_chip_*.c`` 文件
- ``CMakeLists.txt````linker.lf`` 文件
适当修改上述文件,如:
- 将 ``default_registered_chips`` 变量更改为非静态,并删除相关的 #ifdef 逻辑。
- 更新 ``linker.lf`` 文件,重命名分片头部和库名,从而匹配新组件。
- 如果复用其他驱动程序,不在 spi_flash 组件中的分片头部需要在名称中添加 ``spi_flash/`` 前缀。
.. note::
- 在编写自己的 flash 芯片驱动程序时,可以通过 ``spi_flash_chip_***(vendor)_get_caps`` 来设置 flash 芯片的功能,并将函数指针 ``get_chip_caps`` 指向 ``spi_flash_chip_***_get_caps`` 函数以进行保护。步骤如下:
1. 通过查阅 flash 技术规格书,确定自己的 flash 芯片具有 ``spi_flash_caps_t`` 所列出的功能。
2. 编写一个名为 ``spi_flash_chip_***(vendor)_get_caps`` 的函数。如果 flash 支持 ``suspend````read unique id``,可参考以下示例。
3. 将指针 ``get_chip_caps`` (在 ``spi_flash_chip_t`` 中)指向第二步中编写的函数。
.. code-block:: c
spi_flash_caps_t spi_flash_chip_***(vendor)_get_caps(esp_flash_t *chip)
{
spi_flash_caps_t caps_flags = 0;
// 32-bit-address flash is not supported
flash-suspend is supported
caps_flags |= SPI_FLAHS_CHIP_CAP_SUSPEND;
// flash read unique id.
caps_flags |= SPI_FLASH_CHIP_CAP_UNIQUE_ID;
return caps_flags;
}
.. code-block:: c
const spi_flash_chip_t esp_flash_chip_eon = {
// Other function pointers
.get_chip_caps = spi_flash_chip_eon_get_caps,
};
- 也可以在示例 :example:`storage/custom_flash_driver` 中查看如何实现此功能。
4. 为 ``custom_chip_driver`` 组件编写一个新的 ``CMakeLists.txt`` 文件,其中包含额外的一行,添加了从 ``spi_flash````custom_chip_driver`` 的链接依赖项::
idf_component_register(SRCS "spi_flash_chip_drivers.c"
"spi_flash_chip_mychip.c" # modify as needed
REQUIRES hal
PRIV_REQUIRES spi_flash
LDFRAGMENTS linker.lf)
idf_component_add_link_dependency(FROM spi_flash)
- CMakeLists.txt 组件的示例可查阅 :example_file:`storage/custom_flash_driver/components/custom_chip_driver/CMakeLists.txt`
5. ``linker.lf`` 用于在禁用缓存时,把要使用的每个芯片驱动程序都放入内部 RAM 中。详情请参阅 :doc:`/api-guides/linker-script-generation`。请确保此文件包含所有添加的源文件。
6. 构建你的项目,将会看到新的 flash 驱动程序已投入使用。
示例
----
参考 :example:`storage/custom_flash_driver`

View File

@ -1 +1,60 @@
.. include:: ../../../../en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst
USB 主机维护者注释(架构)
===========================
:link_to_translation:`en:[English]`
主机协议栈大致分为多个抽象层,每个层代表不同的 USB 概念和不同级别的 USB 主机操作。例如,较高的层可能呈现为设备和应用数据传输的抽象,而较低的层则为端点和 USB 传输的抽象。
层描述
------
从最低层(离用户最远的层)到最高层(离用户最近的层),主机协议栈的层描述如下表所示:
.. list-table:: 主机协议栈的各层功能简述
:widths: 20 10 70
:header-rows: 1
* - 层
- 文件
- 描述
* - 主机控制器 (DWC_OTG)
- N/A
- 此层代表 {IDF_TARGET_NAME} 的 USB 控制器硬件,所提供的 API 是控制器的寄存器接口。
* - LL
- ``usbh_ll.h``
- LL低级层根据 ESP-IDF 的 :doc:`硬件抽象 API 指南 <../../../api-guides/hardware-abstraction>` 抽象了 USB 控制器的基本寄存器访问。换句话说,此层提供的 API 能访问控制寄存器,也可以格式化/解析控制器的 DMA 描述符。
* - HAL
- ``usbh_hal.h`` ``usbh_hal.c``
- HAL硬件抽象层根据 ESP-IDF 的 :doc:`硬件抽象 API 指南 <../../../api-guides/hardware-abstraction>`,将 USB 控制器的操作步骤抽象成函数。此层还将控制器的主机端口和主机通道抽象化,并提供操作它们的 API。
* - HCD
- ``hcd.h`` ``hcd.c``
- HCD主机控制器驱动程序是一个与硬件无关的 API适用于任何 USB 控制器(理论上,此 API 可以与任何 USB 控制器实现一同使用)。此层还抽象了根端口(根集线器)和 USB 管道。
* - USBH 和集线器驱动程序
- ``usbh.h`` ``usbh.c``
- USBHUSB 主机驱动程序)层等效于 USB2.0 规范第 10 章中描述的 USBD 层。USBH 提供 USB 设备的抽象,在内部管理已连接设备的列表(即,设备池),还仲裁客户端之间的设备共享(即,跟踪正在使用的端点并提供一个共享端点 0
* - 集线器驱动程序
- ``hub.h`` ``hub.c``
- 集线器驱动程序层是 USBH 的特殊客户端,负责处理设备的连接/断开,并通知 USBH 此类事件。对于设备的连接,集线器驱动程序还会处理枚举过程。
* - USB 主机库
- ``usb_host.h`` ``usb_host.c``
- USB 主机库层是主机协议栈的最低公共 API 层,并呈现 USB 主机客户端的概念。客户端的抽象允许多个 class 驱动程序同时存在(其中每个类大致映射到一个单独的客户端),这也是一种分工机制(其中每个客户端负责各自的处理以及事件处理)。
* - 主机 Class 驱动程序
- 请参阅 `ESP-IDF 额外组件存储库 <https://github.com/espressif/idf-extra-components>`_ 或是 ESP-IDF 中的 USB 主机示例 :example:`peripherals/usb/host`
- 主机 Class 驱动程序能实现特定设备类例如CDC、MSC、HID的主机端。每个 class 驱动程序具有特定的公开 API 接口。
层依赖关系
----------
主机协议栈大致遵循自顶向下的层次结构,具有层间依赖关系。假设存在层 A最高层、B 、 C最低层则主机协议栈具有以下层间依赖规则
- 特定层可以使用其直接下层的 API层 A 可以使用层 B 的 API
- 特定层可以使用其间接下层的 API层 A 可以使用层 C 的 API即可以隔层调用。
- 特定层不能使用其任何上层的 API层 C 无法使用层 A/B 的 API
.. note::
允许跳过层次以避免在多个层次之间重复相同的抽象。例如,管道的抽象都位于 HCD 层,但被上面的多个层使用。
.. todo::
添加图示以说明不同层之间的 API 依赖关系