LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 10-04-2004, 11:47 PM   #1
mmarshall
Member
 
Registered: Apr 2004
Location: Bedford, Texas (DFW area)
Distribution: ArchLinux
Posts: 41

Rep: Reputation: 15
using xine inside of an SDL app?


Hello,

I am wanting to create a SDL app that, among other things, plays movies using xine-lib.

I looked over the xine hacker's guide, and I think I understand most of the stuff in the 'frontend' example. (I haven't ever seen any of those X11 functions before, but I think I get the idea as to what they do.) However, I have not the slightest clue as to how to get the 'Display *display;' thingy onto an SDL surface.

Can anyone give me a pointer on this? I have a feeling that this is one of those 'easy when you know it' deals.

Thanks!!

MWM
 
Old 10-05-2004, 09:32 AM   #2
Marius2
Member
 
Registered: Jan 2004
Location: Munich
Distribution: SuSE 9.2, 10.2, 10.3, knoppix
Posts: 274

Rep: Reputation: 30
I've been playing around with this too, in a cursory way (so I may be wrong with
my guesses). But I think you can not do this with the API SDL provides. If you really
want to stick to SDL, you probably will have to modify its source code, and you will
probably end up with code inside SDL which looks like the one in your frontend
(because it's put on top of Xlib), or sxfe sample from the xine site.
I eventually threw SDL overboard in my graphics abstraction layer (working under
both windows and linux) and am now using Xlib instead.

BTW may I ask what your purpose is in playing around with Linux graphics and
video?
 
Old 10-05-2004, 07:27 PM   #3
mmarshall
Member
 
Registered: Apr 2004
Location: Bedford, Texas (DFW area)
Distribution: ArchLinux
Posts: 41

Original Poster
Rep: Reputation: 15
Hi Marius2!

One of the things I am working on, (well, toying with...) is some sort of home control/automation/survalance/what-ever-else-i-want system, specifically designed for my family. I want most of the control to be done through a simple program, simple enough that a child (there are more than a few around here...) could control.

Some of the features I would like to implement involve playing videos... and I would like to use SDL for the gui...

I have been planning on having this app run in it's own X server, so perhaps it would work to simply have the video play in it's own window on top of the SDL app? Without any window decorations, I think it would look like it was part of the same window as the parent.

Something else I was just thinking of... One of the video drives that Xine can use uses SDL. I wonder if I could hack the Xine API a little... I will have to look over the code.

BTW, one of the main reasons that I want to use Xine instead of smpeg, is I would like to make use of the hardware MPEG2 decoding found in some of VIA's motherboards. (I don't actually have one of those boards, but I really want to get one

MWM
 
Old 08-14-2008, 10:32 PM   #4
NDR008
Member
 
Registered: Nov 2006
Location: (Bristol or Coventry) (UK) or Malta
Distribution: openSUSE 11.0
Posts: 170

Rep: Reputation: 30
Have you guy gotten anywhere?
I am making a C++ application with SDL for an digital/analogue/PWM input/output USB board to be used on a car mounted computer. It will interface with the ECU and monitor a few more things. I was originally writing the front end, but found myself using several libraries for just a few features and losing cross platform aspect.

So I went with SDL with the plan to use SDL_mixer for mp3 playback.

However I realised if I could some how use xine-lib I would then not need to worry with mpeg-4 based movies and wma, because as long as the xine engines it should be fine. From what I gather, somehow it is very possible to make xine output to an SDL overlay surface. However as sure I sound - I am by no means an expert and would appreciate ANY help...
 
Old 08-15-2008, 09:49 AM   #5
mmarshall
Member
 
Registered: Apr 2004
Location: Bedford, Texas (DFW area)
Distribution: ArchLinux
Posts: 41

Original Poster
Rep: Reputation: 15
No, I don't think that I ever got anywhere, but that was 4 years ago

I think you would be best off using Qt4 or Gtk+Cairo instead SDL. It's much easier to get much better results with a vector graphics engine. And you might want to use GStreamer instead of xinelib. I have found it to be easier to embed.

If you really want to use SDL, I would still go with GStreamer. I imagine that its modular architecture would make writing a custom image-sink easier.

BTW, a quick google search brought this up:
http://blog.gustavobarbieri.com.br/2...-applications/

Hope that helps

MWM
 
Old 08-15-2008, 11:48 AM   #6
NDR008
Member
 
Registered: Nov 2006
Location: (Bristol or Coventry) (UK) or Malta
Distribution: openSUSE 11.0
Posts: 170

Rep: Reputation: 30
I came across that but was going to try delay using it for as long possible because I cannot get my gstream to play wma and mpeg4 based movies yet, while my xine based players can currently play absolutely anything. But thanks.
 
Old 08-15-2008, 12:18 PM   #7
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
There is a method of getting the Display and window in use from sdl SDL_SysWMInfo which you get from SDL_GetWMInfo. There is also a method, although it is documented with a warning "Using these variables isn't recommened and the names and presence of these variables aren't guaranteed from one release to the next.", this is using SDL_envvars and SDL_WINDOWID.

Hope that is of some use.
 
Old 08-15-2008, 01:14 PM   #8
NDR008
Member
 
Registered: Nov 2006
Location: (Bristol or Coventry) (UK) or Malta
Distribution: openSUSE 11.0
Posts: 170

Rep: Reputation: 30
I am completely lost on what you said. I have gone through that tutorial to use mplayer with SDL. I got the source to compile, but examining the code, it is not really using SDL, because it is still outputting to an X window as opposed to an SDL Overlay surface.

Both Xine and Mplayer say:

"Supported Video Output Devices
general:

* x11: X11 with SHM extension
* xv: X11 using overlays with the Xvideo extension (hardware YUV & scaling)
* sdl: SDL >= v1.1.7 driver"

Am I mis-understanding that?
 
Old 08-15-2008, 08:09 PM   #9
NDR008
Member
 
Registered: Nov 2006
Location: (Bristol or Coventry) (UK) or Malta
Distribution: openSUSE 11.0
Posts: 170

Rep: Reputation: 30
Need some help with this, I know at the minute it looks very dirty, but I am just trying to learn how to use many things at once. Once I get a good handle on it I will clean it up or start fresh. However since I am using many tutorials at once, things are going a bit skew.

Code:
Window create_x11_subwindow (Display *dpy, Window parent, int x, int y, int width, int height){
  Window win;
  int black;

  if (!dpy)
    return 0;

  black = BlackPixel (dpy, DefaultScreen (dpy));
  win = XCreateSimpleWindow (dpy, parent, x, y, width, height,
                             0, black, black);

  if (!win)
    return 0;

  if (!XSelectInput (dpy, win, StructureNotifyMask))
    return 0;

  if (!XMapWindow (dpy, win))
    return 0;

  while (1) {
    XEvent e;
    XNextEvent (dpy, &e);
    if (e.type == MapNotify && e.xmap.window == win)
      break;
  }

  XSelectInput (dpy, win, NoEventMask);

  return win;
}

SDL_SysWMinfo get_sdl_wm_info (void)
{
  SDL_SysWMinfo sdl_info;

  memset (&sdl_info, 0, sizeof (sdl_info));

  SDL_VERSION (&sdl_info.version);
  if (SDL_GetWMInfo (&sdl_info) <= 0 ||
      sdl_info.subsystem != SDL_SYSWM_X11) {
    fprintf (stderr, "This is not X11\n");

    memset (&sdl_info, 0, sizeof (sdl_info));
    return sdl_info;
  }

  return sdl_info;
}

Window create_sdl_x11_subwindow (int x, int y, int width, int height)
{
  SDL_SysWMinfo sdl_info;
  Window play_win;

  sdl_info = get_sdl_wm_info ();
  if (!sdl_info.version.major)
    return 0;

  sdl_info.info.x11.lock_func ();

  play_win = create_x11_subwindow (sdl_info.info.x11.display,
                                   sdl_info.info.x11.window,
                                   x, y, width, height);

  sdl_info.info.x11.unlock_func ();

  return play_win;
}

void check_keys(void) {
Uint8*  g_pKeys = SDL_GetKeyState(NULL);
  
  if((g_pKeys[SDLK_s]==1) && rpm < 9500 ) {rpm+=31; if (rpm > 9500) { rpm = 9500;} }
  if((g_pKeys[SDLK_x]==1) && rpm > 0 ) {rpm-=31; if (rpm < 0) { rpm = 0;} }
  if((g_pKeys[SDLK_a]==1) && speed < 260 ) {speed+=1; if (speed > 260) { speed = 260;} }
  if((g_pKeys[SDLK_z]==1) && speed > 0 ) {speed-=1; if (speed < 0) { speed = 0;} }
  if((g_pKeys[SDLK_d]==1) && af < 7 ) {af+=0.02; if (af > 7) { af = 7;} }
  if((g_pKeys[SDLK_c]==1) && af > 0 ) {af-=0.02; if (af < 0) { af = 0;} }
  if(g_pKeys[SDLK_e]==1) { digital_out[0] = !digital_out[0]; }
  if(g_pKeys[SDLK_r]==1) { digital_out[1] = !digital_out[1]; }
  if(g_pKeys[SDLK_t]==1) { digital_out[2] = !digital_out[2]; }
  if(g_pKeys[SDLK_y]==1) { digital_out[3] = !digital_out[3]; }
  if(g_pKeys[SDLK_u]==1) { digital_out[4] = !digital_out[4]; }
  if(g_pKeys[SDLK_i]==1) { digital_out[5] = !digital_out[5]; }
  if(g_pKeys[SDLK_o]==1) { digital_out[6] = !digital_out[6]; }
  if(g_pKeys[SDLK_p]==1) { digital_out[7] = !digital_out[7]; }
  if(g_pKeys[SDLK_KP2]==1) { mode = 2; }
  if(g_pKeys[SDLK_KP1]==1) { mode = 1; }
  if(g_pKeys[SDLK_w]==1) { fullscreen = toggle_fullscreen(fullscreen); }
  if(g_pKeys[SDLK_p]==1) {clean_up();}
}

void clean_up(void) {
/*
//Free the surfaces 
SDL_FreeSurface( g_pDisplaySurface ); 
SDL_FreeSurface( g_pText ); 
SDL_FreeSurface(LEDimage);
SDL_FreeSurface(temp);
//Close the font that was used 
TTF_CloseFont( font_rpm ); 
TTF_CloseFont( font_speed ); 
//Quit SDL_ttf 
TTF_Quit();
*/ 
//Quit SDL 
k8061_CloseDevices();
SDL_Quit();
exit(0);
} 

void create_mplayer (const char *filename, Window win, FILE **mplayer_fp)
{
  char cmdline[1024];

  snprintf (cmdline, 1024, "mplayer -ao sdl -slave -wid 0x%lx a.avi", win);

  *mplayer_fp = popen (cmdline, "w");
  run = 1;
}

void main_loop (FILE *mplayer_fp)
{
  SDL_Surface *screen;
  Uint32 color;
  unsigned c_shift, run;

  fprintf (stderr, "Type 'q' or Escape to exit\n");

  while (run) {
    SDL_Event event;

    while (SDL_PollEvent (&event)) {
      switch (event.type) {
      case SDL_QUIT:
        fprintf (mplayer_fp, "quit\n");
        run = 0;
        break;

      case SDL_KEYDOWN:
        switch (event.key.keysym.sym) {
        case SDLK_q:
        case SDLK_ESCAPE:
          fprintf (mplayer_fp, "quit\n");
          run = 0;
          break;
        default:
          break;
        }
        break;

      default:
        break;
      }
    }

    SDL_FillRect (g_pDisplaySurface, NULL, color);
    SDL_Flip (g_pDisplaySurface);
    color |= 0x1 << c_shift;
    c_shift ++;

    if (c_shift >= 32) {
      c_shift = 0;
      color = 0;
    }

    SDL_Delay (20);
  }
}

int main(int argc, char* argv[])
{
  int frame = 0;
  Timer fps;
  Timer update;
  Timer rpm_ticks;
  int fps_30;
  Window play_win;
  
  k8061_Init();
  cardaddress = k8061_OpenDevices();
  if (k8061_GetDeviceCount() != 0) { connected = true;}

  SDL_Init(SDL_INIT_VIDEO);
  if(TTF_Init()==0)
  {
    atexit(clean_up);
  }
  
  g_pDisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_ANYFORMAT);
  if(!g_pDisplaySurface) {cout << "Could not Set Video Mode" << endl; exit(1);}
  SDL_ShowCursor(false);

  g_Display.x = g_Display.x = 0;
  g_Display.w = SCREEN_WIDTH;
  g_Display.h = SCREEN_HEIGHT;
  
  font_rpm = TTF_OpenFont("LEDBDREV.TTF", 48);
  if (font_rpm == NULL) {cout << "Font not found1" << endl;}
  
  font_speed = TTF_OpenFont("LEDBDREV.TTF", 28);
  if (font_speed == NULL) {cout << "Font not found2" << endl;}
  
  font_af = TTF_OpenFont("LEDBDREV.TTF", 20);
  if (font_speed == NULL) {cout << "Font not found2" << endl;}
  
  temp = IMG_Load("LED.png");
  if(!temp) {cout << "File not found" << endl; exit(1);}
  LEDimage = SDL_DisplayFormat(temp);
  SDL_FreeSurface(temp);
  
  temp = IMG_Load("warnings_s.png");
  if(!temp) {cout << "File not found" << endl; exit(1);}
  warningsIMG = SDL_DisplayFormat(temp);
  SDL_FreeSurface(temp);
  
  temp = IMG_Load("background3.png");
  if(!temp) {cout << "File not found" << endl; exit(1);}
  background= SDL_DisplayFormat(temp);
  SDL_FreeSurface(temp);

  for (int i = 0; i < 3; i++){
  for (int j = 0; j < 2; j++){
  LED[i][j].x = j*24; LED[i][j].y = i*24; LED[i][j].w = LED[i][j].h=24;
  }
  }
  
  for (int i = 0; i < 5; i++){
  for (int j = 0; j < 2; j++){
  warnings[i][j].x = j*40; warnings[i][j].y = i*40; warnings[i][j].w = warnings[i][j].h = 40;
  }
  }
  
  SDL_SetColorKey(LEDimage,SDL_SRCCOLORKEY, SDL_MapRGB(g_pDisplaySurface->format, 0, 0, 0));
  SDL_SetColorKey(warningsIMG,SDL_SRCCOLORKEY, SDL_MapRGB(g_pDisplaySurface->format, 0, 0, 0));
    
  g_STxtRect.x = 0;
  g_STxtRect.y = 0;
  update.start();
  fps.start();
  rpm_ticks.start();
  
for(;;){
  for(;mode==1;)
  {  
    
    //SDL_FillRect( g_pDisplaySurface, &g_Display, SDL_MapRGB( g_pDisplaySurface->format, 0, 0, 0));
    check_keys();
    
    
    if(SDL_PollEvent(&g_Event)==0)
    {
      SDL_BlitSurface(background,NULL,g_pDisplaySurface,NULL);
      draw_rpm();
      draw_rpm_bar();
      draw_speed();
      draw_speed_bar();
      //draw_warnings();
      draw_af_bar();
      draw_af();
      ndrIODigital();
    }
    //SDL_UpdateRect(g_pDisplaySurface,0,0,0,0); //For Non Fullscreen
    SDL_Flip(g_pDisplaySurface);
    frame++;
     
    if( update.get_ticks() > 200 )
        {
            //The frame rate as a string
            std::stringstream caption;
            
            fps_30 = frame / ( fps.get_ticks() / 1000.f );
            //Calculate the frames per second and create the string
            caption << "Average Frames Per Second: " << fps_30;
            //cout << fps_30 << endl;
            
            //Reset the caption
            SDL_WM_SetCaption( caption.str().c_str(), NULL );
            
            //Restart the update timer
            update.start();
        }
     if (rpm > peak_rpm) { peak_rpm = rpm; rpm_ticks.start();}
     if( rpm_ticks.get_ticks() > 2000 ) {peak_rpm =0; }
  cout << "Console Loop" << endl;
  }
  
  for(;mode==2;){
      play_win = create_sdl_x11_subwindow (60, 60, SCREEN_WIDTH-120, SCREEN_HEIGHT-120);
      mplayer_fp = NULL;
      create_mplayer (argv[1], play_win, &mplayer_fp);
      main_loop (mplayer_fp);
      mode=1;
      pclose (mplayer_fp);
    }
  }
  return(0);
}
Issue 1:
when in mode==2;
The original parent window is no longer handling the key events. Which is fine, only that I have to click on the new Sub Window (that is playing the video). I intend to use this program in an environment where I won't have any keyboards or mice for such things. Anyway to make the new window active without clicking on it?
[workaround]
After switching from mplayer to xine (see Issue 3) this problem got cured when I set the main SDL window created at the start main to the full resolution of my desktop and with SDL_NOFRAME, and creating an X11 video of the same size and telling Xine to output to the same size too (as in issue 3).

