From: <ms...@fr...> - 2005-10-26 16:26:58
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: msmith Date: Wed Oct 26 2005 09:26:56 PDT Log message: * gst/audioconvert/audioconvert.c: (audio_convert_clean_context): When clearing an audioconvert context, set tmpbufsize to zero, so we'll allocate it again later if required. This fixes audioconvert re-negotiating formats, which previously segfaulted with a NULL destination buffer. Modified files: . : ChangeLog gst/audioconvert: audioconvert.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2025&r2=1.2026 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/audioconvert/audioconvert.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2025 retrieving revision 1.2026 diff -u -d -r1.2025 -r1.2026 --- ChangeLog 26 Oct 2005 14:19:21 -0000 1.2025 +++ ChangeLog 26 Oct 2005 16:26:44 -0000 1.2026 @@ -1,3 +1,11 @@ +2005-10-26 Michael Smith <ms...@fl...> + + * gst/audioconvert/audioconvert.c: (audio_convert_clean_context): + When clearing an audioconvert context, set tmpbufsize to zero, so + we'll allocate it again later if required. + This fixes audioconvert re-negotiating formats, which previously + segfaulted with a NULL destination buffer. 2005-10-26 Zeeshan Ali <ze...@gm...> * gst-libs/gst/rtp/gstbasertpdepayload.c: Index: audioconvert.c RCS file: /cvs/gstreamer/gst-plugins-base/gst/audioconvert/audioconvert.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- audioconvert.c 13 Oct 2005 11:36:14 -0000 1.7 +++ audioconvert.c 26 Oct 2005 16:26:44 -0000 1.8 @@ -272,6 +272,7 @@ g_free (ctx->tmpbuf); ctx->tmpbuf = NULL; + ctx->tmpbufsize = 0; return TRUE; } |
From: <ms...@ke...> - 2006-05-29 11:05:06
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: msmith Date: Mon May 29 2006 11:05:00 UTC Log message: * gst/audioconvert/gstaudioconvert.c: (make_lossless_changes), (append_with_other_format), (set_structure_widths), (gst_audio_convert_transform_caps): Patch from #341562: give more specific audio caps in get_caps, so that basetransform can make better decisions on what caps to negotiate. Modified files: . : ChangeLog gst/audioconvert: gstaudioconvert.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2673&r2=1.2674 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/audioconvert/gstaudioconvert.c.diff?r1=1.101&r2=1.102 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2673 retrieving revision 1.2674 diff -u -d -r1.2673 -r1.2674 --- ChangeLog 28 May 2006 20:04:12 -0000 1.2673 +++ ChangeLog 29 May 2006 11:04:47 -0000 1.2674 @@ -1,3 +1,12 @@ +2006-05-29 Michael Smith <ms...@fl...> + + * gst/audioconvert/gstaudioconvert.c: (make_lossless_changes), + (append_with_other_format), (set_structure_widths), + (gst_audio_convert_transform_caps): + Patch from #341562: give more specific audio caps in get_caps, so + that basetransform can make better decisions on what caps to + negotiate. 2006-05-28 Stefan Kost <en...@us...> * tests/check/elements/volume.c: Index: gstaudioconvert.c RCS file: /cvs/gstreamer/gst-plugins-base/gst/audioconvert/gstaudioconvert.c,v retrieving revision 1.101 retrieving revision 1.102 diff -u -d -r1.101 -r1.102 --- gstaudioconvert.c 28 Apr 2006 19:46:36 -0000 1.101 +++ gstaudioconvert.c 29 May 2006 11:04:48 -0000 1.102 @@ -156,8 +156,6 @@ static GstAudioChannelPosition *supported_positions; -static GstStaticCaps gst_audio_convert_static_caps = STATIC_CAPS; - static GstStaticPadTemplate gst_audio_convert_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, @@ -318,37 +316,224 @@ } } -/* audioconvert can convert anything except sample rate; so return template - * caps with rate fixed */ -/* FIXME: - * it would be smart here to return the caps with the same width as the first +/* Modify the structure so that things that must always have a single + * value (for float), or can always be losslessly converted (for int), have + * appropriate values. + */ +static GstStructure * +make_lossless_changes (GstStructure * s, gboolean isfloat) +{ + if (isfloat) { + /* float doesn't have depth, and only supports width 32, and native-endian + */ + gst_structure_remove_field (s, "depth"); + gst_structure_set (s, "width", G_TYPE_INT, 32, NULL); + gst_structure_set (s, "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL); + } else { + /* int supports either endian, and signed or unsigned. GValues are a pain */ + GValue list = { 0 }; + GValue val = { 0 }; + int i; + gint endian[] = { G_LITTLE_ENDIAN, G_BIG_ENDIAN }; + gboolean booleans[] = { TRUE, FALSE }; + g_value_init (&list, GST_TYPE_LIST); + g_value_init (&val, G_TYPE_INT); + for (i = 0; i < 2; i++) { + g_value_set_int (&val, endian[i]); + gst_value_list_append_value (&list, &val); + } + gst_structure_set_value (s, "endianness", &list); + g_value_unset (&val); + g_value_unset (&list); + g_value_init (&val, G_TYPE_BOOLEAN); + g_value_set_boolean (&val, booleans[i]); + gst_structure_set_value (s, "signed", &list); + } + return s; +} +/* Little utility function to create a related structure for float/int */ +static void +append_with_other_format (GstCaps * caps, GstStructure * s, gboolean isfloat) + GstStructure *s2; + s2 = gst_structure_copy (s); + gst_structure_set_name (s2, "audio/x-raw-int"); + s = make_lossless_changes (s2, FALSE); + gst_caps_append_structure (caps, s2); + gst_structure_set_name (s2, "audio/x-raw-float"); + s = make_lossless_changes (s2, TRUE); +/* Set widths (a list); multiples of 8 between min and max */ +set_structure_widths (GstStructure * s, int min, int max) + GValue list = { 0 }; + GValue val = { 0 }; + int width; + if (min == max) { + gst_structure_set (s, "width", G_TYPE_INT, min, NULL); + return; + g_value_init (&list, GST_TYPE_LIST); + g_value_init (&val, G_TYPE_INT); + for (width = min; width <= max; width += 8) { + g_value_set_int (&val, width); + gst_value_list_append_value (&list, &val); + GST_DEBUG ("Appended width %d to widths available", width); + gst_structure_set_value (s, "width", &list); + g_value_unset (&val); + g_value_unset (&list); +/* Audioconvert can perform all conversions on audio except for resampling. + * However, there are some conversions we _prefer_ not to do. For example, it's + * better to convert format (float<->int, endianness, etc) than the number of + * channels, as the latter conversion is not lossless. + * + * So, we return, in order (assuming input caps have only one structure; + * is this right?): +* - input caps with a different format (lossless conversions). + * - input caps with a different format (slightly lossy conversions). + * - input caps with a different number of channels (very lossy!) */ static GstCaps * gst_audio_convert_transform_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps) { - int i; - const GValue *rate; GstCaps *ret; - GstStructure *structure; + GstStructure *s, *structure; + gboolean isfloat; + gint width, depth, channels; + gchar *fields_used[] = { "width", "depth", "rate", "channels", "endianness", + "signed" + }; + int i; g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL); structure = gst_caps_get_structure (caps, 0); - ret = gst_static_caps_get (&gst_audio_convert_static_caps); + isfloat = strcmp (gst_structure_get_name (structure), + "audio/x-raw-float") == 0; - /* if rate not set, we return the template */ - if (!(rate = gst_structure_get_value (structure, "rate"))) - return ret; + /* We operate on a version of the original structure with any additional + * fields absent */ + s = gst_structure_empty_new (gst_structure_get_name (structure)); + 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])); - /* else, write rate in the template caps */ - ret = gst_caps_make_writable (ret); + 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); - for (i = 0; i < gst_caps_get_size (ret); ++i) { - structure = gst_caps_get_structure (ret, i); - gst_structure_set_value (structure, "rate", rate); + ret = gst_caps_new_empty (); + /* All lossless conversions */ + s = make_lossless_changes (s, isfloat); + gst_caps_append_structure (ret, s); + /* 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. */ + s = gst_structure_copy (s); + 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); + if (gst_structure_get_int (structure, "channels", &channels)) { + if (channels == 8) + gst_structure_set (s, "channels", G_TYPE_INT, 8, NULL); + else + gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 8, NULL); + /* We'll reduce depth if we must... only for integer, since we can't do this + * for float. We reduce as low as 16 bits; 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) { + /* These are invalid widths/depths for float, but we don't actually use + * them - we just pass it to append_with_other_format, which makes them + * valid + */ + GstStructure *s2 = gst_structure_copy (s); + set_structure_widths (s2, 16, 32); + gst_structure_set (s2, "depth", GST_TYPE_INT_RANGE, 16, 32, NULL); + append_with_other_format (ret, s2, TRUE); + gst_structure_free (s2); + } 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); + /* Channel conversions to fewer channels is only done if needed - generally + * it's very bad to drop channels entirely. + */ + gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 8, NULL); + /* 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); + append_with_other_format (ret, s, TRUE); + gst_structure_free (s); + } else + gst_caps_append_structure (ret, s); return ret; |