初版
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
|
||||
// 如果定义了 USE_PSRAM,就把 malloc/free 映射到 malloc_psram/free_psram
|
||||
#if TCFG_PSRAM_DEV_ENABLE
|
||||
#define malloc(size) malloc_psram(size)
|
||||
#define free(ptr) free_psram(ptr)
|
||||
#else
|
||||
#define malloc(size) malloc(size)
|
||||
#define free(ptr) free(ptr)
|
||||
#endif
|
||||
|
||||
|
||||
extern int jpgenc_get_heapsize(int width, int height);
|
||||
extern void *jpgenc_init(unsigned char *heap, int width, int height, int stride, int quality);
|
||||
extern void jpgenc_free(void *ctxt);
|
||||
extern void jpgenc_set_quality(void *ctxt, int quality);
|
||||
extern void jpgenc_get_header(void *ctxt, unsigned char **output, int *out_size);
|
||||
extern void jpgenc_encode_yuyv(void *ctxt, unsigned char *data, unsigned char *output, int *out_size, int vlen, int voff);
|
||||
|
||||
struct software_jpegenc_hdl {
|
||||
void *jfif;
|
||||
u8 *heap;
|
||||
u8 *jpeg_header;
|
||||
int jpeg_header_size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_init jpeg软件分行编码初始化
|
||||
*
|
||||
* @param img_width 图像宽
|
||||
* @param img_height 图像高
|
||||
* @param img_stride
|
||||
* @param q_val 编码Q值,范围(1-100)
|
||||
* @return enc_hdl_ptr:成功 NULL:失败
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *software_jpegenc_init(int img_width, int img_height, int img_stride, int q_val)
|
||||
{
|
||||
struct software_jpegenc_hdl *hdl = malloc(sizeof(struct software_jpegenc_hdl));
|
||||
if (!hdl) {
|
||||
printf("jpgenc hdl malloc fail \n");
|
||||
return NULL;
|
||||
}
|
||||
memset(hdl, 0x00, sizeof(struct software_jpegenc_hdl));
|
||||
|
||||
//获取jpg头信息大小
|
||||
int heapsize = jpgenc_get_heapsize(img_width, img_height);
|
||||
/* printf("jpgenc heapsize:%d \n",heapsize); */
|
||||
|
||||
// 申请jpg头部控件
|
||||
u8 *heap = malloc(heapsize);
|
||||
if (!heap) {
|
||||
printf("jpgenc heap malloc fail \n");
|
||||
free(hdl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//JPG图像编码初始化
|
||||
u8 *header;
|
||||
int header_size;
|
||||
void *jfif = jpgenc_init(heap, img_width, img_height, img_stride, q_val);
|
||||
jpgenc_get_header(jfif, &header, &header_size);
|
||||
/* printf("jpgenc header_size:%d \n",header_size); */
|
||||
|
||||
hdl->jfif = jfif;
|
||||
hdl->heap = heap;
|
||||
hdl->jpeg_header = header;
|
||||
hdl->jpeg_header_size = header_size;
|
||||
|
||||
return (void *)hdl;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_line jpeg软件分行编码
|
||||
*
|
||||
* @param jpgenc_hdl 编码句柄,software_jpegenc_init获取
|
||||
* @param out_buf 编码位流保存buf
|
||||
* @param out_buf_size 编码位流保存buf大小
|
||||
* @param in_data 待编码的YUYV数据buf
|
||||
* @param vlen 编码行数
|
||||
* @param voff 编码行数偏移
|
||||
* @param jpgenc_out_size 此次编码输出位流的大小
|
||||
*
|
||||
* @return 0:成功 -1:失败
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int software_jpegenc_line(void *jpgenc_hdl, u8 *out_buf, int out_buf_size, u8 *in_data, int vlen, int voff, int *jpgenc_out_size)
|
||||
{
|
||||
if (!jpgenc_hdl || !out_buf || !in_data) {
|
||||
printf("jpgenc ptr err \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct software_jpegenc_hdl *hdl = (struct software_jpegenc_hdl *)jpgenc_hdl;
|
||||
int total_size = 0;
|
||||
u8 *buf_ptr = out_buf;
|
||||
int buf_size = out_buf_size;
|
||||
|
||||
if (voff == 0) {
|
||||
if (buf_size < hdl->jpeg_header_size) {
|
||||
printf("jpgenc header buf_size err buf_size:%d need size:%d \n",
|
||||
buf_size, hdl->jpeg_header_size);
|
||||
return -1;
|
||||
}
|
||||
memcpy(out_buf, hdl->jpeg_header, hdl->jpeg_header_size);
|
||||
|
||||
buf_ptr += hdl->jpeg_header_size;
|
||||
buf_size -= hdl->jpeg_header_size;
|
||||
total_size += hdl->jpeg_header_size;
|
||||
}
|
||||
|
||||
int out_size = buf_size;
|
||||
jpgenc_encode_yuyv(hdl->jfif, in_data, buf_ptr, &out_size, vlen, voff);
|
||||
if (out_size == buf_size) {
|
||||
printf("jpgenc encode buf_size err \n");
|
||||
return -1;
|
||||
}
|
||||
total_size += out_size;
|
||||
|
||||
*jpgenc_out_size = total_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_exit jpeg软件编码退出流程,释放内存
|
||||
*
|
||||
* @param jpgenc_hdl init时申请的句柄
|
||||
*
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void software_jpegenc_exit(void *jpgenc_hdl)
|
||||
{
|
||||
if (!jpgenc_hdl) {
|
||||
return;
|
||||
}
|
||||
struct software_jpegenc_hdl *hdl = (struct software_jpegenc_hdl *)jpgenc_hdl;
|
||||
if (hdl->heap) {
|
||||
free(hdl->heap);
|
||||
}
|
||||
if (hdl->jfif) {
|
||||
jpgenc_free(hdl->jfif);
|
||||
}
|
||||
free(hdl);
|
||||
}
|
||||
|
||||
|
||||
//测试代码
|
||||
//os_task_create(software_jpegenc_demo_task,NULL,10,2048,1024,"jpegenc_demo_task");
|
||||
void software_jpegenc_demo_task(void *priv)
|
||||
{
|
||||
mem_stats();
|
||||
|
||||
//1.128x128 YUYV
|
||||
int img_width = 240; //图片宽
|
||||
int img_height = 320; //图片高
|
||||
int vlen = 32; //每次编码的行数
|
||||
|
||||
void *fp = NULL, *w_fp = NULL;
|
||||
int jpeg_buf_size, yuv_buf_size, cur_enc_line, out_buf_size, jpgenc_out_total_size;
|
||||
u8 *jpeg_buf = NULL, *yuv_buf = NULL, *out_buf = NULL;
|
||||
void *enc_hdl = NULL;
|
||||
uint32_t enc_time;
|
||||
|
||||
fp = (void *)fopen("storage/sd0/C/output1.yuy", "r");
|
||||
if (!fp) {
|
||||
printf("fopen err \n");
|
||||
goto exit;
|
||||
}
|
||||
printf("yuv file len:%d \n", flen(fp));
|
||||
|
||||
//确保内存足够装下, 测试图片240*320 Q值50,编码出来8K内存
|
||||
jpeg_buf_size = 20 * 1024;
|
||||
jpeg_buf = malloc(jpeg_buf_size);
|
||||
if (!jpeg_buf) {
|
||||
printf("malloc jpg buf err \n");
|
||||
mem_stats();
|
||||
goto exit;
|
||||
}
|
||||
|
||||
yuv_buf_size = img_width * vlen * 2;
|
||||
yuv_buf = malloc(yuv_buf_size);
|
||||
if (!yuv_buf) {
|
||||
printf("malloc yuv buf err \n");
|
||||
mem_stats();
|
||||
goto exit;
|
||||
}
|
||||
|
||||
enc_hdl = software_jpegenc_init(img_width, img_height, img_width, 50);
|
||||
if (!enc_hdl) {
|
||||
printf("software jpegenc init err \n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cur_enc_line = 0;
|
||||
out_buf = jpeg_buf;
|
||||
out_buf_size = jpeg_buf_size;
|
||||
jpgenc_out_total_size = 0;
|
||||
enc_time = 0;
|
||||
|
||||
while (cur_enc_line < img_height) {
|
||||
int jpgenc_out_size = 0;
|
||||
|
||||
if (fread(yuv_buf, 1, yuv_buf_size, fp) != yuv_buf_size) {
|
||||
printf("yuv fread err \n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
uint32_t timer_get_ms(void);
|
||||
uint32_t enc_start_time = timer_get_ms();
|
||||
if (software_jpegenc_line(enc_hdl, out_buf, out_buf_size, yuv_buf, vlen, cur_enc_line, &jpgenc_out_size)) {
|
||||
printf("software jpgenc line err \n");
|
||||
goto exit;
|
||||
}
|
||||
enc_time += timer_get_ms() - enc_start_time;
|
||||
|
||||
out_buf += jpgenc_out_size;
|
||||
out_buf_size -= jpgenc_out_size;
|
||||
jpgenc_out_total_size += jpgenc_out_size;
|
||||
cur_enc_line += vlen;
|
||||
}
|
||||
printf("jpgenc finish use time: %dms jpg size:%d \n", enc_time, jpgenc_out_total_size);
|
||||
|
||||
w_fp = fopen("storage/sd0/C/output1.jpg", "w+");
|
||||
if (!w_fp) {
|
||||
printf("jpeg fopen err \n");
|
||||
goto exit;
|
||||
}
|
||||
if (fwrite(jpeg_buf, 1, jpgenc_out_total_size, w_fp) != jpgenc_out_total_size) {
|
||||
printf("jpeg fwrite err \n");
|
||||
goto exit;
|
||||
}
|
||||
exit:
|
||||
printf("software_jpegenc_demo_task exit \n");
|
||||
if (w_fp) {
|
||||
fclose(w_fp);
|
||||
w_fp = NULL;
|
||||
}
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
if (enc_hdl) {
|
||||
software_jpegenc_exit(enc_hdl);
|
||||
enc_hdl = NULL;
|
||||
}
|
||||
if (yuv_buf) {
|
||||
free(yuv_buf);
|
||||
yuv_buf = NULL;
|
||||
}
|
||||
if (jpeg_buf) {
|
||||
free(jpeg_buf);
|
||||
jpeg_buf = NULL;
|
||||
}
|
||||
mem_stats();
|
||||
os_time_dly(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef SOFTWARE_JPEGENC_H
|
||||
#define SOFTWARE_JPEGENC_H
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_init jpeg软件分行编码初始化
|
||||
*
|
||||
* @param img_width 图像宽
|
||||
* @param img_height 图像高
|
||||
* @param img_stride
|
||||
* @param q_val 编码Q值,范围(1-100)
|
||||
* @return enc_hdl_ptr:成功 NULL:失败
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void *software_jpegenc_init(int img_width, int img_height, int img_stride, int q_val);
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_line jpeg软件分行编码
|
||||
*
|
||||
* @param jpgenc_hdl 编码句柄,software_jpegenc_init获取
|
||||
* @param out_buf 编码位流保存buf
|
||||
* @param out_buf_size 编码位流保存buf大小
|
||||
* @param in_data 待编码的YUYV数据buf
|
||||
* @param vlen 编码行数
|
||||
* @param voff 编码行数偏移
|
||||
* @param jpgenc_out_size 此次编码输出位流的大小
|
||||
*
|
||||
* @return 0:成功 -1:失败
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
int software_jpegenc_line(void *jpgenc_hdl, u8 *out_buf, int out_buf_size, u8 *in_data, int vlen, int voff, int *jpgenc_out_size);
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief software_jpegenc_exit jpeg软件编码退出流程,释放内存
|
||||
*
|
||||
* @param jpgenc_hdl init时申请的句柄
|
||||
*
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
void software_jpegenc_exit(void *jpgenc_hdl);
|
||||
|
||||
|
||||
#endif /* SOFTWARE_JPEGENC_H */
|
||||
|
||||
Reference in New Issue
Block a user