Issue 2:
Once playing the video, I think mplayer is capturing the key events. (and not my application, I am guessing this because the arrow keys are working to go FF / RR through the video). I do not mind this, but when I press 'q', the video stops and starts again. When I press q again, the video stops (as it is meant to), and I go back to the loop of mode==1 (as desired).
Why do I have this issue of pressing 'q' twice?

Issue 3:
After exiting mode==2, I am left with the XSimpleWindow in the middle of my parent window. How can I get rid of this?
I tried XDestorySubwindows(dpy, play_win); but that just closes everything.
[Workaround] Using xine instead of mplayer by changing:
snprintf (cmdline, 1024, "mplayer -ao sdl -slave -wid 0x%lx a.avi", win);
to
snprintf (cmdline, 1024, "xine -I -G %ix%i --no-splash --wid 0x%lx a.avi",(SCREEN_WIDTH), (SCREEN_HEIGHT), win);
Xine closes the window behind it somehow.


If anyone wants the FULL source to try compile it I would be more than happy to send it, but I would have to do some editing because it is communicating to a USB interface board. I could also paste the full source if it helps. Thanks.



Only real annoying issue left is Issue 2 which is super annoying.

Last edited by NDR008; 08-15-2008 at 08:55 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Check if an app is running and if it's not launch this app Coume Linux - General 3 07-28-2008 02:34 AM
iptables inside client to inside host with outside DNS or IP - Help! linuxhelp2 Linux - Networking 1 10-15-2005 06:19 AM
Any way to redirect DISPLAY inside Java app? paulsm4 Programming 0 03-23-2005 07:35 PM
Trying to program an SDL application but cannot find the SDL.h file:SuSE 9.2&KDevelop pujolasdf Linux - Newbie 4 03-13-2005 07:50 AM
New app install, or, I've d/l'd the app, now what? Dani Linux - Newbie 4 01-06-2002 08:24 PM


All times are GMT -5. The time now is 06:00 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration