c - 通过 C 代码实现的 RTSP 管道不起作用?

标签 c network-programming rtsp rtsp-client

我的场景如下:-

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

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

但是当我通过 C 代码实现同样的事情时,它给了我错误。我的 C 代码如下:-

#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;
    }

我能够编译代码,没有任何错误。 但是当我运行使用以下格式生成的二进制文件时:-

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

有人可以建议我们存在内部数据流错误吗?

最佳答案

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

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);
}

希望这会对某人有所帮助......:)

关于c - 通过 C 代码实现的 RTSP 管道不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8093967/

相关文章:

c# - 引用自身的编码类型

c - 为什么我的vaiable不遵循gdb stm32项目中的代码

c++ - 如何通过 irDA 套接字建立连接?

java - 通过 LAN 广播 UDP 数据报包

c - 如何通过串行连接(蓝牙)获取 TCP/IP 数据包

ffmpeg - 使用 RTSP Url 播放媒体文件时出现 DTS 不连续性错误

opencv - RTSP 流的模糊/损坏捕获

c - C语言如何查找句子中的字符

android - 如何在360度视频VR android应用的MediaPlayer中流式传输Youtube视频?

c - 浮点结果