audioresample assertion failed: (out_len >= out_processed)

Maik Scholz Scholz.Maik at t-online.de
Mon Jul 11 12:23:03 UTC 2016


Hi Sebastian,
>Please try to create a (as simple as possible) testcase for reproducing
this problem.
the attached code shows the same problem compiled with gstreamer 1.8.1.

It implements a pipeline with a test noise source, a switched (5 seconds on
+ 5 seconds off) appsrc sine noise,
combined with a audiomixer.

If i run that code, then i see the exception after 10 seconds.
If I disable the "#if 1", the the code runs without exception.

My current understanding is, that the "(out_len >= out_processed)" exception
happens
when i change the caps/samplerate within a gap.

Maik

#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 (AudioSrcDataType* 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");

    GstElement* eA1 = gst_element_factory_make("audiotestsrc",NULL);
    g_object_set(eA1, "volume", 0.01, NULL);
    g_object_set(eA1, "wave", 5, NULL);
    g_object_set(eA1, "samplesperbuffer", 48000*32/1000, NULL);
    GstElement* eA2 = gst_element_factory_make("audioconvert",NULL);

    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),eA1,eA2,NULL);
    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 (eA2,"src"),
                  gst_element_request_pad
(e_mixer,gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS(e_mixer),"sink_%u"),
                                           NULL, 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 (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)%10 ) < 5 )
            {
                /* 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 + 50;
                    } else {
                        rate = 48000 - 50;
                    }
                    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;
}




--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/audioresample-assertion-failed-out-len-out-processed-tp4678533p4678595.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list