基于Android系统的视频传输方法转让专利

申请号 : CN201110213672.7

文献号 : CN102291580B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 王学斌赵安

申请人 : 南京联慧通信技术有限公司熊猫电子集团有限公司南京熊猫电子股份有限公司

摘要 :

基于Android系统的视频传输方法,编程录取获取相应分辨率的H246格式视频;通过解析3GP文件获得该H264压缩视频的SPS/PPS信息;利用LocalSocket获取视频流并发送;1)编程录像:创建录像设备、设置录像源为摄像头、设置文件格式为3GP、启动视频录像;2)分析文件:解析3GP文件,寻找sps/pps信息并记录存盘,即锁定sps/pps信息存储在stsd包中的固定位置;在采样包列表stsd包中首先判断视频类型是否为avc1,即H264的编码文件;将此内容存储到以分辨率命名的文件中;3)视频传输;本发明用于实时视频传输;这类服务类似于视频通话,不但要接收并播放视频,还要将本地摄像头数据压缩后发送出去,来满足Android平台视频传送功能。

权利要求 :

1.基于Android系统的视频传输方法,其特征是:

编程录像获取相应分辨率的H246格式视频;

通过解析3GP文件获得所述H264格式视频的SPS/PPS信息;

利用LocalSocket获取视频流并发送;

其中编程录像具体为:根据设定的分辨率参数录很短的3GP文件;采取如下步骤:创建录像设备、设置录像源为摄像头、设置文件格式为3GP、设置视频帧率、设置编码器为H264、设置显示窗口、设置视频最长1秒、设置输出文件名、启动视频录像;

其中对3GP文件的解析具体为:解析3GP文件,寻找sps/pps信息并记录存盘,即锁定sps/pps信息存储在stsd包中的固定位置;在采样包列表stsd包中首先判断视频类型是否为avc1,即H264的编码文件;紧接着偏移10字节读取此包剩余内容,这些内容就是H264视频的sps/pps信息、大约几十字节;将此内容存储到以分辨率命名的文件中;不同分辨率的视频操作流程类似;

采取如下步骤:定位moov包头;定位trak包头;定位mdia包头;定位hdlr包头;记录媒体类型;定位minf包头;定位stbl包头;定位stsd包头锁定sps/pps信息存储在stsd包中的固定位置;判断是否为vide类型;判断是否为avc1包;偏移并读剩余包;存文件后退出;以上步骤均是成功后进入下一步,如失败或不成功则返回;

其中利用LocalSocket获取视频流视频数据具体为:在视频流传输过程中判断关键帧,并提前发送视频编码信息sps/pps信息;

获取了视频编码信息sps/pps信息之后,按照传输的视频分辨率不同,读取分析后存储的视频编码信息sps/pps信息到内存;启动H264格式视频录像流程,将本地的视频数据通过LocalSocket接口获取;分包并判断视频数据流中的关键帧;以关键帧判断结果为依据,决定是否要发送视频编码信息sps/pps信息;

采取如下步骤:1)进入发送流程;2)创建LocalSocket;3)LocalSocket的文件句柄传入;4)初始化摄像流程;5)读包长,判断是否为空,如空则重读包长,不空时进入下一步;6)判断包长是否大于0且小于128K,是则进入7);7)判断是否读完一包,是则进入8),否则继续读;8)判断是否为关键帧,是则进入9),否则进入10);9)发送SPS/PPS信息后进入10),

10)发送视频数据到网络;11)判断是否有停止信号;是则进入12),否则进入6);12)关闭摄像;13)关闭LocalSocket,14)退出发送流程。

说明书 :

基于Android系统的视频传输方法

技术领域

[0001] 本发明技术是在Android系统框架上实现的视频传输方案,利用系统现有的流传输方式,加上H264关键编码信息的提取方法,实现了通用性的Android平台H264视频传输方案。本方案已在多台Android手机和平板电脑上验证通过。

背景技术

