Two SDL apps running at the same time

I have an SDL video display program, that uses YUV overlays, running on

Linux 2.4.1 (hehe)
Xfree86 4.0.2 with hardware accel support
SDL 1.1.7

and it works fine and dandy. There comes a problem, though, when you run
one copy of the program, then open up another copy. It seems that the
frames being displayed from either application are blitted to BOTH video
windows, and so there is a lot of flickering going on in both windows.
I’m not using any special arguments to the video mode setup. Is this a
known issue, or not? What’s going on, that SDL would somehow share video
buffers across processes?

~jeffrey :j

I have an SDL video display program, that uses YUV overlays, running on

Linux 2.4.1 (hehe)
Xfree86 4.0.2 with hardware accel support
SDL 1.1.7

and it works fine and dandy. There comes a problem, though, when you run
one copy of the program, then open up another copy. It seems that the
frames being displayed from either application are blitted to BOTH video
windows, and so there is a lot of flickering going on in both windows.
I’m not using any special arguments to the video mode setup. Is this a
known issue, or not? What’s going on, that SDL would somehow share video
buffers across processes?

This is just an issue with the X server not handling two simultaneous
video streams very well. Not much that can be done on the client side.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Sam Lantinga wrote:

This is just an issue with the X server not handling two simultaneous
video streams very well. Not much that can be done on the client side.

Nope, it seems to be definitely an SDL issue. I get the same flickering if I
play the two videos with SMPEG and gtv, while there is NO flickering if I use
Adam William’s XMovie, which uses the X11 libraries directly (and does use
hardware YUV overlay).

~jeffrey :j

Jeffrey Bridge wrote:

Nope, it seems to be definitely an SDL issue. I get the same flickering if I
play the two videos with SMPEG and gtv, while there is NO flickering if I use
Adam William’s XMovie, which uses the X11 libraries directly (and does use
hardware YUV overlay).

Interestingly, I added a few printf()s to XMovie, and it appears that the first
instance uses XvImage as normal, but then the second instance does not.
So perhaps the SDL X11 XvImage driver needs to check its error codes
more carefully?

~jeffrey :j

Jeffrey Bridge wrote:

Interestingly, I added a few printf()s to XMovie, and it appears that the first
instance uses XvImage as normal, but then the second instance does not.
So perhaps the SDL X11 XvImage driver needs to check its error codes
more carefully?

And I’m replying to myself… again…

— begin relevant XMovie code —
formats = XvListImageFormats(window->display,
info[i].base_id,
&numFormats);
// for(j = 0; j < numFormats; j++)
// printf("%08x\n", formats[j].id);

  for(j = 0; j < numFormats; j++)
  {

/* this adaptor supports the desired format /
if(formats[j].id == x_color_model)
{
/
Try to grab a port /
for(k = 0; k < info[i].num_ports; k++)
{
/
Got a port */
if(Success == XvGrabPort(top_level->display,
info[i].base_id + k,
CurrentTime))
{
port_id = info[i].base_id + k;
break;
}
}
}
}
if(formats) XFree(formats);
}

— end relevant XMovie code —

— begin relevant SDL code —
XvImageFormatValues *formats;
formats = XvListImageFormats(GFX_Display,
ainfo[i].base_id, &num_formats);
for ( j=0; j<num_formats; ++j ) {
if ( (Uint32)formats[j].id == format ) {
xv_port = ainfo[i].base_id;
break;
}
}
}
}
}
if ( xv_port == -1 ) {
SDL_SetError(“No available video ports for requested format”);
return(NULL);
}
— end relevant SDL code —

It seems that SDL never actually tries to grab a given port, before saying that it
can use it. I am not familiar with X11 programming, but the information here
should make it easy for someone to create a patch.

~jeffrey :j

It seems that SDL never actually tries to grab a given port, before saying that it
can use it. I am not familiar with X11 programming, but the information here
should make it easy for someone to create a patch.

Great detective work!
The latest CVS snapshot has this fixed.

Thanks!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

I writed a simple program to display two yuv files at the same time. but to
my surprise, it turned out only a window, two files show in the window, it
messes up. so i search in the mailing list find a similar question, its
answer is below:

SDL uses XVideo for YUV overlays on the screen, but most cards can’t handle
more than one application which uses XVideo. You can ether set enironment
variable SDL_VIDEO_YUV_HWACCEL to 1 or use non-screen surfaces as
destination for overlays. Notice than anyway you will get some slowdown

but i can not understand what need i do exactly, below goes my code, can you
do some changes in my code or tell me how to change in details to let it
show up two windows playing different yuv files at the same time.

where to set the value of SDL_VIDEO_YUV_HWACCEL or how to use non-screen
surfaces as destination for overlays?

your help will be greatly appreciated.

/*

  • this src is used for testing the v4l and the sdl .
  • Beside this,it provides a simple wrap of v4l and sdl .
  • You can use it any where,but should keep this header.
  • Any suggestion is appreicated.*
  • Tianjin University , China.
  • @dfdf1141_dfdf1141
    */
    #include <stdlib.h>
    #include <math.h>
    #include <malloc.h>
    #include < string.h>
    #include <SDL/SDL.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <stdint.h>

#include <unistd.h>
#include <signal.h>

#define WIDTH 352
#define HEIGHT 288

