[Qt-interest] QSlider::setValue() causing delays in QTimer event delivery
Andrew Hodgkinson
ahodgkinson at endurancetech.co.uk
Thu Feb 18 12:32:32 CET 2010
On 16/02/2010 17:08, Josiah Bryan wrote:
> I've got an odd problem. See, I've got a video player (using ffmpeg as
> the backend) that sets a QTimer to trigger the next frame update.
I'm surprised nobody's responded so I'll have a go! I'm far from an
expert in this area, but my first response was surprise that you would
have application level code manually set its own timer to try and update
video frames. Surely the Phonon video widget should be doing this? I
wouldn't expect an application to have to do anything even close to that
low level just to play video. If forced to take the approach, I would be
most seriously concerned about the performance implications.
> I've also got a QSlider on the GUI that polls the video decoder for the
> clock position and updates a QSlider with the current video position via
> setValue. The polling of the video decoder is also done via a QTimer.
The word "polling" also gives cause for concern. Polling solutions are
inherently inefficient. The MediaObject in Phonon provides a "tick"
signal which looks like it's designed explicitly to allow you to update
your GUI if you want to use a custom progress display. This is emitted at
caller-configurable intervals.
Admittedly this interface is far from ideal, because there's a strong
chance the tick won't be synchronised with the updates of play position
(e.g. you ask for it once a second, but inaccuracies in interval of
generation mean your GUI's clock might pause for a second or, more
likely, appear to jump forward a couple of seconds every now and again).
In an ideal world you'd ask Phonon to send you a signal whenever the play
position had changed by a configurable temporal distance and that
position ought to be encoded in the signal payload. But even with its
limitations, the 'tick' signal seems like the way forward here.
> The problem is that the call to QSlider::setValue() causes the video
> timer to take longer than requested by an extreme amount - often by
> 100ms or longer
Although Qt is considered efficient perhaps in comparison to other very
large GUI frameworks like GTK, it's still quite a big beast. I've
personally found it very sensitive to the precise way you choose to "skin
the cat" when considering how to code a particular aspect of a GUI with
Qt. It's flexible enough and complex enough that there are usually
several answers but only one of them will work particularly well. Indeed
this seems true of most software systems with APIs of comparable depth.
In your case, it seems that the QSlider update code is really pretty
slow. Since this is delaying QTimer, I assume your application is single
threaded. Qt isn't getting around to processing events and emitting your
next timer signal until that update is complete. The standard (if IMHO
rather depressingly heavyweight / complex) answer would be to split your
application into a GUI thread and a timer thread, although quite how
you'd then get the video frame to update at the same time as your GUI
thread is busy updating the QSlider isn't clear - since *both* are in
fact part of the GUI. At least the QTimer API documentation has useful
information on mutlithreaded uses in the "detailed description" section
to get you started.
http://qt.nokia.com/doc/4.6/qtimer.html#details
Perhaps these kind of emerging multithreading / reentrancy issues are
further indications that really the video widget ought to take care of
updating itself, leaving your application to only have to worry about the
QSlider. If your Phonon backend doesn't allow this, now might be a good
time to consider adding support there, to solve the problems you're
having further up the software stack.
--
Andrew Hodgkinson, Endurance Technology
Land line: 01223 369 408, mobile: 07855 866 780
Registered Office: 5 Marine Drive West, Bognor Regis, W. Sussex, PO21 2QA
More information about the Qt-interest-old
mailing list