forked from espressif/esp-idf
change(jpeg): Clean up some mess code in jpeg encoder
This commit is contained in:
@@ -19,11 +19,11 @@ extern "C" {
|
|||||||
* @brief JPEG encoder configure structure
|
* @brief JPEG encoder configure structure
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
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 */
|
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_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 */
|
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;
|
} jpeg_encode_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,14 +31,14 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int intr_priority; /*!< JPEG interrupt priority, if set to 0, driver will select the default priority (1,2,3). */
|
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;
|
} jpeg_encode_engine_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief JPEG encoder memory allocation config
|
* @brief JPEG encoder memory allocation config
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
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;
|
} jpeg_encode_memory_alloc_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -68,11 +68,6 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
typedef struct jpeg_decoder_t *jpeg_decoder_handle_t;
|
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
|
* @brief Type of jpeg encoder handle
|
||||||
*/
|
*/
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "sys/param.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "jpeg_private.h"
|
#include "jpeg_private.h"
|
||||||
#include "private/jpeg_param.h"
|
#include "private/jpeg_param.h"
|
||||||
@@ -13,9 +14,6 @@
|
|||||||
#include "hal/jpeg_defs.h"
|
#include "hal/jpeg_defs.h"
|
||||||
#include "esp_private/esp_cache_private.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)
|
static void emit_byte(jpeg_enc_header_info_t *header_info, uint8_t i)
|
||||||
{
|
{
|
||||||
header_info->header_buf[header_info->header_len] = 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++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
int temp = *basic_table++;
|
int temp = *basic_table++;
|
||||||
temp = (temp * scaling_factor + 50L) / 100L;
|
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;
|
size_t cache_align = 0;
|
||||||
esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_PSRAM, &cache_align);
|
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).
|
// 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_marker(header_info, JPEG_M_COM & 0xff);
|
||||||
emit_word(header_info, compensate_size);
|
emit_word(header_info, compensate_size);
|
||||||
for (int i = 0; i < compensate_size; i++) {
|
for (int i = 0; i < compensate_size; i++) {
|
||||||
|
@@ -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;
|
jpeg_hal_context_t *hal = &encoder_engine->codec_base->hal;
|
||||||
color_space_pixel_format_t picture_format;
|
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;
|
picture_format.color_type_id = encoder_engine->picture_format;
|
||||||
encoder_engine->bytes_per_pixel = color_hal_pixel_format_get_bit_depth(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) {
|
if (encoder_engine->color_space == JPEG_ENC_SRC_GRAY) {
|
||||||
|
@@ -1,2 +1,4 @@
|
|||||||
| Supported Targets | ESP32-P4 |
|
| Supported Targets | ESP32-P4 |
|
||||||
| ----------------- | -------- |
|
| ----------------- | -------- |
|
||||||
|
|
||||||
|
jpeg_decoder can be used to generate '*.rgb' file which to be used for this test.
|
||||||
|
@@ -68,12 +68,12 @@ TEST_CASE("JPEG encode performance test for 480*640 RGB->YUV picture", "[jpeg]")
|
|||||||
|
|
||||||
uint32_t jpg_size_480p = 0;
|
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;
|
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
|
// 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));
|
TEST_ESP_OK(jpeg_new_encoder_engine(&encode_eng_cfg, &jpeg_handle));
|
||||||
|
|
||||||
ccomp_timer_start();
|
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
|
// Decode picture for 50 times, and get the average
|
||||||
uint8_t cnt = 50;
|
uint8_t cnt = 50;
|
||||||
for (int i = 0; i < cnt; i++) {
|
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();
|
int64_t encode_time = ccomp_timer_stop();
|
||||||
|
|
||||||
|
@@ -632,10 +632,10 @@ static inline uint32_t jpeg_ll_get_intr_status(jpeg_dev_t *hw)
|
|||||||
return hw->int_st.val;
|
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;
|
uint8_t cs = 0;
|
||||||
switch (color_space) {
|
switch (pixel_format) {
|
||||||
case JPEG_ENC_SRC_RGB888:
|
case JPEG_ENC_SRC_RGB888:
|
||||||
cs = 0;
|
cs = 0;
|
||||||
break;
|
break;
|
||||||
|
@@ -10,6 +10,7 @@ Peripherals API
|
|||||||
:SOC_ADC_DMA_SUPPORTED: adc_continuous
|
:SOC_ADC_DMA_SUPPORTED: adc_continuous
|
||||||
:SOC_ADC_SUPPORTED: adc_calibration
|
:SOC_ADC_SUPPORTED: adc_calibration
|
||||||
:SOC_ANA_CMPR_SUPPORTED: ana_cmpr
|
:SOC_ANA_CMPR_SUPPORTED: ana_cmpr
|
||||||
|
:SOC_MIPI_CSI_SUPPORTED: camera_driver
|
||||||
:SOC_CLK_TREE_SUPPORTED: clk_tree
|
:SOC_CLK_TREE_SUPPORTED: clk_tree
|
||||||
:SOC_DAC_SUPPORTED: dac
|
:SOC_DAC_SUPPORTED: dac
|
||||||
:SOC_ECDSA_SUPPORTED: ecdsa
|
:SOC_ECDSA_SUPPORTED: ecdsa
|
||||||
@@ -22,11 +23,10 @@ Peripherals API
|
|||||||
i2c
|
i2c
|
||||||
:SOC_I2S_SUPPORTED: i2s
|
:SOC_I2S_SUPPORTED: i2s
|
||||||
:SOC_ISP_SUPPORTED: isp
|
:SOC_ISP_SUPPORTED: isp
|
||||||
|
:SOC_JPEG_CODEC_SUPPORTED: jpeg
|
||||||
lcd/index
|
lcd/index
|
||||||
:SOC_GP_LDO_SUPPORTED: ldo_regulator
|
:SOC_GP_LDO_SUPPORTED: ldo_regulator
|
||||||
ledc
|
ledc
|
||||||
:SOC_JPEG_CODEC_SUPPORTED: jpeg
|
|
||||||
:SOC_MIPI_CSI_SUPPORTED: camera_driver
|
|
||||||
:SOC_MCPWM_SUPPORTED: mcpwm
|
:SOC_MCPWM_SUPPORTED: mcpwm
|
||||||
:SOC_PARLIO_SUPPORTED: parlio
|
:SOC_PARLIO_SUPPORTED: parlio
|
||||||
:SOC_PCNT_SUPPORTED: pcnt
|
:SOC_PCNT_SUPPORTED: pcnt
|
||||||
|
@@ -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
|
* A USB cable for power supply and serial communication
|
||||||
* Computer with ESP-IDF installed and configured
|
* 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).
|
* 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
|
### Build and Flash
|
||||||
|
|
||||||
|
@@ -90,26 +90,20 @@ void app_main(void)
|
|||||||
.buffer_direction = JPEG_DEC_ALLOC_INPUT_BUFFER,
|
.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
|
// Read 1080p raw picture
|
||||||
fseek(file_raw_1080p, 0, SEEK_END);
|
fseek(file_raw_1080p, 0, SEEK_END);
|
||||||
raw_size_1080p = ftell(file_raw_1080p);
|
raw_size_1080p = ftell(file_raw_1080p);
|
||||||
fseek(file_raw_1080p, 0, SEEK_SET);
|
fseek(file_raw_1080p, 0, SEEK_SET);
|
||||||
size_t tx_buffer_size = 0;
|
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);
|
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) {
|
assert(raw_buf_1080p != NULL);
|
||||||
ESP_LOGE(TAG, "alloc 1080p tx buffer error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fread(raw_buf_1080p, 1, raw_size_1080p, file_raw_1080p);
|
fread(raw_buf_1080p, 1, raw_size_1080p, file_raw_1080p);
|
||||||
fclose(file_raw_1080p);
|
fclose(file_raw_1080p);
|
||||||
|
|
||||||
size_t rx_buffer_size = 0;
|
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
|
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) {
|
assert(jpg_buf_1080p != NULL);
|
||||||
ESP_LOGE(TAG, "alloc jpg_buf_1080p error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_encode_cfg_t enc_config = {
|
jpeg_encode_cfg_t enc_config = {
|
||||||
.src_type = JPEG_ENCODE_IN_FORMAT_RGB888,
|
.src_type = JPEG_ENCODE_IN_FORMAT_RGB888,
|
||||||
@@ -119,7 +113,7 @@ void app_main(void)
|
|||||||
.height = 1080,
|
.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");
|
FILE *file_jpg_1080p = fopen(s_outfile_1080p, "wb");
|
||||||
ESP_LOGI(TAG, "outfile:%s", s_outfile_1080p);
|
ESP_LOGI(TAG, "outfile:%s", s_outfile_1080p);
|
||||||
|
Reference in New Issue
Block a user