APP下载

基于Android4.2系统的H.264视频数据的获取

2017-08-12

计算机应用与软件 2017年7期
关键词:视频流原始数据解码

张 斌

(中国兵器工业第五八研究所军品部 四川 绵阳 621000)



基于Android4.2系统的H.264视频数据的获取

张 斌

(中国兵器工业第五八研究所军品部 四川 绵阳 621000)

针对目前Android系统下利用MediaRecorder和LocalSocket类从MPEG4文件数据中获得H.264原始数据存在的问题:需要手工填写SPS、PPS帧数据和没有NAL同步头造成数据读取不可靠,提出新的H.264原始数据的获得方法。利用Android系统MediaRecorder类自身的数据输出格式(DEFAULT)作为参数,在HAL层StagefrightRecorder类的处理方式中,构建H264Writer类,实现H.264原始数据的获得或文件存储。同时兼容MPEG4的所有处理方式,并提高获取数据的效率和稳定性。该方案丰富了Android系统对视频数据的处理方法。

H.264 MPEG4 SPS PPS HAL RTSP

0 引 言

Andriod系统本身不支持H.264视频原始压缩数据(即符合H.264压缩标准,具有NAL同步头的视频流数据)的实时获取。通过研究文献表明,解决方法主要有2种:1)利用MediaCodec[1]类对摄像头数据进行压缩获得H.264数据;2)利用MediaRecorder[2]类、setOutputFile()函数可以接收文件描述符作为参数的特点,用LocalSocket类的文件描述符从MPEG4文件流中获得H.264视频流数据,实现视频数据存储或传输。经过实际测试发现,方法1)存在的缺点是需要从摄像头获得AD数据,不停地传输给MediaCodec编码,对压缩后的数据进行打包传输时,节奏控制不好容易卡顿。方法2)有两个缺点:(1) 在MPEG4文件流中,H.264[3]压缩数据抛弃了同步头NAL(Hex Data:00,00,00,01),转而依靠4字节的帧数据长度来获得一帧数据。当读写错误造成数据指针出错,不能获得有效的数据长度错误,编程人员并不能进行有效的判断,从而造成解码端不能正确解码或数据丢帧,影响视频实时播放效果。(2)视频流数据是MPEG4文件流中获取的, H.264视频流SPS和PPS帧不能直接确定,当视频流的分辨率等相关信息改变后,需要人工填写通过协议传送到解码端,这样不是很灵活。因此,通过分析Android 4.2.2的源代码和MediaRecorder类的框架体系[4],在HAL[5]层上解决了该问题,并实现了H.264视频流数据获取、传输或者数据文件保存。兼容MPEG4等视频格式的所有处理方式,提高了获取数据的效率和稳定性,同时也丰富了Android系统对视频数据的处理方法。

1 软件环境、硬件平台介绍

本文Android版本为4.2.2,硬件平台为OMAP4660开发板PandaBoardES1。OMAP4460包含两个Cortex-A9核,频率达到1.5 GHz,同时集成了两个Cortex-M3核,还包括图像、视频加速子系统IVA-HD3和PowerVR SGX540图形核心,相比于OMAP4430,大幅提升了其图形性能,1080p视频播放性能提升一倍,达到了PC 式 Web 浏览。OMAP4460支持HDMI 1.4接口3D高清视频输出,支持1080p/60FPS高清解码,支持最高1 200万像素双摄像头,支持全高清1080P/30FPS 多标准视频编码/解码。另外,OMAP4460还支持SmartReflexTM2 技术,根据设备活动、操作模式和温度来动态控制电压、频率和功率,进一步降低功耗。

2 Android MediaRecorder介绍

Android的MediaRecorder类是用来实现Audio和video的记录功能,Android系统自带的Music和Video APK就是调用MediaRecorder类开发实现的。 MediaRecorder在底层基于OpenCore(PVMF)库实现的,在上层利用进程间通信等内容(这种进程间通信的基础是Android基本库中的Binder机制[6])构建一个MediaRecorder程序。

MediaRecorder类从上到下的类调用顺序如下:

MediaRecorder.java

+- android_media_MediaRecorder.cpp

+- MediaRecorder.cpp

+- MediaPlayerService.cpp

+- MediaRecorderClient.cpp

+- StagefrightRecorder.cpp

