如何修复Gstreamer AppSRC元素生成的“内部数据流错误”? 我正在尝试在琐碎的示例上使用GSTREAMER的APPSRC元素。我正在创建一个缓冲区,并用虚拟数据填充它,并试图将其发送到fakesink。该代码是water的浇水版本

问题描述 投票:0回答:0

该错误背后的原因是什么?我该如何解决?

感谢所有回应。 link:link到教程

代码:

#include <gst/gst.h> #include <glib.h> #include "glibconfig.h" #include <stdio.h> #include <string.h> #define CHUNK_SIZE 10 typedef struct gstreamstruct { GstElement *pipeline, *app_source, *fakesink; guint sourceid; /* To control the GSource */ GMainLoop *main_loop; /* GLib's Main Loop */ guint sample; } gstreamstruct; static gboolean busCall (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_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } default: break; } return TRUE; } static gboolean pushData (gstreamstruct *streamer) { printf("--->PushData!\n"); GstMapInfo map; GstBuffer *buffer; GstFlowReturn ret; guint8 *raw; int i; /* Create a new empty buffer */ buffer = gst_buffer_new_and_alloc (CHUNK_SIZE); /* Set its timestamp and duration */ GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (streamer->sample, GST_SECOND, 1000); GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (CHUNK_SIZE, GST_SECOND, 1000); //Put some dummy into buffer gst_buffer_map (buffer, &map, GST_MAP_WRITE); raw = (guint8 *)map.data; for(i = 0; i<CHUNK_SIZE; i++) { raw[0] = 0; } //update sample value streamer->sample += CHUNK_SIZE; printf("currentDuration: %d ms\n", streamer->sample); gst_buffer_unmap (buffer, &map); /* Push the buffer into the appsrc */ g_signal_emit_by_name (streamer->app_source, "push-buffer", buffer, &ret); /* Free the buffer now that we are done with it */ gst_buffer_unref (buffer); if (ret != GST_FLOW_OK) { /* We got some error, stop sending data */ printf("Data sending Failed!\n"); return FALSE; } return TRUE; } /* This signal callback triggers when appsrc needs data. * Here, we add an idle handler to the mainloop to start pushing data into the appsrc * * Whenever Gstreamer goes idle, it will call this function. Maybe we can utilize this for * G729 etc! * * */ static void startFeed (GstElement *source, guint size, gstreamstruct *streamer) { if (streamer->sourceid == 0) { g_print ("Start feeding\n"); streamer->sourceid = g_idle_add ((GSourceFunc) pushData, streamer); } } /* This callback triggers when appsrc has enough data and we can stop sending. * We remove the idle handler from the mainloop */ static void stopFeed (GstElement *source, gstreamstruct *streamer) { if (streamer->sourceid != 0) { g_print ("Stop feeding\n"); g_source_remove (streamer->sourceid); streamer->sourceid = 0; } } void appSrcTest (void* args) { printf("---> appSrcTest\n"); gstreamstruct my_streamer; GstCaps *caps; GstBus *bus; //GstPad *pad; guint bus_watch_id; memset (&my_streamer, 0, sizeof (gstreamstruct)); gst_init (NULL, NULL); my_streamer.main_loop = g_main_loop_new (NULL, FALSE); printf("Gst Initialized!\n"); my_streamer.sample = 0; my_streamer.app_source = gst_element_factory_make("appsrc", "appSrc"); my_streamer.fakesink = gst_element_factory_make("fakesink", "fakeSink"); my_streamer.pipeline = gst_pipeline_new ("g729-pipeline"); if(!my_streamer.app_source || !my_streamer.fakesink || !my_streamer.pipeline) { g_printerr ("Not all elements could be created.\n"); return; } printf("Elements Created!\n"); caps=NULL; /* caps = gst_caps_new_simple ("audio/G729", "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL); */ //g_object_set (G_OBJECT(my_streamer.app_source), "caps", caps, "format", GST_FORMAT_TIME, NULL); g_signal_connect (my_streamer.app_source, "need-data", G_CALLBACK (startFeed), &my_streamer); g_signal_connect (my_streamer.app_source, "enough-data", G_CALLBACK (stopFeed), &my_streamer); printf("Properties Set!\n"); /* we add a message handler */ bus = gst_pipeline_get_bus (GST_PIPELINE (my_streamer.pipeline)); bus_watch_id = gst_bus_add_watch (bus, busCall, my_streamer.main_loop); gst_object_unref (bus); gst_bin_add_many (GST_BIN (my_streamer.pipeline), my_streamer.app_source, my_streamer.fakesink, NULL); printf("Elements Added!\n"); printf("Pipeline Starting!\n"); gst_element_set_state (my_streamer.pipeline, GST_STATE_PLAYING); g_main_loop_run (my_streamer.main_loop); gst_element_set_state (my_streamer.pipeline, GST_STATE_NULL); gst_object_unref (my_streamer.pipeline); g_source_remove (bus_watch_id); g_main_loop_unref (my_streamer.main_loop); }
该代码的输出的生成为:

Gst Initialized! Elements Created! Properties Set! Elements Added! Pipeline Starting! Start feeding --->PushData! currentDuration: 10 ms --->PushData! currentDuration: 20 ms --->PushData! currentDuration: 30 ms --->PushData! currentDuration: 40 ms Error: Internal data stream error.

Edit:经过更多的试验,我意识到在4个块始终如一后不会产生错误。当我重新启动系统并调用该函数时,例如在156个块之后生成错误。在进行了几次尝试之后,错误启动会更早发生(例如4个块)。我也尝试使用GST_DEBUG = 2运行代码,但找不到任何有用的东西。您可以在下面找到调试输出。 调试:

---> appSrcTest Gst Initialized! Elements Created! Properties Set! Elements Added! Pipeline Starting! Start feeding --->PushData! currentDuration: 10 ms --->PushData! currentDuration: 20 ms --->PushData! currentDuration: 30 ms --->PushData! currentDuration: 40 ms --->PushData! 0:00:00.084280528 1344 0x18fa00 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop:<appSrc> error: Internal data stream error. currentDuration: 50 ms --->PushData! 0:00:00.084342504 1344 0x18fa00 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop:<appSrc> error: streaming stopped, reason not-linked (-1) currentDuration: 60 ms --->PushData! currentDuration: 70 ms Error: Internal data stream error.

Edit2:在进行进一步调试后,我意识到Fakesink元素与AppSRC没有链接。所以我通过以下行手动将它们链接

gst_element_link_pads (my_streamer.app_source, "src", my_streamer.fakesink, "sink");

我认为现在可以正常工作,在我完全验证它后,我会再次回来。
Edit3:是的,我可以确认这是问题所在。我忘了链接元素。

我忘了链接元素。以下行解决了问题。
gst_element_link_pads (my_streamer.app_source, "src", my_streamer.fakesink, "sink");

不知道如何,但是这个事情对我有用:
sudo apt删除gstreamer1.0-vaapi


gstreamer
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.