Last week in QtGStreamer – week 8

This was a very productive week for the project, with a lot of of activity moving us closer to a first stable release. I worked mostly on refactoring the mechanism that tracks reference counts for miniobjects and caps, while George has been busy with a redesign of the QGlib::Value system that makes it really convenient to use it from Qt, much like QVariant.

Also, we are happy to announce that QtGStreamer is now a Freedesktop.org project, with the repository living at

http://cgit.freedesktop.org/gstreamer/qt-gstreamer/

Bug reporting is already integrated as a GStreamer component in Bugzilla.

These moves makes me very happy. QtGStreamer was started last year by George Kiagiadakis as a personal project and were previously hosted at Gitorious. With this move we are now effectively the “official” Qt bindings for GStreamer, living in the same repository tree and using the same bug reporting system. This makes it easier for us to tap into the knowledge of the existing GStreamer developer community (including people that are using other bindings, like PyGst). And the visibility of the project is increased, which is good in general as we really want to have more people hacking on and using it.

Last week in QtGStreamer – week 7

This week George merged some of the patches I have been working on to the QtGStreamer master repository, including support for Events. (*) He also wrote and committed a bunch of bugfixes and some improvements to the build files.

I started to work on some refactoring for our refCounted object, with an eye on addressing two issues that are common to other GStreamer bindings as well. So far things are promising, but this effort will take a little more time before it is ready to be merged.

And finally, the Kamoso team announced that they have completed the intial port to QtGStreamer. It is still a work in progress, but it is good to be able to collaborate on real world applications instead of just hacking on an “ideal” library API. We have already some adjustments in our long and public TODO list thanks to the input from Alex, and I wish the Kamoso team good luck with the project.

(*) As a comment to that, I still need to adjust my workflow to git: I use to prototype things and commit frequently in the local directory to avoid losing work, but this produces a not-so-good history as things are added and deleted… and do not end up in the final patch, just in the commit history. To avoid this I was rebasing and squashing, but the side effect of this for big changes (like the TagList support I was working on) is that it tends to be a very long and not-so-manageable merge request, which takes more time to process. I promised George I will send smaller, atomic patches from now on :). But generally I think that I am now finally getting into the git mode of thinking: it requires a mental adjustment for people like me that were used to CVS and SVN and were afraid of branching… Once you adjust there is no going back, I am glad KDE is migrating to it.

Last week in QtGStreamer – a recap (and an overview of GStreamer)

This is inspired by the ‘Last week in Krita’ and ‘Last week in KOffice’ series. Boud, the author of these series, mentioned that this is a nice way to “keep everyone who is interested, developers, contributors, users — everyone — up to date on what is happening in the […] community.” I do not promise I will be able to keep up with weekly updates AND still work on development :), but I will do my best to summarize what is happening on a frequent basis.

I guess starting the series with a recap is good. I have worked in this project for a little more than 5 weeks now, so this is going to be the “Week 1-6” edition. Two weeks ago I posted an introduction to the project, and the reaction so far has been mostly positive. I know of at least one KDE project that is trying QtGStreamer already, and this is good because it lets us tweak the API to real-world applications easily, as no official release has been done and there is still flexibility to do so. And because it is important for us to get more people on board we are usually hanging out in the #gstreamer IRC channel on Freenode: please join us there if you have a question, want to help us with development or just need a hand trying QtGStreamer in your application.

Since that last update we have added some of the basic blocks from the GStreamer API that were still missing, including support for Events, Buffers and TagLists. Some of these are already in the master repository and some are still in review, but we are generally in good shape and ready for prototyping. The plan is to work on the next two weeks on stabilizing what is already added and refactoring some of the code that deals with the bridge between Glib/GObject and Qt. George and I have some interesting ideas on how to deal with some of the challenges that face every GStreamer-binding project, as there are a lot of special cases and design choices in the framework that require authors of bindings to be creative and decide where to draw the line: we can give users full access to the engine at expense of making the API complex, or we can hand-hold the developer and maybe limit the inherent flexibility of the engine. It is a tenuous line, but by now we *think* we have a pretty good overview of the main use cases, and are in a good position to try some things.

