Videos get pimped

Posted by tbastian on November 28, 2008 · 20 comments

When I started working on our multimedia framework (aka Phonon) our goal was pretty simple and clear : we needed sound and video support in Qt. We had 3 systems to support and thus 3 completely different underlying API to implement our backends. It was tough and we worked hard on it. But then we got some cool demos and we saw that basic multimedia integration in a cross-platform way is actually possible. We struggled a lot but we got there. The mediaplayer demo is a nice little app that’s fully cross-platform and easy to understand.

Having a look at the bigger picture we realized that another great feature of Qt 4.4 is the ability to get widgets on the canvas (aka QGraphicsView). All our features need to work correctly together. That’s the basic principle of a framework. Displaying video is usually hardware-accelerated and all multimedia API/system use their own way to the graphics card. That means no composition with other widgets, no ability to paint over it and of course no perspective transformation.
My first thought at the time was that we would never be able to achieve the goal of full integration of our own features (ie. having videos on the canvas) and that felt bad.

We still tried and our target was Qt4.5. The biggest challenge was to write our own video renderer. Until Qt 4.4 we always used the native video renderers (you know, the ones without composition at all and no transform).
The 1st thing you have to do is manage the rendering of video frames and use the Qt paint engine. This way you get all the power of Qt.
So after a few weeks of development, tweaking and bug fixing I had something working.

So TADA! (If you were at dev days you’ve already seen that)

Now you can simply do something like that with your VideoWidget:

QGraphicsScene scene;
QGraphicsView view(&scene);
scene.addWidget(videoWidget);

I’m a bit lazy so I didn’t put the code that creates the Phonon objects. You can find out in the documentation and examples how to do that.
And now you can apply transformations to your video. Add things on top with alpha-blending… Possibilities unilimited.
And now you’re probably thinking that there’s a catch… and you’re right. If you look at your CPU usage it will be high. Because now everything is done in software including resizing/transforming/compositing/drawing. So we optimized, rewrote some components provided by the system (“OMG, how can the colorspace-conversion in MS DirectShow be so slow?!”).

Still, there is a way of greatly improve performance. Simply add that line to your code:


view.setViewport(new QGLWidget);

This magical line enables OpenGL through the whole canvas including your video. So scaling/transformation/composition is done by your graphics card. Plus on Windows I also use fragment shader to do the conversion from YUV to RGB (colorspace conversion) on the GPU of your graphics.

To make it even clearer I just made up an additional demo. I simply took the “embedded dialogs” demo from the graphicsview guys and slightly changed it. You can run this videowall demo. You have to pass at least one parameter which is either a video file or a directory (that contains video files) path.
So for example you do: videowall c:\videos
An additional parameter is the dimension of the wall. By default it is 1, meaning 1 video. If you pass for example 3, it will build a video wall with 3×3 videos. I ran it successfully with 9 videos (3×3 wall) with WMV HD content that I got from here. If you want to watch those videos you need to make sure you have the necessary codecs (Windows has them by default).

You can get the little demo here Videowall demo

And if you run it with something like videowall c:\videos 3, you can get the following result:
the video wall example

Now that you have speed and functionality, you can do whatever you want with your videos including using the new animation API!

QShare(this)

Possibly related posts:

  1. Qt experts talking to you almost 50 hours on videos! Irresistible!
  2. A few new things: new learning videos, a place for your video wish list, a new Qt Learning survey
  3. Qt 4.7 scope change regarding Qt Multimedia

20 comments

1 Dimitri Frederickx November 28, 2008 at 12:47 pm
 

Finally I can make use of the functionality on which I’m waiting for more than one year. This is really great news! But I was wondering if this will also be available on Mac? At this moment when I put a video widged on my canvas, I can see the movie on Windows, but not on Mac OS X. Does it mean that this problem is now also solved?

2 tbastian November 28, 2008 at 12:58 pm
 

Hi, Thanks for the reply. We’re still working on it working great on all platforms but it should already more or less work on MacOSX right now (Qt 4.5 of course).

3 Richard Moore November 28, 2008 at 2:16 pm
 

This looks very cool – I’ll have to give it a try over the weekend!

4 notmart November 28, 2008 at 2:58 pm
 

woo this is fantastic, i really wanted this thing so bad!
does it depends upon modifications of phonon in the version included in qt 4.5?
i.e can it be made working in the kde’s phonon? (or will it be merged back?)
because we want it sooo badly in plasma :)

5 Matthias Kretz November 28, 2008 at 3:15 pm
 

