我不确定您的真实用例是什么,但以下内容可能会帮助您进一步调查。
我没有 4K IP cam,所以在这里我将模拟使用 CSI Cam 以 1080p@30 fps 捕获并放大到 3840x2160 并以 H265 编码的 RTSP 服务器测试启动流式传输:
./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 "
请注意,这将编码为具有 30Mb/s 比特率的 H265 格式。您可以先检查是否可以从源中获得高质量的图像并将源比特率调整到最佳状态。假设您的显示器支持 1080p@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 日:
您可以进一步尝试以下操作,我的 AGX Xavier 运行 L4T R32.6.1 似乎可以正常工作:
- 使用 H265 视频读取 RTSP 流、解码、编码到 VP9 并使用 RTP/UDP 流式传输到 localhost 的应用程序:
#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
- 用于从本地主机上的 RTP/UDP 读取 VP9 编码视频的应用程序,解码和重新缩放到 1080p nvvidconv,然后在测量 fps 时显示在 X 中:
#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-H265 RTSP 源,首先gst_testlaunch1
在终端中运行,然后gst_testlaunch2
在第二个终端中运行,以正确的质量显示图像并保持 30 fps。