通过C代码实现的RTSP管道无法正常工作?

我的情景如下: –

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

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

但是当我通过C代码实现相同的东西时,它给了我错误。我的C代码如下: –

 #include  #include  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 

任何人都可以建议我们有内部数据流错误吗?

您可以通过–gst-debug = * rtsp *:5运行应用程序来获取详细的错误日志

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

我也有同样的问题。 您应该使用“pad-added”信号将source链接到sink。 简单来说:

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

希望这会帮助别人.. 🙂