使用GStreamer同步两个RTSP / RTP H264视频流捕获

时间:2016-05-31 20:36:15

标签: gstreamer h.264 rtsp

我有两台AXIS IP摄像机通过RTSP / RTP传输H264流。两台摄像机都设置为与同一台NTP服务器同步,因此我假设两台摄像机都具有相同的精确时钟(可能是毫秒级的微小差异)。

在我的应用程序中,两个摄像头都指向同一视图,并且需要同时处理两个摄像机图像。因此,我想使用GStreamer同步图像捕获。

我尝试在不同的cmd提示下分别调用两个管道但视频相隔2-3秒enter image description here

  1. gst-launch rtspsrc location = rtsp://192.168.16.136:554 / live! rtph264depay! h264parse! splitmuxsink max-size-time = 100000000 location = cam1_video_%d.mp4
  2. gst-launch rtspsrc location = rtsp://192.168.16.186:554 / live! rtph264depay! h264parse! splitmuxsink max-size-time = 100000000 location = cam2_video_%d.mp4
  3. 有人建议使用gstreamer管道同步两个H264流并将它们记录到单独的视频文件中吗?

    谢谢! ARM

2 个答案:

答案 0 :(得分:1)

你是什么意思同步?如果你录制到单独的视频文件,你不需要任何同步..因为这将完全分开它们..每个RT(S)P流将包含不同的时间戳,如果你想以某种方式将它们对齐到同一时间(我意味着真正的人类时间..就像“两者应该从15:00开始”)然后你必须以某种方式配置它们(这只是想法)..

此外,您没有告诉我们这些rtp / rtsp流中的内容(是MPEG ts还是纯IP等等)。所以我将举例说明mpeg ts封装的rtp流。 我们将一步一步走:

假设这只是一台相机,只是为了展示它的外观:

gst-launch-1.0 -v videotestsrc ! videoconvert ! x264enc ! mpegtsmux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=8888

然后这将是接收者(它必须使用rtmp2tdepay。我们将元数据封装在MPEG容器中):

gst-launch-1.0 udpsrc port=8888 caps=application/x-rtp\,\ media\=\(string\)video\,\ encoding-name\=\(string\)MP2T ! rtpmp2tdepay ! decodebin ! videoconvert ! autovideosink

如果您使用相机测试.. autovideosink意味着会弹出一个新窗口显示您的相机..

然后你可以尝试将它存储在文件中..我们将使用mp4mux .. 因此,对于相同的相机输入,我们会这样做:

gst-launch-1.0 -e udpsrc port=8888 caps=application/x-rtp\,\ media\=\(string\)video\,\ encoding-name\=\(string\)MP2T ! rtpmp2tdepay ! tsdemux ! h264parse ! mp4mux ! filesink location=test.mp4

说明:我们不解码和重新编码(浪费处理能力)所以我只是解复用MPEG ts流然后解码H264而不是解析它来接受mp4mux接受视频/ x-h264。

现在你可以为每个摄像头使用相同的管道..或者你可以将所有元素复制到同一个管道中。

现在,因为你没有提供任何 - 至少部分 - 尝试做出一些事情,这将是你的功课:)或者让自己更加清楚同步,因为我不理解它..

<强>更新 在您更新问题之后,这个答案不是很有用,但我会在此作为参考。我不知道如何同步..

另一个建议..尝试在udpsrc之后查看时间戳..也许它们已经同步了......在这种情况下你可以使用streamsynchronizer来同步两个流......或者可能是视频/音频混音器:

gst-launch-1.0 udpsrc -v port=8888 ! identity silent=false ! fakesink

这应该打印时间戳(PTS,DTS,持续时间......):

/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain   ******* (identity0:sink) (1328 bytes, dts: 0:00:02.707033598, pts:0:00:02.707033598, duration: none, offset: -1, offset_end: -1, flags: 00004000 tag-memory ) 0x7f57dc016400

比较每个流的PTS ..也许你可以在一个管道中组合两个udpsrc,并在每个udpsrc之后放置标识(使用不同的name=something1)以使它们一起开始接收..

HTH

答案 1 :(得分:1)

我可以使用gst-launch启动管道,如下所示。与对两个管道进行比较,它显示了对捕获的帧同步的良好改进。大多数情况下它们相差0-500毫秒。虽然,我仍然想要将它们的精度小于150毫秒。

rtspsrc location = rtsp://192.168.16.136:554 / axis-media / media.amp?videocodec = h264! rtph264depay! h264parse! splitmuxsink max-size-time = 10000000000 location = axis / video_136_%d.mp4 rtspsrc location = rtsp://192.168.16.186:554 / axis-media / media.amp?videocodec = h264! rtph264depay! h264parse! splitmuxsink max-size-time = 10000000000 location = axis / video_186_%d.mp4

感谢有人能指出其他想法!

〜臂