Merging gst-examples
[platform/upstream/gstreamer.git] / playback / player / gtk / gtk-video-renderer.c
1 /* GStreamer
2  *
3  * Copyright (C) 2015 Sebastian Dröge <sebastian@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "gtk-video-renderer.h"
22
23 struct _GstPlayGtkVideoRenderer
24 {
25   GObject parent;
26
27   GstElement *sink;
28   GtkWidget *widget;
29 };
30
31 struct _GstPlayGtkVideoRendererClass
32 {
33   GObjectClass parent_class;
34 };
35
36 static void
37     gst_player_gtk_video_renderer_interface_init
38     (GstPlayVideoRendererInterface * iface);
39
40 enum
41 {
42   GTK_VIDEO_RENDERER_PROP_0,
43   GTK_VIDEO_RENDERER_PROP_WIDGET,
44   GTK_VIDEO_RENDERER_PROP_LAST
45 };
46
47 G_DEFINE_TYPE_WITH_CODE (GstPlayGtkVideoRenderer,
48     gst_player_gtk_video_renderer, G_TYPE_OBJECT,
49     G_IMPLEMENT_INTERFACE (GST_TYPE_PLAY_VIDEO_RENDERER,
50         gst_player_gtk_video_renderer_interface_init));
51
52 static GParamSpec
53     * gtk_video_renderer_param_specs[GTK_VIDEO_RENDERER_PROP_LAST] = { NULL, };
54
55 static void
56 gst_player_gtk_video_renderer_get_property (GObject * object,
57     guint prop_id, GValue * value, GParamSpec * pspec)
58 {
59   GstPlayGtkVideoRenderer *self = GST_PLAY_GTK_VIDEO_RENDERER (object);
60
61   switch (prop_id) {
62     case GTK_VIDEO_RENDERER_PROP_WIDGET:
63       g_value_set_object (value, self->widget);
64       break;
65     default:
66       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
67       break;
68   }
69 }
70
71 static void
72 gst_player_gtk_video_renderer_finalize (GObject * object)
73 {
74   GstPlayGtkVideoRenderer *self = GST_PLAY_GTK_VIDEO_RENDERER (object);
75
76   if (self->sink)
77     gst_object_unref (self->sink);
78   if (self->widget)
79     g_object_unref (self->widget);
80
81   G_OBJECT_CLASS
82       (gst_player_gtk_video_renderer_parent_class)->finalize (object);
83 }
84
85 static void
86     gst_player_gtk_video_renderer_class_init
87     (GstPlayGtkVideoRendererClass * klass)
88 {
89   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
90
91   gobject_class->get_property = gst_player_gtk_video_renderer_get_property;
92   gobject_class->finalize = gst_player_gtk_video_renderer_finalize;
93
94   gtk_video_renderer_param_specs
95       [GTK_VIDEO_RENDERER_PROP_WIDGET] =
96       g_param_spec_object ("widget", "Widget",
97       "Widget to render the video into", GTK_TYPE_WIDGET,
98       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
99
100   g_object_class_install_properties (gobject_class,
101       GTK_VIDEO_RENDERER_PROP_LAST, gtk_video_renderer_param_specs);
102 }
103
104 static void
105 gst_player_gtk_video_renderer_init (GstPlayGtkVideoRenderer * self)
106 {
107   GstElement *gtk_sink = gst_element_factory_make ("gtkglsink", NULL);
108
109   if (gtk_sink) {
110     GstElement *sink = gst_element_factory_make ("glsinkbin", NULL);
111     g_object_set (sink, "sink", gtk_sink, NULL);
112
113     self->sink = sink;
114   } else {
115     gtk_sink = gst_element_factory_make ("gtksink", NULL);
116     self->sink = gst_object_ref_sink (gtk_sink);
117   }
118
119   g_assert (self->sink != NULL);
120
121   g_object_get (gtk_sink, "widget", &self->widget, NULL);
122 }
123
124 static GstElement *gst_player_gtk_video_renderer_create_video_sink
125     (GstPlayVideoRenderer * iface, GstPlay * player)
126 {
127   GstPlayGtkVideoRenderer *self = GST_PLAY_GTK_VIDEO_RENDERER (iface);
128
129   return gst_object_ref (self->sink);
130 }
131
132 static void
133     gst_player_gtk_video_renderer_interface_init
134     (GstPlayVideoRendererInterface * iface)
135 {
136   iface->create_video_sink = gst_player_gtk_video_renderer_create_video_sink;
137 }
138
139 /**
140  * gst_play_gtk_video_renderer_new:
141  *
142  * Returns: (transfer full):
143  */
144 GstPlayVideoRenderer *
145 gst_play_gtk_video_renderer_new (void)
146 {
147   GstElementFactory *factory;
148
149   factory = gst_element_factory_find ("gtkglsink");
150   if (!factory)
151     factory = gst_element_factory_find ("gtksink");
152   if (!factory)
153     return NULL;
154
155   gst_object_unref (factory);
156
157   return g_object_new (GST_TYPE_PLAY_GTK_VIDEO_RENDERER, NULL);
158 }
159
160 /**
161  * gst_play_gtk_video_renderer_get_widget:
162  * @self: #GstPlayVideoRenderer instance
163  *
164  * Returns: (transfer full): The GtkWidget
165  */
166 GtkWidget *gst_play_gtk_video_renderer_get_widget
167     (GstPlayGtkVideoRenderer * self)
168 {
169   GtkWidget *widget;
170
171   g_return_val_if_fail (GST_IS_PLAY_GTK_VIDEO_RENDERER (self), NULL);
172
173   g_object_get (self, "widget", &widget, NULL);
174
175   return widget;
176 }