YUV转换成RGB转换公式:
R = Y + 1.4075 *(V-128)
G = Y – 0.3455 *(U –128) – 0.7169 *(V –128)
B = Y + 1.779 *(U – 128)
优化策略,将浮点运算转换成整数运算,创建颜色表,通过查表减少运算提升效率。
变量声明:
uint8_t *auto_color_table;
uint8_t *color_table;
int *colortab;
int *u_b_tab;
int *u_g_tab;
int *v_g_tab;
int *v_r_tab;
int *y_coeff;
创建查找表:
inline long border_color(long color)
{
if (color>255)
return 255;
else if (color<0)
return 0;
else
return color;
}
void CreatColorTab()
{
int i;
//int u1, v1;
auto_color_table = (uint8_t*)malloc(3*256*sizeof(uint8_t));
color_table = &auto_color_table[256];
colortab = (int *)malloc(4*256*sizeof(int));
u_b_tab = &colortab[0*256];
u_g_tab = &colortab[1*256];
v_g_tab = &colortab[2*256];
v_r_tab = &colortab[3*256];
//y_coeff = &colortab[4*256];
for(i=0;i<256*3;i++)
{
auto_color_table[i] = border_color(i-256);
}
for (i=0; i<256; i++)//初始化查找表
{
u_b_tab[i] = (int)((1816 * (i-128))>>10);
u_g_tab[i] = (int)((352 * (i-128))>>10);
v_g_tab[i] = (int)((731 * (i-128))>>10);
v_r_tab[i] = (int)((1436 * (i-128))>>10);
}
}
YUV420转换成RGB24:
void Yuv420ToRgb24(uint32_t *pData,
unsigned char* y,
unsigned char* u,
unsigned char* v,
int width, int height)
{
uint32_t W;//要写入的字;
int y00,y01,y02,y03;//上一行四个像素的y值
int y10,y11,y12,y13;//下一行四个像素的y值
unsigned char* yoff;
unsigned char* uoff;
unsigned char* voff;
//unsigned char* yoff1;
unsigned char* uoff1;
unsigned char* voff1;
int ub0,ug0,vg0,vr0;
int ub1,ug1,vg1,vr1;
uint32_t byte_width;
byte_width = (width * 3 + 3) & ~3;
for(int j=0;j<height;j+=2)//行数
{
for(int i=0;i<width;i+=4)
{
yoff = y + j * width + i;
uoff = u + (j>>1) * (width>>1) +(i >>1 );
voff = v + (j>>1) * (width>>1) +(i >>1 );
//uoff = uoff + (i >> 1);
//voff = voff + (i >> 1);
uoff1 = uoff + 1;
voff1 = voff + 1;
//上一行四个y值
y00 = *yoff;
y01 = *(yoff+1);
y02 = *(yoff+2);
y03 = *(yoff+3);
//左四个像素的 ub, ug , vg, vr
ub0 = u_b_tab[*uoff];
ug0 = u_g_tab[*uoff];
vg0 = v_g_tab[*voff];
vr0 = v_r_tab[*voff];
yoff = y + (j+1)*dst.width + i;
//下一行四个y值
y10 = *yoff;
y11 = *(yoff+1);
y12 = *(yoff+2);
y13 = *(yoff+3);
//右四个像素的 ub, ug , vg, vr
ub1 = u_b_tab[*uoff1];
ug1 = u_g_tab[*uoff1];
vg1 = v_g_tab[*voff1];
vr1 = v_r_tab[*voff1];
pData = (uint32_t*)(pdata + j*byte_width + i*3);
//高字节,高地址,RGBR
W = color_table[y01+vr0]<<24 | color_table[y00+ub0] <<16|
color_table[y00-ug0-vg0]<<8 | color_table[y00+vr0];
*pData = W;
//GBRG
W = color_table[y02-ug1-vg1]<<24 | color_table[y02+vr1]<<16 |
color_table[y01+ub0] <<8 |color_table[y01-ug0-vg0];
*(pData+1) = W;
//BRGB
W = color_table[y03+ub1] <<24 | color_table[y03-ug1-vg1] <<16|
color_table[y03+vr1] << 8 | color_table[y02+ub1];
*(pData+2)=W;
pData = (uint32_t*)(pdata + (j+1)*byte_width +i*3);
//下面一行
W = color_table[y11+vr0]<<24 | color_table[y10+ub0] <<16|
color_table[y10-ug0-vg0]<<8 | color_table[y10+vr0];
*pData = W;
W = color_table[y12-ug1-vg1]<<24 | color_table[y12+vr1]<<16 |
color_table[y11+ub0] <<8 |color_table[y11-ug0-vg0];
*(pData+1) = W;
W = color_table[y13+ub1] <<24 | color_table[y13-ug1-vg1] <<16|
color_table[y13+vr1] << 8 | color_table[y12+ub1];
*(pData+2)=W;
}
}
}
查表,减少内存写入,以此提升效率。