mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
audioresample: Fix buffer size transformations
When calculating the input/output buffer sizes in the transform_size function, take the number of channels into account, so we don't end up calculating a buffer size that only contains a partial number of audio frames. Also, when going from output size to input size, round down rather than up, so as to calculate the minimum number of samples that *might* yield a buffer of the intended destination size. Fixes: #580470 and #580952
This commit is contained in:
parent
d14c80b22e
commit
02a7b31f0e
1 changed files with 17 additions and 17 deletions
|
@ -525,7 +525,7 @@ gst_audio_resample_transform_size (GstBaseTransform * base,
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
guint32 ratio_den, ratio_num;
|
guint32 ratio_den, ratio_num;
|
||||||
gint inrate, outrate, gcd;
|
gint inrate, outrate, gcd;
|
||||||
gint width;
|
gint bytes_per_samp, channels;
|
||||||
|
|
||||||
GST_LOG_OBJECT (base, "asked to transform size %d in direction %s",
|
GST_LOG_OBJECT (base, "asked to transform size %d in direction %s",
|
||||||
size, direction == GST_PAD_SINK ? "SINK" : "SRC");
|
size, direction == GST_PAD_SINK ? "SINK" : "SRC");
|
||||||
|
@ -537,37 +537,37 @@ gst_audio_resample_transform_size (GstBaseTransform * base,
|
||||||
srccaps = caps;
|
srccaps = caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get sample width -> bytes_per_samp, channels, inrate, outrate */
|
||||||
ret =
|
ret =
|
||||||
gst_audio_resample_parse_caps (caps, othercaps, &width, NULL, &inrate,
|
gst_audio_resample_parse_caps (caps, othercaps, &bytes_per_samp,
|
||||||
&outrate, NULL);
|
&channels, &inrate, &outrate, NULL);
|
||||||
if (G_UNLIKELY (!ret)) {
|
if (G_UNLIKELY (!ret)) {
|
||||||
GST_ERROR_OBJECT (base, "Wrong caps");
|
GST_ERROR_OBJECT (base, "Wrong caps");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
/* Number of samples in either buffer is size / (width*channels) ->
|
||||||
|
* calculate the factor */
|
||||||
|
bytes_per_samp = bytes_per_samp * channels / 8;
|
||||||
|
/* Convert source buffer size to samples */
|
||||||
|
size /= bytes_per_samp;
|
||||||
|
|
||||||
|
/* Simplify the conversion ratio factors */
|
||||||
gcd = _gcd (inrate, outrate);
|
gcd = _gcd (inrate, outrate);
|
||||||
ratio_num = inrate / gcd;
|
ratio_num = inrate / gcd;
|
||||||
ratio_den = outrate / gcd;
|
ratio_den = outrate / gcd;
|
||||||
|
|
||||||
if (direction == GST_PAD_SINK) {
|
if (direction == GST_PAD_SINK) {
|
||||||
gint fac = width / 8;
|
/* asked to convert size of an incoming buffer. Round up the output size */
|
||||||
|
|
||||||
/* asked to convert size of an incoming buffer */
|
|
||||||
size /= fac;
|
|
||||||
*othersize = (size * ratio_den + ratio_num - 1) / ratio_num;
|
*othersize = (size * ratio_den + ratio_num - 1) / ratio_num;
|
||||||
*othersize *= fac;
|
*othersize *= bytes_per_samp;
|
||||||
size *= fac;
|
|
||||||
} else {
|
} else {
|
||||||
gint fac = width / 8;
|
/* asked to convert size of an outgoing buffer. Round down the input size */
|
||||||
|
*othersize = (size * ratio_num) / ratio_den;
|
||||||
/* asked to convert size of an outgoing buffer */
|
*othersize *= bytes_per_samp;
|
||||||
size /= fac;
|
|
||||||
*othersize = (size * ratio_num + ratio_den - 1) / ratio_den;
|
|
||||||
*othersize *= fac;
|
|
||||||
size *= fac;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (base, "transformed size %d to %d", size, *othersize);
|
GST_LOG_OBJECT (base, "transformed size %d to %d", size * bytes_per_samp,
|
||||||
|
*othersize);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue