由于yuv原始数据比较大,在进行一些视频流传输的过程中为了减少数据量,通常需要进行压缩。本文探讨的是将yuv420sp压缩为jpeg流,包含灰度和彩色两种方式,下面是代码:
int codeJpeg(const char *scr_frame, int iWidth, int iHeight, int iQuality, int iColorSpace, char *coded_frame, int& code_frame_size)
{
//struct jpeg_decompress_struct cinfo;/* 用于解压缩 */
struct jpeg_compress_struct jcs; /* 用于压缩 */
struct my_error_mgr jerr; /* 错误处理域 */
int i = 0, j = 0;
unsigned char *pY, *pU, *pV;
unsigned char *yuvbuf = new unsigned char[iWidth * iHeight];
jcs.err = jpeg_std_error(&jerr.pub); /* 将申明的错误处理器赋值给jcs.err域 */
jerr.pub.error_exit = my_compress_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_compress(&jcs);
//fclose(infile);
return -1;
}
/* 以下为编码 */
jpeg_create_compress(&jcs);
jpeg_stdio_buffer_dest(&jcs,(unsigned char *)(coded_frame),(INT32*)&code_frame_size); /* 设置JPEG压缩编码的指针 */
/*set parameters for compression */
jcs.image_width = iWidth;
jcs.image_height = iHeight;
if(iColorSpace == CODE_COLOR_GRAY)
{
jcs.input_components = 1; /* = 1表示灰度图, = 3 表示彩色图 */
jcs.in_color_space = JCS_GRAYSCALE; /* JCS_RGB/JCS_YCbCr/JCS_GRAYSCALE */
}
else if(iColorSpace == CODE_COLOR_YCbCr)
{
jcs.input_components = 3;
jcs.in_color_space = JCS_YCbCr;
}
else if(iColorSpace == CODE_COLOR_RGB)
{
jcs.input_components = 3;
jcs.in_color_space = JCS_RGB;
}
jcs.dct_method = JDCT_FLOAT;
jpeg_set_defaults(&jcs); /* 采用默认参数进行压缩 */
jpeg_set_quality(&jcs,iQuality,true);
(void) jpeg_start_compress(&jcs, TRUE);
pY = (unsigned char *)scr_frame ;
pU = (unsigned char *)scr_frame + iWidth* iHeight;
pV = (unsigned char *)scr_frame + iWidth* iHeight*5/4;
j = 1;
int row_stride; /* physical row width in output buffer */
row_stride = jcs.image_width*jcs.input_components;
JSAMPROW row_pointer[1];
/* 设置数据源 */
while(jcs.next_scanline < jcs.image_height)
{
int index = 0;
for (i = 0; i < iWidth; i += 4){
//输入的YUV图片格式为标准的YUV444格式,所以需要把YUV420转化成YUV444.
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY ++;
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY ++;
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY ++;
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY ++;
pU ++;
pV ++;
}
row_pointer[0] = yuvbuf;
(void)jpeg_write_scanlines(&jcs, row_pointer, 1);//单行图片转换压缩
j++;
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
delete []yuvbuf;
return 0;
}
需要注意的是,进行压缩时,yuv420sp格式需要转换为yuv444的格式。完整代码参见:
https://download.csdn.net/download/dawudayudaxue/12460439