论文部分内容阅读
摘要:本文将开源的FFmpeg提供的 H.264解码器进行裁剪优化,从中提取 H.264 解码的核心部分,并移植到Android平台,完成了一种Android平台下的H.264解码方案的设计,并在真机下进行了测试取得了较好的解码播放效果。
关键词:Android;H.264;解码器;FFmpeg
【中图分类号】N94-0
0 引言
H.264/AVC标准是一种高性能的视频编解码技术,相比其它标准具有更高的压缩率、高质量图像、容错功能、并有很强的网络适应性。近年来Android系统的也迅猛发展和日趋成熟,其因其具有开放性、便携性、良好的兼容性和可无缝结合网络通信等特点,Android操作系统在未来嵌入式物联网领域中将会有更广泛的应用。
目前越来越多的Android视频应用被开发出来,而人们追求的视频高清化和目前网络带宽及智能手持设备解码能力均不足的矛盾也逐渐凸显出来,本文设计的基于Android系统的H.264在线高清解码系统就可以解决这一问题。
1 Android操作系统简介
Android系统是一种以Linux为内核开发的专门面向移动平台的开源智能操作系统,具有丰富的硬件资源和软件应用程序资源、支持各种网络协议和触屏输入,短短的几年时间,Android凭借这些特性,已经在智能手机领域占据了非常重要的位置。随着物联网时代的到来,Android系统的前景将更加不可限量。
Android系统由以下三个部分组成: Linux内核层、Android 运行时库和其他库层、应用程序层。
Linux内核层用来提供系统的底层服务,包括安全机制、内存管理、进程管理、网络堆栈及一系列的驱动模块。作为一个虚拟的中间层,该层位于硬件与其它的软件层之间。需要注意的是,这个内核操作系统并非类GNU/Linux的,所以其系统库、系统初始化和编程接口都和标准的Linux系统有所不同的。
Android运行时库和其他库层包含一组核心库(提供Java语言核心库内的大部分功能)和Dalvik虚拟机。在应用层Android开发人员拥有访问框架API的全部权限。应用层的结构化设计简化了各组件之间的重用, 任何应用都可以分发自己的组件, 任何应用也可以使用这些分发的组件。
2 H.264解码方案设计
H.264并没有明确的规定一个编解码器是如何实现的,而是规定了构成编码的比特流的语法、语法元素的语义以及语义元素的解码过程,为不同制造商的编解码器提供兼容性,各个厂商的编码器和解码器在此框架下应能互通,在实现上具有较大的灵活性。
H.264标准的核心思想与现有的其它视频编解码标准一致,也是采用变换和预测的混合编码方法。但H.264 在算法的实现细节上使用了不同于其他标准的新技术,使得 H.264 编码性能远远优于其他标准。H.264 的核心算法主要包括帧内预测模式、整数变换编码、先进的量化、熵编码和高级运动估计与补偿等,H.264编解码的重要变化主要体现在各个模块的细节上,解码就是编码的逆过程。
H.264标准没有规定具体的编解码算法,本文在FFmpeg解码器的基础上进行了适当的裁剪优化并移植到Android系统来实现H.264标准的解码。FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源的音频和视频流解决方案。FFmpeg是基于Linux开发的,可以在大多数操作系统中编译和使用。它支持 MPEG、DivX、MPEG4、FLV 等40多种编码方式和AVI、MPEG、OGG、ASF 等90多种解码方式。FFmpeg被许多开源项目采用,如ffmpeg2theora, MPlayer,Google Chrome等。另外很多著名的播放软件如暴风影音、QQ影音和 KMPlayer和QuickTime等,也采用了FFmpeg的开源代码。
FFmpeg是一个庞大的音视频编解码一体的开源解决方案,完全移植需要耗费大量的资源和时间,这里需要对FFmepg进行精简和优化,裁剪出 H.264 的核心代码进行移植。首先FFmpeg 设计了统一的接口来说实现其内部对各种编解码起的支持。它通过一些公用的结构体来描述各种编解码器需要用到的资源变量和特性,其中很多數据结构对H.264解码器来说是没有用处的。因此首先需要对H.264解码器对 FFmpeg中的结构体进行裁剪优化,去掉与H.264解码器无关的数据结构。另外一个就是对 H.264 解码的核心算法的提取。对于基本的H.264解码来说,仅需保留H264.c、utils.c(H264utils.c)、Cabac.c、golomb.c 这几个源文件就可以了。
3 Android客户端软件设计
3.1 解码器编译移植
在Android平台上使用H.264解码器需要进行解码器的交叉编译移植工作。而Android系统是面向应用的,应用开发者需要使用java 语言进行应用开发。因此,想要在 Android 的应用层调用解码库来实现解码功能,还需要对解码库进行封装,利用java的本地调用来实现解码器。
编译H.264 解码器时需要用到Android 提供的 NDK工具。Android的NDK 是一系列开发工具的集合,集成了交叉编译器,并提供android.mk文件隔离CPU、平台、ABI 等的差异,开发人员只要编写自己的android.mk文件,就可以实现交叉编译,产生.so 文件和 java 打包供开发人员使用。这样,就为开发人员使用 C/C++开发 Android 提供了一个简单而有效地途径。Android 的NDK 需要使用 gcc 进行交叉编译。
在java层声明本地方法后,需要使用javah命令需要生成JNI头文件,这里需要注意完整的包名。这里生成了一个头文件,其中包含了需要利用本地 C实现的方法名。 编译成功后,会在工程目录下自动生成一个/libs/armeabi文件夹,编译得到的动态库 H264Decoder 会安装在这个文件下。然后在工程中的 java 代码部分添加如下代码:
static {System.loadLibrary(―H264Decoder‖);}
這样,就完成了解码器的交叉编译和移植工作。
3.2 H.264解码流程
整个解码的流程可以分成三个功能模块:前端码流处理、H.264 解码和后端视频显示。前端码流处理:主要负责文件的读取,从码流中分割出 NAL 然后交给底层进行解码处理。H.264 解码是整个解码的核心部分,这一步需要通过本地C语言的实现和解码库对码流数据进行处理,完成H.264解码实现图像重建。后端视频显示模块接收H.264解码模块解码后的视频数据,在 Android客户端进行显示。其中H.264解码模块是最耗费资源的。这一模块通过移植的FFmpeg解码库来实现解码。另外两个模块则在Android 的java应用层进行实现。H.264视频标准为了更好的适应网络传输的特性,采用了分层设计的思想既视频编码层VCL和网络提取层 NAL。H.264的解码部分有包括前端码流处理和 H.264 解码两个功能模块。其中,前端码流处理主要完成从码流中分割出NAL,这部分功能由java层实现。在java层,采用java.io.FileInputStream类来实现码流的读取。读取文件后在java层从H.264码流中分割出Nal,然后交给底层的C来实现实时解码。Nal 的分割Android的java应用层来实现。
完成Nal的分割之后,将数据交给底层解码器处理,对于具体视频数据,解码流程如下:打开解码器并为解码帧分配内存,不停的从码流中提取帧数据,对于视频帧调用解码器,解码完成后释放解码器。在移植了 H.264 解码器后,通过Android提供的MediaPlayer类进行播放。
4 结束语
本文将开源的FFmpeg提供的 H.264解码器进行裁剪优化,从中提取 H.264 解码的核心部分,并移植到Android平台,完成了一种Android平台下的H.264解码方案的设计,并在真机下进行了测试取得了较好的解码播放效果。
参考文献:
1 杨丰盛 Android应用开发揭秘 机械工业出版社 2011.12
2 范斐斐 基于OMAP5912的H.264编解码器的实现 武汉理工大学. 2008,5:33-36
3 欧阳合,韩军 H.264和MPEG-4视频压缩 国防 科技大学出版社 2004:17-21
4李振德 基于H.264编码标准的远程视频采集系统的设计与实现 湛江海洋大学学报. 2006,26(3):78-81
关键词:Android;H.264;解码器;FFmpeg
【中图分类号】N94-0
0 引言
H.264/AVC标准是一种高性能的视频编解码技术,相比其它标准具有更高的压缩率、高质量图像、容错功能、并有很强的网络适应性。近年来Android系统的也迅猛发展和日趋成熟,其因其具有开放性、便携性、良好的兼容性和可无缝结合网络通信等特点,Android操作系统在未来嵌入式物联网领域中将会有更广泛的应用。
目前越来越多的Android视频应用被开发出来,而人们追求的视频高清化和目前网络带宽及智能手持设备解码能力均不足的矛盾也逐渐凸显出来,本文设计的基于Android系统的H.264在线高清解码系统就可以解决这一问题。
1 Android操作系统简介
Android系统是一种以Linux为内核开发的专门面向移动平台的开源智能操作系统,具有丰富的硬件资源和软件应用程序资源、支持各种网络协议和触屏输入,短短的几年时间,Android凭借这些特性,已经在智能手机领域占据了非常重要的位置。随着物联网时代的到来,Android系统的前景将更加不可限量。
Android系统由以下三个部分组成: Linux内核层、Android 运行时库和其他库层、应用程序层。
Linux内核层用来提供系统的底层服务,包括安全机制、内存管理、进程管理、网络堆栈及一系列的驱动模块。作为一个虚拟的中间层,该层位于硬件与其它的软件层之间。需要注意的是,这个内核操作系统并非类GNU/Linux的,所以其系统库、系统初始化和编程接口都和标准的Linux系统有所不同的。
Android运行时库和其他库层包含一组核心库(提供Java语言核心库内的大部分功能)和Dalvik虚拟机。在应用层Android开发人员拥有访问框架API的全部权限。应用层的结构化设计简化了各组件之间的重用, 任何应用都可以分发自己的组件, 任何应用也可以使用这些分发的组件。
2 H.264解码方案设计
H.264并没有明确的规定一个编解码器是如何实现的,而是规定了构成编码的比特流的语法、语法元素的语义以及语义元素的解码过程,为不同制造商的编解码器提供兼容性,各个厂商的编码器和解码器在此框架下应能互通,在实现上具有较大的灵活性。
H.264标准的核心思想与现有的其它视频编解码标准一致,也是采用变换和预测的混合编码方法。但H.264 在算法的实现细节上使用了不同于其他标准的新技术,使得 H.264 编码性能远远优于其他标准。H.264 的核心算法主要包括帧内预测模式、整数变换编码、先进的量化、熵编码和高级运动估计与补偿等,H.264编解码的重要变化主要体现在各个模块的细节上,解码就是编码的逆过程。
H.264标准没有规定具体的编解码算法,本文在FFmpeg解码器的基础上进行了适当的裁剪优化并移植到Android系统来实现H.264标准的解码。FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源的音频和视频流解决方案。FFmpeg是基于Linux开发的,可以在大多数操作系统中编译和使用。它支持 MPEG、DivX、MPEG4、FLV 等40多种编码方式和AVI、MPEG、OGG、ASF 等90多种解码方式。FFmpeg被许多开源项目采用,如ffmpeg2theora, MPlayer,Google Chrome等。另外很多著名的播放软件如暴风影音、QQ影音和 KMPlayer和QuickTime等,也采用了FFmpeg的开源代码。
FFmpeg是一个庞大的音视频编解码一体的开源解决方案,完全移植需要耗费大量的资源和时间,这里需要对FFmepg进行精简和优化,裁剪出 H.264 的核心代码进行移植。首先FFmpeg 设计了统一的接口来说实现其内部对各种编解码起的支持。它通过一些公用的结构体来描述各种编解码器需要用到的资源变量和特性,其中很多數据结构对H.264解码器来说是没有用处的。因此首先需要对H.264解码器对 FFmpeg中的结构体进行裁剪优化,去掉与H.264解码器无关的数据结构。另外一个就是对 H.264 解码的核心算法的提取。对于基本的H.264解码来说,仅需保留H264.c、utils.c(H264utils.c)、Cabac.c、golomb.c 这几个源文件就可以了。
3 Android客户端软件设计
3.1 解码器编译移植
在Android平台上使用H.264解码器需要进行解码器的交叉编译移植工作。而Android系统是面向应用的,应用开发者需要使用java 语言进行应用开发。因此,想要在 Android 的应用层调用解码库来实现解码功能,还需要对解码库进行封装,利用java的本地调用来实现解码器。
编译H.264 解码器时需要用到Android 提供的 NDK工具。Android的NDK 是一系列开发工具的集合,集成了交叉编译器,并提供android.mk文件隔离CPU、平台、ABI 等的差异,开发人员只要编写自己的android.mk文件,就可以实现交叉编译,产生.so 文件和 java 打包供开发人员使用。这样,就为开发人员使用 C/C++开发 Android 提供了一个简单而有效地途径。Android 的NDK 需要使用 gcc 进行交叉编译。
在java层声明本地方法后,需要使用javah命令需要生成JNI头文件,这里需要注意完整的包名。这里生成了一个头文件,其中包含了需要利用本地 C实现的方法名。 编译成功后,会在工程目录下自动生成一个/libs/armeabi文件夹,编译得到的动态库 H264Decoder 会安装在这个文件下。然后在工程中的 java 代码部分添加如下代码:
static {System.loadLibrary(―H264Decoder‖);}
這样,就完成了解码器的交叉编译和移植工作。
3.2 H.264解码流程
整个解码的流程可以分成三个功能模块:前端码流处理、H.264 解码和后端视频显示。前端码流处理:主要负责文件的读取,从码流中分割出 NAL 然后交给底层进行解码处理。H.264 解码是整个解码的核心部分,这一步需要通过本地C语言的实现和解码库对码流数据进行处理,完成H.264解码实现图像重建。后端视频显示模块接收H.264解码模块解码后的视频数据,在 Android客户端进行显示。其中H.264解码模块是最耗费资源的。这一模块通过移植的FFmpeg解码库来实现解码。另外两个模块则在Android 的java应用层进行实现。H.264视频标准为了更好的适应网络传输的特性,采用了分层设计的思想既视频编码层VCL和网络提取层 NAL。H.264的解码部分有包括前端码流处理和 H.264 解码两个功能模块。其中,前端码流处理主要完成从码流中分割出NAL,这部分功能由java层实现。在java层,采用java.io.FileInputStream类来实现码流的读取。读取文件后在java层从H.264码流中分割出Nal,然后交给底层的C来实现实时解码。Nal 的分割Android的java应用层来实现。
完成Nal的分割之后,将数据交给底层解码器处理,对于具体视频数据,解码流程如下:打开解码器并为解码帧分配内存,不停的从码流中提取帧数据,对于视频帧调用解码器,解码完成后释放解码器。在移植了 H.264 解码器后,通过Android提供的MediaPlayer类进行播放。
4 结束语
本文将开源的FFmpeg提供的 H.264解码器进行裁剪优化,从中提取 H.264 解码的核心部分,并移植到Android平台,完成了一种Android平台下的H.264解码方案的设计,并在真机下进行了测试取得了较好的解码播放效果。
参考文献:
1 杨丰盛 Android应用开发揭秘 机械工业出版社 2011.12
2 范斐斐 基于OMAP5912的H.264编解码器的实现 武汉理工大学. 2008,5:33-36
3 欧阳合,韩军 H.264和MPEG-4视频压缩 国防 科技大学出版社 2004:17-21
4李振德 基于H.264编码标准的远程视频采集系统的设计与实现 湛江海洋大学学报. 2006,26(3):78-81