Problem combining sw_scale with blit operations on surface

Hello all first post here,

I’m tinkering with SDL in Linux and I’m trying to draw some text onto a JPEG
image that I decompressed to a YUV overlay using a conversion context and
sw_scale. AIUI SDL_DisplayYUVOverlay should copy the contents of the
overlay to the underlying surface, but it doesn’t seem to do that when I’m
at the main X console. When I do an SDL_UpdateRect on the surface, the
image from the overlay vanishes and is replaced with blackness.

The odd thing is that when I run my code using VNCViewer from a Windows PC,
everything looks beautiful. What am I doing wrong? Here is my code:

int dst_pix_fmt = PIX_FMT_YUV420P;
if(img_convert_ctx == NULL) {
int w = pCodecCtx->width;
int h = pCodecCtx->height;
img_convert_ctx = sws_getContext(w, h,
pCodecCtx->pix_fmt,
w, h, dst_pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
if(img_convert_ctx == NULL) {
fprintf(stderr, “Cannot initialize the conversion context!\n”);
exit(1);
}
}

sws_scale(img_convert_ctx, pFrame->data,
pFrame->linesize, 0,
pCodecCtx->height,
pict.data, pict.linesize);

SDL_UnlockYUVOverlay(bmp);

rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;

SDL_DisplayYUVOverlay(bmp, &rect);

// create timestamp overlay
gettimeofday(&tv, NULL);
tp = localtime(&tv.tv_sec);
sprintf(tbuf, “%02d:%02d:%02d”, tp->tm_hour, tp->tm_min, tp->tm_sec);
mysurf = drawtext(myfont, 255, 255, 0, 0, 0, 0, 0, 0, tbuf, shaded);

// Copy the current screen.
// SDL_Surface * backup = SDL_DisplayFormat(screen);
SDL_SetColorKey(mysurf, SDL_SRCCOLORKEY, 0);
// SDL_SetAlpha(mysurf, SDL_SRCCOLORKEY, 0);
// SDL_Surface * temp = SDL_DisplayFormat(mysurf);
SDL_Surface * temp = mysurf;
drawimage(temp, 0, 0, temp->w, temp->h, screen, 0, 400, trans);
SDL_FreeSurface(mysurf);
SDL_UpdateRect(screen, 0, 0, 0, 0);

drawimage does an SDL_BlitSurface after calling SDL_SetAlpha on the source
surface. I’ve tried everything I can think of, and I pretty much give up.
What am I missing? Maybe it’s my something with my X server or the nVidia
drivers? Like I said, it works great thru VNC the alpha blending and color
keying work perfectly. But in a “real” X server, the image vanishes when I
do the SDL_UpdateRect. All I end up with is a black screen with with an
alpha blended timestamp. Thanks for any insight.

Bump, any ideas? Of course I meant sws_scale, sorry for the misspelling.
Am I doing it completely wrong? Is there a way to blit the data to/from the
overlay? Should SDL_DisplayYUVOverlay copy the contents of the overlay to
the underlying surface that is linked to it? Can someone point me to a list
of environment variables that SDL uses? In particular, I’m looking for ones
that disable hardware acceleration.

michael brown wrote:> Hello all first post here,

I’m tinkering with SDL in Linux and I’m trying to draw some text onto
a JPEG image that I decompressed to a YUV overlay using a conversion
context and sw_scale. AIUI SDL_DisplayYUVOverlay should copy the
contents of the overlay to the underlying surface, but it doesn’t
seem to do that when I’m at the main X console. When I do an
SDL_UpdateRect on the surface, the image from the overlay vanishes
and is replaced with blackness.
The odd thing is that when I run my code using VNCViewer from a
Windows PC, everything looks beautiful. What am I doing wrong? Here
is my code:
int dst_pix_fmt = PIX_FMT_YUV420P;
if(img_convert_ctx == NULL) {
int w = pCodecCtx->width;
int h = pCodecCtx->height;
img_convert_ctx = sws_getContext(w, h,
pCodecCtx->pix_fmt,
w, h, dst_pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
if(img_convert_ctx == NULL) {
fprintf(stderr, “Cannot initialize the conversion context!\n”);
exit(1);
}
}

sws_scale(img_convert_ctx, pFrame->data,
pFrame->linesize, 0,
pCodecCtx->height,
pict.data, pict.linesize);

SDL_UnlockYUVOverlay(bmp);

rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;

SDL_DisplayYUVOverlay(bmp, &rect);

// create timestamp overlay
gettimeofday(&tv, NULL);
tp = localtime(&tv.tv_sec);
sprintf(tbuf, “%02d:%02d:%02d”, tp->tm_hour, tp->tm_min, tp->tm_sec);
mysurf = drawtext(myfont, 255, 255, 0, 0, 0, 0, 0, 0, tbuf, shaded);

// Copy the current screen.
// SDL_Surface * backup = SDL_DisplayFormat(screen);
SDL_SetColorKey(mysurf, SDL_SRCCOLORKEY, 0);
// SDL_SetAlpha(mysurf, SDL_SRCCOLORKEY, 0);
// SDL_Surface * temp = SDL_DisplayFormat(mysurf);
SDL_Surface * temp = mysurf;
drawimage(temp, 0, 0, temp->w, temp->h, screen, 0, 400, trans);
SDL_FreeSurface(mysurf);
SDL_UpdateRect(screen, 0, 0, 0, 0);

drawimage does an SDL_BlitSurface after calling SDL_SetAlpha on the
source surface. I’ve tried everything I can think of, and I pretty
much give up. What am I missing? Maybe it’s my something with my X
server or the nVidia drivers? Like I said, it works great thru VNC
the alpha blending and color keying work perfectly. But in a "real"
X server, the image vanishes when I do the SDL_UpdateRect. All I end
up with is a black screen with with an alpha blended timestamp. Thanks for
any insight.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Bump, any ideas? Of course I meant sws_scale, sorry for the misspelling. Am I
doing it completely wrong? Is there a way to blit the data to/from the
overlay? Should SDL_DisplayYUVOverlay copy the contents of the overlay to the
underlying surface that is linked to it? Can someone point me to a list of
environment variables that SDL uses? In particular, I’m looking for ones that
disable hardware acceleration.

You’re not supposed to draw on top of the YUV overlay using normal 2D
blitting operations. If you want graphics on top of the YUV video, you
need to manually draw it into the YUV data before updating the overlay.

// MartinOn Tue, 7 Apr 2009, michael brown wrote:

Martin Storsj? wrote:> On Tue, 7 Apr 2009, michael brown wrote:

Bump, any ideas? Of course I meant sws_scale, sorry for the
misspelling. Am I doing it completely wrong? Is there a way to blit
the data to/from the overlay? Should SDL_DisplayYUVOverlay copy the
contents of the overlay to the underlying surface that is linked to
it? Can someone point me to a list of environment variables that
SDL uses? In particular, I’m looking for ones that disable hardware
acceleration.

You’re not supposed to draw on top of the YUV overlay using normal 2D
blitting operations. If you want graphics on top of the YUV video, you
need to manually draw it into the YUV data before updating the
overlay.

OK, I figured I was doing it wrong. What function(s) could I use to blit
onto the decoded YUV “frame” data with alpha blending support, before
calling sws_scale? Sorry if these are stupdid questions, I’m still trying
to wrap my head around all this stuff. Thanks.

OK, I figured I was doing it wrong. What function(s) could I use to blit
onto the decoded YUV “frame” data with alpha blending support, before calling
sws_scale? Sorry if these are stupdid questions, I’m still trying to wrap my
head around all this stuff. Thanks.

Last time I checked, SDL doesn’t contain any routines for doing this. So
you’d have to do all the conversion yourself, first converting your SDL
surface into the YUV colorspace, and then manually blit it into the YUV
overlay. There are perhaps some external libraries that would help you in
doing this, though; don’t know any off-hand.

// MartinOn Wed, 8 Apr 2009, michael brown wrote: