Re: [gtk-list] Re: gdk_input_add



On May 08, Sascha Ziemann wrote:
> Des Herriott <des@ops.netcom.net.uk> writes:
> 
> | > I want to play a video stream with 25 or 50 Hz.
> 
> | It sounds like you may want to use a timer rather than gdk_input_add() -
> 
> The gtk_timeout_add function seems to be intended for this, but I have
> the impression, that the video runs too slow when I use it. When I do:
> 
>   gtk_timeout_add (20, (GtkFunction) update_frame, preview);
> 
> Can I be sure that the calls to update_frame are executed with 50 Hz?

Probably not :-(

> Or does the time between two calls consists of the timeout time plus
> the time the program spends on other calculations in particular in
> update_frame itself. I think it is a bug, when the time between two
> calls to update_frame is timeout time + time to execute update_frame.

I think (somebody please correct me if I'm wrong) that Gtk's timeouts
are similar in nature to Xt's.  The timeouts get processed in the main
event loop when there are no events to process.  And they don't get
processed if you're in callback code.  It could be construed as a bug,
but it's a rather difficult problem to get around...

You may need to take an alternative approach:

I wrote (but don't maintain anymore) a Sinclair Spectrum (Timex 2068 to
those across the pond) emulator which did something similar.  It's
based on Xlib, no toolkits, but the same principles apply: send an
XImage to the X server and check for X events 50 times/sec.  The
program spends the remainder of its time emulating Z80 instructions -
your program would presumably be spending its time constructing each
frame.

The XZX homepage is http://www.philosys.de/~kunze/xzx/ if you wanted to
take a look at the source.

OK, it actually uses setitimer(), SIGALRM and the sigpause() routine,
but very carefully :-)  setitimer() raises a SIGALRM every 20ms.  You
have 20ms to construct your frame.  If you complete before then, you
can use sigpause() to sleep until the SIGALRM is raised.  This is good
because CPU usage is reduced.

You then write your frame to the X server, ideally with the XShm
extension, since that allows very fast image transfer.  If the machine
is too slow to build a frame in 20ms, you need to reduce the
framerate.

GDK appears to know about the XShm extension, via gdk_image.  This may
be the way to go.

Some pseudocode:

  setitimer(); /* raise a SIGALRM every 20ms */

  while (!finished) {
    build_a_frame();
    sigpause(SIGALRM);
    show_the_frame();
    process_events();
  }

process_events() would need to process Gtk events while there are some
on the queue.  You should make sure it doesn't block.

Does this seem reasonable?  Hopefully I've understood your requirements
right.

-- 
Des Herriott
des@ops.netcom.net.uk



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]