+- MPEG4Writer.cpp,AACWriter.cpp等

针对Android系统与硬件有关的代码处理都集中在HAL层的特点,利用系统视频压缩格式缺省的文件输出格式3GPP(default)作为参数传递,即在MediaRecorder类调用时,设置视频文件的输出格式为MediaRecorder.OutputFormat.DEFAULT。然后在StagefrightRecorder类中对缺省编码方式实现特殊处理,并且参照MPEG4Writer类实现了自定义的H264Writer类,从而实现了H.264原始数据的文件存储和数据传输功能。

3 Stagefright Recorder类修改

本文在StagefrightRecorder类的构造函数中调用reset函数进行了初始化设置。该类默认的文件OutputFormat为3GPP,AudioEncoder为AMR NB,VideoEncoder为H.264。图1为MediaRecorder流程及StagefrightRecorder类支持输出的文件格式。

图1 MediaRecorder流程及Stagefright Recorder支持输出的文件格式

在StartMPEG4Recording的处理中创建MPEG4Writer,用于写数据,设置setupAudioEncoder和setupVideoEncoder,把audio track和video track放入到track。

本文将default选项提取出来,进行单独的处理,如图2所示,图中虚线部分即为添加处理部分。

图2 Stagefright Recorder增加default处理后框图

该类源代码所在目录路径为:

./frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp。

代码修改如下:

1) 添加头文件

#include

2) 修改setOutputFormat()函数

屏蔽对OUTPUT_FORMAT_DEFAULT的处理,直接将参数of赋值给mOutputFormat;

3) 修改start函数

屏蔽系统对OUTPUT_FORMAT_DEFAULT的默认处理,添加单独处理代码:

case OUTPUT_FORMAT_DEFAULT:

startH264Recording();

break;

4) 仿照setupMPEG4Recording()函数,创建setupH264Recording()函数,将new MPEG4Writer(outputFd)替换为new H264Writer(outputFd);

5) 仿照startMPEG4Recording()函数,创建startH264Recording()函数。

4 MPEG4 Writer类介绍

MPEG4Writer类主要实现将H.264压缩编码获得的H.264视频流数据,以MPEG4文件格式为存储方式进行一系列处理,如填写MPEG4文件[7]头块ftpy、压缩视频数据存放等。MPEG4 Writer封装好的视频格式如图3所示。

图3 MPEG4视频文件存储格式

在该封装格式中,首先填写fypy块,然后填写mdat。H.264视频流数据就存放在mdat块中,其中将NAL(00,00,00,01)头以4个字节一帧数据的长度替换,逐帧存储。当结束录像(文件保存)后,再回填moov等box数据,该数据块包含该段视频总帧数和时长等相关数据信息。

5 构建H264 Writer类

H264Writer类主要为获取H.264压缩视频流数据,直接存储到Java层传递来的文件描述符的句柄中。因此MPEG4Writer类里面的填写fypy块,回填moov等box块数据的处理方式都屏蔽了。

1) 仿照MPEG4Writer.cpp,MPEG4Writer.h生成相应的H264Writer.cpp、H264Writer.h,并且将头文件拷贝到相应的include目录。

2) 修改start()函数,屏蔽写FtypBox的过程,屏蔽代码从writeFtypBox(param)开始到status_t err = startWriterThread()之前结束。

3) 修改reset()函数,该函数主要实现moov等各种box块的填写,屏蔽代码从if (mUse32BitOffset)开始到CHECK(mBoxes.empty())之前结束。

4) 修改Track::threadEntry()函数:

① 屏蔽if(buffer->meta_data()->findInt32 (kKeyIsCodecConfig, &isCodecConfig)的整个处理过程;

② 屏蔽代码从mOwner->trackProgressStatus (mTrackId, -1, err)开始到sendTrackSummary (hasMultipleTracks)结束。

5) 修改addLengthPrefixedSample()函数,将代码:

uint8_t x=length >> 24;

::write(mFd, &x, 1);

x=(length >> 16) & 0xff;

::write(mFd, &x, 1);

x=(length >> 8) & 0xff;

::write(mFd, &x, 1);

x=length & 0xff;

::write(mFd, &x, 1);

修改为:

uint8_t x = 0x00;

::write(mFd, &x, 1);

::write(mFd, &x, 1);

::write(mFd, &x, 1);

