本代码是freecamera的一部分,freecamera源代码存在:http://gitorious.org/freecamera
#define BPP 4
#define SCALEBITS 10
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1<
#define RGB_TO_Y(r, g, b) /
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + /
FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
#define RGB_TO_U(r1, g1, b1, shift)/
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + /
FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V(r1, g1, b1, shift)/
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - /
FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_Y_CCIR(r, g, b) /
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + /
FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
#define RGB_TO_U_CCIR(r1, g1, b1, shift)/
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + /
FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V_CCIR(r1, g1, b1, shift)/
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - /
FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_IN(r, g, b, s)/
{/
unsigned int v = ((const guint *)(s))[0];/
r = (v&0xFF0000)>>16;/
g = (v&0xFF00)>>8;/
b = (v&0xFF);/
}
void rgba_to_yuv420p(guchar* dstdata, const guchar* srcdata, int width, int height)
{
int wrap, wrap3, width2;
int r, g, b, r1, g1, b1, w;
guchar *lum, *cb, *cr;
const guchar *p;
//lum = dst->data[0];
//cb = dst->data[1];
//cr = dst->data[2];
lum = dstdata;
cb = dstdata+width*height;
cr = dstdata+width*height*5/4;
width2 = (width + 1) >> 1;
//wrap = dst->linesize[0];
//wrap3 = src->linesize[0];
wrap = width;
wrap3 = width*4;
//p = src->data[0];
p = srcdata;
for (; height >= 2; height -= 2)
{
for (w = width; w >= 2; w -= 2)
{
RGB_IN (r, g, b, p);
r1 = r;
g1 = g;
b1 = b;
lum[0] = RGB_TO_Y_CCIR (r, g, b);
RGB_IN (r, g, b, p + BPP);
r1 += r;
g1 += g;
b1 += b;
lum[1] = RGB_TO_Y_CCIR (r, g, b);
p += wrap3;
lum += wrap;
RGB_IN (r, g, b, p);
r1 += r;
g1 += g;
b1 += b;
lum[0] = RGB_TO_Y_CCIR (r, g, b);
RGB_IN (r, g, b, p + BPP);
r1 += r;
g1 += g;
b1 += b;
lum[1] = RGB_TO_Y_CCIR (r, g, b);
cb[0] = RGB_TO_U_CCIR (r1, g1, b1, 2);
cr[0] = RGB_TO_V_CCIR (r1, g1, b1, 2);
cb++;
cr++;
p += -wrap3 + 2 * BPP;
lum += -wrap + 2;
}
if (w)
{
RGB_IN (r, g, b, p);
r1 = r;
g1 = g;
b1 = b;
lum[0] = RGB_TO_Y_CCIR (r, g, b);
p += wrap3;
lum += wrap;
RGB_IN (r, g, b, p);
r1 += r;
g1 += g;
b1 += b;
lum[0] = RGB_TO_Y_CCIR (r, g, b);
cb[0] = RGB_TO_U_CCIR (r1, g1, b1, 1);
cr[0] = RGB_TO_V_CCIR (r1, g1, b1, 1);
cb++;
cr++;
p += -wrap3 + BPP;
lum += -wrap + 1;
}
p += wrap3 + (wrap3 - width * BPP);
lum += wrap + (wrap - width);
//cb += dst->linesize[1] - width2;
//cr += dst->linesize[2] - width2;
cb += width/2 - width2;
cr += width/2 - width2;
}
/* handle odd height */
if (height)
{
for (w = width; w >= 2; w -= 2)
{
RGB_IN (r, g, b, p);
r1 = r;
g1 = g;
b1 = b;
lum[0] = RGB_TO_Y_CCIR (r, g, b);
RGB_IN (r, g, b, p + BPP);
r1 += r;
g1 += g;
b1 += b;
lum[1] = RGB_TO_Y_CCIR (r, g, b);
cb[0] = RGB_TO_U_CCIR (r1, g1, b1, 1);
cr[0] = RGB_TO_V_CCIR (r1, g1, b1, 1);
cb++;
cr++;
p += 2 * BPP;
lum += 2;
}
if (w)
{
RGB_IN (r, g, b, p);
lum[0] = RGB_TO_Y_CCIR (r, g, b);
cb[0] = RGB_TO_U_CCIR (r, g, b, 0);
cr[0] = RGB_TO_V_CCIR (r, g, b, 0);
}
}
}