gst-launch-1.0 rtspsrc location=rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov is-live=true latency=200 name=src src. ! rtph264depay ! h264parse ! avdec_h264 ! queue ! autovideosink
I'm trying to write the pipeline as c application. This command runs successfully. But C-application give error:
Error received from element udpsrc2: Internal data stream error.
And the Debugging information:
../libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:test-pipeline/GstRTSPSrc:rtspsrc/GstUDPSrc:udpsrc2:streaming stopped, reason not-negotiated (-4)
Here's my c code:
#include <gst/gst.h>
static void cb_new_rtspsrc_pad(GstElement *element, GstPad *pad, gpointer data)
{
GstPad *sink_pad = gst_element_get_static_pad (GST_ELEMENT(data), "sink");
GstPadLinkReturn ret;
GstCaps *pad_caps = NULL;
GstStructure *pad_caps_struct = NULL;
const gchar *pad_caps_type = NULL;
g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (pad), GST_ELEMENT_NAME (element));
/* If our converter is already linked, we have nothing to do here */
if (gst_pad_is_linked (sink_pad)) {
g_print ("We are already linked. Ignoring.\n");
goto exit;
}
/* Get the new pad's type */
pad_caps = gst_pad_get_current_caps (pad);
pad_caps_struct = gst_caps_get_structure (pad_caps, 0);
pad_caps_type = gst_structure_get_name (pad_caps_struct);
/* Attempt the link */
ret = gst_pad_link (pad, sink_pad);
if (GST_PAD_LINK_FAILED (ret)) {
g_print ("Type is '%s' but link failed.\n", pad_caps_type);
} else {
g_print ("Link succeeded (type '%s').\n", pad_caps_type);
}
exit:
/* Unreference the new pad's caps, if we got them */
if (pad_caps != NULL)
gst_caps_unref (pad_caps);
/* Unreference the sink pad */
gst_object_unref (sink_pad);
}
int main(int argc, char *argv[])
{
GstElement *pipeline, *rtspsrc, *h264depay, *h264parse, *h264decoder, *que, *h264sink;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
gboolean terminate = FALSE;
/* Initialize GStreamer */
gst_init(&argc, &argv);
/* Create the elements */
rtspsrc = gst_element_factory_make ("rtspsrc", "rtspsrc"); // Availability: Sometimes
h264depay = gst_element_factory_make ("rtph264depay", "h264depay"); // Availability: Always
h264parse = gst_element_factory_make ("h264parse", "h264parse"); // Availability: Always
h264decoder = gst_element_factory_make ("avdec_h264", "h264decoder"); // Availability: Always
que = gst_element_factory_make ("queue", "queue"); // Availability: Always
h264sink = gst_element_factory_make ("autoaudiosink", "sink"); // Availability: Always
/* Create the empty pipeline */
pipeline = gst_pipeline_new("test-pipeline");
if (!pipeline || !rtspsrc || !h264depay || !h264parse || !h264decoder || !que || !h264sink) {
g_printerr("[ERROR-main]: Not all elements could be created.\n");
return -1;
} else {
g_print("[DEBUG-main]: Elements have been created.\n");
}
gst_bin_add_many(GST_BIN(pipeline), rtspsrc, h264depay, h264parse, h264decoder, que, h264sink, NULL);
g_print("[DEBUG-main]: Elements have been added in the pipeline.\n");
if (!gst_element_link_many(h264depay, h264parse, h264decoder, que, h264sink, NULL)) {
g_printerr ("[ERROR-main]: Elements could not be linked.\n");
gst_object_unref (pipeline);
return -1;
} else {
g_print("[DEBUG-main]: Elements can be linked.\n");
}
g_object_set(rtspsrc, "location", "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", NULL);
g_signal_connect(rtspsrc, "pad-added", G_CALLBACK(cb_new_rtspsrc_pad), h264depay);
g_print("[DEBUG-main]: g_signal_connect() be called.\n");
/* Start playing */
ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("[ERROR-main]: Unable to set the pipeline to the playing state.\n");
gst_object_unref(pipeline);
return -1;
}
// Listen to the bus
bus = gst_element_get_bus(pipeline);
do {
msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
// Parse message
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug_info);
g_printerr("[ERROR-main]: Error received from element [%s]: [%s]\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr("[ERROR-main]: Debugging information --- [%s]\n", debug_info ? debug_info : "none");
g_clear_error(&err);
g_free(debug_info);
terminate = TRUE;
break;
case GST_MESSAGE_EOS:
g_print("[DEBUG-main]: End-Of-Stream reached.\n");
terminate = TRUE;
break;
case GST_MESSAGE_STATE_CHANGED:
// We are only interested in state-changed messages from the pipeline
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (pipeline)) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
g_print("[DEBUG-main]: Pipeline state changed from [%s] to [%s]:\n",
gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
}
break;
default:
// We should not reach here
g_printerr("[ERROR-main]: Unexpected message received.\n");
break;
}
gst_message_unref(msg);
}
} while(!terminate);
// Free resources
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}