通过C代码实现的RTSP管道不起作用? [英] RTSP pipeline implemented via C code not working?

查看:126
本文介绍了通过C代码实现的RTSP管道不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况如下:-

我已经在端口554的IP 192.168.1.24处设置了RTSP服务器.我在客户端使用以下gst-launch命令接收数据包,一切正常.

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

但是当我通过C代码实现相同的东西时,会给我错误.我的C代码如下:-

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

我收到以下错误:-

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 ?

推荐答案

我也遇到了同样的问题. 您应该使用"pad-add"信号将源链接到接收器. 简而言之:

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..:)

这篇关于通过C代码实现的RTSP管道不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