[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