[0002] 1.Android介绍
[0003] 自2007年谷歌在全球推出Android智能系统,众多软硬件厂家纷纷响应,积极参与并合作开发了大量Android智能设备。产品种类也逐渐广泛,从最初的手机,到现在的平板电脑,Android电视,机顶盒等。随之开发的应用软件也在日益地丰富起来,Android设备市场占有率逐渐攀升,甚至超过了苹果iOS的增长势头。
[0004] Android系统目前的软件版本更新很快,从相对成熟的1.6到现在的3.1仅用了两年多时间。当前手机中采用的系统是2.2/2,3版本,而3.0及3.1多用在平板电脑上。Android软件主要思想是在Linux系统的基础上添加Dalvik虚拟机(类似Java虚拟机),上层开发语言使用Java实现框架和应用程序,架构见图1:
[0005] 图中下方是Linux内核和硬件抽象层,中间是基于c/c++实现的各种协议库(其中包含Dalvik虚拟机的实现),上层是Java实现的框架和应用程序。这种架构使得应用程序能够跨平台运行,实现了Java的思想“一次编译,到处运行”,大大增加了软件的重用性,这也是现代软件发展的趋势。
[0006] 2.Android上的视频传输
[0007] 随着消费者的需求增长,Android手机功能日益强大。音视频应用是Wifi和3G网络发展后的迫切需求,一般分为两种:
[0008] (1)在线电影:这类服务已经有很多网络公司在提供,它仅用于视频接收,其主要实现方法是将服务器的视频文件按照mms/rtsp等协议发送到Android终端来播放,其特点是注重影片的连续性而并非实时性,影片播放之前经常会缓冲大量视频数据来保证播放的连续性。
[0009] (2)实时视频:这类服务类似于视频通话,既要接收并播放视频,还要将本地摄像头数据压缩后发送出去(目前Android手机基本没有视频通话的功能,甚至很少有手机带有前置摄像头),与前者不同的地方还有这类服务不但需要保证视频的连续性,还要确保一定的实时性。
[0010] 我们所探讨的视频服务属于后者,在Android系统中,谷歌并没有给出标准接口来实现这种视频流服务。一般的录像功能都要操作文件对象,由于文件有大小限制,且需要长期读写磁盘,所以这个方法不能适用。
[0011] 视频通话和视频监控的需求日益增长,有些软件人员开始研究此类技术。其中一种方法使用了LocalSocket接口实现了录像数据流的截获,它用到了LocalSocket类中的文件接口,即建立本地的Socket连接,将它的文件句柄作为参数传给摄像模块,在启动摄像后系统会通过文件接口的InputSream将视频数据写入,而客户程序通过OutputStream接口将数据读出,这样就获取了编码后的数据流。因为本地的网络接口都属于内存操作,速度非常快,数据获取后经过rtp协议可传输到远端机器,此实现方法基本解决了视频流的获取,但是还有不足的地方是:数据传输到对方系统上并不能正常解码。因为视频解码需要的关键信息sps/pps并没有发送过去,而摄像过程没有结束之前并不会产生此类信息。

发明内容

