使用libjpeg库将yuv420sp压缩为jpeg

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章