我正在使用CSI相机输入的流媒体设备。我想用tee复制传入流,然后使用gst-rtsp-server使用不同的url访问这些流。我的相机上只能有一个消费者,所以不可能有两个独立的管道。这可能吗?请参见下面的伪管道。
source -> tee name=t -> rtsp with url0 .t -> rtsp with url1
谢谢!
编辑1:
我尝试了第一个解决方案与appsink | appsrc对,但我只成功了一半。现在我有两个管道。
nvv4l2camerasrc device=/dev/video0 ! video/x-raw(memory:NVMM), width=1920, height=1080, format=UYVY, framerate=50/1 ! nvvidconv name=conv ! video/x-raw(memory:NVMM), width=1280, height=720, format=NV12, framerate=50/1 ! nvv4l2h264enc control-rate=1 bitrate=10000000 preset-level=1 profile=0 disable-cabac=1 maxperf-enable=1 name=encoder insert-sps-pps=1 insert-vui=1 ! appsink name=appsink sync=false
和
appsrc name=appsrc format=3 is-live=true do-timestamp=true ! queue ! rtph264pay config-interval=1 name=pay0
第二个管道用于创建媒体工厂。我把缓冲区从appsink推到appsrc回调到new-sample信号,就像这样。
static GstFlowReturn
on_new_sample_from_sink (GstElement * elt, void * data)
{
GstSample *sample;
GstFlowReturn ret = GST_FLOW_OK;
/* get the sample from appsink */
sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
if(appsrc)
{
ret = gst_app_src_push_sample(GST_APP_SRC (appsrc), sample);
}
gst_sample_unref (sample);
return ret;
}
这个工作-视频是流的,可以在不同的机器上看到使用gstreamer或vlc。问题在于延迟。由于某些原因,延迟大约是3秒。当我将这两个管道合并为一个直接创建媒体工厂而不使用appsink和appsrc时,它工作得很好,没有大的延迟。
我认为由于某种原因,appsrc一直在排队缓冲区,直到它开始将它们推送到它的源pad -在下面的调试输出中,你可以看到它稳定自己的排队字节数。
0:00:19.202295929 9724 0x7f680030f0 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (1113444 >= 200000)
0:00:19.202331834 9724 0x7f680030f0 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (1113444 >= 200000)
0:00:19.202353818 9724 0x7f680030f0 DEBUG appsrc gstappsrc.c:1863:gst_app_src_push_internal:<appsrc> queueing buffer 0x7f58039690
0:00:19.222150573 9724 0x7f680030f0 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (1141310 >= 200000)
0:00:19.222184302 9724 0x7f680030f0 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (1141310 >= 200000)
编辑2:
我将max-buffers属性添加到appsink并建议属性到队列,但它根本没有帮助。
我只是不明白它怎么能缓冲这么多缓冲区,为什么。如果我用GST_DEBUG=appsrc:5运行我的测试应用程序,那么我得到这样的输出:
0:00:47.923713520 14035 0x7f68003850 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (2507045 >= 200000)
0:00:47.923757840 14035 0x7f68003850 DEBUG appsrc gstappsrc.c:1819:gst_app_src_push_internal:<appsrc> queue filled (2507045 >= 200000)
根据这个调试输出,它都在appsrc中排队,即使它的max-bytes属性设置为200000字节。也许是我理解的不对,但是我觉得很奇怪。
我尝试了第一个解决方案与appsink | appsrc对,但我只成功了一半。现在我有两个管道。
我的管道现在是这样的。
nvv4l2camerasrc device=/dev/video0 ! video/x-raw(memory:NVMM), width=1920, height=1080, format=UYVY, framerate=50/1 ! queue max-size-buffers=3 leaky=downstream ! nvvidconv name=conv ! video/x-raw(memory:NVMM), width=1280, height=720, format=NV12, framerate=50/1 ! nvv4l2h264enc control-rate=1 bitrate=10000000 preset-level=1 profile=0 disable-cabac=1 maxperf-enable=1 name=encoder insert-sps-pps=1 insert-vui=1 ! appsink name=appsink sync=false max-buffers=3
和
appsrc name=appsrc format=3 stream-type=0 is-live=true do-timestamp=true blocksize=16384 max-bytes=200000 ! queue max-size-buffers=3 leaky=no ! rtph264pay config-interval=1 name=pay0
我能想到三种可能性:
-
使用appsink/appsrc(如本例所示)分隔管道,如下:
Factory with URL 1 Capture pipeline .---------------------------. .----------------------. appsrc ! encoder ! rtph264pay v4l2src ! ... ! appsink appsrc ! encoder ! rtph264pay '---------------------------' Factory with URL 2
您将手动从appsink中取出缓冲区并将它们推送到不同的appsrc中。
-
构建类似上面的东西,但是使用像interpipes或intervideosink之类的东西来代替appsink/appsrc来自动执行缓冲区传输
-
使用GstRtspSink(付费产品)