1 /* GStreamer
2  * (c) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
3  * (c) 2006 Jan Schmidt <thaytan@noraisin.net>
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 /**
22  * SECTION:element-autovideosink
23  * @see_also: autoaudiosink, ximagesink, xvimagesink, sdlvideosink
24  *
25  * autovideosink is a video sink that automatically detects an appropriate
26  * video sink to use.  It does so by scanning the registry for all elements
27  * that have <quote>Sink</quote> and <quote>Video</quote> in the class field
28  * of their element information, and also have a non-zero autoplugging rank.
29  *
30  * <refsect2>
31  * <title>Example launch line</title>
32  * |[
33  * gst-launch-1.0 -v -m videotestsrc ! autovideosink
34  * ]|
35  * </refsect2>
36  */
37 
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 
42 #include "gstautovideosink.h"
43 
44 #define DEFAULT_TS_OFFSET           0
45 
46 /* Properties */
47 enum
48 {
49   PROP_0,
50   PROP_TS_OFFSET,
51 };
52 
53 static void gst_auto_video_sink_set_property (GObject * object, guint prop_id,
54     const GValue * value, GParamSpec * pspec);
55 static void gst_auto_video_sink_get_property (GObject * object, guint prop_id,
56     GValue * value, GParamSpec * pspec);
57 static void gst_auto_video_sink_configure (GstAutoDetect * autodetect,
58     GstElement * kid);
59 
60 G_DEFINE_TYPE (GstAutoVideoSink, gst_auto_video_sink, GST_TYPE_AUTO_DETECT);
61 
62 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
63     GST_PAD_SINK,
64     GST_PAD_ALWAYS,
65     GST_STATIC_CAPS_ANY);
66 
67 static void
gst_auto_video_sink_class_init(GstAutoVideoSinkClass * klass)68 gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass)
69 {
70   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
71   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
72   GstAutoDetectClass *aklass = GST_AUTO_DETECT_CLASS (klass);
73 
74   gobject_class->set_property = gst_auto_video_sink_set_property;
75   gobject_class->get_property = gst_auto_video_sink_get_property;
76 
77   aklass->configure = gst_auto_video_sink_configure;
78 
79   g_object_class_install_property (gobject_class, PROP_TS_OFFSET,
80       g_param_spec_int64 ("ts-offset", "TS Offset",
81           "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64,
82           DEFAULT_TS_OFFSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
83 
84   gst_element_class_add_static_pad_template (eklass, &sink_template);
85   gst_element_class_set_static_metadata (eklass, "Auto video sink",
86       "Sink/Video",
87       "Wrapper video sink for automatically detected video sink",
88       "Jan Schmidt <thaytan@noraisin.net>");
89 }
90 
91 static void
gst_auto_video_sink_init(GstAutoVideoSink * sink)92 gst_auto_video_sink_init (GstAutoVideoSink * sink)
93 {
94   GstAutoDetect *autodetect = GST_AUTO_DETECT (sink);
95 
96   autodetect->media_klass = "Video";
97   autodetect->flag = GST_ELEMENT_FLAG_SINK;
98 
99   sink->ts_offset = DEFAULT_TS_OFFSET;
100 }
101 
102 static void
gst_auto_video_sink_configure(GstAutoDetect * autodetect,GstElement * kid)103 gst_auto_video_sink_configure (GstAutoDetect * autodetect, GstElement * kid)
104 {
105   GstAutoVideoSink *self = GST_AUTO_VIDEO_SINK (autodetect);
106 
107   g_object_set (G_OBJECT (kid), "ts-offset", self->ts_offset, NULL);
108 }
109 
110 static void
gst_auto_video_sink_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)111 gst_auto_video_sink_set_property (GObject * object, guint prop_id,
112     const GValue * value, GParamSpec * pspec)
113 {
114   GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (object);
115   GstAutoDetect *autodetect = (GstAutoDetect *) sink;
116 
117   switch (prop_id) {
118     case PROP_TS_OFFSET:
119       sink->ts_offset = g_value_get_int64 (value);
120       if (autodetect->kid)
121         g_object_set_property (G_OBJECT (autodetect->kid), pspec->name, value);
122       break;
123     default:
124       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
125       break;
126   }
127 }
128 
129 static void
gst_auto_video_sink_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)130 gst_auto_video_sink_get_property (GObject * object, guint prop_id,
131     GValue * value, GParamSpec * pspec)
132 {
133   GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (object);
134 
135   switch (prop_id) {
136     case PROP_TS_OFFSET:
137       g_value_set_int64 (value, sink->ts_offset);
138       break;
139     default:
140       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
141       break;
142   }
143 }
144