This was my first experience with Gstreamer in a C program. I used only pipelines. I am trying to write a program that takes a stream, saves it in a buffer, uses OpenCv to edit the stream, and uses the pipeline with appsrc to view the stream. I get an error message:
rb1: 3231): GStreamer-CRITICAL **: gst_caps_get_structure: the statement `index <cap-> structs-> len 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_fixate_field_nearest_fraction: statement `gst_structure_has_field (structure, field_name) 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_get_fraction: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_structure_has_field: the statement `structure! = NULL 'failed
(rb1: 3231): GStreamer-CRITICAL **: gst_pad_set_caps: statement `caps == NULL || gst_caps_is_fixed (caps) 'failed
** ERROR **: interrupt not agreed ... Canceled
Any help would be greatly appreciated.
For reference, I gave the code (I have 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/ */