2 * Copyright (C) <2011> Sebastian Dröge <sebastian.droege@collabora.co.uk>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 #include "gstplaysinkvideoconvert.h"
26 #include <gst/pbutils/pbutils.h>
27 #include <gst/gst-i18n-plugin.h>
29 GST_DEBUG_CATEGORY_STATIC (gst_play_sink_video_convert_debug);
30 #define GST_CAT_DEFAULT gst_play_sink_video_convert_debug
32 #define parent_class gst_play_sink_video_convert_parent_class
34 G_DEFINE_TYPE (GstPlaySinkVideoConvert, gst_play_sink_video_convert,
35 GST_TYPE_PLAY_SINK_CONVERT_BIN);
45 gst_play_sink_video_convert_add_conversion_elements (GstPlaySinkVideoConvert *
48 GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
49 GstElement *el, *prev = NULL;
51 g_assert (cbin->conversion_elements == NULL);
53 GST_DEBUG_OBJECT (self,
54 "Building video conversion with use-converters %d, use-balance %d",
55 self->use_converters, self->use_balance);
57 if (self->use_converters) {
58 el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
63 el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
64 "videoscale", "scale");
66 /* Add black borders if necessary to keep the DAR */
67 g_object_set (el, "add-borders", TRUE, NULL);
69 if (!gst_element_link_pads_full (prev, "src", el, "sink",
70 GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
77 if (self->use_balance && self->balance) {
79 gst_play_sink_convert_bin_add_conversion_element (cbin, el);
81 if (!gst_element_link_pads_full (prev, "src", el, "sink",
82 GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
87 el = gst_play_sink_convert_bin_add_conversion_element_factory (cbin,
90 if (!gst_element_link_pads_full (prev, "src", el, "sink",
91 GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
105 gst_play_sink_video_convert_finalize (GObject * object)
107 GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
110 gst_object_unref (self->balance);
112 G_OBJECT_CLASS (parent_class)->finalize (object);
116 gst_play_sink_video_convert_set_property (GObject * object, guint prop_id,
117 const GValue * value, GParamSpec * pspec)
119 GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
120 gboolean v, changed = FALSE;
122 GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
124 case PROP_USE_CONVERTERS:
125 v = g_value_get_boolean (value);
126 if (v != self->use_converters) {
127 self->use_converters = v;
131 case PROP_USE_BALANCE:
132 v = g_value_get_boolean (value);
133 if (v != self->use_balance) {
134 self->use_balance = v;
143 GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
144 GST_DEBUG_OBJECT (self, "Rebuilding converter bin");
145 gst_play_sink_convert_bin_remove_elements (cbin);
146 gst_play_sink_video_convert_add_conversion_elements (self);
147 gst_play_sink_convert_bin_add_identity (cbin);
148 gst_play_sink_convert_bin_cache_converter_caps (cbin);
150 GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
154 gst_play_sink_video_convert_get_property (GObject * object, guint prop_id,
155 GValue * value, GParamSpec * pspec)
157 GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (object);
159 GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
161 case PROP_USE_CONVERTERS:
162 g_value_set_boolean (value, self->use_converters);
164 case PROP_USE_BALANCE:
165 g_value_set_boolean (value, self->use_balance);
170 GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
174 gst_play_sink_video_convert_class_init (GstPlaySinkVideoConvertClass * klass)
176 GObjectClass *gobject_class;
177 GstElementClass *gstelement_class;
179 GST_DEBUG_CATEGORY_INIT (gst_play_sink_video_convert_debug,
180 "playsinkvideoconvert", 0, "play bin");
182 gobject_class = (GObjectClass *) klass;
183 gstelement_class = (GstElementClass *) klass;
185 gobject_class->finalize = gst_play_sink_video_convert_finalize;
186 gobject_class->set_property = gst_play_sink_video_convert_set_property;
187 gobject_class->get_property = gst_play_sink_video_convert_get_property;
189 g_object_class_install_property (gobject_class, PROP_USE_CONVERTERS,
190 g_param_spec_boolean ("use-converters", "Use converters",
191 "Whether to use conversion elements", FALSE,
192 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
194 g_object_class_install_property (gobject_class, PROP_USE_BALANCE,
195 g_param_spec_boolean ("use-balance", "Use balance",
196 "Whether to use a videobalance element", FALSE,
197 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
199 gst_element_class_set_static_metadata (gstelement_class,
200 "Player Sink Video Converter", "Video/Bin/Converter",
201 "Convenience bin for video conversion",
202 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
206 gst_play_sink_video_convert_init (GstPlaySinkVideoConvert * self)
208 GstPlaySinkConvertBin *cbin = GST_PLAY_SINK_CONVERT_BIN (self);
211 /* FIXME: Only create this on demand but for now we need
212 * it to always exist because of playsink's color balance
215 self->balance = gst_element_factory_make ("videobalance", "videobalance");
217 gst_object_ref_sink (self->balance);
219 gst_play_sink_video_convert_add_conversion_elements (self);
220 gst_play_sink_convert_bin_cache_converter_caps (cbin);