我需要创建从rtspsrc到tcpserversink的代理。这一行是工作
gst-launch-0.10 rtspsrc location=rtsp://192.168.111.203:8554/video ! capsfilter caps='application/x-rtp,payload=26' ! rtpjpegdepay ! queue ! multipartmux ! tcpserversink port=5555
但是这段代码不起作用
void Video_Initialise_RTSP (const char* pAddress, int Port){
gVideoInit = 0;
gVideoStream = 0;
GError *error = NULL;
/* Initialize Gstreamer */
gst_init (0, NULL);
pipeline = gst_pipeline_new ("stream-camera");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline) );
gst_bus_add_signal_watch (bus);
g_signal_connect (bus, "message", (GCallback) cb_message, pipeline);
rtsp_src = gst_element_factory_make ("rtspsrc", "my_rstp");
const char * rtsp_url = "rtsp://192.168.111.203:8554/video";
g_object_set (G_OBJECT (rtsp_src), "location", rtsp_url, NULL);
caps_filter_rtsp = gst_element_factory_make ("capsfilter", "caps_filter_rtsp");
GstCaps * caps = gst_caps_new_simple ("application/x-rtp",
"payload", G_TYPE_INT, 26, NULL);
g_object_set (G_OBJECT (caps_filter_rtsp), "caps", caps, NULL);
rtpdepay = gst_element_factory_make ("rtpjpegdepay", "rtpjpeg_depay");
rtsp_queue = gst_element_factory_make ("queue", "rtsp_queue");
mux_filter = gst_element_factory_make ("multipartmux", "mux_filter");
image_sink = gst_element_factory_make ("tcpserversink", "image_sink");
g_object_set (G_OBJECT (image_sink), "host", "localhost", "port", 5555, NULL);
gst_bin_add_many (GST_BIN (pipeline), rtsp_src, caps_filter_rtsp, rtpdepay, dec_filter,
rtsp_queue,
mux_filter, image_sink, NULL);
gst_element_link_many (rtsp_src, caps_filter_rtsp, rtpdepay, dec_filter,
rtsp_queue,
mux_filter, image_sink, NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
}
int main (int argc, char *argv[]){
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
Video_Initialise_RTSP("localhost", 5555);
g_main_loop_run (loop);
return 0;
}
输出程序:
面部管道错误! 错误:内部数据流错误。 [调试详细信息:gstbasesrc.c(2625):gst_base_src_loop():/ GstPipeline:stream-camera / GstRTSPSrc:my_rstp / GstUDPSrc:udpsrc0: 流媒体任务已暂停,原因未链接(-1)]
为什么呢?我做错了什么?
答案 0 :(得分:0)
rtspsrc需要动态添加pad,如示例所示:
// RTSP pad added handler
void GstWork::rtsp_pad_added_handler (GstElement *src, GstPad *new_pad,gpointer user_data)
{
GstPad * sink_pad = gst_element_get_static_pad(static_cast<GstElement *>(user_data), "sink");
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");
}
else
{
// 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));
}
else
{
#ifdef USE_GSTREAMER_1_0
GstCaps * new_pad_caps = gst_pad_get_pad_template_caps(new_pad);
#else
GstCaps * new_pad_caps = gst_pad_get_caps (new_pad);
#endif
GstStructure * new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
const gchar *new_pad_type = gst_structure_get_name (new_pad_struct);
// Attempt the link
GstPadLinkReturn 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);
}
gst_caps_unref(new_pad_caps);
}
}
gst_object_unref(sink_pad);
}
在功能中:
// 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 (rtsp_src, "pad-added", G_CALLBACK(GstWork::rtsp_pad_added_handler), rtsp_queue);