Simple RTSP Pipeline Works with gst-launch But Not with API

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Simple RTSP Pipeline Works with gst-launch But Not with API

Zheng
This post was updated on .
Thank you in advance!

This is the working gst-launch-1.0 pipeline.

gst-launch-1.0 rtspsrc port-range=5000-5100 location=rtsp://192.168.1.10:8555/right latency=0 ! decodebin ! videoconvert ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink

The following is the NOT working C function.

int startPipeline(const char *vs_location) {
        GstElement *pipeline;
        GstBus *bus;
        guint bus_watch_id;

        gst_init(NULL, NULL);
        pipeline = gst_pipeline_new("my_pipeline");
        bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
        bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL);
        gst_object_unref(bus);

        GstElement *source, *dec_bin, *v_conv, *sink;
        source = gst_element_factory_make("rtspsrc", "source");
        dec_bin = gst_element_factory_make("decodebin", "dec_bin");
        v_conv = gst_element_factory_make("videoconvert", "v_con");
        sink = gst_element_factory_make("autovideosink", "sink");
        gst_bin_add_many(GST_BIN(pipeline), source, dec_bin, v_conv, sink, NULL);

        // Set element properties.
        g_object_set(G_OBJECT(source), "port-range", "5000-5100", NULL);
        g_object_set(G_OBJECT(source), "location", vs_location, NULL);
        g_object_set(G_OBJECT(source), "latency", 0, NULL);

        gst_element_link_many(source, dec_bin, v_conv, NULL);

        GstCaps *caps;
        caps = gst_caps_new_simple(
                        "video/x-raw",
                        "width", G_TYPE_INT, 640,
                        "height", G_TYPE_INT, 480,
                        "format", G_TYPE_STRING, "YUY2",
                        NULL);
        gst_element_link_filtered(v_conv, sink, caps);
        gst_caps_unref(caps);

        gst_element_set_state(pipeline, GST_STATE_PLAYING);

        loop = g_main_loop_new(NULL, FALSE);
        g_main_loop_run(loop);

        // Clean up.
        gst_element_set_state(pipeline, GST_STATE_NULL);
        gst_object_unref(pipeline);
        g_source_remove(bus_watch_id);
        g_main_loop_unref(loop);

        return 0;
}

Then the Errors are here.

0:00:00.442295071 16407 0x7f007c01e940 FIXME                default gstutils.c:3825:gst_pad_create_stream_id_internal:<fakesrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:00.455584401 16407 0x7f006c0025e0 FIXME        rtpjitterbuffer gstrtpjitterbuffer.c:1395:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0> Unsupported timestamp reference clock
0:00:00.455616947 16407 0x7f006c0025e0 FIXME        rtpjitterbuffer gstrtpjitterbuffer.c:1403:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0> Unsupported media clock
0:00:00.457236636 16407 0x7f006c0025e0 WARN                 basesrc gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: Internal data flow error.
0:00:00.457268553 16407 0x7f006c0025e0 WARN                 basesrc gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: streaming task paused, reason not-linked (-1)
Error: Internal data flow error.
Debug: gstbasesrc.c(2947): gst_base_src_loop (): /GstPipeline:my_pipeline/GstRTSPSrc:source/GstUDPSrc:udpsrc0:
streaming task paused, reason not-linked (-1)
0:00:00.458046376 16407      0x10af5e0 WARN                 rtspsrc gstrtspsrc.c:5520:gst_rtspsrc_try_send:<source> receive interrupted
0:00:00.458083322 16407      0x10af5e0 WARN                 rtspsrc gstrtspsrc.c:7546:gst_rtspsrc_pause:<source> PAUSE interrupted

Reply | Threaded
Open this post in threaded view
|

Re: Simple RTSP Pipeline Works with gst-launch But Not with API

Michael Gruner
Hi Zheng

Whenever possible, I use gst_parse_launch to avoid these types of complications. This is what gst-launch uses underneath, so if it works on one it should work on the other.

Specifically in your example:

int startPipeline(const char *vs_location) {
GstElement *pipeline;
GstBus *bus;
guint bus_watch_id;
gchar *pipe_desc;
GError *error = NULL;

gst_init(NULL, NULL);

pipe_desc = g_strdup_printf("rtspsrc port-range=5000-5100 location=%s latency=0 ! decodebin ! videoconvert ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink”, vs_location);

pipeline = gst_parse_launch (pipe_desc, &error);
//Handle errors here
g_free (pipe_desc);

bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL);
gst_object_unref(bus);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);

// Clean up.
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);

return 0;
}

Michael Gruner <[hidden email]>
Embedded Linux and GStreamer solutions
RidgeRun Engineering

On Jun 16, 2016, at 19:45, Zheng <[hidden email]> wrote:

*Thang you in advance!*

*This is the working gst-launch-1.0 pipeline.*

gst-launch-1.0 rtspsrc port-range=5000-5100
location=<a href="rtsp://192.168.1.10:8555/right" class="">rtsp://192.168.1.10:8555/right latency=0 ! decodebin ! videoconvert
! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink

*The following is the NOT working C function.*

int startPipeline(const char *vs_location) {
GstElement *pipeline;
GstBus *bus;
guint bus_watch_id;

gst_init(NULL, NULL);
pipeline = gst_pipeline_new("my_pipeline");
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL);
gst_object_unref(bus);

GstElement *source, *dec_bin, *v_conv, *sink;
source = gst_element_factory_make("rtspsrc", "source");
dec_bin = gst_element_factory_make("decodebin", "dec_bin");
v_conv = gst_element_factory_make("videoconvert", "v_con");
sink = gst_element_factory_make("autovideosink", "sink");
gst_bin_add_many(GST_BIN(pipeline), source, dec_bin, v_conv, sink, NULL);

// Set element properties.
g_object_set(G_OBJECT(source), "port-range", "5000-5100", NULL);
g_object_set(G_OBJECT(source), "location", vs_location, NULL);
g_object_set(G_OBJECT(source), "latency", 0, NULL);

gst_element_link_many(source, dec_bin, v_conv, NULL);

GstCaps *caps;
caps = gst_caps_new_simple(
"video/x-raw",
"width", G_TYPE_INT, 640,
"height", G_TYPE_INT, 480,
"format", G_TYPE_STRING, "YUY2",
NULL);
gst_element_link_filtered(v_conv, sink, caps);
gst_caps_unref(caps);

gst_element_set_state(pipeline, GST_STATE_PLAYING);

loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);

// Clean up.
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);

return 0;
}

*Then the Errors are here.*

0:00:00.442295071 16407 0x7f007c01e940 FIXME                default
gstutils.c:3825:gst_pad_create_stream_id_internal:<fakesrc0:src> Creating
random stream-id, consider implementing a deterministic way of creating a
stream-id
0:00:00.455584401 16407 0x7f006c0025e0 FIXME        rtpjitterbuffer
gstrtpjitterbuffer.c:1395:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0>
Unsupported timestamp reference clock
0:00:00.455616947 16407 0x7f006c0025e0 FIXME        rtpjitterbuffer
gstrtpjitterbuffer.c:1403:gst_jitter_buffer_sink_parse_caps:<rtpjitterbuffer0>
Unsupported media clock
0:00:00.457236636 16407 0x7f006c0025e0 WARN                 basesrc
gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: Internal data flow
error.
0:00:00.457268553 16407 0x7f006c0025e0 WARN                 basesrc
gstbasesrc.c:2947:gst_base_src_loop:<udpsrc0> error: streaming task paused,
reason not-linked (-1)
Error: Internal data flow error.
Debug: gstbasesrc.c(2947): gst_base_src_loop ():
/GstPipeline:my_pipeline/GstRTSPSrc:source/GstUDPSrc:udpsrc0:
streaming task paused, reason not-linked (-1)
0:00:00.458046376 16407      0x10af5e0 WARN                 rtspsrc
gstrtspsrc.c:5520:gst_rtspsrc_try_send:<source> receive interrupted
0:00:00.458083322 16407      0x10af5e0 WARN                 rtspsrc
gstrtspsrc.c:7546:gst_rtspsrc_pause:<source> PAUSE interrupted





--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Simple-RTSP-Pipeline-Works-with-gst-launch-But-Not-with-API-tp4678108.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Simple RTSP Pipeline Works with gst-launch But Not with API

Sebastian Dröge-3
In reply to this post by Zheng
On Do, 2016-06-16 at 18:45 -0700, Zheng wrote:

> *Thang you in advance!*
>
> *This is the working gst-launch-1.0 pipeline.*
>
> gst-launch-1.0 rtspsrc port-range=5000-5100
> location=rtsp://192.168.1.10:8555/right latency=0 ! decodebin !
> videoconvert
> ! video/x-raw,width=640,height=480,format=YUY2 ! autovideosink
>
> *The following is the NOT working C function.*
> [...]
You don't check any return values. If you do, you will probably notice
that one or more of the links are actually failing, which seems to be
the underlying problem here.

The pipeline fails because a pad is producing data but it is not linked
downstream.

--

Sebastian Dröge, Centricular Ltd · http://www.centricular.com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (968 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Simple RTSP Pipeline Works with gst-launch But Not with API

Zheng
Thanks! @Sebastian Dröge-3 and @Michael Gruner

The problem is exactly the one Sebastian said. The rtspsrc's sink pad is not a static one. So a on_pad_added callback function is needed. The following is the working C functions.

static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) {
        gchar *name;
        name = gst_pad_get_name(pad);
        g_print("A new pad %s was created.\n", name);
        g_free(name);

        GstPad *sinkpad;
        GstElement *downstream = (GstElement *) data;

        sinkpad = gst_element_get_static_pad(downstream, "sink");

        gst_pad_link (pad, sinkpad);

        gst_object_unref(sinkpad);
}

int startPipeline(const char *vs_location, const char *socket_path) {
        puts(vs_location);
        puts(socket_path);

        GstElement *pipeline;
        GstBus *bus;
        guint bus_watch_id;

        gst_init(NULL, NULL);
        pipeline = gst_pipeline_new("my_pipeline");
        bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
        bus_watch_id = gst_bus_add_watch(bus, bus_callback, NULL);
        gst_object_unref(bus);

        GstElement *source, *dec_bin, *v_conv, *sink;
        source = gst_element_factory_make("rtspsrc", "source");
        dec_bin = gst_element_factory_make("decodebin", "dec_bin");
        v_conv = gst_element_factory_make("videoconvert", "v_con");
        sink = gst_element_factory_make("autovideosink", "sink");
        gst_bin_add_many(GST_BIN(pipeline), source, dec_bin, v_conv, sink, NULL);

        // Set element properties.
        g_object_set(G_OBJECT(source), "port-range", "5000-5100", NULL);
        g_object_set(G_OBJECT(source), "location", vs_location, NULL);
        g_object_set(G_OBJECT(source), "latency", 0, NULL);

        g_signal_connect(source, "pad-added", G_CALLBACK(on_pad_added), dec_bin);
        g_signal_connect(dec_bin, "pad-added", G_CALLBACK(on_pad_added), v_conv);

        GstCaps *caps;
        caps = gst_caps_new_simple(
                        "video/x-raw",
                        "width", G_TYPE_INT, 640,
                        "height", G_TYPE_INT, 480,
                        "format", G_TYPE_STRING, "YUY2",
                        NULL);
        if(gst_element_link_filtered(v_conv, sink, caps) == FALSE) {
                g_printerr("Error: gst_element_link_filtered() failed.\n");

                gst_element_set_state(pipeline, GST_STATE_NULL);
                gst_object_unref(pipeline);
                g_source_remove(bus_watch_id);

                return -1;
        }
        gst_caps_unref(caps);

        gst_element_set_state(pipeline, GST_STATE_PLAYING);

        loop = g_main_loop_new(NULL, FALSE);
        g_main_loop_run(loop);

        // Clean up.
        gst_element_set_state(pipeline, GST_STATE_NULL);
        gst_object_unref(pipeline);
        g_source_remove(bus_watch_id);
        g_main_loop_unref(loop);

        return 0;
}