RTSP pipeline implemented via C code not working?

社会主义新天地 提交于 2019-12-12 04:38:15

问题


My Scenario is as follows :-

I have set up a RTSP server at IP 192.168.1.24 at port 554.I use the following gst-launch command on client side to receive packets and everything works fine.

gst-launch rtspsrc location = rtsp://admin:admin123@192.168.1.24:554/axis-media/media.amp ! fakesink

But when I implement the same thing via C code it gives me error.My C code is as follows:-

#include <gst.h>
#include <glib.h>

static gboolean bus-call (GstBus *bus, GstMessage *msg, gpointer data)
{
 GMainLoop *loop = (GMainLoop *) data;
 switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_EOS:
             g_print ("End of stream\n");
             g_main_loop_quit (loop);
             break;
        case GST_MESSAGE_ERROR: {
             gchar *debug;
             GError *error;
             gst_message_parse_error (msg, &error, &debug);
             g_free (debug);
             g_printerr ("Error: %s\n", error->message);
             g_error_free (error);
             g_main_loop_quit (loop);
             break;
             }
        default:
             break;
        }
        return true;
 }
int main (int argc, char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, *sink;
GstBus *bus;
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    if (argc != 2) {
             return -1;
       }
    pipeline = gst_pipeline_new ("network-player");
    source = gst_element_factory_make ("rtspsrc","file-source");
    sink = gst_element_factory_make ("fakesink","fake");

    if (!pipeline || !source || !sink) {
                  g_printerr ("One element could not be created. Exiting.\n");
                  return -1;
       }
    g_object_set (G_OBJECT (source), "location", argv[1], NULL);
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    gst_bin_add_many (GST_BIN (pipeline),source, sink, NULL);
    gst_element_link_many (source, sink, NULL);

    /* Set the pipeline to "playing" state*/
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    /* Iterate */
    g_print ("Running...\n");
    g_main_loop_run (loop);

    /* Out of the main loop, clean up nicely */
    g_print ("Returned, stopping playback\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);

    g_print ("Deleting pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));
    return 0;
    }

I am able to compile the code without any error. But when I run the binary generated with the following format:-

user@user:~ ./helloworld rtsp://admin:admin123@192.168.1.24:554/axis-media/media.amp

I get the following error:-

Now playing: rtsp://root:nlss123@192.168.1.24:554/axis-media/media.amp
Running...
**Error: Internal data flow error**.
Returned, stopping playback
Deleting pipeline

Can anyone suggest we there is Internal Data flow error ?


回答1:


you can get verbose error logs by running the apps by --gst-debug=*rtsp*:5 e.g.

./yourApplication --gst-debug=*rtsp*:5




回答2:


i also had the same problem. You should link source to to sink with "pad-added" signal. In brief:

typedef struct myDataTag {
GstElement *pipeline;
GstElement *rtspsrc;
GstElement *depayloader;
GstElement *decoder;
*sink;
} myData_t;

myData_t appData;

appData->pipeline  = gst_pipeline_new ("videoclient");
appData->rtspsrc = gst_element_factory_make ("rtspsrc", "rtspsrc");
g_object_set (G_OBJECT (appData->rtspsrc), "location", "rtsp://192.168.1.10:554/myStreamPath", NULL);
appData->depayloader = gst_element_factory_make ("rtph264depay","depayloader");
appData->decoder = gst_element_factory_make ("h264dec", "decoder");
appData->sink = gst_element_factory_make ("autovideosink", "sink");

//then add all elements together
gst_bin_add_many (GST_BIN (appData->pipeline), appData->rtspsrc, appData->depayloader, appData->decoder, appData->sink, NULL);

//link everythink after source
gst_element_link_many (appData->depayloader, appData->decoder, appData->sink, NULL);

/*
 * Connect to the pad-added signal for the rtpbin.  This allows us to link
 * the dynamic RTP source pad to the depayloader when it is created.
 */
g_signal_connect (appData->rtspsrc, "pad-added", G_CALLBACK (pad_added_handler), &appData);

/* Set the pipeline to "playing" state*/
gst_element_set_state (appData->pipeline, GST_STATE_PLAYING);

/* pad added handler */
static void pad_added_handler (GstElement *src, GstPad *new_pad, myData_t *pThis) {
GstPad *sink_pad = gst_element_get_static_pad (pThis->depayloader, "sink");
GstPadLinkReturn ret;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;

g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));

/* Check the new pad's name */
if (!g_str_has_prefix (GST_PAD_NAME (new_pad), "recv_rtp_src_")) {
    g_print ("  It is not the right pad.  Need recv_rtp_src_. Ignoring.\n");
    goto exit;
}

/* If our converter is already linked, we have nothing to do here */
if (gst_pad_is_linked (sink_pad)) {
    g_print (" Sink pad from %s already linked. Ignoring.\n", GST_ELEMENT_NAME (src));
    goto exit;
}

/* Check the new pad's type */
new_pad_caps = gst_pad_get_caps (new_pad);
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
new_pad_type = gst_structure_get_name (new_pad_struct);

/* Attempt the link */
ret = gst_pad_link (new_pad, sink_pad);
if (GST_PAD_LINK_FAILED (ret)) {
    g_print ("  Type is '%s' but link failed.\n", new_pad_type);
} else {
    g_print ("  Link succeeded (type '%s').\n", new_pad_type);
}

exit:
/* Unreference the new pad's caps, if we got them */
if (new_pad_caps != NULL)
    gst_caps_unref (new_pad_caps);

/* Unreference the sink pad */
gst_object_unref (sink_pad);
}

Hope that this will help someone..:)



来源:https://stackoverflow.com/questions/8093967/rtsp-pipeline-implemented-via-c-code-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!