class CSDLDisplay
{
public:
int init(int width,int height);
void closeIt();

void display(u_int8_t *ybuf,u_int8_t *ubuf,u_int8_t *vbuf);
private:
const SDL_VideoInfo *m_video_info;
SDL_Surface *m_screen;
SDL_Rect m_dst_rect;
SDL_Overlay *m_image;
int m_width;
int m_height;
};

int CSDLDisplay::init(int width, int height)
{
if(SDL_Init(SDL_INIT_VIDEO)<0)
{
//ERROR
return -1;
}

//SDL_VIDEO_YUV_HWACCEL = 1;
m_video_info = SDL_GetVideoInfo();
m_screen = SDL_SetVideoMode(width,height,32,SDL_HWSURFACE|SDL_ASYNCBLIT);
m_width = width;
m_height = height;
m_dst_rect.x = 0;
m_dst_rect.y = 0;
m_dst_rect.w = m_screen->w;
m_dst_rect.h = m_screen->h;
m_image = SDL_CreateYUVOverlay(width,height,SDL_YV12_OVERLAY,m_screen);

return 1;
}

void CSDLDisplay::closeIt()
{
SDL_FreeYUVOverlay(m_image);
SDL_FreeSurface(m_screen);
SDL_Quit();
}

void CSDLDisplay::display(unsigned char * ybuf, unsigned char * ubuf,
unsigned char * vbuf)
{
int ysize = m_width*m_height;
int uvsize = ysize/4;

SDL_LockYUVOverlay(m_image);
memcpy(m_image->pixels[0],ybuf,ysize);
memcpy(m_image->pixels[1],vbuf,uvsize);
memcpy(m_image->pixels[2],ubuf,uvsize);
SDL_DisplayYUVOverlay(m_image,&m_dst_rect);
SDL_UnlockYUVOverlay(m_image);
}

FILE * openYUVFile(const char *yuvFileName)
{
FILE *pFile;
if(((pFile) = fopen(yuvFileName,“r+”)) == NULL)
{
//ERROR
fprintf(stderr,“Error in open yuv file.\n”);
return NULL;
}

return pFile;
}

int getTotalYUVFrame(FILE *srcFile,int width,int height)
{
int frameTotal = 0;

if(fseek(srcFile,0,SEEK_END) == 0)
{
u_int64_t size = ftell(srcFile);
fseek(srcFile,0,SEEK_SET);
frameTotal = (int)(size/(widthheight3/2));
}
else
{
//ERROR
fprintf(stderr,“Error in get total yuv frame.\n”);
return -1;
}

return frameTotal;
}

int readYUVFrame(FILE srcFile,int width,int height,long frameNo,u_int8_t
yuvData)
{
if(fseek(srcFile,frameNo
width
height3/2,SEEK_SET)<0)
{
//ERROR
fprintf(stderr,“Error in read yuv frame.\n”);
return -1;
}
else
{
if(fread(yuvData,1,width
height3/2,srcFile) != widthheight*3/2)
{
//ERROR
fprintf(stderr,“Error in fread yuv frame.\n”);
return -1;
}
}

return 0;
}

void closeYUVFile(FILE *srcFile)
{
if(srcFile != NULL)
{
fclose(srcFile);
}
}

int main()
{
int width = 352;
int height = 288;
int i;
int ysize = widthheight;
int uvsize = ysize/4;
//pY1 = (u_int8_t
)malloc(ysize);
//pU1 = (u_int8_t*)malloc(uvsize);
//pV1 = (u_int8_t*)malloc(uvsize);
//pY2 = (u_int8_t*)malloc(ysize);
//pU2 = (u_int8_t*)malloc(uvsize);
//pV2 = (u_int8_t*)malloc(uvsize);
u_int8_t *yuvData;
u_int8_t *yPtr,*uPtr,*vPtr;

yuvData = (u_int8_t )malloc(ysize3/2);

if(yuvData == NULL)
{
//ERROR
fprintf(stderr,“can not malloc for yuv data.\n”);
//return;
}

yPtr = yuvData;
uPtr = yuvData + ysize;
vPtr = uPtr + uvsize;

u_int8_t *yuvData1;
u_int8_t *yPtr1,*uPtr1,*vPtr1;

yuvData1 = (u_int8_t )malloc(ysize3/2);

if(yuvData1 == NULL)
{
//ERROR
fprintf(stderr,“can not malloc for yuv data.\n”);
//return;
}

yPtr1 = yuvData1;
uPtr1 = yuvData1 + ysize;
vPtr1 = uPtr1 + uvsize;

CSDLDisplay displayer1;
CSDLDisplay displayer2;

displayer1.init(WIDTH, HEIGHT);
displayer2.init(WIDTH, HEIGHT);
char strName2[300];
sprintf(strName2,"/root/mobile_cif.yuv");
char strName[300];
sprintf(strName,"/root/akyio_cif.yuv");
FILE *srcFile =openYUVFile(strName);
FILE *srcFile1 =openYUVFile(strName2);
for (i=0; i<= 200; i++)
{
readYUVFrame(srcFile, width, height, i,yuvData);
readYUVFrame(srcFile1, width, height, i,yuvData1);
displayer1.display(yPtr1, uPtr1, vPtr1);
displayer2.display(yPtr, uPtr, vPtr);
usleep(1000/30);
}
displayer1.closeIt();
displayer2.closeIt();
closeYUVFile(srcFile);
closeYUVFile(srcFile1);
}

thanks in advance!
waiting for your reply!
urgent!!