x=0x01;

::write(mFd, &x, 1);

6) 修改MPEG4Writer.cpp文件所在目录的Android.mk文件,添加H264Writer.cpp。

6 编写APK测试

为了检验以上的驱动开发是否可行、可靠,笔者编写了APK测试程序,利用Media Recorder类进行视频流媒体数据采集[8],同时移植了live555服务器程序,以RTSP[9-11]传输的方式,在两个Android设备之间实现了实时视频传输实现,整个程序的流程如图4、图5所示。

图4 测试APK系统框架图

图5 H.264视频流数据存储或RTSP传输播放流程图

7 结 语

通过以上方法,本文实现了H.264原始数据的文件存储,而且在移植了live555服务器源代码后,利用管道文件的方式,实现了手机端作为RTSP服务器的功能,从而在其他设备上实现了实时视频流播放功能,并且稳定、可靠。同时也扩展了Android系统对视频数据处理的方式,唯一不足是视频延时较大,接近500 ms。如何解决时延问题,不在本文讨论范围内。

[1] 李宗辰. 基于Android的多路视频监控用户平台的研究与实现[D]. 南京:南京邮电大学,2014.

[2] liujikunljk. android流媒体之硬编码代码篇[EB/OL].(2012-10-30)[2016-05-20]. http://www.apkbus.com/blog-86476-43829.html.

[3] 毕厚杰. 新一代视频压缩编码标准—H.264/AVC[M]. 北京: 人民邮电出版社, 2004:162-163.

[4] 李俊. Android系统源代码分析[M]. 北京: 中国铁道出版社, 2015:157-183.

[5] 陈强. Android底层接口与驱动开发技术详解[M]. 北京: 中国铁道出版社, 2012:143-166.

[6] 林学森. 深入理解Android内核设计思想[M]. 北京: 人民邮电出版社, 2014: 676.

[7] Iain Richardson. H.264和MPEG-4视频压缩[M]. 欧阳合,译. 长沙: 国防科技大学出版社, 2004:252-254.

[8] 巢文涵. Android多媒体开发高级编程[M]. 北京: 清华大学出版社, 2012:143-159.

[9] 李洋. 网络协议本质论[M]. 北京: 电子工业出版社, 2011:332-338.

[10] 谢希仁. 计算机网络[M]. 6版. 北京: 电子工业出版社, 2013:331-340.

[11] 陈强. 精通Android 实例开发[M]. 北京: 人民邮电出版社, 2015:522-527.

THE VIDEO DATA OF H.264 ENCODED OBTAIN BASED ON ANDROID 4.2 SYSTEM

Zhang Bin

(DepartmentofMilitaryProducts,No. 58ResearchInstituteofChinaOrdnanceIndustries,Mianyang621000,Sichuan,China)

For the current Android system, the MediaRecorder Class and LocalSocket Class are used to obtain the data of H.264 Encoded data from the MPEG4 file, but the method has the problem that the SPS should be filled manually and the data reading is unreliable since the PPS frame data is not synchronized with the NAL. Thus, the new data obtaining method is proposed. In the article, the self-DEFAULT is used as parameter in the MediaRecorder in Android system, then, the H264Writer class is constructed in the dealing method of the StagefrightRecorder in HAL layer, realizing the achievement and the save of the files of H.264. Meanwhile, the method handling the data of MPEG4 are compatible and improves the efficiency and stability of the data acquisition. The technique enriches a way to handle the video data for Android.

H.264 MPEG4 SPS PPS HAL RTSP

2016-09-18。兵器装备集团公司基金项目(EJ13-8028,EJ11-8014)。张斌,高工,主研领域:嵌入式Linux,Android系统开发。

TP391.41

A

10.3969/j.issn.1000-386x.2017.07.022

猜你喜欢

视频流原始数据解码
边缘实时视频流分析系统配置动态调整算法研究
《解码万吨站》
受特定变化趋势限制的传感器数据处理方法研究
解码eUCP2.0
NAD C368解码/放大器一体机
Quad(国都)Vena解码/放大器一体机
全新Mentor DRS360 平台借助集中式原始数据融合及直接实时传感技术实现5 级自动驾驶
铁路货场智能大门集装箱全景图像采集方法研究
美国视频流市场首现饱和征兆
对物理实验测量仪器读数的思考