Using YUV overlay and RGB(A) Surfaces

I’m working on the SDL output plugin for the videolan project
(www.videolan.org)

I want to display the YUV overlay AND some RGB(A) surfaces on the
screen.

the overlay contains the decoded yuv images from the mpeg file. I want
to add on-screen messages to this images.
(Title, icons, text …). messages are bitmap data loaded in
SDL_Surfaces.
I want to display the overlay as a background and add the messages in
the foreground.

I’ve tried this :

SDL_LockYUVOverlay(p_vout->p_sys->p_overlay);

/* copy the data into video buffers /
/
Y first /
memcpy(p_vout->p_sys->p_overlay->pixels[0], //to
p_vout->p_rendered_pic->p_y, //from
p_vout->p_sys->p_overlay->h * //size = height * length of
a row in bytes
p_vout->p_sys->p_overlay->pitches[0]);
/
then V /
memcpy(…);
/
and U */

disp.w = …
disp.h = …
disp.x = …
disp.y = …

/* add a BMP message */
image = SDL_LoadBMP(“videolan.bmp”); //my test - TODO: load image only
once

dest.x = …
dest.y

/* Display overlay */
SDL_DisplayYUVOverlay( p_vout->p_sys->p_overlay , &disp );

SDL_UnlockSurface ( p_vout->p_sys->p_display );

SDL_BlitSurface(image, NULL, p_vout->p_sys->p_display, &dest);

/* Flip screen to display message*/
//SDL_Flip(p_vout->p_sys->p_display); <----- THISLINE

SDL_LockSurface ( p_vout->p_sys->p_display );

SDL_UnlockYUVOverlay(p_vout->p_sys->p_overlay);

//–
If I try this I only the movie (overlay)

when I uncomment THISLINE: I only see my message on a black
background…
(detail: what exactly happend is: I can see the first image of my movie
(I can’t say if it’s only 1 frame or 2) then my message (bmp) on a black
background)

How can I do to see both ?

my overlay is accelerated (hw_overlay).

Another question:
Is it possible to “combine” overlay with RGB surfaces to obtain
transparency (see the movie through the surface) At last will colorkey
work ?

Thanks–
Xavier Servettaz
Ps: I’m new to overlay so perhaps I missunderstood something :slight_smile:

I want to display the YUV overlay AND some RGB(A) surfaces on the
screen.

How can I do to see both ?

my overlay is accelerated (hw_overlay).

You can’t. It’s a physical property of the display. You have to
convert your surface to YUV and “blit” into the YUV surface area.
Unfortunately I don’t have code to do this, but if somebody writes it
I’ll definitely add it to the SDL demos page.

Another question:
Is it possible to “combine” overlay with RGB surfaces to obtain
transparency (see the movie through the surface) At last will colorkey
work ?

SDL YUV overlays currently don’t support the colorkey. This will be fixed
in the SDL 1.3 redesign.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

Sam Lantinga wrote:

You can’t. It’s a physical property of the display. You have to
convert your surface to YUV and “blit” into the YUV surface area.
Unfortunately I don’t have code to do this, but if somebody writes it
I’ll definitely add it to the SDL demos page.

Ok, I’m working on it. (only for YUV 4.2.0 (YV12 overlay format))
But I have some difficulties with U and V comversions.

I tried a lot of equations found on the Internet, but with no success.

I even “build” my own equations, but the result is not very clean…
Pure blue, red, green and yellow seems to be good but not gray
(U = (Uint8)b
V = (Uint8)(0.5r - 0.5g + 128))

Does anyone of you know whitch one I should use ?
Are U and V signed or unsigned (Uint8 or Sint8);[-127;128] or [0,255] ?

What I’ve noticed is that the walue 127 for both U and V seems to be
"neutral" (good for gray, white…)

SDL YUV overlays currently don’t support the colorkey. This will be fixed
in the SDL 1.3 redesign.

