提示:ARGB alpha通道的A + 原YUV表面的y0 + 要写进去的y1 = 计算出新的y2.
计算公式为
( y1 * a + y0 * ( 255 - a ) ) / 255
void rgb2yuv(int r, int g, int b, int *y, int *u, int *v)
{
int y0, u0, v0;
y0 = 66*r + 129*g + 25*b;
u0 = -38*r + -74*g + 112*b;
v0 = 112*r + -94*g + -18*b;
y0 = (y0+128)>>8;
u0 = (u0+128)>>8;
v0 = (v0+128)>>8;
*y = y0 + 16;
*u = u0 + 128;
*v = v0 + 128;
}
void yuv2rgb(int y, int u, int v, int *r, int *g, int *b)
{
int r0,g0,b0;
v = v - 128;
u = u - 128;
r0 = y + v + (v>>2) + (v>>3) + (v>>5);
g0 = y - ((u>>2) + (u>>4) + (u>>5)) - ((v>>1) + (v>>3) + (v>>4) + (v>>5));
b0 = y + u + (u>>1) + (u>>2) + (u>>6);
*r = r0 > 255 ? 255: r0;
*g = g0 > 255 ? 255: g0;
*b = b0 > 255 ? 255: b0;
}
int blitSurface2YUV(SDL_Surface *src, SDL_Overlay *dst, SDL_Rect *dstrect ,int isBlended)
{
Uint8 r, g, b,a;
int y0,u0,v0;
int y1,u1,v1;
int y2,u2,v2;
int y,x;
int height = src->h < dstrect->h ? src->h: dstrect->h;
int width = src->w < dstrect->w ? src->w: dstrect->w;
int uv_off = 0;
Uint32 pixel;
printf ("src->format->BitsPerPixel %d src->format %08X\r\n",src->format->BitsPerPixel,src->format);
if(dst->format != SDL_YV12_OVERLAY)return 1;
for(y = 0; y < height; ++y)
{
for(x = 0; x < width; ++x)
{
switch(src->format->BitsPerPixel)
{
case 8:
pixel = *((Uint8*)src->pixels + y*src->pitch + x);
break;
case 16:
pixel = *((Uint16*)src->pixels + y*src->pitch/2 + x);
break;
case 32:
pixel = *((Uint32*)src->pixels + y*src->pitch/4 + x);
break;
default:
return -1;
}
//SDL_GetRGB(pixel, src->format, &r, &g, &b);
SDL_GetRGBA(pixel, src->format, &r, &g, &b,&a);
rgb2yuv(r, g, b, &y1, &u1, &v1);
if(isBlended)
{
y0 = (dst->pixels[0][ (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x)]);
v0 = (dst->pixels[1][ (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2)]);
u0 = (dst->pixels[2][ (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2)]);
y2 = (Uint8)(( y1 * a + y0 * ( 255 - a ) ) / 255);
u2 = (Uint8)(( u1 * a + u0 * ( 255 - a ) ) / 255);
v2 = (Uint8)(( v1 * a + v0 * ( 255 - a ) ) / 255);
y1=y2;
u1=u2;
v1=v2;
}
memset(dst->pixels[0] + (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x),
(Uint8)y1 , 1);
if((x%2 == 0 ) && (y%2 == 0 ))
{
memset(dst->pixels[1] + (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2),
(Uint8)v1, 1);
memset(dst->pixels[2] + (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2),
(Uint8)u1, 1);
}
}
if(y%2 == 0)++uv_off;
}
return 0;
}