海思3559A国内基本没货了。原来基于3559A的开发暂时都用不了了。这几天搞了一块nvidia jetson NX板子,拿来做做编解码试试看效果。datasheeet关于编解码这块描述如下:
编码情况:
解码情况:
JPEG编解码情况如下:
根据我自己做的测试,感觉264/265还不错,但是jpeg效果不太好。
我做实验的环境如下:
jetpack和L4T都是最新的官方推荐版本。下面我把一些实验过程与结果记录如下。
第一部分:环境准备
1 首先你要有一个nvidia帐号,用于下载文档和各种软件。
2 在ubuntu1604的个人pc上安装sdk mamager,这里注意是在pc上。
3 启动sdk manager按照官方教程刷机,开始的时候,把该选的不该选的软件/插件都选上,等待下在完成,下班时候做这一步,第二天来看结果。最后把官方image和rootfs烧录到NX上,期间NX板子需要你输入用户名和密码。
4 刷机完成以后,基本不用做什么就可以使用,你可以认为是pc上ghost完整系统即可。
5 接下来你需要安装一个工具jtop,自己百度搜索安装即可。上面关于我的NX环境就是jtop这个小工具的页面截图,这个工具非常推荐。然后就可以进行GStreamer了。如果你对ffmpeg比较熟悉,那你得改成gstreamer,在nvidia上,ffmpeg有些功能不支持。不过264/265没问题。GStreamer开发一般先用命令行进行验证,在进行代码编写,如果你只使用视频相关的业务,用c进行code就可以,如果你还需要进行视觉识别,深度计算....那就得c++和python了。我只进行了视频相关的命令行学习与验证。
第二部分:usb camera相关操作
1 NX安装v4l2-ctl,sudo apt-get install v4l-utils,这个工具很强大。
2 查看usb camera的实际参数性能,了解更多的话,输入v4l2-ctl --help,还有2级help选项:
2.1 v4l2-ctl --list-devices
如果你的usb camera链接了NX的usb口,上面命令会输出/dev/videoX,如果你链接多个usb camera,会输出多个videoX,X从0往后依次增加,我的如下:
我的笔记本接了一个双目,还有笔记本自带的一个,所以显示一共是2个。
2.2 v4l2-ctl -d /dev/videoX --list-format-ext
查看第X个usb camera的具体参数,我看得是X=1,也就是双目,输出大概如下:
说明这个camera支持两种输出:mjpg和yuyv。
2.3 验证camera输出是否如参数所示:
2.3.1 v4l2-ctl --device=/dev/video1 --set-fmt-video=width=2560,height=960,pixelformat=0
pixelformat=0,表示是上面输出的index 0,也就是输出mjpg格式
2.3.2 v4l2-ctl --device=/dev/cideo1 -p 60 设置帧率为60,如果你设置的帧率camera不支持,会自动切换到与你的设置值相近的支持的值。
2.3.3 v4l2-ctl --device=/dev/video1 --stream-mmap=3 --stream-count = 600
通过mmap获取视频流,mmap buffer数量是3,也是默认值,输出600帧
达不到60帧,大概56帧,由于我们设置是输出600帧,所以前10行输出一共大概560帧,最后一行输出大概40帧。虽然达不到60,差不多吧。你也可以尝试验证其它分辨率和帧率是否如产品描述一致。
3 使用GStreamer操作usb camera,具体安装GStreamer自行搜索。
3.1 gst-launch-1.0 v4l2src device=/dev/video1 ! jpegdec ! xvimagesink
上面意思是,v4l2src获取视频流,传输给jpegdec,joegdec处理完传输给xvimagesink,一 共有三个处理单元,在GStreamer里这些单元称之为element。各个单元具体怎么用,有哪些参数可以设置使用如下命令:gst-inspect-1.0 v4l2src(jpegdec或xvimagesink)
上面的实际执行起来就是:v4l2src获取视频,传输给jpegdec解码,然后送给xvimagesink显示,最后你就可以在桌面看见视频了。jpegdec表示使用cpu解码,很流畅。
3.2 gst-launch-1.0 v4l2src device=/dev/video1 ! nvjpegdec ! xvimagesink
nvjpegdec表示使用nvidia的硬件解码,播放视频卡顿的很。
3.3 gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! nvjpegdec ! xvimagesink
播放就流畅了,io-mode=2,表示使用v4l2src使用mmap从驱动获取视频流,比直接copy to user操作快很多。
3.4 gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! 'image/jpeg,width=2560,height=960,framerate=60/1' ! nvjpegdec ! xvimagesink
也能流畅的播放,其中设置了要从camera获取视频的具体格式,当然你也可以设置其它camera支持的格式,‘image/jpeg,width=1280,height=480,framerate=60/1’,如果你设置的格式camera不支持,GStreamer会报错,不能出图。还有一点格式里的'image/jpeg'是必须项,没有的话也报错。
这里说明下,在nvidia NX上,使用nvjpegdec的话,cpu负荷会很大,并且帧率很小。看官方 forums说gstreamer的gstjpeg需要打补丁,但是找了很久,貌似补丁只支持L4T r32.2.1版本,没有找到关于L4T r32.5的有关说法。深入查找,发现官方给出如下说法,并且直到2021-03-08日依旧表示正在解决:https://forums.developer.nvidia.com/t/about-jpeg-decode-different-on-nano-and-nx/164894/10
3.5 gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! 'image/jpeg,width=2560,height=960,framerate=60/1' ! nvjpegdec ! xvimagesink sync=false
也可以正常播放,但是3.4和3.5的帧率都大概是20左右,修改分辨率到640x480,帧率大概能到50-60左右,感觉还是nvjpegdec的问题。
3.6 保存usb-camera的yuv转jpg格式图片
gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 !
'video/x-raw,width=1920,height=1080,framerate=25/1,format=YUY2' ! nvjpeg ! multifilesink location=%03u.jpg
YUY2就是YUYV,v4l2-ctl查看camera一般显示的格式是"MJPG"和"YUYV",但是gstreamer描述YUYV是YUY2。其实是一样的,名字不同而已。
3.7 修改分辨率
gst-launch-1.0 v4l2src device=/dev/cideo1 io-mode=2 ! image/jpeg,width=2560,height=960,framerate=60/1,format=MJPG ! nvjpegdec ! video/x-raw ! nvvidconv !‘video/x-raw(memory:NVMM),format=I420,width=2560,height=960,framerate=60/1’! nvvidconv ! video/x-raw,width=2560,height=960,format=I420 ! xvimagesink sync=false
红色和黄色可以修改成其它数值,黄色部分不能去掉。这里有一个gstreamer的emelent,nvvidconv,这个插件感觉很难理解,我个人的理解就是执行一次这个nvvidconv就进行一次拷贝,这个插件涉及到gpu内存和cpu内存的操作,有些操作必须在gpu执行,有些操作必须在cpu内存中执行,也有的在两种内存里都可以操作,然后按照设置的属性值进行变换,但是这样理解应该是肯定有误,起码不全面。刚开始接触,先这样理解吧。
3.8 usb camera 先jpeg解码,然后分别h264编码、h264解码,最后显示
gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! image/jpeg,width=2560,height=960,framerate=60/1,format=MJPG ! nvjpegdec ! video/x-raw ! nvvidconv ! 'video/x-raw(memory:NVMM),format=I420,width=2560,height=960,framerate=60/1' ! nvv4l2h264enc maxperf-enable=1 profile=4 preset-level=1 iframeinterval=500 control-rate=1 bitrate=4000000 ! nvv4l2decoder enable-max-performance=1 drop-frame-interval=1 ! nvvidconv ! video/x-raw,format=I420,width=2560,height=960 ! xvimagesink sync=false -e -v
延时情况如下图,大概450ms左右,并且修改编码器清晰度,码率,延时没有什么变化,修改上面命令行中的第一个2560为1280,第一个960为480,其它不变化,继续实验,延时大概300ms左右。说明瓶颈并不在264编解码模块,应该在nvjpegdec:
上面命令行,使用了nvidia硬件的nvenc、nvdec,nvjpg,具体的如下图:
具体的命令行中的各个参数,大家可以google或者baidu去了解,我所知也不深入,就不误人子弟了。
3.9
usb camera 先jpeg解码,然后h264编码,通过rtmp发送到公网阿里云端,然后通过公网拉流来观看。
gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! image/jpeg,width=2560,height=960,framerate=60/1,format=MJPG ! nvjpegdec ! video/x-raw ! nvvidconv ! 'video/x-raw(memory:NVMM),format=I420,width=2560,height=960,framerate=60/1' ! nvv4l2h264enc maxperf-enable=1 profile=4 preset-level=1 iframeinterval=500 control-rate=1 bitrate=2000000 ! h264parse ! flvmux ! rtmpsink location=rtmp://xxxxxxxxxxxxxxxxxx
延时情况如下,大概800ms,与3.8对比,网络传输大概350-400ms的样子:
第三部分 rtsp相关操作
1 直接播放海康rtsp流
gst-launch-1.0 rtspsrc location=rtsp://admin:admin1234@192.168.42.173:554/h264/ch1/main/av_stream latency=0 ! rtph264depay ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw ! nveglglessink sync=false
延时情况如下:
大概170ms左右,去掉latency=0和sync=false,很慢。具体延时没有测。
2 获取rtsp流,通过rtmp推流阿里公网,然后拉流播放
gst-launch-1.0 rtspsrc location=rtsp://admin:admin1234@192.168.42.173:554/h264/ch1/main/av_stream latency=0 ! rtph264depay ! h264parse ! queue ! flvmux ! rtmpsink location=rtmp://xxxxxxxxxxxxxxxxxxxx sync=false,延时情况如下:
大概700ms左右吧。就这么多吧,一些具体的参数我也还没有完全搞明白,大家多用v4l2-ctl和gst-inspect两个命令查。
阅读(14701) | 评论(0) | 转发(0) |