音视频基础知识

464 阅读6分钟

流程图解

视音频完整解码播放流程分析。

解码流程.jpg

音视频录制流程

录制流程.png

编码

  • 为什么要编码?

因为视频文件太大了

视频是连续的图像序列,由连续的帧构成,一帧即为一幅图像。 由于人眼的视觉暂留效应,当帧序列以一定的速率播放时,我们看到的就是动作连续的视频。 这么多连续的图像数据如果不经过编码的数据量太大了。

比如一个1920x1080分辨率,32位,每秒30帧的视频,一秒钟需要1920108032*30,大小大概为237MB 数据。

编码的目的:

编码的目的,就是为了压缩。各种视频编码方式,都是为了让视频变得体积更小,有利于存储和传输。编码的 核心思想就是去除冗余信息。

冗余类型:

空间冗余 == 相邻像素重复:

空间冗余:图像内部相邻像素之间存在较强的相关性多造成的冗余。

时间冗余 == 帧之间差值:

时间冗余:视频图像序列中的不同帧之间的相关性所造成的冗余。

视觉冗余 == 人类不敏感的颜色

视觉冗余:是指人眼不能感知或不敏感的那部分图像信息。

信息熵冗余 ==熵编码-哈夫曼算法

信息熵冗余:也称编码冗余,人们用于表达某一信息所需要的比特数总比理论上表示该信息所需要的最少比特 数要大,它们之间的差距就是信息熵冗余,或称编码冗余。

知识冗余 == 人类(头 身体 腿),汽车,房子 不需要记录

知识冗余:是指在有些图像中还包含与某些验证知识有关的信息。

I帧 P帧 B帧 压缩思路

I帧:帧内编码帧,关键帧,I帧可以看作一个图像经过压缩之后的产物,可以单独解码出一个完整的图像; (压缩率最低)

P帧:前向预测/参考 编码帧,记录了本帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画 面叠加上本帧定义的差别,生成最终画面。 (压缩率比I帧高,比B帧低 属于 适中情况)

B帧:双向预测/参考 编码帧,记录了本帧与前后帧的差别,解码需要参考前面一个I帧或者P帧,同时也需要 后面的P帧才能解码一张完整的图像。 (参考前后的预测得到的,压缩率是最高,但是耗时)

H.264进制数据分析

编码标准:

H.264 == MPEG-4 - AVC

HEVC == H.265 [H.264基础上 加入了更多的算法 == 压缩的更小]

视频编码就是通过特定的压缩技术,将某个视频格式文件 转换成另外一种视频格式文件。

视频流传输中最重要的编解码标准有以下两个标准:

  • 国际电联(ITU-T,国际电信联盟)的H.261,H.263,H.264,H.265等。
  • ISO国际标准化组织与IEC国际电子委员会于1988年联合成立 MPEG系列标准MPEG1,MPEG2,MPEG4 ,AVC等。

两者为合作关系:ITU-T方面称之为H.26。但ISO/IEC的则将这个新标准归纳于MPEG系列,称之为MPEG-4 AVC。

而H.265则被视为是ITU-T H.264/MPEG-4 AVC 标准的继承者,又称之为高效率编码(Hight Efficiengcy Video Coding)。

H.264分层结构(VCL与NAL)

VCL:

VCL(Video Coding Layer,视频编码层):负责高效的视频内容表示,

VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。

NAL:

NAL(Network Abstraction Layer,网络提取层):负责以网络所要求的恰当的方式对数据进行打包和 传送, 是传输层。不管在本地播放还是网络播放,都要通过这一层来传输

VCL就是被压缩编码后原始数据,在VCL数据封装到NAL单元中之后,才可以用于传输或存储。

NAL.png

NAL(片(宏块))

一帧图片经过 H.264 编码器之后,NAL单元就是装载着这些片(被编码为一个或多个片 slice), 每片包 含整数个宏块(至少一个宏块,最多包含整个图像宏块)。

宏块.png

一般H.264编码器的默认输出为:起始码+NALU(Nal单元)。起始码为:0x00000001或者0x000001。

一个NALU(PPS, I帧,B帧,P帧)

每个NALU 包含(起始码 与 1个字节的Nal Header 与 若干整数字节的负荷数据EBSP构成)

  • 为什么需求起始码,0x00000001或者0x000001 ?

​ 因为每一个NALU都需要分隔,要分隔帧操作,就相对于写文章断句一样

  • 为什么 0x00000001或者0x000001, 两种起始码 ?

​ 0x00000001 起始码代表:一个NALU里面有很多片。 ​ 0x000001 起始码代表: 一个NALU里面一个片可以搞定。

NAL类型查询表:

NAL类型查找表.png

H.264分析

通过EditorGreen 可以分析H.264数据

SPS序列参数集,记录有多少I帧,多少B帧,多少P帧,帧排列等

PPS 图像参数集(图像宽高信息等)

SEI补充信息单元(可以记录坐标信息,人员信息, 后面解码的时候,可以通过代码获取此信息)

真正开发中只分析:SPS序列参数集,PPS图像参数集 ,I帧

264解析.png

00 00 00 01 67

00 00 00 01 是起始码, 67 是一个字节(16进制) 需要转成二进制 01100111

二进制01100111 取低五位,00111

一个字节八位,前面补0 , 00000111 ,转成十六进制 0x07 ,查表NAL类型表,是序列参数集

为什么要取低五位?

NALU中的字节 01100111,分为三组

0 11 001111

每组代表不同意义:

第一组:0 代表这个帧可以用,1代表这个帧不可以用

第二组:11 代表此帧很重要 , 00 代表此帧不重要

第三组:00111 ,是为了查询NALU类型 , 转成16进制 是7,通过查表 得知 是 SPS

PPS 图像参数集

00 00 00 01 68, 0x68 -> 2进制01101000 -> 取低五位 00001000 ---> 十六进制 0x08

I帧

00 00 00 65, 0x65 ---> 2进制01100101---> 取低五位00000101 ---> ---> 十六进制 0x06 最终是 5

PTS与DTS

DTS表示解码时间戳,在什么时候解码这一帧的数据 ;

PTS表示显示时间戳 ,在什么时候显示这一帧。

在没有B帧的情况下,DTS和PTS的输出顺序是一样的。

因为B帧打乱了解码和显示的顺序(要解码B帧需要先解码后面的P帧),所以一旦存在B帧,PTS和DTS就会不 同。

显示顺序.png

I帧 PBPBPBPPB I帧 ==GOP

从第一个I帧 到 下一个I帧,这样分为一组

SPS PPS I P B P B P B P B I 一组

SPS PPS I P B P B P B P B I 二组

这样一组一组播放才会效率高