我在c++中有一个应用程序,可以从摄像机中使用gstreamer获取视频,然后通过UDP将视频发送到c++中的另一个应用程序,该应用程序获取视频并使用webrct进行重流。jetson AGX下的一切。
如果我从H264中的相机中获取数据,并以肮脏的方式发送数据,那么这些视频在4k内就会运行得非常完美:
第一个获得视频的管道
pipe_source = "rtspsrc location=rtsp://192.168.1.162/z3-1.mp4 ! application/x-rtp,encoding-name=H264,profile=baseline ! ";
pipe_sink = "udpsink host=224.1.1.1 port=5000 sync=false auto-multicast=true";
launch_pipeline = pipe_source + pipe_sink;获得视频并通过webrtc发送的第二个管道
pipeline = "udpsrc multicast-group=224.1.1.1 auto-multicast=true port=5000 ! application/x-rtp,encoding-name=H264,profile=baseline,media=video,clock-rate=90000,payload=96 ! webrtcbin async-handling=true name=sendrecv";但是,如果我想在输入视频中进行一些处理,我无法在4K中完成,因为我需要在udp发送视频之前对帧进行解码(然后编码)。
pipe_source = "rtspsrc location=rtsp://192.168.1.162/z3-1.mp4 ! application/x-rtp,encoding-name=H265 !";
pipe_decode = "rtph265depay ! video/x-h265 ! nvv4l2decoder enable-max-performance=true ! ";
pipe_process = "nvvidconv output-buffers=5 name=myconv ! video/x-raw(memory:NVMM), format=RGBA ! nvvidconv output-buffers=5 ! video/x-raw(memory:NVMM), format=NV12 ! queue max-size-bytes=0 max-size-time=500 !";
pipe_encode ="nvv4l2vp9enc maxperf-enable=true ! video/x-vp9 ! rtpvp9pay !";
pipe_sink = "udpsink host=224.1.1.1 port=5000 sync=false auto-multicast=true";
launch_pipeline = pipe_source + pipe_decode + pipe_process + pipe_encode + pipe_sink;在这个管道的来源,我已经尝试了H 264/H 265。更重要的是,对于我尝试使用h264而不是VP9的编码,但是看起来H264要慢得多。这就是我在编码部分使用VP9的原因。
在这种情况下,第二个管道是:
pipeline = "udpsrc multicast-group=224.1.1.1 auto-multicast=true port=5000 ! application/x-rtp,media=video,clock-rate=90000,encoding-name=VP9,payload=96, framerate=25/1 ! queue max-size-bytes=0 max-size-time=0 ! webrtcbin async-handling=true name=sendrecv";我的问题是,使用这种配置,我无法获得4k的质量良好的视频。我得到了视频,但在一个糟糕的质量,我假设VP9正在改变比特率,使一个连续的视频,而不失去帧。我尝试在编码部分给出比特率,这使图像质量有所提高,但我失去了一些帧。
如果我使用1080,那么我得到的视频质量很好,因此我有这样的感觉,那就是硬件的处理能力问题(我正在使用jetson )进行解码/编码。
有人知道如何提高管道的性能吗?我不确定我是否在做一些“无用”的事情,这使得整个过程对于4k视频来说是缓慢的。
发布于 2022-01-23 21:27:24
我不确定您真正的用例是什么,但下面的内容可能会帮助您进一步研究。
我没有4K的IP摄像头,所以这里我将模拟使用1080 p@30 fps中的CSI凸轮捕获,并将其升级到3840x2160,并通过RTSP服务器测试启动( H265 )进行流编码:
./test-launch "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=1920, height=1080, framerate=30/1, format=NV12 ! nvvidconv ! video/x-raw(memory:NVMM), width=3840, height=2160, pixel-aspect-ratio=1/1 ! nvv4l2h265enc insert-vui=true insert-sps-pps=1 insert-aud=1 maxperf-enable=1 bitrate=30000000 ! h265parse ! video/x-h265, stream-format=byte-stream ! rtph265pay name=pay0 pt=96 "请注意,这将以30/s的比特率编码为H265格式。您可以首先检查您是否可以从您的源获得高质量的图像,并调整源比特率到其最佳水平。假设您的监视器支持1080 p@30:
gst-launch-1.0 rtspsrc location=rtsp://127.0.0.1:8554/test latency=500 ! application/x-rtp,encoding-name=H265 ! rtph265depay ! h265parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,width=1920,height=1080 ! xvimagesink好的时候,让我们走得更远。
这里解码RTSP H265源并将其重新编码为VP9/RTP/UDP:
gst-launch-1.0 rtspsrc location=rtsp://127.0.0.1:8554/test latency=500 ! application/x-rtp,encoding-name=H265 ! rtph265depay ! h265parse ! nvv4l2decoder enable-max-performance=1 ! queue ! nvv4l2vp9enc maxperf-enable=true bitrate=30000000 ! video/x-vp9 ! rtpvp9pay ! udpsink host=224.1.1.1 port=5000 auto-multicast=true buffer-size=32000000注意VP9 30 Mb/s的比特率。你可能也得调整一下。
为了进行检查,您可以使用(假设X正在运行)显示:
gst-launch-1.0 udpsrc multicast-group=224.1.1.1 auto-multicast=true port=5000 buffer-size=32000000 ! application/x-rtp,encoding-name=VP9 ! rtpjitterbuffer latency=500 ! rtpvp9depay ! video/x-vp9 ! nvv4l2decoder ! nvvidconv ! video/x-raw,width=1920,height=1080 ! xvimagesink编辑2022年1月29日:
您可以进一步尝试以下操作,似乎在运行L4T R32.6.1的AGX上运行良好:
流到本地主机
#include <gst/gst.h>
int main (gint argc, gchar * argv[])
{
gst_init (&argc, &argv);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
/* Create the pipeline...this will negociate unspecified caps between plugins */
const gchar *pipeline1 = "rtspsrc location=rtsp://127.0.0.1:8554/test latency=500 ! application/x-rtp,encoding-name=H265 ! rtph265depay ! h265parse ! nvv4l2decoder enable-max-performance=1 ! queue ! nvv4l2vp9enc maxperf-enable=true bitrate=30000000 ! video/x-vp9 ! rtpvp9pay ! udpsink host=127.0.0.1 port=5000 auto-multicast=0 buffer-size=32000000 ";
GstElement *pipeline = gst_parse_launch (pipeline1, NULL);
if (!pipeline) {
g_error ("Failed to create pipeline\n");
exit(-1);
}
/* Ok, successfully created the pipeline, now start it */
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
g_error ("Failed to go into PLAYING state");
exit(-2);
}
g_print ("Running ...\n");
g_main_loop_run (loop);
return 0;
}使用:gcc -Wall -o gst_testlaunch1 -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/aarch64-linux-gnu/glib-2.0/include gst_testlaunch1.cpp -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0构建
#include <gst/gst.h>
int main (gint argc, gchar * argv[])
{
gst_init (&argc, &argv);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
/* Create the pipeline...this will negociate unspecified caps between plugins */
const gchar *pipeline2 = "udpsrc auto-multicast=0 port=5000 buffer-size=32000000 ! application/x-rtp,encoding-name=VP9 ! rtpjitterbuffer latency=500 ! rtpvp9depay ! video/x-vp9 ! nvv4l2decoder ! nvvidconv ! video/x-raw,width=1920,height=1080 ! fpsdisplaysink video-sink=xvimagesink text-overlay=0 ";
GstElement *pipeline = gst_parse_launch (pipeline2, NULL);
if (!pipeline) {
g_error ("Failed to create pipeline\n");
exit(-1);
}
// This will output changes and is required to display fps in terminal, you may remove it later to make it quiet.
g_signal_connect(pipeline, "deep-notify", G_CALLBACK(gst_object_default_deep_notify), NULL);
/* Ok, successfully created the pipeline, now start it */
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
g_error ("Failed to go into PLAYING state");
exit(-2);
}
g_print ("Running ...\n");
g_main_loop_run (loop);
return 0;
}使用:gcc -Wall -o gst_testlaunch2 -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/aarch64-linux-gnu/glib-2.0/include gst_testlaunch2.cpp -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0构建
有了4K-H265RTSP源,首先在终端上运行gst_testlaunch1,然后在第二个终端中运行gst_testlaunch2,以正确的质量显示图像,并保持30 fps。
https://stackoverflow.com/questions/70757292
复制相似问题