[Bug 768836] audioresample crash when sample rate changes within a buffer gap (<= 1.8 only)
GStreamer (GNOME Bugzilla)
bugzilla at gnome.org
Fri Aug 12 13:48:39 UTC 2016
https://bugzilla.gnome.org/show_bug.cgi?id=768836
--- Comment #5 from Maik Scholz <Scholz.Maik at t-online.de> ---
Hi,
I did some analysis by myself.
For me (gstreamer beginner), it looks like, when the rate ratio is changed
during a gap buffer timespan. Then the out_processed calculation results into
a wrong value.
Limiting the out_processed to out_len, avoids the assert.
if( out_processed > out_len ) {
/* take care that out_processed is not greater then out_len */
out_processed = out_len;
}
But I am not sure about the side effects?
With that change, the above testcase works fine.
I will do some tests within out application.
Maik
gstaudioresample.c:
===================
static GstFlowReturn
gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstMapInfo in_map, out_map;
gsize outsize;
guint32 in_len, in_processed;
guint32 out_len, out_processed;
guint filt_len = resample->funcs->get_filt_len (resample->state);
gst_buffer_map (inbuf, &in_map, GST_MAP_READ);
gst_buffer_map (outbuf, &out_map, GST_MAP_WRITE);
in_len = in_map.size / resample->channels;
out_len = out_map.size / resample->channels;
in_len /= (resample->width / 8);
out_len /= (resample->width / 8);
in_processed = in_len;
out_processed = out_len;
if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
resample->num_nongap_samples = 0;
if (resample->num_gap_samples < filt_len) {
guint zeros_to_push;
if (in_len >= filt_len - resample->num_gap_samples)
zeros_to_push = filt_len - resample->num_gap_samples;
else
zeros_to_push = in_len;
gst_audio_resample_push_drain (resample, zeros_to_push);
in_len -= zeros_to_push;
resample->num_gap_samples += zeros_to_push;
}
{
guint num, den;
resample->funcs->get_ratio (resample->state, &num, &den);
if (resample->samples_in + in_len >= filt_len / 2)
out_processed =
gst_util_uint64_scale_int_ceil (resample->samples_in + in_len -
filt_len / 2, den, num) - resample->samples_out;
else
out_processed = 0;
=> POSSIBLE BUGFIX
if( out_processed > out_len ) {
/* take care that out_processed is not greater then out_len */
out_processed = out_len;
}
<= POSSIBLE BUGFIX
memset (out_map.data, 0, out_map.size);
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
resample->num_gap_samples += in_len;
in_processed = in_len;
}
} else { /* not a gap */
gint err;
if (resample->num_gap_samples > filt_len) {
/* push in enough zeros to restore the filter to the right offset */
guint num, den;
resample->funcs->get_ratio (resample->state, &num, &den);
gst_audio_resample_dump_drain (resample,
(resample->num_gap_samples - filt_len) % num);
}
resample->num_gap_samples = 0;
if (resample->num_nongap_samples < filt_len) {
resample->num_nongap_samples += in_len;
if (resample->num_nongap_samples > filt_len)
resample->num_nongap_samples = filt_len;
}
if (resample->funcs->width != resample->width) {
/* need to convert data format for processing; ensure we have enough
* workspace available */
if (!gst_audio_resample_workspace_realloc (&resample->tmp_in,
&resample->tmp_in_size, in_len * resample->channels *
(resample->funcs->width / 8)) ||
!gst_audio_resample_workspace_realloc (&resample->tmp_out,
&resample->tmp_out_size, out_len * resample->channels *
(resample->funcs->width / 8))) {
GST_ERROR_OBJECT (resample, "failed to allocate workspace");
gst_buffer_unmap (inbuf, &in_map);
gst_buffer_unmap (outbuf, &out_map);
return GST_FLOW_ERROR;
}
/* convert input */
gst_audio_resample_convert_buffer (resample, in_map.data,
resample->tmp_in, in_len, FALSE);
/* process */
err = resample->funcs->process (resample->state,
resample->tmp_in, &in_processed, resample->tmp_out, &out_processed);
/* convert output */
gst_audio_resample_convert_buffer (resample, resample->tmp_out,
out_map.data, out_processed, TRUE);
} else {
/* no format conversion required; process */
err = resample->funcs->process (resample->state,
in_map.data, &in_processed, out_map.data, &out_processed);
}
if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
GST_ERROR_OBJECT (resample, "Failed to convert data: %s",
resample->funcs->strerror (err));
gst_buffer_unmap (inbuf, &in_map);
gst_buffer_unmap (outbuf, &out_map);
return GST_FLOW_ERROR;
}
}
/* If we wrote more than allocated something is really wrong now and we
* should better abort immediately */
g_assert (out_len >= out_processed);
--
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.
More information about the gstreamer-bugs
mailing list