从开发板推流到PC上播放
**【触觉智能 Purple Pi开发板试用】视频的采集编码与推流开发 **
大信
在前面的工作基础上,本次将进一步深入测试一下它的音视频支持功能。本次开发测试主要研究Purple Pi开发板对摄像头的支持,视频采集方法,视频编码与网络实时视频传输的实现过程。
## 一、测试USB摄像头驱动
因为之前测试过使用ffmpeg对文件的解码和转码。这次需要对实时视频进行测试,因此拿了一个摄像头来做配合。 首先测试一下该开发板支持摄像头的情况,摄像头还是采用之前经常出镜的 Logitech Webcam C270 USB网络摄像头作为视频采集设备.
把这个摄像头插入Purple Pi开发板的USB-A口,在终端里可以看到弹出识别出USB新设备的信息,如下图:
从信息中可看出,该摄像头识别为 uvc Camera 设备,并显示加载了驱动。通过 lsusb 命令也可以看到插入摄像头前后系统中USB设备信息的变化。
再查看系统驱动的接口设备信息,在dev 下出现了video0 设备文件。
再查看用户层视频采集驱动框架文件,在 /sys/class/video4linux/ 下也出现了 video0 的设备,如果这里将是空,则说明的摄像头没有识别出来。出现了 video0 说明已经发现并支持了该设备。
然后在启动一下之前写好的一个 v4l2_capture 软件,没有修改,在这个平台上编译一下,就可以在上面运行,运行主要是检测一下支持的视频采集类型与规格,运行命令如下:
./v4l2_capture -m list -d /dev/video0
从上面可以看到开发板系统支持的采集类型与规格。
## 二、视频采集测试
在准备好摄像头驱动检测时候,就可以进行视频采集测试,这里直接使用了在之前一款开发板的基于 v4l2 的采集程序,这个程序是在开源项目v4l2_capture基础上修改而成的,主要功能是调用v4l2框架,采集摄像头帧数据,然后把原始数据保存下来。这里为了方便测试,增加了一些命令参数。
另外注意到,摄像头视频数据规格里是YUYV422,而编码器和播放器一般都需要YUYV420格式,关于这个格式的区别,见下图:
YUV 4:4:4采样,每一个Y对应一组UV分量。 YUV 4:2:2采样,每两个Y共用一组UV分量。 YUV 4:2:0采样,每四个Y共用一组UV分量。 YUV存储格式 YUV存储可以分为两种:packed(打包)和planar(平面); packed:Y、U、V分量穿插着排列,三个分量存在一个Byte型数组里; planar:Y、U、V分量分别存在三个Byte型数组中; packed存储像素格式的顺序如下: 1.YUV422:YUYV、YVYU、UYVY、VYUY 而这些格式够可以相互转换,其算法网上很多,这里不再赘述。 启动v4l2的视频采集程序,命令如下: ./v4l2_capture -m capture -d /dev/video0 -o ./output.yuv
输出结果如下图:
生成的YUV 文件体积比较大,而开发板flash的剩余空间只有20M,大概能存几份钟文件空间就满了。再把yuv文件传送到pc文件夹下,使用yuvview.exe 播放器,进行播放,设置好视频格式以及尺寸,既可以看到采集的原始视频了,效果如下图:
## 三、视频编码测试
测试完视频采集后,就可以进行视频编码的测试,这里使用上次编译好的ffmpeg来进行采集编码测试。
开始测试时,ffmpeg启动一下就报出错误,崩溃掉,崩溃的信息如下图:
经过仔细分析,发现是内存空间不够,因为ffmpeg做视频采集和编码需要较大的内存,而该开发板内容只有64M,被系统占用后,留给应用的已经不多了,对ffmpeg这样的重量级程序显然需要更大内存。
通过查看系统内存,发现有几个进程占用较大内存,主要有屏幕显示进程与音乐播放服务进程,于是把这些进程杀掉之后,释放出了一些内容,具体如下图:
在释放出一些内存后,再开始进行ffmpeg的采集编码测试。
这里补充一下,ffmepg默认编译时是不带编码功能的,需要修改编译配置脚本,打开需要的编码选项后,才能进行编码。
由于开发板只有硬解码,并没有硬编码,只能使用软编码的方式,而软编码对系统的运算要求较高。通过反复测试,发现视频尺寸在 640x480以内,帧率在10帧以下时,才能够顺利的执行。
在开发板上启动ffmpeg进行采集编码,输出文件的命令如下:
./ffmpeg -f v4l2 -s 640*360 -r 10 -i /dev/video0 test.mp4
运行的输出信息如下图:
在使用编码之后,产生的文件尺寸大大缩小,20M的空间也可以存储将近30分钟以上的视频了。
把编码生成后的文件传到PC 上,点击生成的mp4文件,能够正常的播放,说明视频采集编码验证通过。
播放采集编码的视频效果如下图:
## 四、视频采集编码推流开发
在完成视频采集编码之后,那么就可以再结合网络进一步将编码的数据,通过视频流媒体协议发送出去,形成实时视频流,这样就可以在线观看直播了。
由于ffmpeg可以把视频文件进行网络推流,在开发板上无法对摄像头采集编码并推流,因此这里采用了基于ffmpeg的库,通过编写代码来实现 rtp over udp的流推送方式,同时也支持文件推流和编码保存到文件功能。使用rtp/udp的推流这样在播放端可以使用任何支持rtp/udp的播放器来播放了,而不需要再开发播放端了,非常方便。
在采集编码推流都采用调用ffmpeg的方式来进行。具体代码和主要调用的ffmpeg函数如下图:
编写代码如下图:
在写一个makefile编译脚本文件,如下:
然后进行编译,为了方便测试加入了命令行的提示和帮助,首先切换到交叉编译环境,使用命令: source /home/lutherluo/workspace/Purple_Pi/env.sh
然后进行编译: make
再传输到开发板上:
操作编译过程如图:
在开发板上执行以下,看一下运行输出如下图;
## 五、推流到PC上播放测试
接下来首先测试推流到PC电脑上,进行播放测试。首先确定PC的IP地址,如下图:
因为是推流,所以需要先打开播放端,准备好接收,当然后打开也没问题。打开windows下的 VLC 播放软件,这里使用的是VLC Player 3.0.17.4版本,不同版本的流地址格式会有不同,查看相关资料可以看到。 这里点 media -> Open Network Streaming ,在network url 输入播放地址: udp://@:5000 –demux=h264 这个地址意思是,打开本机5000端口,接收编码为h264的udp视频流,准备接收并播放视频流。 然后在开发板上运行开发的软件,命令如下: ./ffmpeg_live -m camera -d /dev/video0 -u "udp://192.168.50.197:5000"
-u 后面的参数就是推流的目标地址和端口,即windows电脑。然后vlc player顺利的出现了摄像头的实时画面,即PC上推流成功。
视频效果帧率为10,码率为1M,画幅为640x360,播放画面效果如下:
在PC上测试通过后,又进一步在手机上进行流接收播放测试,测试开发板通过采集编码通过wifi推流到手机上播放的情况。
和PC类似,首先手机连入和开发板在同一路网络下的路由器上,然后查看本机的IP地址,为192.168.50.116。在手机上安装android版本的VLC Player,点击启动,添加直播地址和PC一样,播放网络流媒体,地址:
udp://@:5000 –demux=h264 然后在开发板上启动推流程序,命令为: ./ffmpeg_live -m camera -d /dev/video0 -u "udp://192.168.50.116:5000"
稍后在手机上,就能看摄像头的实时画面了。画面完成没有出现丢数据活花屏的现象。即验证推流到手机上成功。 推流操作和手机上播放如下面两图:
## 七、PurplePi上视频开发总结
在该开发板上验证了连接uvc摄像头,进行视频采集,编码与实时推流的过程。该开发板并不带硬编码,但通过软编码的方式,对较小的画面和10fps左右的帧率,可以达到实时的采集编码与传输。
由于板上资料紧张,因此在编译ffmpeg中,需要不断的进行修改配置文件,既要保留必要的软件组件又要减少体积和运行时的内存消耗。同时在基于ffmpeg开发过程,也要随时注意内存使用,比如减少缓冲区的大小,增加GOP参数等,通过多管齐下进行优化,才能开发出较为理想的视频应用。
同时因为使用视频h264软编码,因此软件在运行时,系统占用率比较高,通过查看cpu使用率,可以我们的采集编码进程占用了超过90%的系统资源,系统使用率见下图。
通过本次的开发验证,可以看到在PurplePi开发音视频应用非常方便,由于基于开源的ffmpeg,使开发能够方便的进行裁剪开发,从而在让通常需要更高硬件资源的应用能在此硬件上运行。在相同功能下,无疑该方案更具有竞争力。
为方便网友测试最后附上两个编译好的程序,可以直接复制到开发板上解压运行。同时附上在PC和手机上推流的测试视频。 -------------------------------------干货分割线-------------------------------------- v4l2 工具,检测usb摄像头,并采集视频:
实时采集+编码+推流程序:
从开发板推流到手机上播放
|