It doesn’t need any libphonon specific things. Anyway Qt 4.5 contains a copy of the same Phonon version as KDE 4.2 will ship. Where work is needed is in the backends. They need to support rendering via QWidget::render, i.e. paintEvent. Which is also my question. Do you already have documentation for Qt 4.5 what a widget needs to do to be able to accelerate its paintEvents via OpenGL when that is available?

I have to get a recent Qt 4.5 I guess…

6 tbastian November 28, 2008 at 4:05 pm
 

Phonon in Qt 4. It is the same as te one from KDE. I insist on that. We’re not cheating ;-) .
Thant being said, it depends on the support from the backend. So basically the gstreamer backend supports it. I’ve talked to Matthias Kretz recently and he also wanted the xine backend to be able to do something like that.

7 notmart November 28, 2008 at 4:49 pm
 

yes, switching the backend to Gstreamer works like a charm indeed,
great work dudes :)

8 qtuser November 28, 2008 at 4:57 pm
 

I have not been able to do much Phonon work yet, does it support Quicktime Videos on OS X and Windows if Quicktime has been installed?

thanks.

9 john dalton November 28, 2008 at 7:36 pm
 

Is Phonon in Qt 4.5 going to support video output? So that you could render frame images and then output them using a supported platform compression codec?

10 David November 30, 2008 at 10:51 am
 

Does it render in software even if the driver provides textured video under Linux?

11 Scorp1us November 30, 2008 at 6:22 pm
 

zOMG!!1!1 I’ve been waiting for this for ev4r… w00t!

One question though.. those black bars are kind of unsightly. Is there a way to apply an alpha mask, or set a color key to be transparent?

12 Jens December 1, 2008 at 10:31 am
 

dalton: Video compression will not make it into 4.5, it is certainly being considered for a future release though
david: Driver support for X overlays can not be utilized when embedded in a graphics view. We are not using any driver specific texture optimizations at the moment though on some platforms we make use of hardware pixelshaders to accellerate the color conversion.

13 tbastian December 1, 2008 at 10:35 am
 

To john dalton: Nothing like that in Qt 4.5.
To David : If you use opengl (by stting a QGWidget) as the viewport the rendering is hardware accelerated. We’re working on shaders to accelerate this even more.

14 tbastian December 3, 2008 at 9:29 am
 

Sorry for not spotting those comments before…

Matthias: when you get a paintevent you can create a QPainter and then check that the type of QPainter::paintEngine is opengl. In this case you can use OpenGL. In addition to that we check for the flag WA_DontShowOnScreen which is set by the graphics view and tells us that we need to use the Qt paint engine.
qtuser: Quicktime is supported on MacOSX (and not Windows).
Scorp1us: you can resize your videoWidget to fit the exact size of the video and then the black borders will disappear. You can also play with its scaling/aspect ratio.

15 David Johnson December 3, 2008 at 6:59 pm
 

Speaking of Widgets on the Canvas, can Nokia/Qt provide some instructions on how to configure X.org to deal with it? Yesterday I tried to show off this feature at the Qt Quickstart, and the pad navigator example did not work. It took about two full minutes to “flip” to the back widgets.

16 sroedal December 3, 2008 at 7:03 pm
 

David: the pad navigator example uses a QGLWidget as viewport by default, so maybe there’s some problem with your graphics driver or you’re lacking hardware acceleration?

17 David Johnson December 4, 2008 at 6:21 pm
 

I have perfectly adequate hardware accelerated OpenGL. You are right that it is OpenGL related, because if I edit the example to remove then then it works. And it is driver related, because it works with VESA/Mesa. But it is not the fault of driver because the OpenGL does work. I am using KDE4 desktop effects through OpenGL, no problem. I have several dozen 3D screensavers using OpenGL, no problem. I can run all of the OpenGL Qt examples (except pixel buffers), no problem. Only WOC fails, and only when it is using OpenGL for the viewport.

18 Giacomo Graziosi December 9, 2008 at 10:34 am
 

Is it possible to use directly Gstreamer without putting Phonon in the way?

19 tbastian December 9, 2008 at 11:16 am
 

Giacomo: It could be possible but then you’d lose the integration effort and you would have to duplicate code (or at least functionality) from our gstreamer backend.

20 Giacomo Graziosi December 9, 2008 at 11:23 pm
 

I need Gstreamer because I need to read both v4l/v4l2 and mjpeg streams over http, is it possible with Phonon?

Comments on this entry are closed.

Previous post:

Next post: