从appsink解析数据时出现内部数据流错误

时间:2014-03-25 21:33:14

标签: c gstreamer

我正在使用gstreamer 1.0编写C应用程序

我将alsa音频源录制到appsink中,以便解析数据,然后再显示图表。

初始化gst_init

后,在main中调用create_loop()函数

我遇到的问题是两次收到样品后 我收到错误内部数据流错误。

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

当我多次运行它有时它可以正常工作但大部分时间它在2次迭代后停止。我甚至尝试使用audiotestsrc而不是alsasrc,我也遇到了同样的问题。

这是代码:

#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);

}

为何会发生这种想法?

1 个答案:

答案 0 :(得分:2)

对new-event的回调函数,应返回GSTFlowReturn类型,其值为GST_FLOW_OK

表示:

函数定义为:

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

并以:

结束
return GST_FLOW_OK;