基于Android平台的可视对讲系统设计

2022-04-16 00:24:34蒋海诚
导读 大家好,我是本期栏目编辑小友,现在为大家讲解 基于Android平台的可视对讲系统设计问题。 安卓是谷歌推出的一款基于Linux的开源手机操作

大家好,我是本期栏目编辑小友,现在为大家讲解 基于Android平台的可视对讲系统设计问题。

安卓是谷歌推出的一款基于Linux的开源手机操作系统,因其开源代码而受到众多手机厂商的青睐。可视对讲系统在安卓操作系统出现之前,软件开发一般采用底层语言,容易出现功能单一、产品升级困难的问题。在对讲系统中开发具有三维图形效果的界面更加困难。鉴于此,本文利用安卓平台的可移植性、开源代码等优势,结合JNI和NDK技术,提出了一种基于安卓平台的可视对讲系统的设计方案并实现。

JNI[1](Java NaTIve Interface)是一个Java本地调用接口,它使运行在Android平台上的Java程序能够使用用C、C甚至汇编语言编写的动态链接库。在频繁访问内存或计算复杂的情况下,使用C动态链接库比使用Java语言在Android平台上实现同样的功能更有效率[2]。NDK[3](NaTIve Development Kit)提供了一系列工具,可以生成ARM二进制代码的动态库,并且可以将生成的动态库与Java应用程序一起自动打包成一个可以直接由Android系统安装的apk安装包,即NDK可以编译包含JNI接口函数的C源程序文件生成动态库供Android应用程序调用,提高了现有代码的可重用性,加快了开发进度。

提出了一种可视对讲系统的设计方案,该系统由门机和室内机组成,设计方案在i.MX51硬件平台上实现。门机采集、编码、传输音视频,解码、播放音频;室内机采用安卓平台,但考虑到用户室内信息的保密性,室内机没有视频采集功能,只解码播放音视频,采集、编码、传输音频。

1可视对讲系统设计

1.1沟通流程设计

数据包传输协议采用无连接、资源消耗低、处理速度快的UDP协议。在寻址并建立UDP直连后,门卫首先对视频进行编码传输,直到被叫方按下接听键,门卫才传输音频数据。为了保证通话始终在线,室内机定期向门机发送通话在线查询,如果收到在线确认回复,则保持通话状态,否则结束通话。可视对讲系统的通信流程如图1所示。

在表2中,数据包报头是内部通信数据包的标识符。命令类型和操作类型详见表3。时间戳主要用于音频和视频同步。数据类型为音频和视频,帧数为0~65 535。如果没有包分段,总的包号和当前的包号都是1。音频和视频数据从第41位开始,音频和视频数据的长度由数据包格式中的数据长度指定。

根据系统通信流程图1和数据包格式,本对讲系统的参数如表3所示。命令类型和操作类型分别对应表2中的数据包格式。

1.5音频和视频编解码器选择

音频编码系统选择G.711编码[4]。G.711是国际电信联盟设定的音频编解码方法,具有双倍压缩率,是语音通信中最常用的编解码方法之一。采样和量化是音频编程和声音数字化的两个关键步骤。该系统使用的音频采样频率为8千赫,量化位为16位,音频为单声道。

FFmpeg是一个开源的音频和视频解决方案。由于其开源、免费、跨平台的特点,受到开发者的青睐。FFmpeg支持多达90种解码器,包括xvid等。并用C语言实现。它不仅适用于PC机软件平台,也适用于嵌入式设备。在该系统中,视频采用xvid编解码器,视频格式为MPEG-4。(xvid是开源MPEG-4视频编解码器)视频标准为NTSC,视频大小为352倍;20,帧率为30f/s;使用NDK提供的交叉编译工具,将包含JNI接口函数的音视频编解码源文件编译成动态链接库,供安卓平台调用。

2系统实施

2.1系统硬件

