RGBA转化成YV12 或YUV420格式的源代码

本代码是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);
        }
    }
}

你可能感兴趣的:(RGBA转化成YV12 或YUV420格式的源代码)