视频编码原理

572 阅读5分钟

视频解码

  • 视频接封装
  • aac - pcm 交给gpu
  • h264 - yuv 交给扬声器

视频编码

  • pcm编码成aac
  • yuv编码成h264
  • 增加封装信息

硬解码

  • 解码芯片: 移动端SoC的视频硬解码靠的是SoC里的DSP芯片,不是GPU也不是CPU

  • 指的是系统将flv(举个例子)文件分离成H.264视频数据流和aac音频数据流,然后再将H.264视频数据流转交 给DSP芯片进行处理,DSP将处理好的一帧帧画面转交给GPU/CPU然后显示在屏幕上,这就是视频硬解码的过程

mediaCodec

它的目的就是调用dsp的接口,实现硬编码。

如何保证编解码的兼容性

先硬编解码,然后软编解码兜底。

视频编码的目的

从摄像头出来的yuv数据,虽然相比于rgb,有了部分压缩,但是从人眼的角度来看,仍然存在着帧内冗余和帧间冗余。

帧内冗余:每帧图片的每个像素点与其周围的像素点存在着高度相似性。 帧间冗余:两帧图片很多内容相似。通过存储图片之间的运动矢量和原始图片,可以还原出相似的帧。

视频编码流程图

image.png

信源编码器

  • 划分宏块
  • 生成预测函数 将每帧数据,按照宏块划分网格,以及生成预测函数。h264默认的宏块大小为16*16

image.png

宏块

将一副图像数据,划分为n*n大小的网格,每个网格称为宏块

预测函数

由于每个宏块内部的内容非常相似,可以通过保存左边cl和上边ct像素,加上插值函数f的形式来推导出其余位置像素的值:

cij = f(cl , ct)

image.png

残差数据

每个宏块挑选好模式之后,我们就可以使用块预测模式.预测完了之后,它就得到一个张"预测图",由预测图与原图数据存在着差异,这个差异数据称为残差数据。

DCT

DCT将残差数据做整数离散余弦变换,去掉数据的相关性,进一步压缩数据

视频复合编码器

  • 整理残差数据
  • 输出运动矢量 视频复合编码器将每帧图像数据编排成四层结构,并通过熵编码对视频数据进一步压缩输出

image.png

传输缓冲器

传输缓冲器和码率控制器用于保证输出码流尽可能稳定。它的主要目的是为了缓存B帧。

传输编码器

传输编码器则用于视频数据的误码检测和纠正,以及最终输出为压缩后的二进制数据

视频编码结果

I帧:

  • 帧内编码帧(intra picture),I帧通常是每个GOP的第一帧。
  • GOP:两个I帧之间是一个图像序列,在一个图像序列中只有一个I帧。
  • 可以独立解码

image.png

P帧:

  • 前向预测编码帧(predictive-frame),存储与I帧差异信息的帧,也称为预测帧。实际上存储的是运动矢量和宏块
  • 它的解码仅依赖I帧
  • 当帧数据与最近的I帧相似程度低于70%时,编码成P帧

B帧:

  • 双向预测内插编码帧(bi-directionalinterpolated prediction frame),保存差异信息的百分比,也称为双向预测帧.
  • 它的解码依赖前面的I帧和后面的P帧
  • 当帧数据与最近的I帧相似程度高于70%时,编码成B帧。
  • 硬编码中部分手机关闭了B帧的编码,它编码耗时较长。

一个简单的编码例子

image.png

  • 第一帧数据到来,经过信源编码器,复合编码器,传输编码器被编码成I帧,输出到文件中
  • 第二帧由于与第一帧非常相似,因此被交给复合编码器编码成B帧,进入到传输缓冲器,不会进入传输编码器
  • 第三帧同样由于差异低于30%,被编码成B帧进入传输缓冲器,不会输出到文件
  • 第四帧由于差异高于30%,编码成P帧,输出到文件,同时通知传输缓冲器,将B帧输出到文件。
  • 在每个GOP编码结果文件中首帧一定是I帧,第二帧一定是P帧,所以输出一般都是IPBBBBB

DTS/PTS

  • DTS(英文全称Decoding Time Stamp)主要用于视频的解码,
  • PTS(Presentation Time Stamp)主要用于视频解码阶段进行视频的同步和输出

image.png 如图所示,码流顺序表示帧数据在文件的实际顺序,也是解码的顺序DTS。播放的时候,需要按照PTS同步。

编码的原始数据

H.264 原始码流(又称为裸流),是由NALU序列 组成的,而它的功能分为两层:视频编码层(VCL, Video Coding Layer)和网络提取层(NAL, Network Abstraction Layer)。 VCL 数据即编码处理的输出,它表示被压缩编码后的视频数据 序列。在 VCL 数据传输或存储之前,这些编码的 VCL 数据,先被映射或封装进 NAL 单元(以下简称 NALU,Nal Unit) 中。每个 NALU 包括一个原始字节序列负荷(RBSP, Raw Byte Sequence Payload)、一组 对应于视频编码的 NALU 头部信息。RBSP 的基本结构是:在原始编码数据的后面填加了结尾 比特。一个 bit“1”若干比特“0”,以便字节对齐

image.png

编码的码流格式

image.png image.png