mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
Merge branch 'fix/jpeg_enc_encrypt_v6.0' into 'release/v6.0'
fix(jpeg): Jpeg can encode and decode in encryption situation (backport v6.0) See merge request espressif/esp-idf!50664
This commit is contained in:
@@ -97,7 +97,9 @@ esp_err_t jpeg_decoder_get_info(const uint8_t *bit_stream, uint32_t stream_size,
|
||||
* returned through the `out_size` pointer.
|
||||
*
|
||||
* @note 1.Please make sure that the content of `bit_stream` pointer cannot be modified until this function returns.
|
||||
* 2.Please note that the output size of image is always the multiple of 16 depends on protocol of JPEG.
|
||||
* 2.For JPEGs encoded with YUV420 or YUV422 sampling, the decoded output dimensions can be padded
|
||||
* to 16-pixel boundaries by the JPEG block layout. Make sure `decode_outbuf` is large enough for
|
||||
* that padded output size, not only for the visible width and height.
|
||||
*
|
||||
* @param[in] decoder_engine Handle of the JPEG decoder instance to use for processing.
|
||||
* @param[in] decode_cfg Config structure of decoder.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "hal/jpeg_periph.h"
|
||||
#include "esp_psram.h"
|
||||
#if JPEG_USE_RETENTION_LINK
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#endif
|
||||
@@ -252,3 +253,17 @@ esp_err_t jpeg_check_intr_priority(jpeg_codec_handle_t jpeg_codec, int intr_prio
|
||||
ESP_RETURN_ON_FALSE(!intr_priority_conflict, ESP_ERR_INVALID_STATE, TAG, "intr_priority conflict, already is %d but attempt to %d", jpeg_codec->intr_priority, intr_priority);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool jpeg_check_dma2d_buffer(const void *buffer)
|
||||
{
|
||||
#if CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
// jpeg cannot handle encrypted data.
|
||||
if (esp_ptr_external_ram(buffer) && !esp_psram_ptr_is_no_enc(buffer)) {
|
||||
return false;
|
||||
}
|
||||
if (esp_ptr_in_drom(buffer)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/jpeg_defs.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
@@ -287,6 +288,10 @@ esp_err_t jpeg_decoder_process(jpeg_decoder_handle_t decoder_engine, const jpeg_
|
||||
ESP_RETURN_ON_FALSE(_check_buffer_alignment(decode_outbuf, outbuf_size, outbuf_cache_line_size), ESP_ERR_INVALID_ARG, TAG,
|
||||
"jpeg decode decode_outbuf or out_buffer size is not aligned, please use jpeg_alloc_decoder_mem to malloc your buffer");
|
||||
|
||||
// both the bitstream and output buffer are accessed by the 2D-DMA
|
||||
ESP_RETURN_ON_FALSE(jpeg_check_dma2d_buffer(bit_stream) && jpeg_check_dma2d_buffer(decode_outbuf), ESP_ERR_INVALID_ARG, TAG,
|
||||
"jpeg decode buffer is not 16-byte aligned or not in unencrypted PSRAM, please use jpeg_alloc_decoder_mem to malloc your buffer");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
@@ -426,15 +431,21 @@ void *jpeg_alloc_decoder_mem(size_t size, const jpeg_decode_memory_alloc_cfg_t *
|
||||
FOr input buffer(for decoder is PSRAM write to 2DDMA), no restriction for any align (both cache writeback and requirement from 2DDMA).
|
||||
*/
|
||||
size_t cache_align = 0;
|
||||
size_t buffer_align = 0;
|
||||
esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_align);
|
||||
if (mem_cfg->buffer_direction == JPEG_DEC_ALLOC_OUTPUT_BUFFER) {
|
||||
size = JPEG_ALIGN_UP(size, cache_align);
|
||||
*allocated_size = size;
|
||||
return heap_caps_aligned_calloc(cache_align, 1, size, MALLOC_CAP_SPIRAM);
|
||||
} else {
|
||||
*allocated_size = size;
|
||||
return heap_caps_calloc(1, size, MALLOC_CAP_SPIRAM);
|
||||
buffer_align = MAX(cache_align, JPEG_DMA2D_BUFFER_ALIGN);
|
||||
size = JPEG_ALIGN_UP(size, buffer_align);
|
||||
*allocated_size = size;
|
||||
// To simplify the logic, we always use the LCM of cache and 2D-DMA alignment to satisfy both requirements
|
||||
void *buffer = heap_caps_aligned_calloc(buffer_align, 1, size, JPEG_SPIRAM_ALLOC_CAPS);
|
||||
if (buffer == NULL) {
|
||||
#if CONFIG_SPIRAM_ENC_EXEMPT
|
||||
ESP_LOGE(TAG, "no mem for %zu bytes decode buffer in unencrypted PSRAM, please enlarge CONFIG_SPIRAM_ENC_EXEMPT_SIZE", size);
|
||||
#else
|
||||
ESP_LOGE(TAG, "no mem for %zu bytes decode buffer", size);
|
||||
#endif
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "hal/jpeg_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "esp_private/dma2d.h"
|
||||
#include "jpeg_private.h"
|
||||
#include "driver/jpeg_encode.h"
|
||||
@@ -175,6 +176,8 @@ esp_err_t jpeg_encoder_process(jpeg_encoder_handle_t encoder_engine, const jpeg_
|
||||
ESP_RETURN_ON_FALSE(bit_stream, ESP_ERR_INVALID_ARG, TAG, "jpeg encode output buffer is null");
|
||||
ESP_RETURN_ON_FALSE(out_size, ESP_ERR_INVALID_ARG, TAG, "jpeg encode picture out_size is null");
|
||||
ESP_RETURN_ON_FALSE(((uintptr_t)bit_stream % cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA)) == 0, ESP_ERR_INVALID_ARG, TAG, "jpeg encode bit stream is not aligned, please use jpeg_alloc_encoder_mem to malloc your buffer");
|
||||
// both the input picture and output bitstream are accessed by the 2D-DMA
|
||||
ESP_RETURN_ON_FALSE(jpeg_check_dma2d_buffer(encode_inbuf) && jpeg_check_dma2d_buffer(bit_stream), ESP_ERR_INVALID_ARG, TAG, "jpeg encode buffer is not 16-byte aligned or not in unencrypted PSRAM, please use jpeg_alloc_encoder_mem to malloc your buffer");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
@@ -392,15 +395,21 @@ void *jpeg_alloc_encoder_mem(size_t size, const jpeg_encode_memory_alloc_cfg_t *
|
||||
For input buffer(for decoder is PSRAM write to 2DDMA), no restriction for any align (both cache writeback and requirement from 2DDMA).
|
||||
*/
|
||||
size_t cache_align = 0;
|
||||
size_t buffer_align = 0;
|
||||
esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_align);
|
||||
if (mem_cfg->buffer_direction == JPEG_ENC_ALLOC_OUTPUT_BUFFER) {
|
||||
size = JPEG_ALIGN_UP(size, cache_align);
|
||||
*allocated_size = size;
|
||||
return heap_caps_aligned_calloc(cache_align, 1, size, MALLOC_CAP_SPIRAM);
|
||||
} else {
|
||||
*allocated_size = size;
|
||||
return heap_caps_calloc(1, size, MALLOC_CAP_SPIRAM);
|
||||
buffer_align = MAX(cache_align, JPEG_DMA2D_BUFFER_ALIGN);
|
||||
size = JPEG_ALIGN_UP(size, buffer_align);
|
||||
*allocated_size = size;
|
||||
// To simplify the logic, we always use the LCM of cache and 2D-DMA alignment to satisfy both requirements
|
||||
void *buffer = heap_caps_aligned_calloc(buffer_align, 1, size, JPEG_SPIRAM_ALLOC_CAPS);
|
||||
if (buffer == NULL) {
|
||||
#if CONFIG_SPIRAM_ENC_EXEMPT
|
||||
ESP_LOGE(TAG, "no mem for %zu bytes encode buffer in unencrypted PSRAM, please enlarge CONFIG_SPIRAM_ENC_EXEMPT_SIZE", size);
|
||||
#else
|
||||
ESP_LOGE(TAG, "no mem for %zu bytes encode buffer", size);
|
||||
#endif
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
||||
@@ -31,6 +31,17 @@ extern "C" {
|
||||
#define JPEG_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED)
|
||||
|
||||
#define JPEG_ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
// Buffers fed to the 2D-DMA must be at least 16-byte aligned.
|
||||
#define JPEG_DMA2D_BUFFER_ALIGN 16
|
||||
|
||||
// The JPEG codec cannot work with encrypted buffer, because it deals with macro block. When an
|
||||
// unencrypted PSRAM region is reserved (CONFIG_SPIRAM_ENC_EXEMPT), codec buffers
|
||||
// must come from it; otherwise use normal PSRAM.
|
||||
#if CONFIG_SPIRAM_ENC_EXEMPT
|
||||
#define JPEG_SPIRAM_ALLOC_CAPS (MALLOC_CAP_SPIRAM_NO_ENC)
|
||||
#else
|
||||
#define JPEG_SPIRAM_ALLOC_CAPS (MALLOC_CAP_SPIRAM)
|
||||
#endif
|
||||
|
||||
// Use retention link only when the target supports sleep retention and PM is enabled
|
||||
#define JPEG_USE_RETENTION_LINK (CONFIG_PM_ENABLE && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
|
||||
@@ -251,6 +262,18 @@ esp_err_t jpeg_isr_deregister(jpeg_codec_handle_t jpeg_codec, jpeg_isr_handler_t
|
||||
*/
|
||||
esp_err_t jpeg_check_intr_priority(jpeg_codec_handle_t jpeg_codec, int intr_priority);
|
||||
|
||||
/**
|
||||
* @brief Validate a user buffer that will be accessed by the 2D-DMA
|
||||
*
|
||||
* The buffer must be 16-byte aligned. When CONFIG_SPIRAM_ENC_EXEMPT is enabled,
|
||||
* a PSRAM buffer must reside in the unencrypted carve-out, since the 2D-DMA
|
||||
* cannot access encrypted PSRAM. Internal RAM buffers are always accepted.
|
||||
*
|
||||
* @param buffer Buffer pointer provided by the user
|
||||
* @return true if the buffer can be used by the 2D-DMA, false otherwise
|
||||
*/
|
||||
bool jpeg_check_dma2d_buffer(const void *buffer);
|
||||
|
||||
/**
|
||||
* @brief Create sleep retention link
|
||||
*
|
||||
|
||||
@@ -9,8 +9,8 @@ set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/test_apps/components")
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(jpeg_test)
|
||||
|
||||
target_add_binary_data(jpeg_test.elf "${IDF_PATH}/examples/peripherals/jpeg/jpeg_decode/resources/esp720.jpg" BINARY)
|
||||
target_add_binary_data(jpeg_test.elf "${IDF_PATH}/examples/peripherals/jpeg/jpeg_decode/resources/esp1080.jpg" BINARY)
|
||||
target_add_binary_data(jpeg_test.elf "resources/esp720.jpg" BINARY)
|
||||
target_add_binary_data(jpeg_test.elf "resources/esp1080.jpg" BINARY)
|
||||
target_add_binary_data(jpeg_test.elf "resources/no_huff.jpg" BINARY)
|
||||
target_add_binary_data(jpeg_test.elf "resources/esp480.rgb" BINARY)
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Reference in New Issue
Block a user