[Bug 768836] New: audioresample crash when sample rate changes within a buffer gap
GStreamer (GNOME Bugzilla)
bugzilla at gnome.org
Fri Jul 15 08:54:56 UTC 2016
https://bugzilla.gnome.org/show_bug.cgi?id=768836
Bug ID: 768836
Summary: audioresample crash when sample rate changes within a
buffer gap
Classification: Platform
Product: GStreamer
Version: 1.8.2
OS: Linux
Status: NEW
Severity: critical
Priority: Normal
Component: gst-plugins-base
Assignee: gstreamer-bugs at lists.freedesktop.org
Reporter: Scholz.Maik at t-online.de
QA Contact: gstreamer-bugs at lists.freedesktop.org
GNOME version: ---
Hi,
In my application, I need to change the audio samplerate dynamical during
runtime.
My code crashes with "audioresample assertion failed: (out_len >=
out_processed)", when I change the sink pad sample rate while a GAP is active.
related GStreamer-devel discussion:
===================================
http://gstreamer-devel.966125.n4.nabble.com/audioresample-assertion-failed-out-len-gt-out-processed-td4678533.html
Comment from S. Dröge:
I didn't look closely at your code (or the crash), but I can confirm
that it crashes like that with 1.8 but it doesn't seem to crash at all
here with 1.9.1. It is also using a completely new resampler, so that's
not too surprising.
Test Results:
=============
with 1.4.5:
rate change not audible, no crash, but GStreamer-CRITICAL **:
gst_buffer_resize_range: assertion 'bufmax >= bufoffs + offset + size' failed
with 1.6.4:
rate change not audible, no crash, but GStreamer-CRITICAL **:
gst_buffer_resize_range: assertion 'bufmax >= bufoffs + offset + size' failed
with 1.8.1 & 1.8.2:
./test
src=120ms sink=120ms set audioresample input rate to 47950
src=1200ms sink=1200ms set audioresample input rate to 48050
src=2279ms sink=2280ms set audioresample input rate to 47950
src=3360ms sink=3360ms set audioresample input rate to 48050
src=4439ms sink=4440ms set audioresample input rate to 47950
ERROR:gstaudioresample.c:1125:gst_audio_resample_process: assertion failed:
(out_len >= out_processed)
with 1.9.1:
no crash but "WARN audio-resampler
audio-resampler.c:362:convert_taps_gint16_c: can't find exact taps" on each
rate change
test.c Compiled with:
=====================
gcc -o test `pkg-config --cflags --libs gstreamer-base-1.0 gstreamer-audio-1.0
gstreamer-1.0 gstreamer-app-1.0 gstreamer-plugins-good-1.0 gstreamer-audio-1.0`
test.c -lm `pkg-config --libs gstreamer-base-1.0 gstreamer-audio-1.0
gstreamer-1.0 gstreamer-app-1.0 gstreamer-plugins-good-1.0 gstreamer-audio-1.0`
test.c:
=======
#include <stdio.h>
#include <math.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/gstcaps.h>
#define TESTCAPS
"audio/x-raw,format=S16LE,channels=2,rate=48000,layout=interleaved"
GstPad* eB3_sink_pad;
GstClockTime eB3_sink_time = 0;
GstPad* eB3_src_pad;
GstClockTime eB3_src_time = 0;
GstClockTime eB3_next_src_time = 0;
typedef struct
{
GstElement* e;
guint frequency;
guint samplerate;
guint period;
GstClockTime src_timestamp;
gboolean gap;
} AudioSrcDataType;
gboolean appsrc_feed_function (void* me);
GstPadProbeReturn audioresample_pad_probe (GstPad *pad,
GstPadProbeInfo *info,
gpointer user_data);
/* Main */
int main(void)
{
gst_init(NULL, NULL);
GstElement* p = gst_pipeline_new("pipeline");
AudioSrcDataType live_audio_B = {NULL,300,48000,120,0,TRUE};
live_audio_B.e = gst_element_factory_make("appsrc",NULL);
gst_app_src_set_caps(GST_APP_SRC(live_audio_B.e),gst_caps_from_string(TESTCAPS));
gst_base_src_set_live(GST_BASE_SRC(live_audio_B.e),TRUE);
g_object_set (G_OBJECT(GST_APP_SRC(live_audio_B.e)), "format",
GST_FORMAT_TIME, NULL);
g_object_set (G_OBJECT(GST_APP_SRC(live_audio_B.e)), "block", FALSE, NULL);
gst_app_src_set_stream_type(GST_APP_SRC(live_audio_B.e),GST_APP_STREAM_TYPE_STREAM);
gst_app_src_set_latency(GST_APP_SRC(live_audio_B.e),1*live_audio_B.period*GST_MSECOND,1*live_audio_B.period*GST_MSECOND);
g_timeout_add (live_audio_B.period/2,appsrc_feed_function,&live_audio_B);
GstElement* eB2 = gst_element_factory_make("audiorate",NULL);
g_object_set(eB2, "tolerance", (120+10)*GST_MSECOND, NULL);
GstElement* eB3 = gst_element_factory_make("audioresample",NULL);
g_object_set(eB3, "quality", 4, NULL);
g_object_set(eB3, "sinc-filter-mode", 2, NULL);
GstElement* e_mixer = gst_element_factory_make("audiomixer",NULL);
g_object_set(e_mixer, "latency", 512*GST_MSECOND, NULL);
GstElement* e_sink = gst_element_factory_make("autoaudiosink",NULL);
/* add ... */
gst_bin_add_many(GST_BIN(p),live_audio_B.e,eB2,/*eB3,*/eB3,NULL);
gst_bin_add_many(GST_BIN(p),e_mixer,e_sink,NULL);
/* link ... */
//gst_element_link_filtered(eA1, eA2, gst_caps_from_string(TESTCAPS));
gst_element_link_many(live_audio_B.e, eB2, eB3, NULL);
gst_pad_link (gst_element_get_static_pad (eB3,"src"),
gst_element_request_pad
(e_mixer,gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS(e_mixer),"sink_%u"),
NULL, NULL));
gst_element_link_many(e_mixer, e_sink, NULL);
#if 1 /* Enable audioresample control loop, if disabled, the error does not
ocure */
{
eB3_sink_pad = gst_element_get_static_pad (eB3, "sink");
gst_pad_add_probe
(eB3_sink_pad,GST_PAD_PROBE_TYPE_BUFFER,(GstPadProbeCallback)
audioresample_pad_probe,NULL,NULL);
eB3_src_pad = gst_element_get_static_pad (eB3, "src");
gst_pad_add_probe
(eB3_src_pad,GST_PAD_PROBE_TYPE_BUFFER,(GstPadProbeCallback)
audioresample_pad_probe,NULL,NULL);
}
#endif
/* run ... */
{
static GMainLoop *loop;
loop = g_main_loop_new(NULL, FALSE);
gst_element_set_state(GST_ELEMENT(p), GST_STATE_PLAYING);
g_main_loop_run(loop);
}
return 0;
}
/* timer based appsrc feed function.
* 5 seconds sine + 5 seconds gap
*/
gboolean appsrc_feed_function (void* _me)
{
AudioSrcDataType* me = (AudioSrcDataType*)_me;
if( GST_BASE_SRC_IS_STARTED(me->e) )
{
GstClockTime t_now;
while( ( t_now =
gst_clock_get_time(gst_element_get_clock(GST_ELEMENT(me->e)))-gst_element_get_base_time(GST_ELEMENT(me->e)))
> me->src_timestamp )
{
GstMapInfo buffer_info; guint i;
guint buffer_size =
2*sizeof(gint16)*me->samplerate*me->period/1000;
GstBuffer* buffer = gst_buffer_new_and_alloc(buffer_size);
if( gst_buffer_map(buffer,&buffer_info,GST_MAP_WRITE) )
{
gst_buffer_ref(buffer);
for(i=0;i<(buffer_size/sizeof(gint16));)
{
static glong t=0;
gint16 v =
(gint16)(1000.0*sin(me->frequency*(t++)*2*3.14/me->samplerate));
((gint16*)(buffer_info.data))[i++] = v;
((gint16*)(buffer_info.data))[i++] = v;
}
GST_BUFFER_PTS(buffer) = t_now;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
//GST_BUFFER_DURATION (buffer) = me->period * GST_MSECOND;
me->src_timestamp += me->period*GST_MSECOND;
gst_buffer_unmap(buffer,&buffer_info);
}
if( (GST_TIME_AS_SECONDS(t_now)%20 ) < 10 )
{
/* 5 seconds push audio to pipeline */
if(me->gap)
{
me->gap = FALSE;
GST_BUFFER_FLAG_SET(buffer,GST_BUFFER_FLAG_RESYNC);
}
if( gst_app_src_push_buffer(GST_APP_SRC(me->e),buffer) !=
GST_FLOW_OK )
{
gst_buffer_unref (buffer);
}
}
else
{
/* 5 seconds GAP */
gst_buffer_unref (buffer);
if(!me->gap)
{
me->gap = TRUE;
}
gst_pad_push_event(GST_BASE_SRC_PAD(me->e),gst_event_new_gap(t_now,GST_CLOCK_TIME_NONE));
}
}
}
return TRUE;
}
/* audioresample PAD prob
*/
GstPadProbeReturn audioresample_pad_probe (GstPad *pad,
GstPadProbeInfo *info,
gpointer user_data)
{
(void)user_data;
if(((info->type&GST_PAD_PROBE_TYPE_BUFFER)!=0)&&(info->data != NULL))
{
if( pad == eB3_sink_pad )
{
eB3_sink_time = GST_BUFFER_TIMESTAMP(GST_BUFFER(info->data));
}
else if( pad == eB3_src_pad )
{
eB3_src_time = GST_BUFFER_TIMESTAMP(GST_BUFFER(info->data));
if(( eB3_next_src_time < eB3_src_time
)&&(GST_PAD_STREAM_TRYLOCK(eB3_sink_pad)))
{
gint rate;
GstCaps* caps = gst_pad_get_current_caps(eB3_sink_pad);
GstStructure* structure;
caps = gst_caps_make_writable(caps);
structure = gst_caps_get_structure(caps,0);
if (gst_structure_get_int (structure, "rate", &rate) )
{
if( eB3_src_time > eB3_sink_time ) {
rate = 48000 + 8;
} else {
rate = 48000 - 8;
}
printf("src=%dms sink=%dms set audioresample input rate to
%d\n",
(gint)GST_TIME_AS_MSECONDS(eB3_src_time),
(gint)GST_TIME_AS_MSECONDS(eB3_sink_time),
rate);
gst_caps_set_simple(caps,"rate",G_TYPE_INT,rate,NULL);
gst_pad_set_caps(eB3_sink_pad,caps);
gst_pad_send_event (eB3_sink_pad, gst_event_new_caps
(caps));
}
eB3_next_src_time = eB3_src_time + 1000 * GST_MSECOND; /* next
adjustment in 5 seconds */
GST_PAD_STREAM_UNLOCK(eB3_sink_pad);
}
}
}
return GST_PAD_PROBE_OK;
}
--
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