diff --git a/components/esp_driver_jpeg/include/driver/jpeg_encode.h b/components/esp_driver_jpeg/include/driver/jpeg_encode.h index 79e5535543..c782bd5ce2 100644 --- a/components/esp_driver_jpeg/include/driver/jpeg_encode.h +++ b/components/esp_driver_jpeg/include/driver/jpeg_encode.h @@ -19,11 +19,11 @@ extern "C" { * @brief JPEG encoder configure structure */ typedef struct { - uint32_t height; /*!< Number of pixels in the horizontal direction */ + uint32_t height; /*!< Number of pixels in the horizontal direction */ uint32_t width; /*!< Number of pixels in the vertical direction */ jpeg_enc_input_format_t src_type; /*!< Source type of raw image to be encoded, see `jpeg_enc_src_type_t` */ jpeg_down_sampling_type_t sub_sample; /*!< JPEG subsampling method */ - uint32_t image_quality; /*!< JPEG compressing quality, value from 1-100 */ + uint32_t image_quality; /*!< JPEG compressing quality, value from 1-100, higher value means higher quality */ } jpeg_encode_cfg_t; /** @@ -31,14 +31,14 @@ typedef struct { */ typedef struct { int intr_priority; /*!< JPEG interrupt priority, if set to 0, driver will select the default priority (1,2,3). */ - int timeout_ms; /*!< JPEG timeout threshold for handling a picture, should larger than valid decode time in ms. For example, for 30fps decode, this value must larger than 34. -1 means wait forever */ + int timeout_ms; /*!< JPEG timeout threshold for handling a picture, should larger than valid encode time in ms. For example, for 30fps encode, this value must larger than 34. -1 means wait forever */ } jpeg_encode_engine_cfg_t; /** * @brief JPEG encoder memory allocation config */ typedef struct { - jpeg_enc_buffer_alloc_direction_t buffer_direction; /*!< Buffer direction for jpeg decoder memory allocation */ + jpeg_enc_buffer_alloc_direction_t buffer_direction; /*!< Buffer direction for jpeg encoder memory allocation */ } jpeg_encode_memory_alloc_cfg_t; /** diff --git a/components/esp_driver_jpeg/include/driver/jpeg_types.h b/components/esp_driver_jpeg/include/driver/jpeg_types.h index 8a98db6062..f9fa8dcd07 100644 --- a/components/esp_driver_jpeg/include/driver/jpeg_types.h +++ b/components/esp_driver_jpeg/include/driver/jpeg_types.h @@ -68,11 +68,6 @@ typedef enum { */ typedef struct jpeg_decoder_t *jpeg_decoder_handle_t; -/** - * @brief Type of jpeg codec handle - */ -typedef struct jpeg_codec_t *jpeg_codec_handle_t; - /** * @brief Type of jpeg encoder handle */ diff --git a/components/esp_driver_jpeg/jpeg_emit_marker.c b/components/esp_driver_jpeg/jpeg_emit_marker.c index 23bf3baed9..34db223917 100644 --- a/components/esp_driver_jpeg/jpeg_emit_marker.c +++ b/components/esp_driver_jpeg/jpeg_emit_marker.c @@ -6,6 +6,7 @@ #include #include +#include "sys/param.h" #include "esp_log.h" #include "jpeg_private.h" #include "private/jpeg_param.h" @@ -13,9 +14,6 @@ #include "hal/jpeg_defs.h" #include "esp_private/esp_cache_private.h" -#define JPEG_MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define JPEG_MIN(a, b) (((a) < (b)) ? (a) : (b)) - static void emit_byte(jpeg_enc_header_info_t *header_info, uint8_t i) { header_info->header_buf[header_info->header_len] = i; @@ -66,7 +64,7 @@ static void compute_quant_table(uint32_t *quant_table, const uint32_t *basic_tab for (int i = 0; i < 64; i++) { int temp = *basic_table++; temp = (temp * scaling_factor + 50L) / 100L; - *quant_table++ = JPEG_MIN(JPEG_MAX(temp, 1), 255); + *quant_table++ = MIN(MAX(temp, 1), 255); } } @@ -232,7 +230,10 @@ esp_err_t emit_com_marker(jpeg_enc_header_info_t *header_info) size_t cache_align = 0; esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_PSRAM, &cache_align); // compensate_size = aligned_size - SOS marker size(2 * header_info->num_components + 2 + 1 + 3 + 2) - COM marker size(4). - uint32_t compensate_size = ((header_info->header_len / cache_align + 1) * cache_align) - header_info->header_len - (2 * header_info->num_components + 2 + 1 + 3 + 2) - 4; + int compensate_size = ((header_info->header_len / cache_align + 1) * cache_align) - header_info->header_len - (2 * header_info->num_components + 2 + 1 + 3 + 2) - 4; + if (compensate_size < 0) { + compensate_size += cache_align; + } emit_marker(header_info, JPEG_M_COM & 0xff); emit_word(header_info, compensate_size); for (int i = 0; i < compensate_size; i++) { diff --git a/components/esp_driver_jpeg/jpeg_encode.c b/components/esp_driver_jpeg/jpeg_encode.c index 2ac9ad1196..d03b3fcce1 100644 --- a/components/esp_driver_jpeg/jpeg_encode.c +++ b/components/esp_driver_jpeg/jpeg_encode.c @@ -441,7 +441,7 @@ static void s_jpeg_enc_config_picture_color_space(jpeg_encoder_handle_t encoder_ { jpeg_hal_context_t *hal = &encoder_engine->codec_base->hal; color_space_pixel_format_t picture_format; - jpeg_ll_config_picture_color_space(hal->dev, encoder_engine->color_space); + jpeg_ll_config_picture_pixel_format(hal->dev, encoder_engine->color_space); picture_format.color_type_id = encoder_engine->picture_format; encoder_engine->bytes_per_pixel = color_hal_pixel_format_get_bit_depth(picture_format); if (encoder_engine->color_space == JPEG_ENC_SRC_GRAY) { diff --git a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/README.md b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/README.md index 6373a3ce6f..12cad491b1 100644 --- a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/README.md +++ b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/README.md @@ -1,2 +1,4 @@ | Supported Targets | ESP32-P4 | | ----------------- | -------- | + +jpeg_decoder can be used to generate '*.rgb' file which to be used for this test. diff --git a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/main/test_jpeg_encode.c b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/main/test_jpeg_encode.c index dbf174c328..24c3eed427 100644 --- a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/main/test_jpeg_encode.c +++ b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/main/test_jpeg_encode.c @@ -68,12 +68,12 @@ TEST_CASE("JPEG encode performance test for 480*640 RGB->YUV picture", "[jpeg]") uint32_t jpg_size_480p = 0; - size_t bit_stream_length = (size_t)image_esp480_rgb_end - (size_t)image_esp480_rgb_start; + size_t rgb_file_size = (size_t)image_esp480_rgb_end - (size_t)image_esp480_rgb_start; size_t tx_buffer_size = 0; - uint8_t *raw_buf_480p = (uint8_t*)jpeg_alloc_encoder_mem(bit_stream_length, &tx_mem_cfg, &tx_buffer_size); + uint8_t *raw_buf_480p = (uint8_t*)jpeg_alloc_encoder_mem(rgb_file_size, &tx_mem_cfg, &tx_buffer_size); // Copy bit stream to psram - memcpy(raw_buf_480p, image_esp480_rgb_start, bit_stream_length); + memcpy(raw_buf_480p, image_esp480_rgb_start, rgb_file_size); TEST_ESP_OK(jpeg_new_encoder_engine(&encode_eng_cfg, &jpeg_handle)); ccomp_timer_start(); @@ -81,7 +81,7 @@ TEST_CASE("JPEG encode performance test for 480*640 RGB->YUV picture", "[jpeg]") // Decode picture for 50 times, and get the average uint8_t cnt = 50; for (int i = 0; i < cnt; i++) { - TEST_ESP_OK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_480p, bit_stream_length, jpg_buf_480p, rx_buffer_size, &jpg_size_480p)); + TEST_ESP_OK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_480p, rgb_file_size, jpg_buf_480p, rx_buffer_size, &jpg_size_480p)); } int64_t encode_time = ccomp_timer_stop(); diff --git a/components/hal/esp32p4/include/hal/jpeg_ll.h b/components/hal/esp32p4/include/hal/jpeg_ll.h index 3eebfd7235..9285576f2e 100644 --- a/components/hal/esp32p4/include/hal/jpeg_ll.h +++ b/components/hal/esp32p4/include/hal/jpeg_ll.h @@ -632,10 +632,10 @@ static inline uint32_t jpeg_ll_get_intr_status(jpeg_dev_t *hw) return hw->int_st.val; } -static inline void jpeg_ll_config_picture_color_space(jpeg_dev_t *hw, jpeg_enc_src_type_t color_space) +static inline void jpeg_ll_config_picture_pixel_format(jpeg_dev_t *hw, jpeg_enc_src_type_t pixel_format) { uint8_t cs = 0; - switch (color_space) { + switch (pixel_format) { case JPEG_ENC_SRC_RGB888: cs = 0; break; diff --git a/docs/en/api-reference/peripherals/index.rst b/docs/en/api-reference/peripherals/index.rst index 054a03ad30..a4cd5e7271 100644 --- a/docs/en/api-reference/peripherals/index.rst +++ b/docs/en/api-reference/peripherals/index.rst @@ -10,6 +10,7 @@ Peripherals API :SOC_ADC_DMA_SUPPORTED: adc_continuous :SOC_ADC_SUPPORTED: adc_calibration :SOC_ANA_CMPR_SUPPORTED: ana_cmpr + :SOC_MIPI_CSI_SUPPORTED: camera_driver :SOC_CLK_TREE_SUPPORTED: clk_tree :SOC_DAC_SUPPORTED: dac :SOC_ECDSA_SUPPORTED: ecdsa @@ -22,11 +23,10 @@ Peripherals API i2c :SOC_I2S_SUPPORTED: i2s :SOC_ISP_SUPPORTED: isp + :SOC_JPEG_CODEC_SUPPORTED: jpeg lcd/index :SOC_GP_LDO_SUPPORTED: ldo_regulator ledc - :SOC_JPEG_CODEC_SUPPORTED: jpeg - :SOC_MIPI_CSI_SUPPORTED: camera_driver :SOC_MCPWM_SUPPORTED: mcpwm :SOC_PARLIO_SUPPORTED: parlio :SOC_PCNT_SUPPORTED: pcnt diff --git a/examples/peripherals/jpeg/jpeg_encode/README.md b/examples/peripherals/jpeg/jpeg_encode/README.md index 3ab6bf7f3e..82aa2704b4 100644 --- a/examples/peripherals/jpeg/jpeg_encode/README.md +++ b/examples/peripherals/jpeg/jpeg_encode/README.md @@ -17,6 +17,7 @@ This example makes use of the hardware-based JPEG encoder. If you have multiple * A USB cable for power supply and serial communication * Computer with ESP-IDF installed and configured * The raw picture is the only source that you need to prepare (We have an [esp1080p.rgb](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/jpeg/jpeg_encode/resources/esp1080.rgb) in resources folder, you can also get it from [jpeg_decode](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/jpeg/jpeg_decode) example). +* ffmpeg can also be used to produce rgb picture. For example `ffmpeg -i input.jpg -pix_fmt rgb24 output.rgb` ### Build and Flash diff --git a/examples/peripherals/jpeg/jpeg_encode/main/jpeg_encode_main.c b/examples/peripherals/jpeg/jpeg_encode/main/jpeg_encode_main.c index 039062876a..8ee0a49a86 100644 --- a/examples/peripherals/jpeg/jpeg_encode/main/jpeg_encode_main.c +++ b/examples/peripherals/jpeg/jpeg_encode/main/jpeg_encode_main.c @@ -90,26 +90,20 @@ void app_main(void) .buffer_direction = JPEG_DEC_ALLOC_INPUT_BUFFER, }; - jpeg_new_encoder_engine(&encode_eng_cfg, &jpeg_handle); + ESP_ERROR_CHECK(jpeg_new_encoder_engine(&encode_eng_cfg, &jpeg_handle)); // Read 1080p raw picture fseek(file_raw_1080p, 0, SEEK_END); raw_size_1080p = ftell(file_raw_1080p); fseek(file_raw_1080p, 0, SEEK_SET); size_t tx_buffer_size = 0; uint8_t *raw_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p, &tx_mem_cfg, &tx_buffer_size); - if (raw_buf_1080p == NULL) { - ESP_LOGE(TAG, "alloc 1080p tx buffer error"); - return; - } + assert(raw_buf_1080p != NULL); fread(raw_buf_1080p, 1, raw_size_1080p, file_raw_1080p); fclose(file_raw_1080p); size_t rx_buffer_size = 0; uint8_t *jpg_buf_1080p = (uint8_t*)jpeg_alloc_encoder_mem(raw_size_1080p / 10, &rx_mem_cfg, &rx_buffer_size); // Assume that compression ratio of 10 to 1 - if (jpg_buf_1080p == NULL) { - ESP_LOGE(TAG, "alloc jpg_buf_1080p error"); - return; - } + assert(jpg_buf_1080p != NULL); jpeg_encode_cfg_t enc_config = { .src_type = JPEG_ENCODE_IN_FORMAT_RGB888, @@ -119,7 +113,7 @@ void app_main(void) .height = 1080, }; - jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, rx_buffer_size, &jpg_size_1080p); + ESP_ERROR_CHECK(jpeg_encoder_process(jpeg_handle, &enc_config, raw_buf_1080p, raw_size_1080p, jpg_buf_1080p, rx_buffer_size, &jpg_size_1080p)); FILE *file_jpg_1080p = fopen(s_outfile_1080p, "wb"); ESP_LOGI(TAG, "outfile:%s", s_outfile_1080p);