使用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

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