How to correctly init GTK app with GStreamer?

What’s the correct approach for initialising GTK apps that use GStreamer?

The code that I’ve inherited has a main() method that does Gst.init(ref args) before a GLib.Settings.init() and then creating the Gtk.Application and calling its run() method. Some users complained about crashes when playing GStreamer videos and it only seems to be solved by calling XInitThreads (from C code, because I’m doing it conditionally with #ifdef GDK_WINDOWING_X11) before the Gst.Init.

That all felt a bit ugly and wrong, like I was working around a problem with the wrong (but seemingly functioning) solution.

I’ve now seen this post, which says that Gtk.init is the wrong way to go about things and that OptionContext should be used instead (which the app is also using with Gtk.get_option_group(false) and Gst.init_get_option_group()). Does that apply to GStreamer and XInitThreads as well? What’s the correct way of initialising the app so that GStreamer doesn’t crash and everything is initialised in the right order?

1 Like

According to this example, I should just be able to call Gst.init() as I am doing. But some users (using i3 on a integrated Radeon R5, or Awesome/Gnome/KDE using nouveau) reported crashes until I did the XInitThreads first.

Also, some of the later Vala examples still show Gtk.init() use.

Calling Gst.init() or the option group API is sufficient to initialize GStreamer and use GStreamer API.

It is necessary to call XInitThreads() before initializing GTK if you’re using any of the X11 GStreamer elements due to how X11 works. If you don’t use any (not even indirectly), then this is not needed.

XInitThreads() must be called before the first usage of any X11 APIs and GTK doesn’t call it itself while calling it from the X11 GStreamer elements would usually be too late.

You won’t have such problems when using Wayland or on literally any other platform than X11.

2 Likes

Okay, thanks, makes sense.

I guess the other question is: Is there a Vala equivalent to #ifdef GDK_WINDOWING_X11 so that people can make Wayland-only builds? Or a way to do it in Meson? I’ve found that we don’t need to check whether we’re on an X11 display, just that it was built with X11 support.

I can do enable_x11 = get_option('x11') and

if (enable_x11)
  cb_deps += [dependency('x11')]
  add_project_arguments('-DX11', language: 'c')
  add_project_arguments('-D', 'X11', language: 'vala')
endif

in the meson config and then: #if X11 … #endif in the code, but is that the best/right way?

I don’t know how you get access to C #defines inside Vala, sorry :slight_smile: The available GDK backends are also in the pkg-config file, see pkg-config --variable=targets gdk-3.0. Maybe using that instead would be an easier option?

Ah, thanks, I didn’t know about that. But wouldn’t that force X11 builds on any platform that could build X11? So, if the build server supports X11 and Wayland then it’ll build the “with X11” version and won’t be able to build the “without X11” version.

I found a thread about passing #ifdef from Vala to C code that said it was hard/impossible, so I suspect accessing it in the inverse way isn’t possible either.

If GTK/GDK is built with X11, you can’t know whether X11 is actually used before calling gtk_init(). So if it is built with X11 support you need to call XInitThreads() in any case, even if Wayland is actually used at runtime later.

That’s all not really ideal but I don’t think there’s a better solution on the application or GStreamer side. The only other solution I could think of is to modify GTK to call XInitThreads(), or to make that the default in libX11/libxcb but I don’t see either of that happening.

Okay. The people reporting the issue had said that calling the X11 code on Wayland didn’t cause issues (because it just initialises mutexes etc) but I assumed that there would be a way to make a Wayland-only build on a build server that supports X11. If that’s not the case and building on a platform that supports X11 means the compiled build supports X11 then I can live with that. I just wanted to make sure I was doing things “properly”.

I think this is as proper as it gets with the current state of things :slight_smile:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.