该错误背后的原因是什么?我该如何解决?
感谢所有回应。 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运行代码,但找不到任何有用的东西。您可以在下面找到调试输出。 调试: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