gst: Update for the GstBaseTransform::transform_caps() changes

This commit is contained in:
Sebastian Dröge 2011-05-27 12:13:14 +02:00
parent 8501753033
commit d8e0af1fc1
4 changed files with 170 additions and 155 deletions

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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) {