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

时间:2021-12-11 08:49:28

I'm trying to transmit RTP video stream through network via UDP protocol.

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

Here is pipeline code on sender side:

这里是发送方的管道代码:

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

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

I can receive and see actual video if I run receiver with gst-launch-1.0 command-line like this:

如果使用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

But I cannot see window with video when I execute receiver for same pipeline in c code. Here is pipeline code on receiver side (in full - because I believe here is error somewhere):

但是当我在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;
  }
}

Error onserved from code:

错误onserved代码:

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.

How can I debug this issue?

如何调试这个问题?

1 个解决方案

#1


1  

This is too long for comment - its not answer but how to analyse:

这段时间太长了,无法评论——这不是答案,而是如何分析:

Try making dot files to spot the differences.. I noticed in logs that there is opengl stuff involved - do you need that? Try changing autovideosink to something that is not using opengl.. not sure what options do you have on Mac (I hope I guessed it correctly) - on Linux I use ximagesink or xvimagesink.. on Mac there is osxvideosink (not sure if its build by default) - you can check this ..

试着做点文件来找出区别。我在日志中注意到有opengl相关的东西——你需要吗?尝试将autovideosink更改为不使用opengl的东西。我不确定你在Mac上有什么选择(我希望我猜对了)——在Linux上我使用ximagesink或xvimagesink。在Mac上有osxvideosink(不确定是否默认构建)-你可以检查这个。

My guess of why is it behaving differently in gst-launch and your app is that you have some additional overhead in your app which causes the processing to be slowed or something and you get the not negotiated error as something is postponed..

我的猜测是为什么在gst-launch和你的应用程序中它的行为方式不同你的应用程序中有一些额外的开销会导致处理速度变慢或者其他一些事情,你会得到不协商的错误,因为某些事情被推迟了。

I noticed this in logs:

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

0:00:00.608577000 29168 0x7fb5a401d850 INFO basesrc gstbasesrc.c:2838:void gst_base_src_loop(GstPad *): marking pending DISCONT

这是一个很好的例子。c:2838:void gst_base_src_loop(GstPad *):标记待定DISCONT。

which means that some packets came later than expected and were discarded..

这意味着一些数据包比预期的要晚,并且被丢弃了。

Try adding queues after udpsrc which will buffer few packets:

尝试添加udpsrc后的队列,它将缓冲几个包:

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

and of course add to pipe and link between:

当然还要加上管道和链接:

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

#1


1  

This is too long for comment - its not answer but how to analyse:

这段时间太长了,无法评论——这不是答案,而是如何分析:

Try making dot files to spot the differences.. I noticed in logs that there is opengl stuff involved - do you need that? Try changing autovideosink to something that is not using opengl.. not sure what options do you have on Mac (I hope I guessed it correctly) - on Linux I use ximagesink or xvimagesink.. on Mac there is osxvideosink (not sure if its build by default) - you can check this ..

试着做点文件来找出区别。我在日志中注意到有opengl相关的东西——你需要吗?尝试将autovideosink更改为不使用opengl的东西。我不确定你在Mac上有什么选择(我希望我猜对了)——在Linux上我使用ximagesink或xvimagesink。在Mac上有osxvideosink(不确定是否默认构建)-你可以检查这个。

My guess of why is it behaving differently in gst-launch and your app is that you have some additional overhead in your app which causes the processing to be slowed or something and you get the not negotiated error as something is postponed..

我的猜测是为什么在gst-launch和你的应用程序中它的行为方式不同你的应用程序中有一些额外的开销会导致处理速度变慢或者其他一些事情,你会得到不协商的错误,因为某些事情被推迟了。

I noticed this in logs:

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

0:00:00.608577000 29168 0x7fb5a401d850 INFO basesrc gstbasesrc.c:2838:void gst_base_src_loop(GstPad *): marking pending DISCONT

这是一个很好的例子。c:2838:void gst_base_src_loop(GstPad *):标记待定DISCONT。

which means that some packets came later than expected and were discarded..

这意味着一些数据包比预期的要晚,并且被丢弃了。

Try adding queues after udpsrc which will buffer few packets:

尝试添加udpsrc后的队列,它将缓冲几个包:

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

and of course add to pipe and link between:

当然还要加上管道和链接:

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