Saturday, March 23, 2013

Why do not simply use QtGStreamer?

Off course the question arises: "Why do not simply use QtGStreamer?" Ya, actually this should be the way to do. Since redoing it by your self is often useless. The downside is: currently only gstreamer-0.10 is supported and on updates this will not change. And the installation on Windows is difficult.
In QtGstreamer there are principally two ways of integrating a video into a GUI:
1) QGst::Ui::GraphicsVideoWidget (in conjunction with QGst::Ui::GraphicsVideoSurface)
2) QGst::Ui::VideoWidget

Here is an example for option 1:

qtgraphicswidget.pro


main.cpp:



And here is an example for option 2:

main.cpp:


The project file can be the sane as for option 1

Thursday, March 14, 2013

Xoverlay

Last time I wanted to fix some issues with the conversion from a gst_buffer video frame into a QImage. I fixed one of three issues. But before fixing the other two:
  • The mutex might be not optimally designed since it's a producer newSample() and a consumer getFrame()
  • A serious problem is that the data of the QImage must remain valid also if the image is used from the Display class. This is not given here since the lifetime of the GstBuffer is unknown
I will try another approach: To use the xvimagesink directly. Here is the working source code:

xoverlay.pro


For the video player I will use a gst_video_overlay element which is part of the gstreamer base plugins (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideooverlay.html).
Nevertheless pkg-config gave following insight:
shows:
-pthread -lgstreamer-1.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0
shows:
-pthread -lgstvideo-1.0 -lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0

Thus it seems they mixed some things up and in order to use gst_video_overlay one has to include gstreamer-video-1.0 instead of gstreamer-plugins-base-1.0

main.cpp


videoplayer.h


videoplayer.cpp


I remember I got that idea from somewhere in the Internet, but i don't remember where. But it looks easy to use. This does however not work in Windows and I will avoid that solution in the future.
Note that the size of the widget is hard coded to 320x240. This results from the default caps negotiation between the videotestsrc and the xvimagesink.

Monday, March 11, 2013

Last time I was showing three problems with the conversion from a gst buffer data to QImage.
The code snipped was:

And the problems were:
  • The mutex might be not optimally designed since it's a producer newSample() and a consumer getFrame()
  • The QImage construction should be done with const data since the data is not intended to get changed
  • A serious problem is that the data of the QImage must remain valid also if the image is used from the Display class. This is not given here since the lifetime of the GstBuffer is unknown

I was trying to solve the simplest first: construct for const data. The difference as described in the Qt documentation is
Unlike the similar QImage constructor that takes a non-const data buffer, this version will never alter the contents of the buffer. For example, calling QImage::bits() will return a deep copy of the image, rather than the buffer passed to the constructor. This allows for the efficiency of constructing a QImage from raw data, without the possibility of the raw data being changed.

For a solution I intended to use the const_cast operator. And it seems it is working fine:


The other two are somewhat more complex to solve. I will continue with the lifetime of the gstBuffer.

Saturday, March 9, 2013

Displaying a Videotestsrc in a Qt Application

Since quite a while I am trying to get gstreamer working properly inside of Qt applications. Whereas I am not taking sound into account, solely video. I wanted to use gstreamer-1.0 and since the QtGstreamer binding is only binding gstreamer-0.10 this was not possible to use. Honestly speaking QtGstreamer with the older gstreamer might have been the better choice. But I also wanted to know how it works and switch later to the Qt binding. There is also hope that the developer will port the Qt binding to gstreamer-1.0. My first testing application I wrote with QtCreator. Here is the source code:


videotest.pro



main.cpp



capture.h


capture.cpp

The Capture class is a subclass of QLabel only because I intended to include a signal which is emitted each time a frame arrives. The approach is based on the gst_app_sink plugin. With the caps "video/x-raw, format=RGB, bpp=8" and the correct dimension the data can be safely mapped to a QImage with QImage::Format_RGB888 format. The whole code of getting the data from the gstBuffer in newSample() is very different from the approach in gstreamer-0.10. I find the way of gstreamer-1.0 pretty tedious. Several problems remain here:
  • The mutex might be not optimally designed since its a producer newSample() and a consumer getFrame()
  • The QImage construction should be done with const data since the data is not intended to get changed
  • A serious problem is that the data of the QImage must remain valid also if the image is used from the Display class. This is not given here since the lifetime of the GstBuffer is unknown


display.h


display.cpp


The Display class is a subclassed QLabel. For the testing purpose it is sufficient to display the QLabel widget only. In a real applications this widget can be included in a QMainWindow or QDialog easily. The paintEvent is overwritten to enable the rendering of the pixmap. I don't know why the paintEvent occurs frequently enough without doing nothing. There is no explicit update() or repaint() slot executed.

Its raining ...

A test for the syntax highlighter:
I followed the advices at Geek Talkin Siebel: Embed Code Syntax Highlighting in Blog. Thus I copied the the source code into this blog's template HTML code. After putting it in the compose mode the source was not formated. After adding the source code directly into the HTML edit mode, the source code was properly highlighted. Unfortunately the whole source is not visible in the "Compose" mode.
It is however not straightforward to cascade the code in order to show the source of the above embedded code. With the <pre> it was however possible:

And the above with:

The above code was generated with another <pre> node.