Cool

Another question, have you any idea about calculating transparency in
YUV format ? I meen something like alpha transparency but in YUV
format.(YUVA)

thanks–
Xavier

I tried a lot of equations found on the Internet, but with no success.

I even “build” my own equations, but the result is not very clean…
Pure blue, red, green and yellow seems to be good but not gray
(U = (Uint8)b
V = (Uint8)(0.5r - 0.5g + 128))

Does anyone of you know whitch one I should use ?
Are U and V signed or unsigned (Uint8 or Sint8);[-127;128] or [0,255] ?

What I’ve noticed is that the walue 127 for both U and V seems to be
"neutral" (good for gray, white…)

AFAIK 128 for U & V should be pure grey. I’ve seen following equations:

conversion from YUV to RGB
r = 1.164*(y-16) + 1.596*(v-128);
g = 1.164*(y-16) - 0.813*(v-128) - 0.391*(u-128);
b = 1.164*(y-16) + 2.018*(u-128);

conversion from RGB to YUV
y = 0.257r + 0.504g + 0.098b + 16
u = -0.148
r - 0.291g + 0.439b + 128
v = 0.439r - 0.368g - 0.071*b + 128

I’m not sure if they’re correct, but results should be quite good… You
might want to precalculate those multiplications though. Also if you don’t
intend to use output for tv-out it might be better not to add 16 to
y-component IMO. Some adjusting to factors might need to be done if this
tweak is used.

  • Mikko

Hi,

Try this routine (yep…I know its slow and uses doubles) its for video
compression and for that I need reasonable accuracy. You could use ints or even convert it to use bit shifts to speed it up. Its actually Y:Cr:Cb but
dont tell anyone...theyll only start an arugment about it :).

void rgb2yuv(Uint8 r, Uint8 g, Uint8 b, Uint8* y, Uint8* u, Uint8* v)
{
//convert RGB colourspace to YUV
double red, green, blue, yy, cr, cb, ry, ru, rv;
red = (double)r / 255.0;
green = (double)g / 255.0;
blue = (double)b / 255.0;
yy = 0.299 * red + 0.587 * green + 0.114 * blue;
cb = blue - yy;
cr = red - yy;
ry = 16.0 + 219.0 * yy;
ru = 128.0 + 126.0 * cb;
rv = 128.0 + 160.0 * cr;
*y = (Uint8) ry;
*u = (Uint8) ru;
*v = (Uint8) rv;
}

Hope that helps

Dave

P.s. This is my first post as Ive been lurking for some time......Im using
SDL in a project for work and Ill post some more info when im allowed to
:). Good work sam!On Tuesday 11 September 2001 7:21 pm, you wrote:

Does anyone of you know whitch one I should use ?
Are U and V signed or unsigned (Uint8 or Sint8);[-127;128] or [0,255] ?

What I’ve noticed is that the walue 127 for both U and V seems to be
"neutral" (good for gray, white…)

Thank you guys,

I found the good equations:

y = (Uint8)(0.299r+0.587g+0.098b);
u = (Sint8)(0.558
(b - y) +127);
v = (Sint8)(0.709*(r - y) +127);

from http://www.video-demystified.com/mm/tutor/ch03.pdf

(I added 127 to U and V)

I have another question:

I load a RGB BMP whitch is 233x52 into a 16BPP surface

and surface->pitch is 468 (2234) and not 2233 = 466
then I create an overlay:

overlay = SDL_CreateYUVOverlay(image->w,
image->h,
SDL_YV12_OVERLAY, //YUV 4.2.0
screen);

but
overlay->pitches[0] = 236 //Y why not 233 ?
overlay->pitches[1] = 120 //V
overlay->pitches[2] = 120 //U

So when I convert my surface I’ve got a problem because line sizes are
not equals and my picture “slides” from line to line…

Why are sizes differents ?
How can I correct this?–
Xav