音视频解码过程
为什么编码
- 压缩数据
- 便于传输
- 利于存储
如何编码
编码的核心去除冗余信息
- 空间冗余: 图像内部相邻像素之间存在较强的相关性多造成的冗余 相邻的像素点可以用一个像素点表示;
- 时间冗余: 视频图像序列中的不同帧之间的相关性所造成的冗余
- 视觉冗余: 是指人眼不能感知或不敏感的部分图像信息
- 信息熵冗余: 也成编码冗余,人们用于表达某一信息所需要的比特数总比理论上表示该信息所需要的最少比特数要大,它们之间的差距就是信息熵冗余
- 知识冗余: 是指有些图像中还包含与某些验证知识相关的信息,
空间冗余:片和宏块
一帧图片经过H.264 编码器之后,就被编码为一个或多个片(Slice),每个片包含整数个宏块,至少一个, NAL 单元就是装载着这些片的载体。
- 一帧 = 多个片
- 一片 = 多个宏块
- 一宏块 = 多个像素
时间冗余:视频IBP帧
I帧: 关键帧,I帧可以看作一个图像经过研所之后的产物, 可以单独解码出一个完整的图像;
B帧: 双向预测编码帧,记录本帧和前后帧的差别,解码时需要参考前面一个I 帧或者P帧,同时也需要后面的P帧才能解码出一个完整的画面
P帧: 前向预测编码帧,记录本帧跟之前的一个关键帧或者P帧的差别,解码时需要用之前缓存的画面叠加上本帧,生产最终画面
YUV RGB
YUV主要应用于优化彩色视频信号的传输,与RGB相比,YUV只需要占用极少的频宽(RGB需要三个独立的视频信号同时传输)。YUV中代表明亮度也称灰阶值;U与V表示的则是色度(色调和饱和度)也可记作YCbCr ,如果只是Y数据,那么表示灰度图
使用 YUV 格式才能极大地去除视觉冗余信息, 人眼对亮点信息更敏感,对色度敏感度不高,也就是说,可以压缩 UV 数据,而人眼难以发现,所以压缩算法的第一步,往往先把RGB数据转换成YUV 数据,对 Y 少压缩一些,对 UV 多压缩一些,以平衡图像效果和压缩率,
这也是为什么编码选择使用 YUV 而不是 RGB
Y = Gray = R0.30 + G0.59 + B*0.11
Y = R0.30 + G0.59 + B*0.11 U = -0.147R - 0.289G - 0.436B V = 0.615R - 0.515G - 0.100B
R = Y + 1.140V G = Y - 0.395U - 0.581V B = Y + 2.032U
NV21与I420
YUV 因为采样和排列方式的不同,又分为不同的存储格式
一般的Android摄像头输出为 NV21 格式,而 I420 格式则是绝大多数编解码器默认输入输出格式
以下是一个 4 * 4
- NV21
Y0 | Y1 | Y2 | Y3 |
Y4 | Y5 | Y6 | Y7 |
Y8 | Y9 | Y10 | Y11 |
Y12 | Y13 | Y14 | Y15 |
V0 | U0 | V1 | U1 |
V1 | U2 | V3 | U3 |
- I420
Y0 | Y1 | Y2 | Y3 |
Y4 | Y5 | Y6 | Y7 |
Y8 | Y9 | Y10 | Y11 |
Y12 | Y13 | Y14 | Y15 |
U0 | U1 | U2 | U3 |
V0 | V1 | V2 | V3 |
大小计算 width * height + width * heigh / 4 + width * heigh / 4
width * height * 3/2
H.264码流分析
H.264码流文件分两层
1、VCL(Viedeo Coding Layer 视频编码层)负责高效的视频内容表示, VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列
2、NAL(Network abstract Layer 网络提取层)负责以网络所要求的恰当的方式对数据进行打包和传输,是传输层。不管在本地播放还是网络播放,都要通过这一层来传输。
视频编码
所谓视频编码是指通过特定的压缩技术,将某个视频格式文件转换成另外一种视频格式文件的方式;视频流传输中最重要的编码标准有:
-
国际电信联盟(ITU-T) H.261 H.263 H.264 ;
-
运动静止图像专家组(ISO/IEC)的MPEG系列标准: MPEG1、MPEG2、MPEG4 AVC等;
其中 H.264/MPEG-4 AVC是两家联合制定的新标准,
H.265则是H.264/MPEG-4 AVC标准的升级版,又称为高效率视频编码(HEVC)
MediaCodec 的软件编解码 和 硬件编解码
MediaCodec 类可用于访问 Android 底层是多媒体编解码器,例如编码器、解码器组件,它是Android底层多媒体支持基础架构的一部分
Android 底层多媒体模块采用的是 OpenMAx 框架,任何 Android 底层编解码模块的实现都必须遵循 OpenMax 标准,Google 官方默认提供了一系列的软件编解码器, 而硬件编解码功能需要芯片厂商按照 OpenMax 标准来完成, 所以不同手机是不确定是否有硬件编解码加速的。
软件编解码
优点:
- 兼容性强,对系统版本要求低,出现问题少
- 解码方面,软解码的色彩一般比硬解码柔和
- 编码的可操作空间比较大,自由度高
缺点:
- CPU 消耗大
- 机器容易发热
- 功耗较高
硬件编解码
优点:
- 功耗低,效率高
缺点:
- 不同型号的芯片对编解码的实现不同,并不能保证编解码效果与其他机型一样不出问题
- 可控性差,依赖底层编解码实现
MediaCodec 流程
- 码率:kbps 1kps表示每秒1000位数据
- 帧率:每秒多少帧画面
- 关键帧的间隔: IPPPI I:压缩率最低, 间隔越多,压缩率越高,画面变动越小, P 是前向预测帧
MediaCodec 生产消费模式
图像采集
- 构建预览布局 使用SurfaceView 或者 TextureView
- 打开相机 - Camera.open
- 设置参数 - Camera.Parameters
- 设置预览数据回调 - PreviewCallback
- 设置预览动画并启动 - setPreviewTexture/startPreview
- 释放相机 - stopPreview/release
相机硬件是一种共享资源,因此必须小心管理,让其不会与其他可能也要用到相机的应用发生冲突