api: Introduce custom gstreamer init function

Initializes GStreamer library and tweaks some of its defaults to our liking.
This also allows usage of GstClapper API alone without importing GStreamer on the implementation side.

It changes preferred hardware acceleration order (depending on plugins versions) into:
v4l2sl -> nv -> va -> vaapi -> v4l2
This commit is contained in:
Rafał Dzięgiel
2021-08-24 13:10:25 +02:00
parent 87a0dd473e
commit 5874db45ea
3 changed files with 101 additions and 3 deletions

View File

@@ -65,6 +65,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_clapper_debug);
#define DEFAULT_SUBTITLE_VIDEO_OFFSET 0
#define DEFAULT_SEEK_MODE GST_CLAPPER_SEEK_MODE_DEFAULT
static gboolean gst_clapper_gstreamer_prepared = FALSE;
/**
* gst_clapper_error_quark:
*/
@@ -270,7 +272,6 @@ static void remove_seek_source (GstClapper * self);
static void
gst_clapper_init (GstClapper * self)
{
GST_DEBUG_CATEGORY_INIT (gst_clapper_debug, "Clapper", 0, "GstClapper");
GST_TRACE_OBJECT (self, "Initializing");
self = gst_clapper_get_instance_private (self);
@@ -302,6 +303,8 @@ gst_clapper_class_init (GstClapperClass * klass)
gobject_class->finalize = gst_clapper_finalize;
gobject_class->constructed = gst_clapper_constructed;
GST_DEBUG_CATEGORY_INIT (gst_clapper_debug, "Clapper", 0, "GstClapper");
param_specs[PROP_VIDEO_RENDERER] =
g_param_spec_object ("video-renderer",
"Video Renderer", "Video renderer to use for rendering videos",
@@ -3237,6 +3240,98 @@ gst_clapper_main (gpointer data)
return NULL;
}
static gboolean
gst_clapper_set_feature_rank_versioned (const gchar * name, guint rank,
guint min_major, guint min_minor, guint min_micro)
{
GstRegistry *registry = gst_registry_get ();
GstPluginFeature *feature = gst_registry_lookup_feature (registry, name);
gboolean res = FALSE;
if (!feature) {
GST_DEBUG ("Cannot change rank of unavailable feature: %s", name);
goto out;
}
if (gst_plugin_feature_check_version (feature, min_major, min_minor, min_micro)) {
guint old_rank = gst_plugin_feature_get_rank (feature);
gst_plugin_feature_set_rank (feature, rank);
res = TRUE;
GST_DEBUG ("Changed rank: %i -> %i for %s", old_rank, rank, name);
} else {
GST_DEBUG ("Feature %s is at older version then required", name);
}
out:
gst_object_unref (feature);
return res;
}
static gboolean
gst_clapper_set_feature_rank (const gchar * name, guint rank)
{
return gst_clapper_set_feature_rank_versioned (name, rank, 0, 0, 0);
}
static gboolean
gst_clapper_has_plugin_with_features (const gchar * name)
{
GstRegistry *registry = gst_registry_get ();
GList *features = gst_registry_get_feature_list_by_plugin (registry, name);
gboolean ret = g_list_length (features) > 0;
gst_plugin_feature_list_free (features);
return ret;
}
static void
gst_clapper_prepare_gstreamer (void)
{
GstRegistry *registry = gst_registry_get ();
const guint rank = GST_RANK_PRIMARY + 24;
GST_DEBUG ("Preparing GStreamer plugins");
if (gst_clapper_has_plugin_with_features ("va")) {
gst_clapper_set_feature_rank_versioned ("vah264dec", rank, 1, 19, 1);
gst_clapper_set_feature_rank_versioned ("vampeg2dec", rank, 1, 19, 1);
}
if (gst_clapper_has_plugin_with_features ("nvcodec")) {
gst_clapper_set_feature_rank ("nvh264dec", rank + 4);
gst_clapper_set_feature_rank ("nvh265dec", rank + 4);
}
if (gst_clapper_has_plugin_with_features ("v4l2codecs")) {
if (!gst_clapper_set_feature_rank_versioned ("v4l2slh264dec", rank + 10, 1, 19, 1))
gst_clapper_set_feature_rank ("v4l2slh264dec", GST_RANK_NONE);
if (!gst_clapper_set_feature_rank_versioned ("v4l2slvp8dec", rank + 10, 1, 19, 2))
gst_clapper_set_feature_rank ("v4l2slvp8dec", GST_RANK_NONE);
}
gst_clapper_gstreamer_prepared = TRUE;
GST_DEBUG ("GStreamer plugins prepared");
}
/**
* gst_clapper_gst_init:
* @argc: (inout) (allow-none): pointer to application's argc
* @argv: (inout) (array length=argc) (allow-none): pointer to application's argv
*
* Automatically initializes GStreamer library if this was not done by the user yet
* and tweaks some of its defaults to our liking. It is recommended to use this
* function instead of plain gst_init().
*
* This also allows usage of GstClapper API alone without importing GStreamer
* on the implementation side.
*/
void
gst_clapper_gst_init (int * argc, char ** argv[])
{
if (!gst_is_initialized ())
gst_init (argc, argv);
if (!gst_clapper_gstreamer_prepared)
gst_clapper_prepare_gstreamer ();
}
/**
* gst_clapper_new:
* @video_renderer: (transfer full) (allow-none): GstClapperVideoRenderer to use

View File

@@ -153,6 +153,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstClapper, gst_object_unref)
GST_CLAPPER_API
GType gst_clapper_get_type (void);
GST_CLAPPER_API
void gst_clapper_gst_init (int *argc, char **argv[]);
GST_CLAPPER_API
GstClapper * gst_clapper_new (GstClapperVideoRenderer *video_renderer, GstClapperSignalDispatcher *signal_dispatcher,
GstClapperMpris *mpris);

View File

@@ -2,9 +2,9 @@ imports.gi.versions.Gdk = '4.0';
imports.gi.versions.Gtk = '4.0';
imports.gi.versions.Soup = '2.4';
const { Gst, Gtk, Adw } = imports.gi;
const { GstClapper, Gtk, Adw } = imports.gi;
Gst.init(null);
GstClapper.Clapper.gst_init(null);
Gtk.init();
Adw.init();