I realized after reading the paragraph above that it might not make more sense to people not familiarized with how GStreamer is designed, so I will write a “5 minute overview” of the technology. If you have more time I recommend reading the first chapter of the online docs instead. But, in short, the GStreamer framework is pipeline based. The pipeline is composed of different elements, which are GStreamer’s building blocks. See the image below for the pipeline that can be assembled for a simple ogg player:

Simple Player
A simple GStreamer pipeline

In this example each block is a GStreamer element. An element in its simplest form is a box that generates, processes or outputs data: it can have one or more “pads”, which are the ports that make the connections so data can flow from one element to the other. Pads can be source pads (produce data) or sink pads (consume data). There are over 1000 elements in a typical GStreamer installation, dealing with everything from getting data from cameras (a v4l2 element with a single source pad) to decoding VP8 streams (a vp8 decoder element) to displaying data on the screen (several specialized elements that only have one sink pad, including for example the xvvideosink one).

The pipeline concept is what makes GStreamer so flexible. It is not that different from Unix pipelines in design: the idea is that you build complex solutions starting from simple and discrete elements. As this is supposed to be a 5-minute introduction I will not get into much more detail, but it is important to mention that in GStreamer communication events between elements can flow upstream and downstream, and there are facilities that let the elements communicate back to the application and vice-versa using messages and queries, as well for assembling pipelines dynamically.

So in QtGStreamer we give you all the power to link these GStreamer elements as you wish. A real world example might help: let us say you want to display the image of your webcam in a Qt application window. In Linux you can do this by linking the v4l2src to a qwidgetsink, which as the name implies is a QtGStreamer element that can display images and inherits from QWidget.. Actual code for this is something like:

//Creates the pipeline
m_pipeline = QGst::Pipeline::create();
//Construct the source Video for Linux element
QGst::ElementPtr src = QGst::ElementFactory::make(“v4l2src”);
//Construct the QWidget sink element
m_sink = QGst::ElementFactory::make(“qwidgetvideosink”);
//Add both to the pipeline
m_pipeline->add(src);
m_pipeline->add(m_sink);
//Link the source to the sink
src->link(m_sink);
//Tell the sink to use one widget defined in our UI file
m_ui.videoWidget->setVideoSink(m_sink);
//Start the pipeline
m_pipeline->setState(QGst::StatePlaying);

That’s it: video should now be flowing from your v4l2 drivers directly to your screen. The example above can be expanded: it is typical to include an element called “ffmpegcolorspace” in between the v4l2src and the qwidgetvideosink, to handle color space conversion if necessary. You could also add an element that duplicates the data before it reaches the qwidget, followed by a VP8 encoder element, a Matroska muxer and an element that writes data to a file, and your application would already compress and record WebM video. But this is a quick tutorial, so we will not expand on that right now. The idea is to show that you have a lot of flexibility and QtGStreamer already lets you construct any pipeline you wish using the make and link functions.

But constructing pipelines manually can be complex. This is where higher-level objects come handy: next week I plan to continue this series with an update on the progress of the project and at the same time will write about how GStreamer’s pre-made bins (which are complex elements that internally have their own collection of elements) can be used to easily play/decode/capture almost any kind of media on several platform, as they auto-discover the elements that need to be used and connect them automatically for you.

Disclaimer: the above description of GStreamer’s design is extremely simplified of course, so I recommend checking the documentation if you are really interested in finding out more about its internals.

Renaming KBattleShip and KTron

As you all know, KDE is a project that encourages as much cooperation with upstream as possible. So if a distro has a reasonable request we generally try to find a way to make life easier for them, as this will ultimately benefit all KDE users when they migrate between different environments.

So it is time for us to make life easier for our Fedora friends, as they have been maintaining patches against some of our games for a while. Please help us choose a new name for KBattleship and also a new one for KTron. These will be considered for KDE 4.6, so we need you to act fast! The poll closes on Sunday, November 14th.