diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/media/gtkgstbin.c | 104 | ||||
-rw-r--r-- | modules/media/gtkgstbinprivate.h | 33 | ||||
-rw-r--r-- | modules/media/gtkgstmediafile.c | 62 | ||||
-rw-r--r-- | modules/media/meson.build | 1 |
4 files changed, 180 insertions, 20 deletions
diff --git a/modules/media/gtkgstbin.c b/modules/media/gtkgstbin.c new file mode 100644 index 0000000000..56680c1d1d --- /dev/null +++ b/modules/media/gtkgstbin.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "gtkgstbinprivate.h" + +struct _GtkGstBin { + GstBin parent; + + GstElement *src; + char *uri; +}; + +struct _GtkGstBinClass { + GstBinClass parent_class; +}; + +static GstURIType +gtk_gst_uri_handler_get_type (GType type) +{ + return GST_URI_SRC; +} + +static const char * const * +gtk_gst_uri_handler_get_protocols (GType type) +{ + static const char *protocols[] = { "gtk-media-stream", NULL }; + + return protocols; +} + +static char * +gtk_gst_uri_handler_get_uri (GstURIHandler *handler) +{ + GtkGstBin *self = GTK_GST_BIN (handler); + + return g_strdup (self->uri); +} + +static gboolean +gtk_gst_uri_handler_set_uri (GstURIHandler *handler, + const char *uri, + GError **error) +{ + GtkGstBin *self = GTK_GST_BIN (handler); + + g_free (self->uri); + self->uri = g_strdup (uri); + + return TRUE; +} + +static void +gtk_gst_uri_handler_iface_init (GstURIHandlerInterface *iface) +{ + iface->get_type = gtk_gst_uri_handler_get_type; + iface->get_protocols = gtk_gst_uri_handler_get_protocols; + iface->get_uri = gtk_gst_uri_handler_get_uri; + iface->set_uri = gtk_gst_uri_handler_set_uri; +} + +G_DEFINE_TYPE_WITH_CODE (GtkGstBin, gtk_gst_bin, GST_TYPE_BIN, + G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gtk_gst_uri_handler_iface_init)) + +static void +gtk_gst_bin_init (GtkGstBin *self) +{ + self->src = gst_element_factory_make ("giostreamsrc", "src"); + g_object_ref_sink (self->src); + gst_bin_add (GST_BIN (self), self->src); +} + +static void +gtk_gst_bin_class_init (GtkGstBinClass *class) +{ + gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (class), + "GtkGstBin", + "Source", "Handles GtkMediaFile sources", + "Matthias Clasen"); +} + +void +gtk_gst_bin_set_stream (GtkGstBin *bin, + GInputStream *stream) +{ + g_object_set (bin->src, "stream", stream, NULL); +} diff --git a/modules/media/gtkgstbinprivate.h b/modules/media/gtkgstbinprivate.h new file mode 100644 index 0000000000..8e6099e37e --- /dev/null +++ b/modules/media/gtkgstbinprivate.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GTK_GST_BIN_PRIVATE_H__ +#define __GTK_GST_BIN_PRIVATE_H__ + +#include <gio/gio.h> +#include <gst/gst.h> + +#define GTK_TYPE_GST_BIN (gtk_gst_bin_get_type ()) +G_DECLARE_FINAL_TYPE (GtkGstBin, gtk_gst_bin, GTK, GST_BIN, GstBin); + +void +gtk_gst_bin_set_stream (GtkGstBin *bin, + GInputStream *stream); + +#endif /* __GTK_GST_BIN_PRIVATE_H__ */ diff --git a/modules/media/gtkgstmediafile.c b/modules/media/gtkgstmediafile.c index 9e9edbd68c..6116a2183c 100644 --- a/modules/media/gtkgstmediafile.c +++ b/modules/media/gtkgstmediafile.c @@ -21,6 +21,7 @@ #include "gtkgstmediafileprivate.h" #include "gtkgstpaintableprivate.h" +#include "gtkgstbinprivate.h" #include <gst/player/gstplayer.h> #include <gst/player/gstplayer-g-main-context-signal-dispatcher.h> @@ -31,6 +32,8 @@ struct _GtkGstMediaFile GstPlayer *player; GdkPaintable *paintable; + GstElement *playbin; + GtkGstBin *src; }; struct _GtkGstMediaFileClass @@ -214,6 +217,35 @@ gtk_gst_media_file_end_of_stream_cb (GstPlayer *player, } static void +gtk_gst_media_file_source_setup_cb (GstElement *playbin, + GstElement *source, + GtkGstMediaFile *self) +{ + GFile *file; + GInputStream *stream; + + g_return_if_fail (GTK_IS_GST_BIN (source)); + + self->src = GTK_GST_BIN (g_object_ref (source)); + + file = gtk_media_file_get_file (GTK_MEDIA_FILE (self)); + stream = gtk_media_file_get_input_stream (GTK_MEDIA_FILE (self)); + + if (stream) + g_object_ref (stream); + else if (file) + stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL)); + else + stream = NULL; + + g_return_if_fail (stream != NULL); + + gtk_gst_bin_set_stream (self->src, stream); + + g_clear_object (&stream); +} + +static void gtk_gst_media_file_destroy_player (GtkGstMediaFile *self) { if (self->player == NULL) @@ -223,8 +255,10 @@ gtk_gst_media_file_destroy_player (GtkGstMediaFile *self) g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_end_of_stream_cb, self); g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_seek_done_cb, self); g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_error_cb, self); - g_object_unref (self->player); - self->player = NULL; + g_signal_handlers_disconnect_by_func (self->playbin, gtk_gst_media_file_source_setup_cb, self); + g_clear_object (&self->player); + g_clear_object (&self->playbin); + g_clear_object (&self->src); } static void @@ -241,32 +275,19 @@ gtk_gst_media_file_create_player (GtkGstMediaFile *file) g_signal_connect (self->player, "end-of-stream", G_CALLBACK (gtk_gst_media_file_end_of_stream_cb), self); g_signal_connect (self->player, "seek-done", G_CALLBACK (gtk_gst_media_file_seek_done_cb), self); g_signal_connect (self->player, "error", G_CALLBACK (gtk_gst_media_file_error_cb), self); + + self->playbin = gst_player_get_pipeline (self->player); + g_signal_connect (self->playbin, "source-setup", G_CALLBACK (gtk_gst_media_file_source_setup_cb), self); } static void gtk_gst_media_file_open (GtkMediaFile *media_file) { GtkGstMediaFile *self = GTK_GST_MEDIA_FILE (media_file); - GFile *file; gtk_gst_media_file_create_player (self); - file = gtk_media_file_get_file (media_file); - - if (file) - { - /* XXX: This is technically incorrect because GFile uris aren't real uris */ - char *uri = g_file_get_uri (file); - - gst_player_set_uri (self->player, uri); - - g_free (uri); - } - else - { - /* It's an input stream */ - g_assert_not_reached (); - } + gst_player_set_uri (self->player, "gtk-media-stream://"); gst_player_pause (self->player); } @@ -361,6 +382,8 @@ gtk_gst_media_file_class_init (GtkGstMediaFileClass *klass) GtkMediaStreamClass *stream_class = GTK_MEDIA_STREAM_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gst_element_register (NULL, "GtkGstBin", GST_RANK_PRIMARY, GTK_TYPE_GST_BIN); + file_class->open = gtk_gst_media_file_open; file_class->close = gtk_gst_media_file_close; @@ -381,4 +404,3 @@ gtk_gst_media_file_init (GtkGstMediaFile *self) g_signal_connect_swapped (self->paintable, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self); g_signal_connect_swapped (self->paintable, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self); } - diff --git a/modules/media/meson.build b/modules/media/meson.build index 1bd91821d8..7c0ab8fc2a 100644 --- a/modules/media/meson.build +++ b/modules/media/meson.build @@ -69,6 +69,7 @@ if gstplayer_dep.found() and gstgl_dep.found() 'gtkgstmediafile.c', 'gtkgstpaintable.c', 'gtkgstsink.c', + 'gtkgstbin.c', ], c_args: extra_c_args + extra_win_cflags, dependencies: [ libm, libgtk_dep, gstplayer_dep, gstgl_dep ], |