系统硬件平台为i.mx51evk,I.MX51 EVK由飞思卡尔自主研发,CPU基于ARM Cortex A8内核的I.MX51处理器。主频可扩展至1ghz处理器集成了DDR/DDR2内存控制器、OpenGL/OpenVG图形内核、ATA控制器、以太网控制器等。并支持720 p高清视频播放。指令缓存和数据缓存为32 KB,L2缓存为256 KB。其容量指标是之前ARM11产品的两倍,可以大大提升CPU的处理能力。同时,处理器内部还集成了矢量运算的浮点运算和信号处理加速器,为多媒体信息娱乐终端提供了强大的处理核心支持[5]。

软件平台采用Linux操作系统和eclipse集成开发环境。Android SDK[6]版本为2.2,Android NDK版本为android-ndk-r6。使用串口调试。

2.2安卓平台在i.MX51 EVK上的移植

系统使用4 GB SD卡存储引导程序、内核、根文件系统等镜像。引导程序使用U-Boot,Linux内核版本为2.6.31。移植过程:安卓源代码可以从http://source.android.com获得。编译好U-Boot、Linux内核、根文件系统和Android系统镜像[7]后,将i.MX51板上的S1 Boot Switch模式设置为110000001,使用ATK工具下载镜像。SD卡上下载的系统镜像分布如图3所示。

图3中,MBR主要存储SD卡的分区号。

息表,起始地址为0 KB。引导程序、内核、根文件系统的起始地址分别为1 KB、1 MB、4 MB。System和Recovery分别各占一个分区,System为Android操作系统的镜像文件所占分区,Recovery分区主要是用来备份和还原系统。 2.3 音视频编解码实现 2.3.1 音频编解码实现 音频编码与解码的区别仅在于调用的C库函数不一样,音频编解码调用的C库函数分别为G711Encoder、G711Decoder(本文以解码为例)。音频解码具体流程如下: (1)音频Java本地调用函数 在使用音频解码的类中编写Java本地调用函数: public naTIve void G711Decoder(byte[]pcm,byte[]code,int size,int lawflag); (2)生成头文件 C库与Java间需要一个后缀为“.h”的头文件来衔接,这个头文件通过javah命令生成,javah工具包含在JDK中。JDK是Java的核心,包含Java运行环境、Java工具、Java基础类库。 (3)JNI接口函数 JNI接口函数编写在C语言文件中,与音视频解码源码一起打包生成动态链接库。在接口函数中声明4个无符号指针变量:decode指向待解码的数据、depcm指向解码后的数据、enpcm指向待编码的数据、encode指向编码后的数据。解码代码如下: void Java_com_qsa_play_G711Decoder (JNIEnv*env,jobject this,jbyteArray pcm,jbyteArray code,jint size,jint lawflag) { depcm=(unsigned char*)(*env)-> GetByteArrayElements(env,pcm,0); decode=(unsigned char*)(*env)-> GetByteArrayElements(env,code,0); G711Decoder(depcm,decode,size,lawflag); (*env)->ReleaseByteArrayElements(env, pcm, (jbyte)depcm,0); (*env)->ReleaseByteArrayElements(env,code,(jbyte) decode,0); } 其中,depcm=(unsigned char*)(*env)->GetByteArrayElements(env,pcm,0)用来获取Java层传递的待解码字节数组的首地址,G711Decoder()函数实现音频解码,(*env)->ReleaseByteArrayElements(env,pcm, (jbyte)depcm,0)释放传递的数组成员,进行资源回收。 (4)使用NDK中ndk-build命令编译生成动态链接库 ndk-build命令是ndk命令工具集中的一个命令,与Linux下shell编程中的make命令相似,它会查找文件夹中的后缀为“.mk”的Makefile文件,根据该文件的依赖文件,将源文件编译成动态链接库。 2.3.2 视频编解码实现 视频的编解码流程与音频编解码流程基本相似,视频编解码调用的C库函数分别为avcodec_encode_video、avcodec_decode_video2。限于篇幅,在此重点介绍Android平台视频的解码及显示。 在解码视频数据前,要先做一系列的准备工作:

12下一页全文
免责声明:本文由用户上传,如有侵权请联系删除!