当ffmpeg获取桌面图像数据时, 数据格式是ARGB8888, 需要转换成yuv420p.
ARGB8888 --> RGB888 --> yuv444 --> yuv420p
Y Y = 0.299 x R + 0.587 x G + 0.114 x B + 0
U Cb = -0.169 x R - 0.331 x G + 0.499 x B + 128
V Cr = 0.499 x R - 0.418 x G - 0.0813 x B + 128
rgb32转换成yuv420p的实现代码:
int rgb32_2_yuv420p(unsigned char *rgb32, unsigned char *y, unsigned char *u, unsigned char *v, int w, int h)
{
int i, j, n;
int r, g, b;
for (i = 0; i < h; i+=2) //每两行来操作, 每行两个像素组合操作
{
for (j = 0; j < w; j+=2) //第一行 Y0 U0 Y1
{
n = (i*w+j); //第几个像素, 在rgb32每个像素4字节
b = rgb32[n*4];
g = rgb32[n*4+1];
r = rgb32[n*4+2];
// rgb32的高8位丢掉
*y++ = 0.299*r + 0.587*g + 0.114*b + 0;
*u++ = -0.169*r - 0.331*g + 0.499*b + 128;
// v数据丢掉
/////////////
n += 1; //同一行的下一个像素
b = rgb32[n*4];
g = rgb32[n*4+1];
r = rgb32[n*4+2];
*y++ = 0.299*r + 0.587*g + 0.114*b + 0;
// u, v数据丢掉
}
for (j = 0; j < w; j+=2) //第二行 Y0 V0 Y1
{
n = ((i+1)*w+j); //第几个像素, 在rgb32每个像素4字节
b = rgb32[n*4];
g = rgb32[n*4+1];
r = rgb32[n*4+2];
*y++ = 0.299*r + 0.587*g + 0.114*b + 0;
*v++ = 0.499*r - 0.418*g - 0.0813*b + 128 ;
/////////////
n += 1; //同一行的下一个像素
b = rgb32[n*4];
g = rgb32[n*4+1];
r = rgb32[n*4+2];
*y++ = 0.299*r + 0.587*g + 0.114*b + 0;
}
}
return (w*h*3)>>1;
}
编码过程与上一例子完全一样.