Max*_*hka 5 c rtp video-streaming gstreamer
我正在尝试通过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
Run Code Online (Sandbox Code Playgroud)
但是当我在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;
}
}
Run Code Online (Sandbox Code Playgroud)
代码中出现错误:
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.
Run Code Online (Sandbox Code Playgroud)
我该如何调试这个问题?
小智 6
我在构建 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
Run Code Online (Sandbox Code Playgroud)
gst-launch 一切顺利,但在 C 中它没有启动流。
我在日志文件中有相同的警告,并搜索“未协商”的原因。
事实证明,我的caps配置错误/不完整。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
Run Code Online (Sandbox Code Playgroud)
这太长了,无法发表评论 - 它不是答案,而是如何分析:
尝试制作点文件来发现差异。我在日志中注意到涉及 opengl 的内容 - 你需要它吗?尝试将autovideosink更改为不使用opengl的东西..不确定Mac上有什么选项(我希望我猜对了) - 在Linux上我使用ximagesink或xvimagesink..在Mac上有osxvideosink(不确定它的版本是否默认情况下) - 你可以检查这个..
我猜测为什么它在 gst-launch 和您的应用程序中的行为不同,是因为您的应用程序中有一些额外的开销,这会导致处理速度变慢或其他原因,并且由于某些事情被推迟,您会收到未协商的错误。
我在日志中注意到这一点:
0:00:00.608577000 29168 0x7fb5a401d850信息basesrc gstbasesrc.c:2838:void gst_base_src_loop(GstPad *):标记待处理DISCONT
这意味着一些数据包比预期晚到达并被丢弃。
尝试在 udpsrc 之后添加队列,这将缓冲一些数据包:
queue = gst_element_factory_make ("queue", "srcqueue");
Run Code Online (Sandbox Code Playgroud)
当然,添加到管道和链接之间:
if (gst_element_link_many (source, queue
rtph263pdepay, h263p, sink, NULL) != TRUE) {
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20576 次 |
| 最近记录: |