[0012] 本发明目的是用来解决上述提及的问题,并利用技术方案实现实时的视频传输,在Android平台上具有通用性。它通过编程方法获取对应手机的H264视频编码参数(sps/pps),用于传输完整的H264视频数据。
[0013] 本发明的技术方案是:基于Android系统的视频传输方法,其特征是:通过编程方法获取对应手机的H264视频编码参数,编程录取获取相应分辨率的H246格式视频;通过解析3GP文件获得该H264压缩视频的SPS/PPS信息;利用LocalSocket获取视频流并发送;
[0014] (1)编程录像:根据设定的分辨率参数录很短的3GP格式文件;采取如下步骤:创建录像设备、设置录像源为摄像头、设置文件格式为3GP、设置视频帧率、设置编码器为H264、设置显示窗口、设置视频最长1秒、设置输出文件名,启动视频录像;
[0015] (2)分析文件:解析3GP文件,寻找sps/pps信息并记录存盘,即锁定sps/pps信息存储在stsd包中的固定位置;在采样包列表stsd包中首先判断视频类型是否为avc1,即H264的编码文件;紧接着偏移10字节读取此包剩余内容,这些内容就是H264视频的sps/pps信息(大约几十字节);将此内容存储到以分辨率命名的文件中;不同分辨率的视频操作流程类似;
[0016] 采取如下步骤:定位moov包头;定位trak包头;定位mdia包头;定位hdlr包头;记录媒体类型;定位minf包头;定位stbl包头;定位stsd包头锁定sps/pps信息存储在stsd包中的固定位置;是否vide类型;是否avc1包;偏移并读剩余包;存文件后退出;以上步骤均是成功后进入下一步,如失败或不成功则返回;
[0017] (3)视频传输:在视频流传输过程中判断关键帧,并提前发送sps/pps信息;获取了视频编码信息(sps/pps)之后,按照传输的视频分辨率不同,读取分析后存储的sps/pps信息到内存;启动H264视频录像流程,将本地的视频数据通过LocalSocket接口获取;分包并判断视频数据流中的关键帧;以关键帧判断结果为依据,决定是否要发送sps/pps信息;
[0018] 采取如下步骤:1)进入发送流程;2)创建LocalSocket;3)LocalSocket的文件句柄传入;4)初始化摄像流程;5)读包长,是否为空、如空则重读包长,不空时进入进一步;6)判断包长是否大于0,<128K,是则进入7);7)读完一包?是则进入8),否则继续读);9)判断是否为关键帧?是则进入10),否则进入11);10)发送SPS/PPS信息后进入11),11)发送视频数据到网络;12)判断是否有停止信号?是则进入13),否则进入6);13)关闭摄像;14)关闭LocalSocket,15)退出发送流程。
[0019] 本发明的有益效果是:用于实时视频传输;这类服务类似于视频通话,不但要接收并播放视频,还要将本地摄像头数据压缩后发送出去,来满足Android平台视频传送功能。这类服务不但需要保证视频的连续性,还要确保一定的实时性。本发明利用Android平台通用接口,提出一种编程方法来获取H264视频编码信息(sps/pps),实现Android平台的视频流服务。

附图说明

