USB Camera V4L2 视频录制——Android(1)

博主QQ:1356438802

QQ群:473383394——UVC&OpenCV47


前传:

前面研究了大半年的OpenCV开源库,其实也是断断续续的研究哈,本来是要做USB Camera图像识别的。但是公司有个项目要做USB Camera视频录制,所以先看了下OpenCV对于USB Camera录像的支持,在windows平台是可以的《win7_64bits下QT使用openCV库(3)》,在Ubuntu也是可以的《我的Ubuntu安装使用openCV记录(3)——for QT》,在Android上就不行《我的Opencv4Android添加V4L2支持的移植记录(3)》,需要FFMPEG的支持,而前面我已经研究过了FFMPEG,其在Android上的运行效率不乐观。所以我就打消了用OpenCV来做USB Camera录像的念头!


正文:

经过前面文章的实验《USB Camera V4L2 视频录制——ubuntu(1)》,我已经成功的将各种视频编码流写入avi视频文件,现在我要将其移植到Android上。

USB Camera V4L2 视频录制——Android(1)_第1张图片

需要源码的童鞋,加QQ1356438802



1. UVC_FFMPEG

UVC_FFMPEG在《FFMPEG研究: Android下录制/dev/video0设备h264编码保存为mp4格式视频》中已经讲过,是调用FFMPEG开源库来操作V4L2设备,读取视频,并且编码保存视频文件,同时将AVFrame刷到SurfaceView预览。但是由于这个开源库结构复杂,函数调用效率降低,另外它也是外接x264-lib进行h264编码,属于软件编码,非常消耗资源,从而导致预览的时候卡顿。

2. UVC_h264

UVC_h264和UVC_h2642,直接用V4L2-API读取帧数据,刷显示,多线程h264编码、avilib录制。

a. 从这个代码运行时可以看出,由于是多线程机制,h264编码是独立的线程,所以预览并不会卡顿,结果是预览线程刷新了大概50个Frame,录制线程才压缩完一个Frame,可见h264编码多么的消耗系统资源。在Ubuntu中不明显,而在Android平台就很鸡肋!

b. 这里也是用的x264-lib来编码,有很多参数需要初始化,前面Ubuntu中的h264encoder代码直接用在这里,compress_frame会返回错误。所以在没有深入研究时,很难做一个有用的编码!现在的代码编码后的视频帧率不对。

c. Android java的Thread类及Runnable接口,如何做到随时暂停、随时重启,在UVC_h2642中得到解决!


3. UVC_MJPEG

UVC_MJPEG,也是直接用V4L2-API读取帧数据,刷显示,多线程MJPEG4编码、avilib录制。

a. 首先MTK平台USB Camera只支持MJPEG格式读取数据,不支持YUV或者RGB等比较原始的数据格式,因为数据量很大。

b. avi只是一个封装格式,里面的视频,可以是任何格式。avi mkv mp4都是封装格式,里面可以有视频流,音频流,字幕流。h264 MJPEG YUV是视频流编码格式。封装格式和视频流编码格式是两个不同的概念。所以avi视频文件里面的视频流可以是h264编码,也可以是MJPEG编码,也可以是YUV编码。如下图
USB Camera V4L2 视频录制——Android(1)_第2张图片

同样是300帧的视频,同样是avi视频文件,视频流编码格式不同,大小差别太大。MTK USB Camera不支持YUYV,估计是因为其USB带宽不足以支撑这么大的数据流。另外h264的压缩率真的很高很高!

c. 数据流:MJPEG-->MJPEG-->avilib,过程中完全不需要解码编码,直接把MJPEG流写入AVI文件。这个方式是最省事,节省资源的。只是MJPEG编码 压缩率没h264那么高。

d. 在多线程机制下,临界资源保护时,如果对于资源的处理过程很耗时,那么这个处理过程不应该放在保护区内。最好的方式是,在临界区将资源拷贝一份,离开临界区后再去处理资源,比如涉及到编解码过程,或者写avi文件。典型的,需要用空间换时间的策略!


综上:
1. 现在看来,也就UVC_MJPEG能够满足稳定的实时预览和录制功能,它的编码压缩率属于中等,对于公司项目基本可以。
2. 在Android平台放弃对x264编码库的研究,转而研究Android原生MediaCodec,它支持硬编解码,有网友说效果不错。




你可能感兴趣的:(Android,UVC_V4L2)