Compare commits
6 Commits
async-dial
...
wip/gstmed
Author | SHA1 | Date | |
---|---|---|---|
|
5abdbf8505 | ||
|
c5265dfa63 | ||
|
0ea3449d6d | ||
|
bc87da771f | ||
|
92989dd89a | ||
|
ab44159ca8 |
@@ -2310,6 +2310,20 @@ activate (GApplication *app)
|
||||
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
|
||||
set_up_context_popover (widget, model);
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "video");
|
||||
|
||||
GFile *file;
|
||||
GInputStream *input_stream;
|
||||
GtkMediaStream *media_stream;
|
||||
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/WidgetFactory4/gtk-logo.webm");
|
||||
input_stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL));
|
||||
media_stream = gtk_media_file_new_for_input_stream (input_stream);
|
||||
gtk_video_set_media_stream (GTK_VIDEO (widget), media_stream);
|
||||
g_object_unref (media_stream);
|
||||
g_object_unref (input_stream);
|
||||
g_object_unref (file);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
|
||||
g_object_unref (builder);
|
||||
|
@@ -1060,16 +1060,17 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVideo">
|
||||
<object class="GtkVideo" id="video">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<!--
|
||||
<property name="autoplay">1</property>
|
||||
<property name="loop">1</property>
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/gtk-logo.webm</property>
|
||||
-->
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
119
modules/media/gtkgstbin.c
Normal file
119
modules/media/gtkgstbin.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
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)
|
||||
{
|
||||
GstPadTemplate *templ;
|
||||
GstPad *pad;
|
||||
|
||||
self->src = gst_element_factory_make ("giostreamsrc", "src");
|
||||
gst_bin_add (GST_BIN (self), self->src);
|
||||
|
||||
templ = gst_element_get_pad_template (GST_ELEMENT (self), "src");
|
||||
pad = gst_element_get_static_pad (self->src, "src");
|
||||
gst_element_add_pad (GST_ELEMENT (self),
|
||||
gst_ghost_pad_new_from_template ("src", pad, templ));
|
||||
gst_object_unref (pad);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (class), &src_templ);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_gst_bin_set_stream (GtkGstBin *bin,
|
||||
GInputStream *stream)
|
||||
{
|
||||
g_object_set (bin->src, "stream", stream, NULL);
|
||||
}
|
33
modules/media/gtkgstbinprivate.h
Normal file
33
modules/media/gtkgstbinprivate.h
Normal file
@@ -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__ */
|
@@ -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
|
||||
@@ -106,6 +109,8 @@ g_io_module_load (GIOModule *module)
|
||||
GTK_TYPE_GST_MEDIA_FILE,
|
||||
"gstreamer",
|
||||
10);
|
||||
|
||||
gst_init (NULL, NULL);
|
||||
}
|
||||
|
||||
G_GNUC_NORETURN
|
||||
@@ -211,6 +216,37 @@ gtk_gst_media_file_end_of_stream_cb (GstPlayer *player,
|
||||
gtk_media_stream_stream_ended (GTK_MEDIA_STREAM (self));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
gst_player_pause (self->player);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_gst_media_file_destroy_player (GtkGstMediaFile *self)
|
||||
{
|
||||
@@ -221,8 +257,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
|
||||
@@ -239,34 +277,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_pause (self->player);
|
||||
gst_player_set_uri (self->player, "gtk-media-stream://");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -359,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;
|
||||
|
||||
@@ -379,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);
|
||||
}
|
||||
|
||||
|
@@ -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 ],
|
||||
|
Reference in New Issue
Block a user