菜鸟手册9:Jetson gstreamer视频编码和解码
还记得之前建议大家在NVIDIA Jetson产品上安装一个小工具么? 答应我,NVIDIA Jetson这个小工具一定要装上!
没错,就是这个!
然后好几个用户就跑来问:Lady,为啥我的NVENC和NVDEC都是off的,难道我不配用硬件编解码么?
言外之意就是:
这里,我们借用这个开发者的文章,好好说道说道:
视频/成像和机器人技术是我感兴趣的主要领域,我经常希望/需要一个嵌入式平台来连续或按需从边缘设备传输视频。在其他情况下,您只需要在边缘设备上保存一些事件的记录,而不需要占用TB的存储空间。对于实时系统,视频传输的帧速率和延迟也很重要。通过最常用的媒介(以太网、无线局域网等)发送或存储未压缩的视频效果不佳;未压缩视频只需要大量带宽。
让我们举几个例子。
720p60(高清)视频:以每秒60帧的1280x720彩色视频为例。所需带宽=1280(宽度)x 720(高度)x 3(每像素颜色)x 8(每像素位数)x 60(帧/秒)=1.33 Gbps!!!
公共(有线)LAN连接(1Gb以太网)无法满足这一巨大的带宽需求。别想通过Wifi发送这个。还要记住,我们使用了一个简化的情况;由于开销(帧信号等),实际带宽消耗将更高。而且,大多数通信信道的实际带宽远低于大多数实际情况下的最大带宽。
我们甚至还没有达到全高清视频(剧透:彩色1080p60视频将需要超过3Gbps的带宽。每秒3G比特!!!)
这就是视频压缩的用武之地。这取决于您使用的压缩设置,但是要给出一个大致的数字,您可以期望带宽需求至少减少一个数量级。
例如,一个1080p30流可以以低于12Mbps的质量(H.264-base,高质量)进行流式传输。将其与未压缩视频的1.5Gbps相比,你就知道了!类似地,当压缩到H.264时,720p60流(前面讨论过)也可以以低于12Mbps的速率进行流式传输。对于H.265压缩,这些值进一步减小。
Nvidia Jetson的Gstreamer Pipeline(管道)
视频编码/解码是一个计算量很大的操作,最好使用专用的编码器/解码器硬件来完成。Nvidia Jetson设备配有内置的硬件编码器和解码器(分别称为NVENC和NVDEC),Jetpack附带gstreamer插件,以超简单的方式利用此功能。
在这篇文章中,我们将分享一些基本的gstreamer“管道”,让您开始(并兴奋)之后,您将有望进一步探索。我们不谈太多细节。
我已经尝试了以下使用Jetpack4.4和Nvidia Jetson NX设备,但这些应该可以在其他Jetson设备上正常工作。
准备工作
1.用Jetpack 4.4 刷机(以下省略500字)
2.安装Jetson-Stats (见文章顶部连接)
3.因为我要使用旧的usb-2网络摄像头作为源,所以我们将安装v4l-utils(视频用于Linux的实用程序)。要安装,只需在终端中键入以下内容
要查询v4l设备(将它们连接到您的Jetson的USB端口后),请使用以下命令
查询设备支持的格式(在这种情况下为video0)
或者,您可以简单地查询所有已连接的v4l设备
GSTREAMER管道
在gstreamer中,您构建“管道”来完成您的目标。把它想象成一系列的块,从源(测试源、摄像机等)开始,中间的任何处理块(格式转换、编码/解码等),以“sink”(屏幕显示、udp流地址、文件等)结束。
为了保持它的趣味性,我们将直接尝试一些简单的管道,从最简单的管道开始。
将视频测试源播放到屏幕:
从测试源开始总是个好主意
这将在屏幕上以30fps的速度显示1280x720的测试模式,如管道参数中指定的那样。
在屏幕上显示实时usb网络摄像头源:
这是最简单的gstreamer管道:
如果您的Jetson设备上连接了多个摄像头,可以按如下方式指定一个:
将测试模式视频编码为H264并保存到磁盘上的文件:
这里我们在末尾使用了filesink元素来指定保存到文件以及文件名。请注意,这将保存到您当前的工作目录中。通过在同一终端窗口中执行以下操作,可以查看当前的工作目录:
从文件读取、解码并在屏幕上显示:
现在我们可以读取之前保存的文件并在屏幕上显示内容
从网络摄像头对实时视频进行编码、解码和显示:
它可能看起来没什么用,但它可以用来查看仅仅通过编码和解码过程就为视频增加了多少延迟,而不受网络等因素的影响。
将网络摄像头视频编码为H.264并使用rtp(实时协议)流媒体:
这里有一个简单的管道来实现这一点
为了接收、解码和显示这个流,我们可以使用以下命令(在一个单独的终端中)
我们使用host=127.0.0.1流式传输到“localhost”(自己的机器)。要流式传输到另一台主机,您可以替换为该PC的IP地址。
从网络摄像头编码多个流:
你知道吗,Jetson视频编码器和解码器可以同时编码和解码多达4k的视频流,而不会消耗所有的CPU功率。为了演示和利用这一点,我们将构建一个gstreamer管道,以执行以下操作:
- 使用我们的usb摄像头作为源
- 使用“tee”元素制作我们的摄像机视频流的3个副本
- 按原样显示第一个流(即,在任何压缩之前)
- 使用H.264和流到端口5000对流的第二个副本进行编码
- 使用H.265和流到端口5001对流的第三个副本进行编码
注意,在本例中,当我们转换到同一个设备(localhost/127.0.0.1)时,您也可以将其替换为网络上另一台计算机/jetson设备的IP。
现在,在另一个终端(或者在另一个设备上,如果您使用的IP不是127.0.0.1),我们可以使用以下方法接收、解码和显示H.264流
类似地,我们可以使用下面的管道对H.265流执行相同的操作
注意Jetson设备上编码器和解码器功能的完整列表:
这个时候你再看看Jetson-Stats这个小工具,是否就开始工作了?
其他信息/提示...
1您可以使用详细模式获取有关gstreamer管道执行的其他信息。只需将-v添加到管道中即可显示其他信息。例如,请注意以下管道中的-v参数。
2要深入了解gstreamer管道,请阅读这里的更多内容:
https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/accelerated_gstreamer.html