Gstreamer接收视频:流媒体任务暂停,原因未协商(-4)

时间:2016-06-07 13:30:35

标签: c video-streaming gstreamer rtp

我试图通过UDP协议通过网络传输RTP视频流。

以下是发送方的管道代码:

https://gist.github.com/mgalushka/68d8ee034849a7db4f1f234e73a41405

如果我使用gst-launch-1.0命令行运行接收器,我可以接收和查看实际视频:

gst-launch-1.0 -v udpsrc address=127.0.0.1 port=1234 caps="application/x-rtp" ! rtph263pdepay ! avdec_h263 ! autovideosink

但是当我在 c 代码中执行相同管道的接收器时,我看不到带有视频的窗口。 这是接收器端的管道代码(完全 - 因为我相信这里是错误):

void  _receive_video_init_gstreamer(NiceAgent *magent, guint stream_id, CustomData *data)
{
  GstElement *pipeline, *source, *capsfilter, *videoconvert, *h263p, *rtph263pdepay, *sink;
  GstBus *bus;
  GstMessage *msg;
  GstStateChangeReturn ret;
  GSource *bus_source;

  source = gst_element_factory_make ("udpsrc", "source");
  rtph263pdepay = gst_element_factory_make ("rtph263pdepay", "rtph263pdepay");
  h263p = gst_element_factory_make ("avdec_h263p", "h263p");
  sink = gst_element_factory_make ("autovideosink", "sink");

  g_object_set (source, "address", "127.0.0.1", NULL);
  g_object_set (source, "port", 1234, NULL);

  g_object_set (source, "caps", gst_caps_from_string("application/x-rtp"), NULL);

  g_object_set (sink, "sync", FALSE, NULL);

  pipeline = gst_pipeline_new ("Video receive pipeline");

  if (!pipeline || !source ||
      !h263p || !rtph263pdepay || !sink)
  {
    g_printerr ("Not all elements could be created.\n");
    return;
  }

  gst_bin_add_many (GST_BIN (pipeline), source,
            rtph263pdepay, h263p, sink, NULL);

  if (gst_element_link_many (source,
                rtph263pdepay, h263p, sink, NULL) != TRUE) {
    g_printerr ("Elements could not be linked.\n");
    gst_object_unref (pipeline);
    return;
  }

  bus = gst_element_get_bus (pipeline);
  gst_bus_enable_sync_message_emission (bus);
  gst_bus_add_signal_watch (bus);

  g_signal_connect (bus, "message::error",
      (GCallback) on_error, NULL);

  data->pipeline = pipeline;
  ret = gst_element_set_state(data->pipeline, GST_STATE_PLAYING);

  if (ret == GST_STATE_CHANGE_FAILURE) {
    g_printerr ("Unable to set the pipeline to the playing state.\n");
    gst_object_unref (pipeline);
    return;
  }
}

从代码中保留错误:

WARN    basesrc gstbasesrc.c:2943:void gst_base_src_loop(GstPad *):<source> error: Internal data flow error. 
WARN    basesrc gstbasesrc.c:2943:void gst_base_src_loop(GstPad *):<source> error: streaming task paused, reason not-negotiated (-4) 
ERROR   default gstreamer_utils.c:42:on_error: Error received from element source: Internal data flow error.

如何调试此问题?

2 个答案:

答案 0 :(得分:1)

评论时间过长 - 不是答案,而是如何分析:

尝试制作点文件以发现差异..我在日志中注意到涉及到opengl的东西 - 你需要吗?尝试将autovideosink更改为不使用opengl的东西..不确定你在Mac上有什么选项(我希望我猜对了) - 在Linux上我使用ximagesink或xvimagesink ..在Mac上有osxvideosink(不确定它是否构建)默认情况下) - 您可以查看this ..

我猜测为什么它在gst-launch中表现不同而且你的应用程序是你的应用程序中有一些额外的开销导致处理速度变慢或某些事情因为某些事情被推迟而得到未协商的错误。

我在日志中注意到了这一点:

  

0:00:00.608577000 29168 0x7fb5a401d850 INFO basesrc gstbasesrc.c:2838:void gst_base_src_loop(GstPad *):标记待定DISCONT

这意味着某些数据包的发送时间晚于预期并被丢弃..

尝试在udpsrc之后添加队列,这将缓冲一些数据包:

queue = gst_element_factory_make ("queue", "srcqueue");

当然要添加到管道和链接:

if (gst_element_link_many (source, queue
            rtph263pdepay, h263p, sink, NULL) != TRUE) {

答案 1 :(得分:0)

在构建RTP H264管道时,我也面临同样的警告,并且可以对其进行修复。

gst-launch-1.0 -v udpsrc port=5004 caps="application/x-rtp,media=(string)video,encoding-name=(string)H264,payload=(int)96" ! rtpjitterbuffer ! rtph264depay ! decodebin ! videoconvert ! autovideosink

使用gst启动一切正常,但是在C语言中并没有启动流。

我在日志文件中有相同的警告,并搜索“未协商”的原因。

原来,我的大写字母配置错误/不完整。 Gstreamer可以接受所有内容,并且在您看到“未协商”消息之前不会抱怨。

您应该仔细检查所有元素的配置是否正确。 我必须比较gst-launch和应用程序日志消息以找到解决方案。

顺便说一句。这是我的测试源流,我使用的是Windows,gstreamer版本1.14.4

gst-launch-1.0 -v videotestsrc ! video/x-raw,framerate=20/1 ! videoscale ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5004