*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
static GstCaps *gst_video_rate_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
-static void gst_video_rate_fixate_caps (GstBaseTransform * trans,
+static GstCaps *gst_video_rate_fixate_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static GstFlowReturn gst_video_rate_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
static gboolean gst_video_rate_start (GstBaseTransform * trans);
+static gboolean gst_video_rate_stop (GstBaseTransform * trans);
static void gst_video_rate_set_property (GObject * object,
base_class->transform_ip = GST_DEBUG_FUNCPTR (gst_video_rate_transform_ip);
base_class->sink_event = GST_DEBUG_FUNCPTR (gst_video_rate_sink_event);
base_class->start = GST_DEBUG_FUNCPTR (gst_video_rate_start);
+ base_class->stop = GST_DEBUG_FUNCPTR (gst_video_rate_stop);
base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
1, G_MAXINT, DEFAULT_MAX_RATE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
- gst_element_class_set_details_simple (element_class,
+ gst_element_class_set_static_metadata (element_class,
"Video rate adjuster", "Filter/Effect/Video",
"Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
"Wim Taymans <wim@fluendo.com>");
{
GstVideoRate *videorate = GST_VIDEO_RATE (trans);
GstCaps *ret;
- GstStructure *s, *s2;
- GstStructure *s3 = NULL;
+ GstStructure *s, *s1, *s2, *s3 = NULL;
int maxrate = g_atomic_int_get (&videorate->max_rate);
+ gint i;
+
+ ret = gst_caps_new_empty ();
+
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ s = gst_caps_get_structure (caps, i);
+
+ s1 = gst_structure_copy (s);
+ s2 = gst_structure_copy (s);
+
+ if (videorate->drop_only) {
+ gint min_num = 0, min_denom = 1;
+ gint max_num = G_MAXINT, max_denom = 1;
+
+ /* Clamp the caps to our maximum rate as the first caps if possible */
+ if (!gst_video_max_rate_clamp_structure (s1, maxrate,
+ &min_num, &min_denom, &max_num, &max_denom)) {
+ min_num = 0;
+ min_denom = 1;
+ max_num = maxrate;
+ max_denom = 1;
+
+ /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
+ * caps should become [1..maxrate], [1..maxint] and the src caps just
+ * [1..maxrate]. In case there was a caps incompatibility things will
+ * explode later as appropriate :)
+ *
+ * In case [X..maxrate] == [X..maxint], skip as we'll set it later
+ */
+ if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
+ gst_structure_set (s1, "framerate", GST_TYPE_FRACTION_RANGE,
+ min_num, min_denom, maxrate, 1, NULL);
+ else {
+ gst_structure_free (s1);
+ s1 = NULL;
+ }
+ }
- /* Should always be called with simple caps */
- g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
-
- ret = gst_caps_copy (caps);
-
- s = gst_caps_get_structure (ret, 0);
- s2 = gst_structure_copy (s);
-
- if (videorate->drop_only) {
- gint min_num = 0, min_denom = 1;
- gint max_num = G_MAXINT, max_denom = 1;
-
- /* Clamp the caps to our maximum rate as the first caps if possible */
- if (!gst_video_max_rate_clamp_structure (s, maxrate,
- &min_num, &min_denom, &max_num, &max_denom)) {
- min_num = 0;
- min_denom = 1;
- max_num = maxrate;
- max_denom = 1;
-
- /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
- * caps should become [1..maxrate], [1..maxint] and the src caps just
- * [1..maxrate]. In case there was a caps incompatibility things will
- * explode later as appropriate :)
- *
- * In case [X..maxrate] == [X..maxint], skip as we'll set it later
- */
- if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
- gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE,
- min_num, min_denom, maxrate, 1, NULL);
- else
- gst_caps_remove_structure (ret, 0);
- }
-
- if (direction == GST_PAD_SRC) {
- /* We can accept anything as long as it's at least the minimal framerate
- * the the sink needs */
- gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
- min_num, min_denom, G_MAXINT, 1, NULL);
+ if (direction == GST_PAD_SRC) {
+ /* We can accept anything as long as it's at least the minimal framerate
+ * the the sink needs */
+ gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
+ min_num, min_denom, G_MAXINT, 1, NULL);
- /* Also allow unknown framerate, if it isn't already */
- if (min_num != 0 || min_denom != 1) {
- s3 = gst_structure_copy (s);
- gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
+ /* Also allow unknown framerate, if it isn't already */
+ if (min_num != 0 || min_denom != 1) {
+ s3 = gst_structure_copy (s);
+ gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
+ }
+ } else if (max_num != 0 || max_denom != 1) {
+ /* We can provide everything upto the maximum framerate at the src */
+ gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
+ 0, 1, max_num, max_denom, NULL);
+ }
+ } else if (direction == GST_PAD_SINK) {
+ gint min_num = 0, min_denom = 1;
+ gint max_num = G_MAXINT, max_denom = 1;
+
+ if (!gst_video_max_rate_clamp_structure (s1, maxrate,
+ &min_num, &min_denom, &max_num, &max_denom)) {
+ gst_structure_free (s1);
+ s1 = NULL;
}
- } else if (max_num != 0 || max_denom != 1) {
- /* We can provide everything upto the maximum framerate at the src */
- gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
- 0, 1, max_num, max_denom, NULL);
+ gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
+ maxrate, 1, NULL);
+ } else {
+ /* set the framerate as a range */
+ gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
+ G_MAXINT, 1, NULL);
}
- } else if (direction == GST_PAD_SINK) {
- gint min_num = 0, min_denom = 1;
- gint max_num = G_MAXINT, max_denom = 1;
-
- if (!gst_video_max_rate_clamp_structure (s, maxrate,
- &min_num, &min_denom, &max_num, &max_denom))
- gst_caps_remove_structure (ret, 0);
-
- gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
- maxrate, 1, NULL);
- } else {
- /* set the framerate as a range */
- gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
- G_MAXINT, 1, NULL);
+ if (s1 != NULL)
+ ret = gst_caps_merge_structure (ret, s1);
+ ret = gst_caps_merge_structure (ret, s2);
+ if (s3 != NULL)
+ ret = gst_caps_merge_structure (ret, s3);
}
+ if (filter) {
+ GstCaps *intersection;
- gst_caps_merge_structure (ret, s2);
- if (s3 != NULL)
- gst_caps_merge_structure (ret, s3);
-
+ intersection =
+ gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (ret);
+ ret = intersection;
+ }
return ret;
}
-static void
+static GstCaps *
gst_video_rate_fixate_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
s = gst_caps_get_structure (caps, 0);
if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
- return;
+ return othercaps;
+ othercaps = gst_caps_truncate (othercaps);
+ othercaps = gst_caps_make_writable (othercaps);
s = gst_caps_get_structure (othercaps, 0);
gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);
+
+ return othercaps;
}
static gboolean
static void
gst_video_rate_notify_drop (GstVideoRate * videorate)
{
-#if !GLIB_CHECK_VERSION(2,26,0)
- g_object_notify ((GObject *) videorate, "drop");
-#else
g_object_notify_by_pspec ((GObject *) videorate, pspec_drop);
-#endif
}
static void
gst_video_rate_notify_duplicate (GstVideoRate * videorate)
{
-#if !GLIB_CHECK_VERSION(2,26,0)
- g_object_notify ((GObject *) videorate, "duplicate");
-#else
g_object_notify_by_pspec ((GObject *) videorate, pspec_duplicate);
-#endif
}
#define MAGIC_LIMIT 25
break;
}
- return TRUE;
+ return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
/* ERRORS */
format_error:
return TRUE;
}
+static gboolean
+gst_video_rate_stop (GstBaseTransform * trans)
+{
+ gst_video_rate_reset (GST_VIDEO_RATE (trans));
+ return TRUE;
+}
+
static void
gst_video_rate_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
reconfigure:
GST_OBJECT_UNLOCK (videorate);
- gst_base_transform_reconfigure (GST_BASE_TRANSFORM (videorate));
+ gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (videorate));
}
static void
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
- "videorate",
+ videorate,
"Adjusts video frames",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)