mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(jpeg): JPEG can encode and decode in encryption situation
This commit is contained in:
@@ -17,15 +17,18 @@ Functional Overview
|
||||
|
||||
This document covers the following sections:
|
||||
|
||||
- `Resource Allocation <#resource-allocation>`__ - covers how to allocate JPEG resources with properly set of configurations. It also covers how to recycle the resources when they finished working.
|
||||
- `Finite State Machine <#finite-state-machine>`__ - covers JPEG workflow. Introduce how jpeg driver uses internal resources and its software process.
|
||||
- `JPEG Decoder Engine <#jpeg-decoder-engine>`__ - covers behavior of JPEG decoder engine. Introduce how to use decoder engine functions to decode an image (from jpg format to raw format).
|
||||
- `JPEG Encoder Engine <#jpeg-encoder-engine>`__ - covers behavior of JPEG encoder engine. Introduce how to use encoder engine functions to encode an image (from raw format to jpg format).
|
||||
- `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.
|
||||
- `Kconfig Options <#kconfig-options>`__ - lists the supported Kconfig options that can bring different effects to the driver.
|
||||
- :ref:`jpeg-resource-allocation` - covers how to allocate JPEG resources with properly set of configurations. It also covers how to recycle the resources when they finished working.
|
||||
- :ref:`jpeg-finite-state-machine` - covers JPEG workflow. Introduce how jpeg driver uses internal resources and its software process.
|
||||
- :ref:`jpeg-decoder-engine` - covers behavior of JPEG decoder engine. Introduce how to use decoder engine functions to decode an image (from jpg format to raw format).
|
||||
- :ref:`jpeg-encoder-engine` - covers behavior of JPEG encoder engine. Introduce how to use encoder engine functions to encode an image (from raw format to jpg format).
|
||||
- :ref:`jpeg-performance-overview` - covers encoder and decoder performance.
|
||||
- :ref:`jpeg-pixel-storage-layout` - covers color space order overview required in this JPEG decoder and encoder.
|
||||
- :ref:`jpeg-thread-safety` - lists which APIs are guaranteed to be thread safe by the driver.
|
||||
- :ref:`jpeg-power-management` - describes how JPEG driver would be affected by power consumption.
|
||||
- :ref:`jpeg-flash-encryption` - describes how to use the JPEG codec correctly when flash/PSRAM encryption is enabled.
|
||||
- :ref:`jpeg-kconfig-options` - lists the supported Kconfig options that can bring different effects to the driver.
|
||||
|
||||
.. _jpeg-resource-allocation:
|
||||
|
||||
Resource Allocation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
@@ -85,6 +88,8 @@ If a previously installed JPEG engine is no longer needed, it's recommended to r
|
||||
|
||||
ESP_ERROR_CHECK(jpeg_del_encoder_engine(encoder_engine));
|
||||
|
||||
.. _jpeg-finite-state-machine:
|
||||
|
||||
Finite State Machine
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -96,6 +101,8 @@ The JPEG driver usage of hardware resources and its process workflow are shown i
|
||||
|
||||
JPEG finite state machine
|
||||
|
||||
.. _jpeg-decoder-engine:
|
||||
|
||||
JPEG Decoder Engine
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -153,6 +160,8 @@ There are some tips that can help you use this driver more accurately:
|
||||
|
||||
3. If the source JPEG uses YUV420 or YUV422 sampling, the decoded output dimensions can be padded up to 16-pixel boundaries. For example, if the visible image size is 1080*1920, the decoder may require an output buffer sized for 1088*1920 pixels. This comes from the JPEG block layout, so please provide enough output buffer memory for the padded image, not only for the visible width and height.
|
||||
|
||||
.. _jpeg-encoder-engine:
|
||||
|
||||
JPEG Encoder Engine
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -173,40 +182,46 @@ The format conversions supported by this driver are listed in the table below:
|
||||
- GRAY
|
||||
|
||||
|
||||
Below is the example of code that encodes a 1080*1920 picture:
|
||||
Below is the example of code that encodes a 1280x720 picture from an embedded raw buffer:
|
||||
|
||||
.. code:: c
|
||||
|
||||
int raw_size_1080p = 0;/* Your raw image size */
|
||||
size_t raw_size_720p = EXAMPLE_WIDTH * EXAMPLE_HEIGHT * 3; /* 1280x720 bgr24 frame */
|
||||
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,
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.pixel_reverse = false, // Whether to reverse the pixel order of the input image, or pixel order detail please refer to technical reference manual
|
||||
};
|
||||
|
||||
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");
|
||||
jpeg_encode_memory_alloc_cfg_t rx_mem_cfg = {
|
||||
.buffer_direction = JPEG_ENC_ALLOC_OUTPUT_BUFFER,
|
||||
};
|
||||
size_t jpg_buffer_size = 0;
|
||||
uint8_t *jpg_buf_720p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_720p / 10, &rx_mem_cfg, &jpg_buffer_size);
|
||||
if (jpg_buf_720p == NULL) {
|
||||
ESP_LOGE(TAG, "alloc jpg_buf_720p error");
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, &jpg_size_1080p););
|
||||
/* The current JPEG encoder input path expects BGR24-style raw bytes for
|
||||
* JPEG_ENCODE_IN_FORMAT_RGB888. The embedded asset can be read directly
|
||||
* from flash as long as it remains valid until this call returns. */
|
||||
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, embedded_bgr24_start, raw_size_720p, jpg_buf_720p, jpg_buffer_size, &jpg_size_720p));
|
||||
|
||||
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`.
|
||||
1. In the above code, the output buffer `jpg_buf_720p` should be allocated by calling :cpp:func:`jpeg_alloc_encoder_mem`, because the JPEG bitstream buffer must satisfy the driver's alignment requirements.
|
||||
|
||||
2. The content of `raw_buf_1080p` buffer should not be changed until :cpp:func:`jpeg_encoder_process` returns.
|
||||
2. The content pointed to by `embedded_bgr24_start` should not be changed until :cpp:func:`jpeg_encoder_process` returns. This input buffer can come from flash-mapped embedded data or another memory region that stays readable for the full call.
|
||||
|
||||
3. The compression ratio depends on the chosen `image_quality` and the content of the image itself. Generally, a higher `image_quality` value obviously results in better image quality but a smaller compression ratio. As for the image content, it is hard to give any specific guidelines, so this question is out of the scope of this document. Generally, the baseline JPEG compression ratio can vary from 40:1 to 10:1. Please take the actual situation into account.
|
||||
3. For :cpp:enumerator:`JPEG_ENCODE_IN_FORMAT_RGB888`, the current driver expects the raw input bytes in a BGR24-style layout. Supplying RGB24 raw data would swap the red and blue channels in the encoded JPEG.
|
||||
|
||||
4. The compression ratio depends on the chosen `image_quality` and the content of the image itself. Generally, a higher `image_quality` value obviously results in better image quality but a smaller compression ratio. As for the image content, it is hard to give any specific guidelines, so this question is out of the scope of this document. Generally, the baseline JPEG compression ratio can vary from 40:1 to 10:1. Please take the actual situation into account.
|
||||
|
||||
.. _jpeg-performance-overview:
|
||||
|
||||
Performance Overview
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -339,6 +354,8 @@ JPEG encoder performance
|
||||
.. [#] Format of Original Image
|
||||
.. [#] Down sampling method
|
||||
|
||||
.. _jpeg-pixel-storage-layout:
|
||||
|
||||
Pixel Storage Layout for Different Color Formats
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -415,11 +432,15 @@ In the following picture, each small block means one byte.
|
||||
|
||||
YUV420 pixel order
|
||||
|
||||
.. _jpeg-thread-safety:
|
||||
|
||||
Thread Safety
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The factory function :cpp:func:`jpeg_new_decoder_engine`, :cpp:func:`jpeg_decoder_get_info`, :cpp:func:`jpeg_decoder_process`, and :cpp:func:`jpeg_del_decoder_engine` are guaranteed to be thread safe by the driver, which means, user can call them from different RTOS tasks without protection by extra locks.
|
||||
|
||||
.. _jpeg-power-management:
|
||||
|
||||
Power Management
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -427,6 +448,26 @@ When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is set), the sys
|
||||
|
||||
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.
|
||||
|
||||
.. _jpeg-flash-encryption:
|
||||
|
||||
Usage Under Encryption
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The JPEG codec moves data via the 2D-DMA, and the JPEG codec **cannot process encrypted data**. Therefore, when PSRAM encryption is enabled, the JPEG input/output buffers must reside in an unencrypted memory region, otherwise encoding/decoding fails.
|
||||
|
||||
To support the encrypted scenario, the driver does the following:
|
||||
|
||||
- When ``CONFIG_SPIRAM_ENC_EXEMPT`` is enabled, :cpp:func:`jpeg_alloc_decoder_mem` and :cpp:func:`jpeg_alloc_encoder_mem` allocate buffers from the unencrypted PSRAM region (``MALLOC_CAP_SPIRAM_NO_ENC``) automatically.
|
||||
- The allocated buffers satisfy both the cache line alignment and the byte alignment required by the 2D-DMA.
|
||||
|
||||
Please note the following when using it:
|
||||
|
||||
1. It is recommended to always allocate buffers via :cpp:func:`jpeg_alloc_encoder_mem` / :cpp:func:`jpeg_alloc_decoder_mem` to ensure correct alignment and memory region.
|
||||
|
||||
2. The size of the unencrypted region is determined by ``CONFIG_SPIRAM_ENC_EXEMPT_SIZE``. Since the JPEG buffer size depends on the image resolution and cannot be predicted automatically, configure it according to the largest image you actually process. If the region is insufficient, the allocation fails and an error log is printed, suggesting to enlarge ``CONFIG_SPIRAM_ENC_EXEMPT_SIZE``. Also note that this value must not be greater than or equal to the actual PSRAM size, otherwise the unencrypted region is disabled.
|
||||
|
||||
.. _jpeg-kconfig-options:
|
||||
|
||||
Kconfig Options
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -448,7 +489,7 @@ Application Examples
|
||||
|
||||
- :example:`peripherals/jpeg/jpeg_decode` demonstrates how to use the JPEG hardware decoder to parse one embedded JPEG, decode it into RGB888, stream the raw output as base64 over UART, and validate the result with pytest.
|
||||
|
||||
- :example:`peripherals/jpeg/jpeg_encode` demonstrates how to use the JPEG hardware encoder to encode a 1080p picture, specifically converting `*.rgb` files to `*.jpg` files.
|
||||
- :example:`peripherals/jpeg/jpeg_encode` demonstrates how to use the JPEG hardware encoder to encode an embedded 720p raw picture, stream the JPEG as base64 over UART, and validate the result with pytest.
|
||||
|
||||
|
||||
API Reference
|
||||
|
||||
@@ -17,15 +17,18 @@ 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 选项,可以为驱动程序带来不同的效果。
|
||||
- :ref:`jpeg-resource-allocation`,包括如何正确地设置配置来分配 JPEG 资源、如何在完成工作时回收资源。
|
||||
- :ref:`jpeg-finite-state-machine`,涵盖了 JPEG 的工作流程,介绍了 JPEG 驱动程序的软件流程,以及是如何使用内部资源的。
|
||||
- :ref:`jpeg-decoder-engine`,包括 JPEG 解码器引擎的行为。介绍了如何使用解码器引擎函数为图像解码(从 jpg 格式到 raw 格式)。
|
||||
- :ref:`jpeg-encoder-engine`,包括 JPEG 编码器引擎的行为。介绍了如何使用编码器引擎函数为图像编码(从 raw 格式到 jpg 格式)。
|
||||
- :ref:`jpeg-performance-overview`,介绍了编码器和解码器的性能。
|
||||
- :ref:`jpeg-pixel-storage-layout`,涵盖了 JPEG 解码器和编码器所需的颜色空间顺序。
|
||||
- :ref:`jpeg-thread-safety`,列出了驱动程序能保证线程安全的 API。
|
||||
- :ref:`jpeg-power-management`,描述了影响 JPEG 驱动程序功耗的因素。
|
||||
- :ref:`jpeg-flash-encryption`,介绍了在 flash/PSRAM 加密场景下如何正确使用 JPEG 编解码器。
|
||||
- :ref:`jpeg-kconfig-options`,列出了支持的 Kconfig 选项,可以为驱动程序带来不同的效果。
|
||||
|
||||
.. _jpeg-resource-allocation:
|
||||
|
||||
资源分配
|
||||
^^^^^^^^
|
||||
@@ -85,6 +88,8 @@ JPEG 编码器引擎的配置需要由 :cpp:type:`jpeg_encode_engine_cfg_t` 指
|
||||
|
||||
ESP_ERROR_CHECK(jpeg_del_encoder_engine(encoder_engine));
|
||||
|
||||
.. _jpeg-finite-state-machine:
|
||||
|
||||
有限状态机
|
||||
^^^^^^^^^^
|
||||
|
||||
@@ -96,6 +101,8 @@ JPEG 驱动程序对硬件资源的使用情况及其处理流程如下图所示
|
||||
|
||||
JPEG 有限状态机
|
||||
|
||||
.. _jpeg-decoder-engine:
|
||||
|
||||
JPEG 解码器引擎
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -153,6 +160,8 @@ JPEG 解码器引擎
|
||||
|
||||
3. 如果源 JPEG 使用 YUV420 或 YUV422 采样方式,解码后的输出图像尺寸可能会被补齐到 16 像素边界。例如,当可见图像大小为 1080*1920 时,解码器可能需要按 1088*1920 像素来分配输出缓冲区。这来自 JPEG 的块布局限制,因此请按补齐后的图像尺寸而不是仅按可见宽高准备足够的输出缓冲区内存。
|
||||
|
||||
.. _jpeg-encoder-engine:
|
||||
|
||||
JPEG 编码器引擎
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -173,40 +182,46 @@ JPEG 编码器引擎
|
||||
- GRAY
|
||||
|
||||
|
||||
可参考以下代码,为 1080*1920 大小的图片编码:
|
||||
可参考以下代码,将一张嵌入到固件中的 1280x720 原始图片编码为 JPEG:
|
||||
|
||||
.. code:: c
|
||||
|
||||
int raw_size_1080p = 0;/* Your raw image size */
|
||||
size_t raw_size_720p = EXAMPLE_WIDTH * EXAMPLE_HEIGHT * 3; /* 1280x720 bgr24 帧 */
|
||||
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,
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.pixel_reverse = false, // 是否反转输入图像的像素顺序,或像素顺序细节请参考技术参考手册
|
||||
};
|
||||
|
||||
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");
|
||||
jpeg_encode_memory_alloc_cfg_t rx_mem_cfg = {
|
||||
.buffer_direction = JPEG_ENC_ALLOC_OUTPUT_BUFFER,
|
||||
};
|
||||
size_t jpg_buffer_size = 0;
|
||||
uint8_t *jpg_buf_720p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_720p / 10, &rx_mem_cfg, &jpg_buffer_size);
|
||||
if (jpg_buf_720p == NULL) {
|
||||
ESP_LOGE(TAG, "alloc jpg_buf_720p error");
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, &jpg_size_1080p););
|
||||
/* 当前 JPEG 编码输入路径下,JPEG_ENCODE_IN_FORMAT_RGB888 实际要求
|
||||
* 原始字节按 BGR24 风格排列。只要数据在本次调用返回前保持可读,
|
||||
* 就可以直接从 flash 中映射出来的嵌入资源读取。 */
|
||||
ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, embedded_bgr24_start, raw_size_720p, jpg_buf_720p, jpg_buffer_size, &jpg_size_720p));
|
||||
|
||||
参考以下提示,可以更准确地使用该驱动程序:
|
||||
|
||||
1. 在上述代码中,应调用 :cpp:func:`jpeg_alloc_encoder_mem` 函数,确保 `raw_buf_1080p` 和 `jpg_buf_1080p` 对齐。
|
||||
1. 在上述代码中,应调用 :cpp:func:`jpeg_alloc_encoder_mem` 函数来分配 `jpg_buf_720p`,因为 JPEG 输出码流缓冲区需要满足驱动的对齐要求。
|
||||
|
||||
2. 在 :cpp:func:`jpeg_encoder_process` 返回前, `raw_buf_1080p` 缓冲区的内容不应有更改。
|
||||
2. 在 :cpp:func:`jpeg_encoder_process` 返回前, `embedded_bgr24_start` 所指向的输入内容不应有更改。该输入缓冲区既可以来自嵌入到 flash 中的映射资源,也可以来自其他在整个调用期间保持可读的内存区域。
|
||||
|
||||
3. 压缩比取决于所选择的 `image_quality` 和图像本身的内容。一般来说, `image_quality` 值越高,图像质量越好,相应的压缩比就越小。至于图像内容,则很难给出具体的指导方针,因此本文也就不再讨论。基准 JPEG 压缩比通常从 40:1 到 10:1 不等,请依实际情况而定。
|
||||
3. 对于 :cpp:enumerator:`JPEG_ENCODE_IN_FORMAT_RGB888`,当前驱动实际要求原始输入字节按 BGR24 风格排列。如果直接提供 RGB24 原始数据,则编码后的 JPEG 会出现红蓝通道互换。
|
||||
|
||||
4. 压缩比取决于所选择的 `image_quality` 和图像本身的内容。一般来说, `image_quality` 值越高,图像质量越好,相应的压缩比就越小。至于图像内容,则很难给出具体的指导方针,因此本文也就不再讨论。基准 JPEG 压缩比通常从 40:1 到 10:1 不等,请依实际情况而定。
|
||||
|
||||
.. _jpeg-performance-overview:
|
||||
|
||||
性能概述
|
||||
^^^^^^^^
|
||||
@@ -339,6 +354,8 @@ JPEG 编码器性能
|
||||
.. [#] 原图格式
|
||||
.. [#] 下采样法
|
||||
|
||||
.. _jpeg-pixel-storage-layout:
|
||||
|
||||
不同颜色格式的像素存储布局
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -415,11 +432,15 @@ YUV420
|
||||
|
||||
YUV420 像素顺序
|
||||
|
||||
.. _jpeg-thread-safety:
|
||||
|
||||
线程安全性
|
||||
^^^^^^^^^^
|
||||
|
||||
驱动程序能保证工厂函数 :cpp:func:`jpeg_new_decoder_engine`, :cpp:func:`jpeg_decoder_get_info`, :cpp:func:`jpeg_decoder_process`,以及 :cpp:func:`jpeg_del_decoder_engine` 是线程安全的,这意味着无需额外的锁保护,也可以从不同的 RTOS 任务中调用这些函数。
|
||||
|
||||
.. _jpeg-power-management:
|
||||
|
||||
电源管理
|
||||
^^^^^^^^
|
||||
|
||||
@@ -427,6 +448,26 @@ YUV420
|
||||
|
||||
每当用户通过 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 模式。
|
||||
|
||||
.. _jpeg-flash-encryption:
|
||||
|
||||
加密场景下的使用
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
JPEG 编解码器通过 2D-DMA 搬运数据,而 JPEG 编解码器 **无法处理已加密的数据**。因此在开启 PSRAM 加密时,需要让 JPEG 的输入/输出缓冲区位于非加密的内存区域,否则编解码会失败。
|
||||
|
||||
为支持加密场景,驱动程序做了如下处理:
|
||||
|
||||
- 当启用 ``CONFIG_SPIRAM_ENC_EXEMPT`` 时, :cpp:func:`jpeg_alloc_decoder_mem` 和 :cpp:func:`jpeg_alloc_encoder_mem` 会自动从非加密 PSRAM 区域(``MALLOC_CAP_SPIRAM_NO_ENC``)分配缓冲区。
|
||||
- 分配的缓冲区会同时满足 cache 行对齐与 2D-DMA 的字节对齐要求。
|
||||
|
||||
使用时请注意:
|
||||
|
||||
1. 建议始终通过 :cpp:func:`jpeg_alloc_encoder_mem` / :cpp:func:`jpeg_alloc_decoder_mem` 分配缓冲区,以保证对齐与内存区域正确。
|
||||
|
||||
2. 非加密区的大小由 ``CONFIG_SPIRAM_ENC_EXEMPT_SIZE`` 决定。由于 JPEG 缓冲区大小取决于图像分辨率,无法自动预测,需根据实际处理的最大图像自行配置。若该区域不足,分配会失败并打印错误日志,提示增大 ``CONFIG_SPIRAM_ENC_EXEMPT_SIZE``;同时注意该值不能大于等于实际 PSRAM 容量,否则非加密区会被禁用。
|
||||
|
||||
.. _jpeg-kconfig-options:
|
||||
|
||||
Kconfig 选项
|
||||
^^^^^^^^^^^^
|
||||
- :ref:`CONFIG_JPEG_ENABLE_DEBUG_LOG` 可启用调试日志,但会增加固件二进制大小。
|
||||
@@ -448,7 +489,7 @@ Kconfig 选项
|
||||
|
||||
- :example:`peripherals/jpeg/jpeg_decode` 演示了如何使用 JPEG 硬件解码器解析一张嵌入式 JPEG,将其解码为 RGB888,通过 UART 输出 base64 原始结果,并使用 pytest 做回归校验。
|
||||
|
||||
- :example:`peripherals/jpeg/jpeg_encode` 演示了如何使用 JPEG 硬件编码器编码一张 1080p 的图像,即将 `*.rgb` 文件转换为 `*.jpg` 文件。
|
||||
- :example:`peripherals/jpeg/jpeg_encode` 演示了如何使用 JPEG 硬件编码器对一张嵌入式 720p 原始图像进行编码,并通过 UART 输出 base64 JPEG,再用 pytest 做结果校验。
|
||||
|
||||
|
||||
API 参考
|
||||
|
||||
Reference in New Issue
Block a user