Это мой первый опыт работы с Gstreamer в программе на Си.Я использовал только трубопроводы.Я пытаюсь написать программу, которая принимает поток, сохраняет его в буфере, использует OpenCv для редактирования потока и использует конвейер с appsrc для просмотра потока.Я получаю сообщение об ошибке:
rb1: 3231): GStreamer-CRITICAL **: gst_caps_get_structure: утверждение `index structs-> len 'не удалось
(rb1: 3231): GStreamer-CRITICAL **: поле gst_structure_has_field: утверждение "структура! = NULL" не выполнено
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_get_fraction: утверждение "структура! = NULL" не выполнена
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: утверждение `структура! = NULL 'не выполнена
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: утверждение `структура! = NULL' не выполнена
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: утверждение `структура! = NULL 'не удалось
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: утверждение` структура! = NULL' не удалось
(rb1: 3231): GStreamer-CRITICAL **: gst_pad_set_caps: утверждение `caps == NULL ||gst_caps_is_fixed (caps) 'не удалось
** ОШИБКА **: прерывание не согласовано ... Прервано
Любая помощь приветствуется.
Для справки я привел код (я еще не реализовал часть 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/ */