esp-idf/components/esp_driver_jpeg/jpeg_private.h
Cao Sen Miao 7f97a9e524 fix(jpeg): Fix several issues reported recently,
1. Fix decode images with dri marker failed,
2. Fix encode sometimes get length error
2024-04-28 15:16:48 +08:00

246 lines
12 KiB
C

/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdatomic.h>
#include "sys/queue.h"
#include "esp_private/dma2d.h"
#include "driver/jpeg_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "hal/jpeg_hal.h"
#include "esp_intr_types.h"
#include "esp_pm.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#define JPEG_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT)
#define JPEG_ALLOW_INTR_PRIORITY_MASK (ESP_INTR_FLAG_LOWMED)
// JPEG encoder and decoder shares same interrupt ID.
#define JPEG_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED)
#define JPEG_ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
typedef struct jpeg_decoder_t jpeg_decoder_t;
typedef struct jpeg_encoder_t jpeg_encoder_t;
typedef struct jpeg_codec_t jpeg_codec_t;
typedef struct jpeg_codec_t *jpeg_codec_handle_t;
typedef struct jpeg_isr_handler_ {
uint32_t mask;
intr_handler_t handler;
void* handler_arg;
uint32_t flags;
SLIST_ENTRY(jpeg_isr_handler_) next;
} jpeg_isr_handler_t;
struct jpeg_codec_t {
SemaphoreHandle_t codec_mutex; // pretend that one picture is in process, no other picture can interrupt current stage.
jpeg_hal_context_t hal; // Hal layer for each port(bus)
portMUX_TYPE spinlock; // To protect pre-group register level concurrency access
intr_handle_t intr_handle; // jpeg codec interrupt handler
int intr_priority; // jpeg codec interrupt priority
SLIST_HEAD(jpeg_isr_handler_list_, jpeg_isr_handler_) jpeg_isr_handler_list; // List for jpeg interrupt.
esp_pm_lock_handle_t pm_lock; // power manage lock
};
typedef enum {
JPEG_DEC_DIRECT_OUTPUT_HB = 0, /*!< Direct output */
JPEG_DEC_YUV444_HB = 1, /*!< output YUV444 format */
JPEG_DEC_RGB888_HB = 2, /*!< output RGB888 format */
JPEG_DEC_RGB565_HB = 3, /*!< output RGB565 format */
JPEG_DEC_GRAY_HB = 4, /*!< output the gray picture */
JPEG_DEC_BEST_HB_MAX, /*!< Max value of output formats */
} jpeg_dec_format_hb_t;
typedef struct {
uint8_t *buffer_offset; // Pointer points to picture buffer.
uint32_t buffer_left; // Data left in the picture.
uint32_t header_size; // record the picture header size.
uint32_t process_v; // vertical output in processing, multiple of mcu.
uint32_t process_h; // horizontal output in processing, multiple of mcu.
uint32_t origin_v; // vertical for the origin size of picture.
uint32_t origin_h; // horizontal for the origin size of picture.
uint8_t mcux; // the best value of minimum coding unit horizontal unit
uint8_t mcuy; // minimum coding unit vertical unit
uint8_t qt_tbl_num; // quantization table number
uint32_t qt_tbl[JPEG_COMPONENT_NUMBER_MAX][JPEG_QUANTIZATION_TABLE_LEN]; // quantization table content [id]
uint8_t nf; // number of frames
uint8_t ci[JPEG_COMPONENT_NUMBER_MAX]; // Component identifier.
uint8_t hivi[JPEG_COMPONENT_NUMBER_MAX]; // H&V sampling factor
uint8_t hi[JPEG_COMPONENT_NUMBER_MAX]; // Horizontal sampling factor
uint8_t vi[JPEG_COMPONENT_NUMBER_MAX]; // Vertical sampling factor
uint8_t qtid[JPEG_COMPONENT_NUMBER_MAX]; // Quantization table destination selector
jpeg_huffman_table_info_t huffinfo; // Huffman table specification information
uint8_t huffbits[2][2][JPEG_HUFFMAN_BITS_LEN_TABLE_LEN]; // Huffman bit distribution tables [id][dcac]
uint8_t huffcode[2][2][JPEG_HUFFMAN_AC_VALUE_TABLE_LEN]; // Huffman decoded data tables [id][dcac]
uint32_t tmp_huff[JPEG_HUFFMAN_AC_VALUE_TABLE_LEN]; // temp buffer to store huffman code
bool dri_marker; // If we have dri marker in table
uint16_t ri; // Restart interval
} jpeg_dec_header_info_t;
struct jpeg_decoder_t {
jpeg_codec_t *codec_base; // Pointer to jpeg codec hardware base
jpeg_dec_header_info_t *header_info; // Pointer to current picture information
jpeg_down_sampling_type_t sample_method; // method of sampling the JPEG picture.
jpeg_dec_output_format_t output_format; // picture output format.
jpeg_dec_rgb_element_order_t rgb_order; // RGB pixel order
jpeg_yuv_rgb_conv_std_t conv_std; // YUV RGB conversion standard
bool no_color_conversion; // No color conversion, directly output based on compressed format
uint8_t bit_per_pixel; // bit size per pixel
QueueHandle_t evt_queue; // jpeg event from 2DDMA and JPEG engine
uint8_t *decoded_buf; // pointer to the rx buffer.
uint32_t total_size; // jpeg picture origin size (in bytes)
TickType_t timeout_tick; // timeout value for jpeg decoder (in cpu tick).
jpeg_isr_handler_t *intr_handle; // jpeg decoder interrupt handler
//dma handles
dma2d_pool_handle_t dma2d_group_handle; // 2D-DMA group handle
dma2d_descriptor_t *rxlink; // Pointer to 2D-DMA rx descriptor
dma2d_descriptor_t *txlink; // Pointer to 2D-DMA tx descriptor
uint32_t dma_desc_size; // tx and rx linker alignment
dma2d_channel_handle_t dma2d_rx_channel; // DMA2D RX channel handle
dma2d_channel_handle_t dma2d_tx_channel; // DMA2D TX channel handle
dma2d_trans_t* trans_desc; // DMA2D transaction descriptor
};
typedef enum {
JPEG_DMA2D_RX_EOF = BIT(0), // DMA2D rx eof event
JPEG_DMA2D_RX_DONE = BIT(1), // DMA2D rx done event
JPEG_DMA2D_TX_DONE = BIT(2), // DMA2D tx done event
} jpeg_dma2d_evt_enum_t;
typedef struct {
jpeg_dma2d_evt_enum_t dma_evt; // jpeg-2ddma event, (triggered from 2ddma interrupt)
uint32_t jpgd_status; // jpeg decoder status, (triggered from jpeg interrupt)
} jpeg_dma2d_dec_evt_t;
typedef enum {
JPEG_ENC_SRC_RGB888_HB = 0, // Input RGB888 format
JPEG_ENC_SRC_YUV422_HB = 1, // Input YUV422 format
JPEG_ENC_SRC_RGB565_HB = 2, // Input RGB565 format
JPEG_ENC_SRC_GRAY_HB = 3, // Input GRAY format
JPEG_ENC_BEST_HB_MAX,
} jpeg_enc_format_hb_t;
typedef struct {
jpeg_dma2d_evt_enum_t dma_evt; // jpeg-2ddma event, (triggered from 2ddma interrupt)
uint32_t encoder_status; // jpeg encoder status, (triggered from jpeg interrupt)
} jpeg_enc_dma2d_evt_t;
typedef struct {
uint8_t *header_buf; // Pointer to the header of jpeg header buffer
uint32_t header_len; // Record for header length
uint32_t m_quantization_tables[2][JPEG_QUANTIZATION_TABLE_LEN]; // quantization tables
uint8_t num_components; // number of components
uint32_t origin_h; // horizontal of original picture
uint32_t origin_v; // vertical of original picture
uint32_t quality; // JPEG compressed quality.
jpeg_down_sampling_type_t sub_sample; // Picture sub-sampling method
} jpeg_enc_header_info_t;
struct jpeg_encoder_t {
jpeg_codec_t *codec_base; // Pointer to jpeg codec hardware base
jpeg_enc_src_type_t color_space; // Picture source color space
jpeg_enc_input_format_t picture_format; // Source picture format
jpeg_enc_header_info_t *header_info; // Pointer to header buffer information
uint32_t bytes_per_pixel; // Bytes per pixel of source image format
uint8_t mcux; // the best value of minimum coding unit horizontal unit
uint8_t mcuy; // minimum coding unit vertical unit
jpeg_isr_handler_t *intr_handle; // jpeg encoder interrupt handler
TickType_t timeout_tick; // timeout value for jpeg decoder (in cpu tick).
QueueHandle_t evt_queue; // jpeg event from 2DDMA and JPEG engine
// dma_handles
dma2d_pool_handle_t dma2d_group_handle; // 2D-DMA group handle
dma2d_descriptor_t *rxlink; // Pointer to 2D-DMA rx descriptor
dma2d_descriptor_t *txlink; // Pointer to 2D-DMA tx descriptor
uint32_t dma_desc_size; // tx and rx linker alignment
dma2d_trans_t* trans_desc; // DMA2D transaction descriptor
dma2d_channel_handle_t dma2d_rx_channel; // DMA2D RX channel handle
dma2d_channel_handle_t dma2d_tx_channel; // DMA2D TX channel handle
};
#define JPEG_DMA2D_2D_ENABLE (1) // DMA2D two dimension enable
#define JPEG_DMA2D_2D_DISABLE (0) // DMA2D one dimension enable
#define JPEG_DMA2D_MAX_SIZE (0x3fff) // DMA2D max size (low 14 bit)
#define JPEG_DMA2D_EOF_LAST (1) // DMA2D EOF last
#define JPEG_DMA2D_EOF_NOT_LAST (0) // DMA2D EOF not last
#define JPEG_DMA2D_1D_HIGH_14BIT (14) // 1D high 14 bites
/**
* @brief Acquire a JPEG codec handle.
*
* @param[out] jpeg_new_codec Pointer to the variable where the acquired JPEG codec handle will be stored.
*
* @return
* - ESP_OK if the JPEG codec handle is successfully acquired.
* - ESP_ERR_NO_MEM if there is not enough memory to acquire the codec handle.
* - Other error codes indicating the cause of the failure.
*/
esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec);
/**
* @brief Release a JPEG codec handle.
*
* @param[in] jpeg_codec The JPEG codec handle to release.
*
* @return
* - ESP_OK if the JPEG codec handle is successfully released.
* - ESP_ERR_INVALID_ARG if the provided JPEG codec handle is invalid.
* - Other error codes indicating the cause of the failure.
*/
esp_err_t jpeg_release_codec_handle(jpeg_codec_handle_t jpeg_codec);
/**
* @brief Register an ISR handler for JPEG interrupt
*
* This function registers an Interrupt Service Routine (ISR) handler for JPEG interrupt.
*
* @param jpeg_codec The JPEG codec handle
* @param handler The ISR handler function to be registered
* @param handler_arg An argument to be passed to the ISR handler function
* @param jpeg_intr_mask The JPEG interrupt mask value
* @param flags Additional flags for ISR registration
* @param jpeg_intr_handler JPEG interrupt handler
* @return esp_err_t Returns ESP_OK on success, or an error code on failure
*/
esp_err_t jpeg_isr_register(jpeg_codec_handle_t jpeg_codec, intr_handler_t handler, void* handler_arg, uint32_t jpeg_intr_mask, uint32_t flags, jpeg_isr_handler_t** jpeg_intr_handler);
/**
* @brief Deregister an ISR handler for JPEG interrupt
*
* This function deregisters an Interrupt Service Routine (ISR) handler for JPEG interrupt.
*
* @param jpeg_codec The JPEG codec handle
* @param handler The ISR handler function to be deregistered
* @param handler_arg The argument previously passed to the ISR handler function
* @param jpeg_intr_handler JPEG interrupt handler
* @return esp_err_t Returns ESP_OK on success, or an error code on failure
*/
esp_err_t jpeg_isr_deregister(jpeg_codec_handle_t jpeg_codec, jpeg_isr_handler_t *jpeg_intr_handler);
/**
* @brief Check the interrupt priority for JPEG codec
*
* This function checks the interrupt priority for the JPEG codec to ensure it meets the specified requirements.
*
* @param jpeg_codec The JPEG codec handle
* @param intr_priority The interrupt priority value to be checked
* @return esp_err_t Returns ESP_OK if the interrupt priority meets the requirements, or an error code on failure
*/
esp_err_t jpeg_check_intr_priority(jpeg_codec_handle_t jpeg_codec, int intr_priority);
#ifdef __cplusplus
}
#endif