由於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