今天我们继续给大家讲解Android手机直播流程中的编码技术,编码过程分为视频和音频解码,这篇文字先介绍视频编码的技术。

编码

通过摄像头和麦克风我们可以采集到相应的视音频数据,但是这些是固定格式的原始数据,一般来说摄像头采集到的是一帧一帧画面,而麦克风采集的是PCM音频数据。如果直接将这些数据进行发送,这样往往会数据量很大,造成很大的带宽浪费,因此在发送前往往需要对视音频进行编码。

视频编码

1、预测编码

众所周知,一幅图像由许多个所谓像素的点组成,大量的统计表明,同一幅图像中像素之间具有较强的相关性,两个像素之间的距离越短,则其相关性越强,通俗地讲,即两个像素的值越接近。于是,人们可利用这种像素间的相关性进行压缩编码,这种压缩方式称为帧内预测编码。不仅如此,邻近帧之间的相关性一般比帧内像素间的相关性更强,压缩比也更大。由此可见,利用像素之间(帧内)的相关性和帧间的相关性,即找到相应的参考像素或参考帧作为预测值,可以实现视频压缩编码。

2、变换编码

大量统计表明,视频信号中包含着能量上占大部分的直流和低频成分,即图像的平坦部分,也有少量的高频成分,即图像的细节。因此,可以用另一种方法进行视频编码,将图像经过某种数学变换后,得到变换域中的图像(如图所示),其中 u,v 分别是空间频率坐标。

3、基于波形的编码

基于波形的编码采用了把预测编码和变换编码组合起来的基于块的混合编码方法。为了减少编码的复杂性,使视频编码操作易于执行,采用混合编码方法时,首先把一幅图像分成固定大小的块,例如块 8×8(即每块 8 行,每行 8 个像素)、块 16×16(每块 16 行,每行 16 个像素)等等,然后对块进行压缩编码处理。

自 1989 年 ITU-T 发布第一个数字视频编码标准——H.261 以来,已陆续发布了 H.263 等视频编码标准及 H.320、H.323 等多媒体终端标准。ISO 下属的运动图像专家组(MPEG)定义了 MPEG-1、MPEG-2、MPEG-4 等娱乐和数字电视压缩编码国际标准。

2003 年 3 月份,ITU-T 颁布了 H.264 视频编码标准。它不仅使视频压缩比较以往标准有明显提高,而且具有良好的网络亲和性,特别是对 IP 互联网、无线移动网等易误码、易阻塞、QoS 不易保证的网络视频传输性能有明显的改善。 所有这些视频编码都采用了基于块的混合编码法,都属于基于波形的编码。

4、基于内容的编码

还有一种基于内容的编码技术,这时先把视频帧分成对应于不同物体的区域,然后对其编码。具体说来,即对不同物体的形状、运动和纹理进行编码。在最简单情况下,利用二维轮廓描述物体的形状,利用运动矢量描述其运动状态,而纹理则用颜色的波形进行描述。

当视频序列中的物体种类已知时,可采用基于知识或基于模型的编码。例如,对人的脸部,已开发了一些预定义的线框对脸的特征进行编码,这时编码效率很高,只需少数比特就能描述其特征。对于人脸的表情(如生气、高兴等),可能的行为可用语义编码,由于物体可能的行为数目非常小,可获得非常高的编码效率。

MPEG-4 采用的编码方法就既基于块的混合编码,又有基于内容的编码方法。

5、软编与硬编

在Android平台上实现视频的编码有两种实现方式,一种是软编,一种是硬编。软编的话,往往是依托于cpu,利用cpu的计算能力去进行编码。比如我们可以下载x264编码库,写好相关的jni接口,然后传入相应的图像数据。经过x264库的处理以后就将原始的图像转换成为h264格式的视频。

硬编则是采用Android自身提供的MediaCodec,使用MediaCodec需要传入相应的数据,这些数据可以是yuv的图像信息,也可以是一个Surface,一般推荐使用Surface,这样的话效率更高。Surface直接使用本地视频数据缓存,而没有映射或复制它们到ByteBuffers;因此,这种方式会更加高效。在使用Surface的时候,通常不能直接访问原始视频数据,但是可以使用ImageReader类来访问不可靠的解码后(或原始)的视频帧。这可能仍然比使用ByteBuffers更加高效,因为一些本地缓存可以被映射到 direct ByteBuffers。当使用ByteBuffer模式,可以利用Image类和getInput/OutputImage(int)方法来访问到原始视频数据帧。