使用 Appsrc Appsink 时出错
这是我第一次在 C 程序中使用 Gstreamer。我只用过管道。我正在尝试编写一个程序,该程序采用流将其存储在缓冲区中,使用 OpenCv 编辑流并使用带有 appsrc 的管道来查看流。我收到错误:
rb1:3231): GStreamer-CRITICAL **: gst_caps_get_struct: 断言`index <; caps->structs->len' 失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_has_field:断言“结构!= NULL”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_fixate_field_nearest_fraction:断言“gst_struct_has_field(结构,field_name)”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_get_fraction:断言“结构!= NULL”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_has_field:断言“结构!= NULL”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_has_field:断言“结构!= NULL”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_has_field:断言“结构!= NULL”失败
(rb1:3231):GStreamer-CRITICAL **:gst_struct_has_field:断言“结构!= NULL”失败
(rb1:3231): GStreamer-CRITICAL **: gst_pad_set_caps: 断言 `caps == NULL || gst_caps_is_fixed(大写字母)'失败
** 错误 **:未协商 正在中止... 已中止
感激。
作为参考,我给出了代码(我还没有实现 OpenCV 部分):
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappbuffer.h>
#include <gst/app/gstappsink.h>
#include <gst/gstbuffer.h>
#include <stdbool.h>
#include <stdio.h>
static GMainLoop *loop;
GstBuffer *buffer;
GstAppSinkCallbacks callbacks;
GstElement *pipeline_in;
GstElement *pipeline_out;
GstBus *bus;
GError *error;
const char app_sink_name[] = "app-sink";
const char app_src_name[] = "app-src";
const char pipeline_in_str[500];
const char pipeline_out_str[500];
static gboolean bus_call(GstBus * bus, GstMessage * msg, void *user_data)
{
gchar *userdata = (gchar *) user_data;
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS:{
//sender check - pipeline1 sends a EOS msg to AppSrc in pipeline2
if (g_ascii_strcasecmp(userdata, gst_element_get_name(pipeline_in)) == 0) {
g_print("EOS detected (%s)n", userdata);
gst_app_src_end_of_stream(GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline_out), app_src_name)));
}
//sender check - when pipeline2 sends the EOS msg, quite.
if (g_ascii_strcasecmp(userdata, gst_element_get_name(pipeline_out)) == 0) {
g_print("Finished playback (%s)n", userdata);
g_main_loop_quit(loop);
}
break;
}
case GST_MESSAGE_ERROR:{
GError *err;
gst_message_parse_error(msg, &err, NULL);
g_error("%s", err->message);
g_error_free(err);
g_main_loop_quit(loop);
break;
}
default:
break;
}
return true;
}
GstFlowReturn newbuffer(GstAppSink * app_sink, gpointer user_data)
{
GstBuffer *buffer = gst_app_sink_pull_buffer((GstAppSink *) gst_bin_get_by_name(GST_BIN(pipeline_in), app_sink_name));
gst_app_src_push_buffer(GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline_out), app_src_name)), buffer);
return GST_FLOW_OK;
}
int main(int argc, char *argv[])
{
int result;
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
pipeline_in = gst_pipeline_new("my_pipeline");
pipeline_out = gst_pipeline_new("my_pipeline2");
//result=sprintf(pipeline_in_str, "udpsrc port=5000 ! video/x-h264, width=(int)640, height=(int)480, framerate=(fraction)30/1, pixel-aspect-ratio=(fraction )1/1, codec_data=(buffer )0142c01effe100176742c01e92540501ed8088000003000bb9aca00078b17501000468ce3c80, stream-format=(string)avc, alignment=(string)au ! ffdec_h264 ! video/x-raw-yuv,width=640,height=480 ! ffmpegcolorspace ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! appsink name="%s"", app_sink_name);
result = sprintf(pipeline_in_str, "videotestsrc ! video/x-raw-rgb, width=640, height=480 ! ffmpegcolorspace ! appsink name=%s", app_sink_name);
printf("First pipeline string nn%sn", pipeline_in_str);
pipeline_in = gst_parse_launch(pipeline_in_str, &error);
if (error) {
g_printerr("Error in first pipeline: %sn", error->message);
return -1;
}
result = sprintf(pipeline_out_str, "appsrc name=%s ! queue ! videoparse format=14 width=640 height=480 ! videorate ! videoscale ! ffmpegcolorspace ! video/x- raw-rgb,width=640,height=480 ! xvimagesink", app_src_name);
printf("Second pipeline stringnn%sn", pipeline_out_str);
pipeline_out = gst_parse_launch(pipeline_out_str, &error);
if (error) {
g_printerr("Error in first pipeline: %sn", error->message);
return -1;
}
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_in));
gst_bus_add_watch(bus, bus_call, NULL);
gst_object_unref(bus);
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_out));
gst_bus_add_watch(bus, bus_call, NULL);
gst_object_unref(bus);
gst_element_set_state(GST_ELEMENT(pipeline_in), GST_STATE_PLAYING);
gst_element_set_state(GST_ELEMENT(pipeline_out), GST_STATE_PLAYING);
callbacks.eos = NULL;
callbacks.new_preroll = NULL;
callbacks.new_buffer = newbuffer;
gst_app_sink_set_callbacks((GstAppSink *) gst_bin_get_by_name(GST_BIN(pipeline_in), app_sink_name), &callbacks, NULL, NULL);
g_main_loop_run(loop);
gst_element_set_state(GST_ELEMENT(pipeline_in), GST_STATE_NULL);
gst_element_set_state(GST_ELEMENT(pipeline_out), GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline_in));
gst_object_unref(GST_OBJECT(pipeline_out));
return 0;
}
/* indented using http://indentcode.net/ */
This would be my first time working with Gstreamer in a C program. I've only used pipelines. I'm trying to write a program which takes a stream stores it in a buffer, uses OpenCv to edit the stream and use a pipeline with appsrc to view the stream. I'm getting the error:
rb1:3231): GStreamer-CRITICAL **: gst_caps_get_structure: assertion `index < caps->structs->len' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_has_field: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_fixate_field_nearest_fraction: assertion `gst_structure_has_field (structure, field_name)' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_get_fraction: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_has_field: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_has_field: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_has_field: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_structure_has_field: assertion `structure != NULL' failed
(rb1:3231): GStreamer-CRITICAL **: gst_pad_set_caps: assertion `caps == NULL || gst_caps_is_fixed (caps)' failed
** ERROR **: not negotiated
aborting...
Aborted
Any help would be appreciated.
For reference i've given the code (I"ve not implemented the OpenCV part yet):
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappbuffer.h>
#include <gst/app/gstappsink.h>
#include <gst/gstbuffer.h>
#include <stdbool.h>
#include <stdio.h>
static GMainLoop *loop;
GstBuffer *buffer;
GstAppSinkCallbacks callbacks;
GstElement *pipeline_in;
GstElement *pipeline_out;
GstBus *bus;
GError *error;
const char app_sink_name[] = "app-sink";
const char app_src_name[] = "app-src";
const char pipeline_in_str[500];
const char pipeline_out_str[500];
static gboolean bus_call(GstBus * bus, GstMessage * msg, void *user_data)
{
gchar *userdata = (gchar *) user_data;
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS:{
//sender check - pipeline1 sends a EOS msg to AppSrc in pipeline2
if (g_ascii_strcasecmp(userdata, gst_element_get_name(pipeline_in)) == 0) {
g_print("EOS detected (%s)n", userdata);
gst_app_src_end_of_stream(GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline_out), app_src_name)));
}
//sender check - when pipeline2 sends the EOS msg, quite.
if (g_ascii_strcasecmp(userdata, gst_element_get_name(pipeline_out)) == 0) {
g_print("Finished playback (%s)n", userdata);
g_main_loop_quit(loop);
}
break;
}
case GST_MESSAGE_ERROR:{
GError *err;
gst_message_parse_error(msg, &err, NULL);
g_error("%s", err->message);
g_error_free(err);
g_main_loop_quit(loop);
break;
}
default:
break;
}
return true;
}
GstFlowReturn newbuffer(GstAppSink * app_sink, gpointer user_data)
{
GstBuffer *buffer = gst_app_sink_pull_buffer((GstAppSink *) gst_bin_get_by_name(GST_BIN(pipeline_in), app_sink_name));
gst_app_src_push_buffer(GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline_out), app_src_name)), buffer);
return GST_FLOW_OK;
}
int main(int argc, char *argv[])
{
int result;
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
pipeline_in = gst_pipeline_new("my_pipeline");
pipeline_out = gst_pipeline_new("my_pipeline2");
//result=sprintf(pipeline_in_str, "udpsrc port=5000 ! video/x-h264, width=(int)640, height=(int)480, framerate=(fraction)30/1, pixel-aspect-ratio=(fraction )1/1, codec_data=(buffer )0142c01effe100176742c01e92540501ed8088000003000bb9aca00078b17501000468ce3c80, stream-format=(string)avc, alignment=(string)au ! ffdec_h264 ! video/x-raw-yuv,width=640,height=480 ! ffmpegcolorspace ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! appsink name="%s"", app_sink_name);
result = sprintf(pipeline_in_str, "videotestsrc ! video/x-raw-rgb, width=640, height=480 ! ffmpegcolorspace ! appsink name=%s", app_sink_name);
printf("First pipeline string nn%sn", pipeline_in_str);
pipeline_in = gst_parse_launch(pipeline_in_str, &error);
if (error) {
g_printerr("Error in first pipeline: %sn", error->message);
return -1;
}
result = sprintf(pipeline_out_str, "appsrc name=%s ! queue ! videoparse format=14 width=640 height=480 ! videorate ! videoscale ! ffmpegcolorspace ! video/x- raw-rgb,width=640,height=480 ! xvimagesink", app_src_name);
printf("Second pipeline stringnn%sn", pipeline_out_str);
pipeline_out = gst_parse_launch(pipeline_out_str, &error);
if (error) {
g_printerr("Error in first pipeline: %sn", error->message);
return -1;
}
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_in));
gst_bus_add_watch(bus, bus_call, NULL);
gst_object_unref(bus);
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_out));
gst_bus_add_watch(bus, bus_call, NULL);
gst_object_unref(bus);
gst_element_set_state(GST_ELEMENT(pipeline_in), GST_STATE_PLAYING);
gst_element_set_state(GST_ELEMENT(pipeline_out), GST_STATE_PLAYING);
callbacks.eos = NULL;
callbacks.new_preroll = NULL;
callbacks.new_buffer = newbuffer;
gst_app_sink_set_callbacks((GstAppSink *) gst_bin_get_by_name(GST_BIN(pipeline_in), app_sink_name), &callbacks, NULL, NULL);
g_main_loop_run(loop);
gst_element_set_state(GST_ELEMENT(pipeline_in), GST_STATE_NULL);
gst_element_set_state(GST_ELEMENT(pipeline_out), GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline_in));
gst_object_unref(GST_OBJECT(pipeline_out));
return 0;
}
/* indented using http://indentcode.net/ */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
检查为什么你会得到断言。
例如:
使用 GST_DEBUG=*:5 获取失败原因的更详细输出。
结合 G_DEBUG 设置以确保它在遇到断言时停止。
Check why you are getting the assertions.
For example:
Use GST_DEBUG=*:5 to get a more detailed output of what is failing.
Combine the G_DEBUG setting to make sure it stops when it hits the assertion.
虽然我还没有完全弄清楚错误到底是什么,但我设法让它工作。我更改了管道的字符串(在 gst_parse_launch 函数中)。第二个管道 *pipeline_out* 中一定有一些错误。
Though I haven't quite figured out what exactly the error was, i managed to get it working. I changed the string for the pipeline (in the gst_parse_launch function). It must've been some error in the second pipeline, *pipeline_out*.
播放应该在设置回调后完成,并尝试使用传递到缓冲区的 appsink 从缓冲区中拉取,您将获得良好的性能。
Playing should be done after you have set the callbacks, and try to use the appsink that's passed to the buffer to pull from the buffer, you'd get good performance.