Files
AC707N/SDK/interface/ui/cpu/br35/jljpeg_decode.h
T

377 lines
14 KiB
C

/*----------------------------------------------*/
/* JL HW JEPG CODEC */
/*----------------------------------------------*/
#ifndef _JL_HW_JPGDEC
#define _JL_HW_JPGDEC
#include "typedef.h"
#include "generic/rect.h"
#ifdef __cplusplus
extern "C" {
#endif
//#define MCU_BUFF_NUM 1
#ifndef MCU_BUFF_NUM
#define MCU_BUFF_NUM 2
#endif
/* Allow the number of cached MUC blocks , Default to 2 , 默认双buff乒乓,支持多 buff 模式,最小可以设置为 1 */
/* 当上层触发解码动作的速度比解码速度快时,适当改大可以提高速度,比如直接设置整幅图片的总 MCU 数量, 即硬件直接解完,效率只受限于解码速度*/
/* 当上层触发解码动作的速度比解码速度慢时,使用 2 个buff即保证每次来取数据都有已经解码完成的内容,改大没有意义 */
//#define BIT_BUFF_NUM 1
// #ifndef BIT_BUFF_NUM
// #define BIT_BUFF_NUM 1
// #endif
/* Allow the number of cached MUC blocks , Default to 2 , 双buff乒乓或者单buff阻塞使用 */
/* 大致情况和 MCU 类似,主要考虑到输入bit流需要时32位对齐的地址空间,原始 bit 流需要从 flash 或者 SD 卡之中进行拷贝到RAM中,因此建议乒乓操作, 更多的 buff 没有意义,因为取 bit 流的动作会比解码动作慢 */
//#define JDEC_SZBUF 1024 * 8
#ifndef JDEC_SZBUF
#define JDEC_SZBUF 512
#endif
/* Specifies size of stream input buffer , >= 17 + 256 */
#define JDEC_MAGIC "JLHWJPEG"
typedef enum {
JPG_TEM = 0X01, //算术编码中作临时之用
//非层次哈夫曼编码
JPIF_SOF0 = 0XC0, //基线离散余弦变换/*只支持这种编码格式的图片*/
JPIF_SOF1, //扩展顺序离散余弦变换
JPIF_SOF2, //递进离散余弦变换
JPIF_SOF3, //空间顺序无损
JPIF_DHT = 0XC4, //哈夫曼表
//层次哈夫曼编码
JPIF_SOF5, //差分离散余弦变换
JPIF_SOF6, //差分层次离散余弦变换
JPIF_SOF7, //差分空间无损
//非层次算术编码
JPIF_SOF8, //为JPEG扩展保留
JPIF_SOF9, //扩展顺序离散余弦变换
JPIF_SOF10, //递进离散余弦变换
JPIF_SOF11, //空间顺序无损
JPIF_DAC = 0XCC, //算术编码表
//层次算术编码
JPIF_SOF13, //差分离散余弦变换
JPIF_SOF14, //差分层次离散余弦变换
JPIF_SOF15, //差分空间无损
JPIF_RST0 = 0XD0, //每隔n个MCU 块就有一个RST标记
JPIF_RST1,
JPIF_RST2,
JPIF_RST3,
JPIF_RST4,
JPIF_RST5,
JPIF_RST6,
JPIF_RST7 = 0XD7,
JPIF_SOI = 0XD8, //文件头
JPIF_EOI = 0XD9, //文件尾
JPIF_SOS = 0XDA, //扫描行开始
JPIF_DQT = 0XDB, //量化表
JPIF_DNL = 0XDC, //线数
JPIF_DRI = 0XDD, //重新开始间隔
JPIF_DHP = 0XDE, //层次级数
JPIF_EXP = 0XDF, //展开参考图像
JPIF_APP0 = 0XE0, //交换格式和图像识别信息
JPIF_APP1,
JPIF_APP2,
JPIF_APP3,
JPIF_APP4,
JPIF_APP5,
JPIF_APP6,
JPIF_APP7,
JPIF_APP8,
JPIF_APP9,
JPIF_APP10,
JPIF_APP11,
JPIF_APP12,
JPIF_APP13,
JPIF_APP14,
JPIF_APP15,
JPIF_COM = 0XFE, //注释
JPIF_MASK = 0XFF,
} JPG_TYPE;
/* Decode event code */
typedef enum {
JDEC_INTER_MCU, /* 0: The specified number of MCU blocks finishes decoding */
JDEC_INTER_BIT, /* 1: End of bit stream */
JDEC_INTER_FINISH, /* 2: End of file decoding */
} jdec_msg;
/* Error code */
typedef enum {
JDEC_OK = 0, /* 0: Succeeded */
JDEC_INP, /* 1: Device error or wrong termination of input stream */
JDEC_MEM1, /* 2: Memory request failed */
JDEC_MEM2, /* 3: Memory space not requested */
JDEC_MEM3, /* 4: Exceeds input buffer size : > JDEC_SZBUF */
JDEC_FMT1, /* 5: Data format error (may be broken data) */
JDEC_FMT2, /* 6: Right format but not supported */
JDEC_FMT3, /* 7: Not supported JPEG standard */
JDEC_FMT4, /* 8: Decoding execution error*/
JDEC_STA, /* 9: Jpeg work status error*/
JDEC_TIMEOUT,/*10: DEC_TIMEOUT*/
JDEC_HD_ERR,/*11:DEC_HD ERR*/
} jdec_err;
/* HW JPEG work state code */
typedef enum {
JDEC_WORK_STATE_CLOSE = 0, /* The jpeg decoding module is turned off */
JDEC_WORK_STATE_INIT, /* The jpeg decoding module is inited*/
JDEC_WORK_STATE_OPEN, /* The jpeg decoding module is enabled */
JDEC_WORK_STATE_START, /* jpeg decoding begins */
JDEC_WORK_STATE_STOP, /* End of jpeg decoding */
JDEC_WORK_STATE_SUSPEND, /* Pause during jpeg decoding */
} jdec_work_state;
/* MCU/BIT buff state code */
typedef enum {
JDEC_BUFF_STATE_INVALID = 0, /* 0: The buff is invalid, and the data is outdated or invalid */
JDEC_BUFF_STATE_UNDECODED, /* 1: The mcu block or bit stream that has not yet begun decoding */
JDEC_BUFF_STATE_DECODING, /* 2: Wait for the mcu block or bit stream to decode */
JDEC_BUFF_STATE_DECODED, /* 3: The decoding of the mcu block or bit stream is completed */
JDEC_BUFF_STATE_COPY, /* 4: MCU buf copy to line buf */
} jdec_buff_state;
/* Mcu buff information structure */
typedef struct _jdec_muc_buff {
jdec_buff_state state; /* mcu block usage status */
u16 mcuid; /* mcu block ID */
u8 *buf; /* data buffer */
} jdec_mcu_buff;
/* Bit buff information structure */
typedef struct _jdec_bit_buff {
jdec_buff_state state; /* bit stream usage status */
u32 len; /* data len */
u8 *buf; /* data buffer */
} jdec_bit_buff;
/* Huffman table structs */
typedef struct _huff_tab {
u16 *min;
u8 *index;
u8 *pval;
} huff_tab;
/* Decompressor object structure */
typedef struct _jdec_opj {
void *magic; /* Decoder magic */
jdec_work_state work_state: 4; /* Working state of the jpeg decoder module */
u8 msx: 4;
u8 msy: 4; /* MCU size in unit of block (width, height) */
u8 ycnt: 2; /* Y in the proportion of MCU components: 0:YUV444;1:YUV422;3:YUV411/YUV420 */
u8 isr_flags: 4; /* BIT0:MCU BIT2:BITS BIT3:LINE BIT4:REV */
u8 ncomp: 2; /* Number of color components 1:grayscale, 3:color */
u8 format: 1; /*1:565 0:888*/
u8 line_buf_vaild: 1; /*line buf 有效位*/
u8 bit_buff_sw: 1; /*bits_buff*/
u8 dri_enable: 1; /*dri_enable*/
u8 cur_rst_flag: 3; /*rst_flag:0xff d0~d7*/
u32 rev: 5; /* 预留拓展*/
u16 wmcu_num; /* The number of mcu blocks in the horizontal direction */
u16 hmcu_num; /* The number of mcu blocks in the vertical direction */
u16 all_mcucnt; /* The total number of mcu blocks of the picture */
u16 curr_mcuid; /* The mcu block ID currently to be decodeid: 0 - (all_mcucnt - 1) */
u16 start_mcuid; /*单次解码的开始id*/
u16 end_mcuid; /*单次解码的结束id*/
u16 mcu_cnt; /*单次解码 MCU 块的数量*/
u16 mcu_size; /*单个 MCU 块的大小*/
u8 qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */
u16 width; /* Size of the input image (pixel) */
u16 height; /* Size of the input image (pixel) */
u32(*infunc)(struct _jdec_opj *, u8 *buf, u32 len); /* Pointer to jpeg stream input function */
void (*decode_msg)(struct _jdec_opj *, jdec_msg); /* Pointer to the jpeg decoding event function */
void (*decode_wait)(struct _jdec_opj *); /* The decoder event waits for the callback */
void *device; /* Pointer to I/O device identifiler for the session */
int curr_offset; /*文件内偏移*/
u8 *outbuf; /* YUV422 to RGB buff: 这个 buff 从上层应用传下来装载数据 */
huff_tab hufftbl[2][2]; /* Huffman tables [id][dcac] */
u16 *qt_table;
s16 *qttbl[2]; /* Dequantizer tables [id] */
u16 *std_huffman_table;
u32 *huffman;
jdec_mcu_buff mcu_buff[MCU_BUFF_NUM]; /* MCU_BUFF_NUM mcu block buffers: 这些 buff 负责暂存解码后的 MCU 块数据和 MCU 块信息 */
jdec_bit_buff *bit_buff; /* BIT_BUFF_NUM bit stream buffers: 这些 buff 负责暂存原始的 JPEG 数据或者 JPEG 段信息 */
u8 *line_buf; /*mcu解码后数据先暂存到linebuf再统一变换输出,同时缓存部分数据给下一次解码使用,避免重复*/
struct rect draw_rect; /*jpeg在屏幕的绘制区域*/
struct rect jpeg_rect; /*在jpeg解码的相对位置*/
struct rect obuf_rect; /*输出buffer的区域*/
struct rect cover_rect;
void *matrix; /* affine matrix: 用于合成这个JPG时做GPU变换 */
s16 surplus_line; /* line buf 剩余未使用数据*/
u16 nrst;
u32 bit_cnt_start; /*位流起始地址*/
unsigned long bit_usec; /*bit usec*/
unsigned long mcu_usec; /*mcu_usec*/
} jdec_opj;
extern const char jljpeg_magic[]; //识别解码器的标志字
/* JL JPEG DEC API functions */
void jljpeg_os_init(void);
void jljpeg_hw_config_stage1(jdec_opj *opj, bool os_flag);
jdec_err jljpeg_hw_config_stage2(void (*decode_msg)(struct _jdec_opj *, jdec_msg), void (*decode_wait)(struct _jdec_opj *), \
uint16_t mcu_cnt, uint8_t *mcu_buff);
jdec_err jljpeg_hw_config_stage3(uint16_t x, uint16_t y, uint8_t *buf);
void jljpeg_hw_release(void);
void jljpeg_hw_resource_release(bool os_flag);
jdec_opj *jpeg_hw_get(void);
void jpeg_hw_set(jdec_opj *opj);
void jljpeg_hw_init(jdec_opj *opj);
void jljpeg_hw_reset(void);
void jljpeg_hw_restart(void);
void jljpeg_hw_mcubuff_reset(jdec_opj *opj, uint16_t mcu_cnt, uint8_t *mcu_buff);
void *jpeg_malloc(int size);
void jpeg_free(void *p);
#define JPEG_MALLOC(a) jpeg_malloc(a)
#define JPEG_FREE(a) jpeg_free(a)
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_img_info_get 读取文件头
*
* @param opj
* @param infunc
* @param dev
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
jdec_err jljpeg_img_info_get(jdec_opj *opj, u32(*infunc)(jdec_opj *opj, u8 *buf, u32 size), void *dev);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jpeg_decode_module_init jpeg 模块初始化
*
* @param malloc 申请
* @param free 释放
* @param gpu_blend 绘图
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jpeg_decode_module_init(
void *(*malloc)(int size, u32 ram_type, u32 module_type),
void (*free)(void *p, u32 ram_type, u32 module_type),
int (*gpu_blend)(u8 *dst_buf, struct rect *dst_rect, u8 *src_buf, struct rect *src_rect, struct rect *draw_rect, int src_stride, int format, void *p, int line_surpule, struct rect *cover)
);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_init 初始化解码
*
* @param opj
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jljpeg_decode_init(jdec_opj *opj);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_set_callback 注册回调
*
* @param opj 句柄
* @param infunc 输入数据流回调
* @param decode_msg
* @param decode_wait
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jljpeg_decode_set_callback(jdec_opj *opj,
u32(*infunc)(struct _jdec_opj *opj, u8 *buf, u32 len),
void (*decode_msg)(struct _jdec_opj *, jdec_msg),
void (*decode_wait)(struct _jdec_opj *)
);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_start 启动jpeg解码
*
* @param opj 解码句柄
* @param draw_rect 图片绘制区域
* @param jpeg_rect 在jpeg中的解码区域
* @param cover_rect 图片限制区域
* @param obuf_rect 输出buf区域
* @param dec_out_buf 输出buf
*
* @return jdec_err
*/
/* ------------------------------------------------------------------------------------*/
jdec_err jljpeg_decode_start(jdec_opj *opj, struct rect *draw_rect, struct rect *jpeg_rect, struct rect *cover_rect, struct rect *obuf_rect, void *dec_out_buf);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_release
*
* @param opj 解码句柄
* @param global_hd_clr 将全局解码句柄置为NULL,需应用层free句柄
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jljpeg_decode_release(jdec_opj *opj, int global_hd_clr);
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_get_decode_hd 将当前解码句柄置为NULL,需应用层free句柄
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
void jljpeg_get_decode_hd_clr();
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_get_decode_hd 获取文件句柄
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
void *jljpeg_get_decode_hd();
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_reset_curr 重新解码当前文件(废)
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jljpeg_decode_reset_curr();
/* ------------------------------------------------------------------------------------*/
/**
* @brief jljpeg_decode_hdl_reset 重新解码当前文件
*
* @param opj
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int jljpeg_decode_hdl_reset(jdec_opj *opj);
#ifdef __cplusplus
}
#endif
#endif /* _JL_HW_JPGDEC */