From d8e0af1fc1e753358b7de1643153c970e653f3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 27 May 2011 12:13:14 +0200 Subject: [PATCH] gst: Update for the GstBaseTransform::transform_caps() changes --- gst/audioconvert/gstaudioconvert.c | 231 +++++++++++---------- gst/audioresample/gstaudioresample.c | 40 ++-- gst/ffmpegcolorspace/gstffmpegcolorspace.c | 34 +-- gst/videoscale/gstvideoscale.c | 20 +- 4 files changed, 170 insertions(+), 155 deletions(-) diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index 3c7084d9eb..b3250a7609 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -490,7 +490,8 @@ strip_width_64 (GstStructure * s) /* Little utility function to create a related structure for float/int */ static void -append_with_other_format (GstCaps * caps, GstStructure * s, gboolean isfloat) +append_with_other_format (GstCaps * caps, const GstStructure * s, + gboolean isfloat) { GstStructure *s2; @@ -501,12 +502,12 @@ append_with_other_format (GstCaps * caps, GstStructure * s, gboolean isfloat) /* If 64 bit float was allowed; remove width 64: we don't support it for * integer*/ strip_width_64 (s2); - gst_caps_append_structure (caps, s2); + gst_caps_merge_structure (caps, s2); } else { s2 = gst_structure_copy (s); gst_structure_set_name (s2, "audio/x-raw-float"); make_lossless_changes (s2, TRUE); - gst_caps_append_structure (caps, s2); + gst_caps_merge_structure (caps, s2); } } @@ -567,135 +568,137 @@ gst_audio_convert_transform_caps (GstBaseTransform * base, "width", "depth", "rate", "channels", "endianness", "signed" }; const gchar *structure_name; + gint n, j; int i; - g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL); - - structure = gst_caps_get_structure (caps, 0); - structure_name = gst_structure_get_name (structure); - - isfloat = strcmp (structure_name, "audio/x-raw-float") == 0; - - /* We operate on a version of the original structure with any additional - * fields absent */ - s = gst_structure_empty_new (structure_name); - for (i = 0; i < sizeof (fields_used) / sizeof (*fields_used); i++) { - if (gst_structure_has_field (structure, fields_used[i])) - gst_structure_set_value (s, fields_used[i], - gst_structure_get_value (structure, fields_used[i])); - } - - if (!isfloat) { - /* Commonly, depth is left out: set it equal to width if we have a fixed - * width, if so */ - if (!gst_structure_has_field (s, "depth") && - gst_structure_get_int (s, "width", &width)) - gst_structure_set (s, "depth", G_TYPE_INT, width, NULL); - } + n = gst_caps_get_size (caps); ret = gst_caps_new_empty (); - /* All lossless conversions */ - s = make_lossless_changes (s, isfloat); - gst_caps_append_structure (ret, s); + for (j = 0; j < n; j++) { + structure = gst_caps_get_structure (caps, j); + structure_name = gst_structure_get_name (structure); - /* Same, plus a float<->int conversion */ - append_with_other_format (ret, s, isfloat); - GST_DEBUG_OBJECT (base, " step1: (%d) %" GST_PTR_FORMAT, - gst_caps_get_size (ret), ret); + isfloat = strcmp (structure_name, "audio/x-raw-float") == 0; - /* We don't mind increasing width/depth/channels, but reducing them is - * Very Bad. Only available if width, depth, channels are already fixed. */ - s = gst_structure_copy (s); - if (!isfloat) { - if (gst_structure_get_int (structure, "width", &width)) - set_structure_widths (s, width, 32); - if (gst_structure_get_int (structure, "depth", &depth)) { - if (depth == 32) - gst_structure_set (s, "depth", G_TYPE_INT, 32, NULL); - else - gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, depth, 32, NULL); + /* We operate on a version of the original structure with any additional + * fields absent */ + s = gst_structure_empty_new (structure_name); + for (i = 0; i < sizeof (fields_used) / sizeof (*fields_used); i++) { + if (gst_structure_has_field (structure, fields_used[i])) + gst_structure_set_value (s, fields_used[i], + gst_structure_get_value (structure, fields_used[i])); } - } - allow_mixing = TRUE; - if (gst_structure_get_int (structure, "channels", &channels)) { - gboolean unpositioned; + if (!isfloat) { + /* Commonly, depth is left out: set it equal to width if we have a fixed + * width, if so */ + if (!gst_structure_has_field (s, "depth") && + gst_structure_get_int (s, "width", &width)) + gst_structure_set (s, "depth", G_TYPE_INT, width, NULL); + } - /* we don't support mixing for channels without channel positions */ - if (structure_has_fixed_channel_positions (structure, &unpositioned)) - allow_mixing = (unpositioned == FALSE); - } + /* All lossless conversions */ + s = make_lossless_changes (s, isfloat); + gst_caps_merge_structure (ret, gst_structure_copy (s)); - if (!allow_mixing) { - gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL); - if (gst_structure_has_field (structure, "channel-positions")) - gst_structure_set_value (s, "channel-positions", - gst_structure_get_value (structure, "channel-positions")); - } else { - if (channels == 0) - gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL); - else if (channels == 11) - gst_structure_set (s, "channels", G_TYPE_INT, 11, NULL); - else - gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 11, NULL); - gst_structure_remove_field (s, "channel-positions"); - } - gst_caps_append_structure (ret, s); + /* Same, plus a float<->int conversion */ + append_with_other_format (ret, s, isfloat); + GST_DEBUG_OBJECT (base, " step1: (%d) %" GST_PTR_FORMAT, + gst_caps_get_size (ret), ret); - /* Same, plus a float<->int conversion */ - append_with_other_format (ret, s, isfloat); + /* We don't mind increasing width/depth/channels, but reducing them is + * Very Bad. Only available if width, depth, channels are already fixed. */ + if (!isfloat) { + if (gst_structure_get_int (structure, "width", &width)) + set_structure_widths (s, width, 32); + if (gst_structure_get_int (structure, "depth", &depth)) { + if (depth == 32) + gst_structure_set (s, "depth", G_TYPE_INT, 32, NULL); + else + gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, depth, 32, NULL); + } + } - /* We'll reduce depth if we must. We reduce as low as 16 bits (for integer); - * reducing to less than this is even worse than dropping channels. We only - * do this if we haven't already done the equivalent above. */ - if (!gst_structure_get_int (structure, "width", &width) || width > 16) { - if (isfloat) { - GstStructure *s2 = gst_structure_copy (s); + allow_mixing = TRUE; + if (gst_structure_get_int (structure, "channels", &channels)) { + gboolean unpositioned; - set_structure_widths_32_and_64 (s2); - append_with_other_format (ret, s2, TRUE); - gst_structure_free (s2); + /* we don't support mixing for channels without channel positions */ + if (structure_has_fixed_channel_positions (structure, &unpositioned)) + allow_mixing = (unpositioned == FALSE); + } + + if (!allow_mixing) { + gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL); + if (gst_structure_has_field (structure, "channel-positions")) + gst_structure_set_value (s, "channel-positions", + gst_structure_get_value (structure, "channel-positions")); } else { - s = gst_structure_copy (s); - set_structure_widths (s, 16, 32); - gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, 16, 32, NULL); - gst_caps_append_structure (ret, s); + if (channels == 0) + gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL); + else if (channels == 11) + gst_structure_set (s, "channels", G_TYPE_INT, 11, NULL); + else + gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 11, + NULL); + gst_structure_remove_field (s, "channel-positions"); } + gst_caps_merge_structure (ret, gst_structure_copy (s)); + + /* Same, plus a float<->int conversion */ + append_with_other_format (ret, s, isfloat); + + /* We'll reduce depth if we must. We reduce as low as 16 bits (for integer); + * reducing to less than this is even worse than dropping channels. We only + * do this if we haven't already done the equivalent above. */ + if (!gst_structure_get_int (structure, "width", &width) || width > 16) { + if (isfloat) { + GstStructure *s2 = gst_structure_copy (s); + + set_structure_widths_32_and_64 (s2); + append_with_other_format (ret, s2, TRUE); + gst_structure_free (s2); + } else { + GstStructure *s2 = gst_structure_copy (s); + + set_structure_widths (s2, 16, 32); + gst_structure_set (s2, "depth", GST_TYPE_INT_RANGE, 16, 32, NULL); + gst_caps_merge_structure (ret, s2); + } + } + + /* Channel conversions to fewer channels is only done if needed - generally + * it's very bad to drop channels entirely. + */ + if (allow_mixing) { + gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL); + gst_structure_remove_field (s, "channel-positions"); + } else { + /* allow_mixing can only be FALSE if we got a fixed number of channels */ + gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL); + if (gst_structure_has_field (structure, "channel-positions")) + gst_structure_set_value (s, "channel-positions", + gst_structure_get_value (structure, "channel-positions")); + } + gst_caps_merge_structure (ret, gst_structure_copy (s)); + + /* Same, plus a float<->int conversion */ + append_with_other_format (ret, s, isfloat); + + /* And, finally, for integer only, we allow conversion to any width/depth we + * support: this should be equivalent to our (non-float) template caps. (the + * floating point case should be being handled just above) */ + set_structure_widths (s, 8, 32); + gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, 1, 32, NULL); + + if (isfloat) { + append_with_other_format (ret, s, TRUE); + gst_structure_free (s); + } else + gst_caps_merge_structure (ret, s); } - /* Channel conversions to fewer channels is only done if needed - generally - * it's very bad to drop channels entirely. - */ - s = gst_structure_copy (s); - if (allow_mixing) { - gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL); - gst_structure_remove_field (s, "channel-positions"); - } else { - /* allow_mixing can only be FALSE if we got a fixed number of channels */ - gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL); - if (gst_structure_has_field (structure, "channel-positions")) - gst_structure_set_value (s, "channel-positions", - gst_structure_get_value (structure, "channel-positions")); - } - gst_caps_append_structure (ret, s); - - /* Same, plus a float<->int conversion */ - append_with_other_format (ret, s, isfloat); - - /* And, finally, for integer only, we allow conversion to any width/depth we - * support: this should be equivalent to our (non-float) template caps. (the - * floating point case should be being handled just above) */ - s = gst_structure_copy (s); - set_structure_widths (s, 8, 32); - gst_structure_set (s, "depth", GST_TYPE_INT_RANGE, 1, 32, NULL); - - if (isfloat) { - append_with_other_format (ret, s, TRUE); - gst_structure_free (s); - } else - gst_caps_append_structure (ret, s); - GST_DEBUG_OBJECT (base, "Caps transformed to %" GST_PTR_FORMAT, ret); if (filter) { diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 6839c4d8d1..1d0462f475 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -288,30 +288,34 @@ gst_audio_resample_transform_caps (GstBaseTransform * base, const GValue *val; GstStructure *s; GstCaps *res; + gint i, n; /* transform single caps into input_caps + input_caps with the rate * field set to our supported range. This ensures that upstream knows * about downstream's prefered rate(s) and can negotiate accordingly. */ res = gst_caps_copy (caps); - /* first, however, check if the caps contain a range for the rate field, in - * which case that side isn't going to care much about the exact sample rate - * chosen and we should just assume things will get fixated to something sane - * and we may just as well offer our full range instead of the range in the - * caps. If the rate is not an int range value, it's likely to express a - * real preference or limitation and we should maintain that structure as - * preference by putting it first into the transformed caps, and only add - * our full rate range as second option */ - s = gst_caps_get_structure (res, 0); - val = gst_structure_get_value (s, "rate"); - if (val == NULL || GST_VALUE_HOLDS_INT_RANGE (val)) { - /* overwrite existing range, or add field if it doesn't exist yet */ - gst_structure_set (s, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - } else { - /* append caps with full range to existing caps with non-range rate field */ - s = gst_structure_copy (s); - gst_structure_set (s, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_append_structure (res, s); + n = gst_caps_get_size (res); + for (i = 0; i < n; i++) { + /* first, however, check if the caps contain a range for the rate field, in + * which case that side isn't going to care much about the exact sample rate + * chosen and we should just assume things will get fixated to something sane + * and we may just as well offer our full range instead of the range in the + * caps. If the rate is not an int range value, it's likely to express a + * real preference or limitation and we should maintain that structure as + * preference by putting it first into the transformed caps, and only add + * our full rate range as second option */ + s = gst_caps_get_structure (res, i); + val = gst_structure_get_value (s, "rate"); + if (val == NULL || GST_VALUE_HOLDS_INT_RANGE (val)) { + /* overwrite existing range, or add field if it doesn't exist yet */ + gst_structure_set (s, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + } else { + /* append caps with full range to existing caps with non-range rate field */ + s = gst_structure_copy (s); + gst_structure_set (s, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + gst_caps_merge_structure (res, s); + } } if (filter) { diff --git a/gst/ffmpegcolorspace/gstffmpegcolorspace.c b/gst/ffmpegcolorspace/gstffmpegcolorspace.c index 8aecc4f314..3fdb4ea471 100644 --- a/gst/ffmpegcolorspace/gstffmpegcolorspace.c +++ b/gst/ffmpegcolorspace/gstffmpegcolorspace.c @@ -100,26 +100,29 @@ static GstCaps * gst_ffmpegcsp_caps_remove_format_info (GstCaps * caps) { GstStructure *yuvst, *rgbst, *grayst; + gint i, n; - /* We know there's only one structure since we're given simple caps */ caps = gst_caps_copy (caps); - yuvst = gst_caps_get_structure (caps, 0); + n = gst_caps_get_size (caps); + for (i = 0; i < n; i++) { + yuvst = gst_caps_get_structure (caps, i); - gst_structure_set_name (yuvst, "video/x-raw-yuv"); - gst_structure_remove_fields (yuvst, "format", "endianness", "depth", - "bpp", "red_mask", "green_mask", "blue_mask", "alpha_mask", - "palette_data", NULL); + gst_structure_set_name (yuvst, "video/x-raw-yuv"); + gst_structure_remove_fields (yuvst, "format", "endianness", "depth", + "bpp", "red_mask", "green_mask", "blue_mask", "alpha_mask", + "palette_data", NULL); - rgbst = gst_structure_copy (yuvst); - gst_structure_set_name (rgbst, "video/x-raw-rgb"); - gst_structure_remove_fields (rgbst, "color-matrix", "chroma-site", NULL); + rgbst = gst_structure_copy (yuvst); + gst_structure_set_name (rgbst, "video/x-raw-rgb"); + gst_structure_remove_fields (rgbst, "color-matrix", "chroma-site", NULL); - grayst = gst_structure_copy (rgbst); - gst_structure_set_name (grayst, "video/x-raw-gray"); + grayst = gst_structure_copy (rgbst); + gst_structure_set_name (grayst, "video/x-raw-gray"); - gst_caps_append_structure (caps, rgbst); - gst_caps_append_structure (caps, grayst); + gst_caps_merge_structure (caps, rgbst); + gst_caps_merge_structure (caps, grayst); + } return caps; } @@ -136,11 +139,10 @@ gst_ffmpegcsp_transform_caps (GstBaseTransform * btrans, GstCaps *result; template = gst_static_pad_template_get_caps (&gst_ffmpegcsp_src_template); - result = gst_caps_copy (caps); /* Get all possible caps that we can transform to */ tmp = gst_ffmpegcsp_caps_remove_format_info (caps); - tmp2 = gst_caps_intersect (tmp, template); + tmp2 = gst_caps_intersect_full (tmp, template, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (tmp); tmp = tmp2; @@ -150,6 +152,8 @@ gst_ffmpegcsp_transform_caps (GstBaseTransform * btrans, tmp = tmp2; } + result = tmp; + GST_DEBUG_OBJECT (btrans, "transformed %" GST_PTR_FORMAT " into %" GST_PTR_FORMAT, caps, result); diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c index a3c4e08c9a..74f0c7940c 100644 --- a/gst/videoscale/gstvideoscale.c +++ b/gst/videoscale/gstvideoscale.c @@ -326,6 +326,7 @@ gst_video_scale_transform_caps (GstBaseTransform * trans, { GstCaps *ret; GstStructure *structure; + gint i, n; /* this function is always called with a simple caps */ g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL); @@ -335,16 +336,19 @@ gst_video_scale_transform_caps (GstBaseTransform * trans, (direction == GST_PAD_SINK) ? "sink" : "src"); ret = gst_caps_copy (caps); - structure = gst_caps_get_structure (ret, 0); + n = gst_caps_get_size (caps); + for (i = 0; i < n; i++) { + structure = gst_caps_get_structure (ret, i); - gst_structure_set (structure, - "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + gst_structure_set (structure, + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - /* if pixel aspect ratio, make a range of it */ - if (gst_structure_has_field (structure, "pixel-aspect-ratio")) { - gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, - 1, G_MAXINT, G_MAXINT, 1, NULL); + /* if pixel aspect ratio, make a range of it */ + if (gst_structure_has_field (structure, "pixel-aspect-ratio")) { + gst_structure_set (structure, "pixel-aspect-ratio", + GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL); + } } if (filter) {