summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2012-01-02 17:28:12 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2012-01-02 17:28:12 +0100
commitf4e58e3e8e34afbe6754afc40add02da81e28f97 (patch)
treefd802003a2e2ea59f4d0aaec0a76841f99102809
parent2f3cf3a7eeea409b1cdfa1b39b3486289a72ded4 (diff)
videorate: fix caps negotiation function
-rw-r--r--gst/videorate/gstvideorate.c147
1 files changed, 80 insertions, 67 deletions
diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c
index 57d5071e6..d0d5aeeaf 100644
--- a/gst/videorate/gstvideorate.c
+++ b/gst/videorate/gstvideorate.c
@@ -365,80 +365,92 @@ gst_video_rate_transform_caps (GstBaseTransform * trans,
{
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)
+ gst_caps_merge_structure (ret, s1);
+ gst_caps_merge_structure (ret, s2);
+ if (s3 != NULL)
+ 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;
}
@@ -453,6 +465,7 @@ gst_video_rate_fixate_caps (GstBaseTransform * trans,
if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
return;
+ gst_caps_truncate (othercaps);
s = gst_caps_get_structure (othercaps, 0);
gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);
}