mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
gst: Update for the GstBaseTransform::transform_caps() changes
This commit is contained in:
parent
8501753033
commit
d8e0af1fc1
4 changed files with 170 additions and 155 deletions
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue