문제

I'm writing a C application with gstreamer 1.0

I'm recording an alsa audio source into an appsink in order to parse the data and later on display a graph.

the create_loop() function is called in main after initializing gst_init

the problem that I encounter is that after two times the samples are received i get the error Internal data flow error.

new sample
buffer size 1280
new sample
buffer size 1280
debug: gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:audio-player/GstAlsaSrc:alsasrc0:
streaming task paused, reason custom-error (-335484816)
Error: Internal data flow error.
Returned, stopping playback
Deleting pipeline

when i run it many times sometimes it works properly but most of the times it stops after 2 iterations. i even tried using audiotestsrc instead of alsasrc and I got the same problem.

this is the code:

#include <gst/gst.h>
#include <glib.h>
#include <gst/app/gstappsink.h>

static gboolean
bus_call (GstBus *bus, GstMessage *msg, gpointer data)  
{

    GMainLoop *loop = (GMainLoop *) data;
    switch (GST_MESSAGE_TYPE (msg)) {

        case GST_MESSAGE_EOS:
          g_print ("End of stream\n");
          g_main_loop_quit (loop);
          break;

        case GST_MESSAGE_ERROR: {
          gchar  *debug;
          GError *error;

          gst_message_parse_error (msg, &error, &debug);
          g_print("debug: %s\n",debug);
          g_free (debug);

          g_printerr ("Error: %s\n", error->message);
          g_error_free (error);

          g_main_loop_quit (loop);
          break;
        }
        default:
          break;
    }

    return TRUE;
}

void new_sample(GstElement *sink, gpointer *data) {
    g_print("new sample\n");
    GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
    if (sample != NULL) {
        GstBuffer *buffer = gst_sample_get_buffer(sample); 
        GstMapInfo map;
        if (buffer != NULL) {
            gst_buffer_map(buffer, &map, GST_MAP_READ);
            g_print("buffer size %zu\n",map.size);
            gst_buffer_unmap(buffer, &map);
            gst_sample_unref(sample);

         }
    }

}


void create_loop()
{
    GMainLoop *loop;

    GstElement *pipeline, *source, *sink;
    GstBus *bus;
    guint bus_watch_id;

    loop = g_main_loop_new (NULL, FALSE);



    pipeline = gst_pipeline_new ("audio-player");
    source   = gst_element_factory_make ("alsasrc",  NULL);
    sink     = gst_element_factory_make ("appsink", NULL);

    gst_app_sink_set_emit_signals(GST_APP_SINK(sink),TRUE);
    g_signal_connect(sink, "new-sample", G_CALLBACK(new_sample),NULL);

    if (!pipeline || !source  || !sink) {
         g_printerr ("One element could not be created. Exiting.\n");
    return;
    }

    g_object_set (G_OBJECT(source),"device","hw:3,0",NULL);

    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    gst_bin_add_many (GST_BIN (pipeline),
                    source,  sink, NULL);

    gst_element_link (source, sink);
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    g_print ("Running...\n");
    g_main_loop_run (loop);

    g_print ("Returned, stopping playback\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);

    g_print ("Deleting pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));
    g_source_remove (bus_watch_id);
    g_main_loop_unref (loop);

}

any ideas why it happens?

도움이 되었습니까?

해결책

the callback function to new-event, should return a GstFlowReturn type with the value of GST_FLOW_OK

which means:

function defined as:

GstFlowReturn new_sample(GstElement *sink, gpointer *data) {
...

and ends with:

return GST_FLOW_OK;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top