本文借鉴了别人的一些查表算法,改造成RGB2YUV420算法,计算速度更快,直接可用。
typedef struct RGB
{
unsigned char r;
unsigned char g;
unsigned char b;
}RGB;
struct RGB in[IMGSIZE]; //需要计算的原始数据
unsigned char out[XSIZE*YSIZE * 3/2]; //计算后的结果
unsigned short Y_R[COLORSIZE],Y_G[COLORSIZE],Y_B[COLORSIZE],U_R[COLORSIZE],U_G[COLORSIZE],U_B[COLORSIZE],V_G[COLORSIZE],V_B[COLORSIZE]; //查表数组V_R[COLORSIZE]
表的初始化
void table_init()
{
int i;
for(i = 0; i < COLORSIZE; i++)
{
Y_R[i] = (i * 1224) >> 12; //Y对应的查表数组0.2988
Y_G[i] = (i * 2404) >> 12; //0.5869
Y_B[i] = (i * 469) >> 12; //0.1162
U_R[i] = (i * 692) >> 12; //U对应的查表数组0.1688
U_G[i] = (i * 1356) >> 12; //0.3312
U_B[i] = i /*(* 2048) */>> 1; //0.5
// V_R[i] = (i * 2048) >> 12; ///V对应的查表数组
V_G[i] = (i * 1731) >> 12; //0.4184
V_B[i] = (i * 334) >> 12; //0.0816
}
}
数值计算
inline void calc_lum()
{
int pix;
int pixP4;
for(int y = 0; y < YSIZE; y++) //line
{
for(int x=0;x<XSIZE;x++)//pixf
{
pix=y*XSIZE + x;
int i = Y_R[in[pix].r] + Y_G[in[pix].g] + Y_B[in[pix].b];
out[pix]= i; //Y
if((x%2==1)&&(y%2==1))
{
pixP4=(XSIZE>>1) *(y>>1) + (x>>1);
i=U_B[in[pix].b] - U_R[in[pix].r] - U_G[in[pix].g]+128;
out[pixP4+IMGSIZE] = i;
/*+ U_B[in[pix+1].b] - U_R[in[pix+1].r] - U_G[in[pix+1].g]
+U_B[in[pix+XSIZE].b] - U_R[in[pix+XSIZE].r] - U_G[in[pix+XSIZE].g]
+U_B[in[pix+1+XSIZE].b] - U_R[in[pix+1+XSIZE].r] - U_G[in[pix+1+XSIZE].g] )/4*/
//U
i=U_B[in[pix].r] - V_G[in[pix].g] - V_B[in[pix].b]+128;
out[pixP4 + 5 * IMGSIZE /4] = i;
/*+U_B[in[pix+1].r] - V_G[in[pix+1].g] - V_B[in[pix+1].b]
+U_B[in[pix+XSIZE].r] - V_G[in[pix+XSIZE].g] - V_B[in[pix+XSIZE].b]
+U_B[in[pix+1+XSIZE].r] - V_G[in[pix+1+XSIZE].g] - V_B[in[pix+1+XSIZE].b])/4*/
//V
}
}
}
}
在回调函数中使用
if(g_i_VideoState==VideoState_Record)
{
for(int y=0;y<YSIZE;y++)
{
memcpy(in+XSIZE*(YSIZE-y+1),CurRGB+XSIZE*y*iPixelSize,XSIZE*iPixelSize);
}
byte temp;
for(unsigned int i=0; i < XSIZE*YSIZE; i++)
{
temp = in[i].r; //顺序调整
in[i].r = in[i].b;
in[i].b = temp;
}//颜色互换
calc_lum();
memcpy(CurYUV,out,XSIZE*YSIZE*3>>1);
fwrite(CurYUV,352*288*3>>1,1,m_yuv);