[0020] 图1是Android系统软件框架图
[0021] 图2是编程录像流程图
[0022] 图3是分析流程图
[0023] 图4是视频发送流程图具体实施方案
[0024] 1.编程录像得到3GP文件
[0025] 此处采用编程接口来录像,而非直接采用Android平台的录像软件,原因是[0026] (1)必需录取H246格式的视频
[0027] (2)必需能够任意设置视频分辨率
[0028] (3)录像文件不包含音频信息
[0029] (4)文件要足够小
[0030] Android原录像软件不能很好地满足以上要求来设置参数并录下文件;但本发明用编程方法可以很方便地设置参数并启动录像,获取H246格式的视频,从而得到我们想要的3GP文件。文件大小根据分辨率不同约为几K或几十K字节不等,所以它对存储卡的要求很低,而小文件也可以十分方便和快速地进行分析。录像按照以下流程启动,内容达到1秒钟后结束并生成文件。(录像启动流程见图2)。
[0031] 编程接口列举:
[0032] 1.new MediaRecorder();//创建录像设备
[0033] 2.setVideoSource(MediaRecorder.VideoSource.CAMERA);//设置录像源为摄像头
[0034] 3.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置文件格式为3GP
[0035] 4.setVideoFrameRate(15);//设置视频帧率
[0036] 5.setVideoSize(352,288);//设置视频分辨率
[0037] 6.setVideoEncodingBitRate(256K);//设置视频编码率
[0038] 7.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设 置编码器 为H264
[0039] 8.setPreviewDisplay(..);//设置显示窗口
[0040] 9.setMaxDuration(1000);//设置视频最长1秒
[0041] 10.setoutputFile(″\sdcard\cif.3gp″);//设置输出文件名
[0042] 11.MediaRecorder.prepare();MediaRecorder.start();//启动视频录像[0043] 2.分析文件
[0044] 3GP文件分析是实现获取视频信息的关键,录下的文件是按照H264的格式存储的,其中含有H264视频中的关键信息(sps/pps)。
[0045] 3gp文件基于mpeg4,由若干个box组成,一般常见的有:
[0046] 文件类型包:简称代码ftyp
[0047] 媒体数据包:简称代码mdat)
[0048] 影片包:简称代码moov
[0049] 影片头包:简称代码mvhd
[0050] 轨迹包:trak包是一个容器,是单个媒体流频道的信息的容器,包含子包:tkhd,mdia
[0051] 媒体头:简称代码mdhd
[0052] 媒体类型:简称代码hdlr
[0053] 媒体信息容器:简称代码minf
[0054] 媒体采样信息:简称代码stbl
[0055] 采样时间长度信息:简称代码stts
[0056] 采样包列表:简称代码stsd
[0057] 我们解析文件的目标很明确,就是为了获取sps/pps结构信息。根据3GP格式的定义,每包的组成结构都一样,即Length(4字节)+Head(4字节)+Data(Length-8),编程可以很方便寻找其中某一个数据包。经反复试验,锁定了sps/pps信息存储在采样包列表stsd包中的某固定位置。在采样包列表stsd包中首先判断视频类型是否为avc1,即H264的编码文件;紧接着偏移10字节读取此包剩余内容,这些内容就是H264视频的sps/pps信息(大约几十字节);将此内容存储到以分辨率命名的文件中供以后调用。不同分辨率的视频操作流程类似。(分析流程见图)定位moov包头;定位trak包头;定位mdia包头;定位hdlr包头;记录媒体类型;定位minf包头;定位stbl包头;定位stsd包头锁定sps/pps信息存储在stsd包中的固定位置;是否vide类型;是否avc1包;偏移并读剩余包;存文件后退出;以上步骤均是成功后进入下一步,如失败或不成功则返回。
[0058] 3.视频传输
[0059] 获取了视频编码信息(sps/pps)之后,可采用前文介绍的类似方法:
[0060] (1)按照传输的视频分辨率不同,读取分析后存储的文件到内存
[0061] (2)启动H264视频录像流程,将本地的视频数据通过LocalSocket接口获取[0062] (3)分包并判断视频数据流中的关键帧
[0063] (4)以关键帧判断结果为依据,决定是否要先发送sps/pps信息
[0064] 1)进入发送流程;2)创建LocalSocket;3)LocalSocket的文件句柄传入;4)初始化摄像流程;5)读包长,是否为空、如空则重读包长,不空时进入进一步;6)判断包长是否大于0,<128K,是则进入7);7)读完一包?是则进入8),否则继续读);9)判断是否为关键帧?是则进入10),否则进入11);10)发送SPS/PPS信息后进入11),11)发送视频数据到网络;12)判断是否有停止信号?是则进入13),否则进入6);13)关闭摄像;14)关闭LocalSocket,15)退出发送流程。
[0065] 关键点描述:
[0066] 1).创建LocalSocket:
[0067] LocalServerSocket lss;
[0068] LocalSocket receiver,sender;
[0069] receiver=new LocalSocket();
[0070] lss=new LocalServerSocket(NAME);
[0071] receiver.connect(new LocalSocketAddress(NAME));
[0072] sender=lss.accept();
[0073] 同时建立发送与接收的Socket,并且用LocalServerSocket将两者建立关联。
[0074] 2).LocalSocket创建成功后,将sender的文件描述符作为视频录像时的文件句柄(参考编程录像流程),文件接口会将视频数据写入本地缓存,如下:
[0075] setOutputFile(sender.getFileDescriptor());//设置输出文件名[0076] 3).读取视频数据用以下接口
[0077] InputStream fis=receiver.getInputStream();
[0078] 对fis的循环读操作能够获取连续的视频数据,每数据包开头的4字节是包长,而且每数据包之间有明显的空歇时间,程序可以判断出包头。如果包长小于0或大于128K,说明数据包可能有误,需要继续寻找包头。寻或包头后读取整包的数据准备发送到网络。
[0079] 4).视频数据发送前判断是否为关键帧,以此决定是否发送SPS/PPS信息。H264视频的关键帧解码必须要有SPS/PPS信息支持,所以判断出关键帧后先发送SPS/PPS数据,再发送关键帧数据,才能满足解码需求。
[0080] 试验证明,通过以上流程发送了H264视频数据和相应的sps/pps信息到网络接收端,硬件支持的任意分辨率H264视频均能顺利完成解码并显示。
[0081] 视频发送流程见图4。