H264是一种视频压缩标准。
根据不同类别,编码器会使用不同类型的帧,I帧、P帧和B帧。
I帧:自身可以通过视频解压算法解压成一张单独的完整的图片。P帧只需要参考前面的I帧或P帧,而B帧则需要同时参考前面和后面的I帧或P帧。
在H.264基准类中,仅使用I帧和P帧以实现低延时,因此是网络摄像机和视频编码器的理想选择。
网络提取层(NAL network abstraction layer )和视频编码层(VCL video coding layer)
H264有严格的规范,以00 00 00 01分割之后的下一个字节就是NALU类型,用来描述此帧的意义。
NALU类型:
(1)第1位禁止位,值为1表示语法出错
(2)第2~3位为参考级别
(3)第4~8为是nal单元类型
以通常的首帧来看:
打印出来为103(用十六进制软件分析的话值为67),转为二进制为0110 0111,4-8为00111,转为十进制为7,释义见下:
- 1
0,未使用
1,不分区,非IDR图像的片
2,片分区A 3,片分区B 4,片分区C
5,IDR图像的片段
6,补充增强信息单元(SEI)
7,序列参数集sps
8,图像参数集pps
9,分界符 10,序列结束符 11,流结束符 12填充 13..23保留 24..31未使用
即是sps,仔细看还有第二个分隔符,为104释义为8,即pps。这一帧内包含了H264的大部分精华,在使用中把此帧喂入解码器是很关键的,简单介绍一下:
SPS:包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
PPS:包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)
在后面的实践Demo中会观察到此帧的重要性。
接下来的第二帧是实际意义上的关键帧(I帧):
打印出来为103(用十六进制软件分析的话值为67),转为二进制为0110 0111,4-8为00111,转为十进制为7,释义见下:
通常的首帧来看:
打印出来为103(用十六进制软件分析的话值为67),转为二进制为0110 0111,4-8为00111,转为十进制为7,释义见下:
- 1
0,未使用
1,不分区,非IDR图像的片
2,片分区A 3,片分区B 4,片分区C
5,IDR图像的片段
6,补充增强信息单元(SEI)
7,序列参数集sps
8,图像参数集pps
9,分界符 10,序列结束符 11,流结束符 12填充 13..23保留 24..31未使用
即是sps,仔细看还有第二个分隔符,为104释义为8,即pps。这一帧内包含了H264的大部分精华,在使用中把此帧喂入解码器是很关键的,简单介绍一下:
SPS:包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
PPS:包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)
在后面的实践Demo中会观察到此帧的重要性。
接下来的第二帧是实际意义上的关键帧(I帧):
int value = buf[4] & 0x0f;//nalu, 5是I帧, 7是sps 8是pps.
VCL即编码处理的输出,它表示被压缩编码后的视频数据序列,这里有几个知识点,差分编码、运动补偿、帧内预测,有心的朋友可以去详细搜索学习,知识点这里用笔记里的记录做一个简单介绍:
差分编码:包括H.264在内的大多数视频压缩标准都采用这种方法,只有第一个图像(I帧)是将全帧图像信息进行编码。在后面的两个图像(P帧)中,其静态部分将参考第一个图像,而仅对运动部分使用运动矢量进行编码,从而减少发送和存储的信息量。
运动补偿:将一个帧分为一系列的宏块。然后,通过在参考帧中查找匹配块的方式,逐块地构建一个新帧。
帧内预测:对帧中每个宏块内较小的像素块进行连续预测。
码率、帧率、分辨率
这三个参数直观的影响到视频流的大小,视频清晰度等观看体验。码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。分辨率一定的情况下,码率与清晰度成正比关系,码率越高,图像越清晰;码率越低,图像越不清晰。下面是一张参考图:
码率单位是kbps即千位每秒。也就是取样率(和音频的采样率有区别,采样率单位是Hz,表示每秒采样次数),单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真。码率越高越清晰,反之则画面粗糙而多马赛克,1080P不一定比720P清晰,打开看码率对比最实际~
其它
IDR帧和I帧:首个I帧叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像,不过I帧不一定是IDR图像。H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空(DPB,DecodedPictureBuffer 参考帧列表),将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
H265和H264
同样的画质和同样的码率,H.265比H.264 占用的存储空间要少理论50%;如果存储空间一样大,那么意味着,在一样的码率下H.265会比H2.64 画质要高一些理论值是30%~40%,但是因为部分专利价太高(部分公司创建联盟,收取专利费),计算复杂度(编码要求的硬件性能较高) 普及难度直线上升。
带宽,码流,在线人数之间的关系:
带宽 / (码流 * 8) = 同时在线人数
文件大小 = 时间×码率/8
一个视频文件的大小为5.86M,播放时长为3分7秒:
1:该文件对应的码流就是
5.86 * 1024 * 1024 * 8 / (3 * 60 + 7) =262872.95657754bps
2:10M独享带宽能支撑的同时在线人数
10* 1024 * 1024 / 262872.95657754 =39.889078498294
3:支撑1000人同时在线的系统最少需要的带宽数为
262872* 1000 / (1024 * 1024) = 250.69427490234M
场频:画面刷新次数。
行频:屏幕的水平扫描频率,以Hz为单位。它越大就意味着显示器可以提供的分辨率越高,稳定性越好。
行频 = height(垂直分辨率) * 1.04~1.08 * 场频
YUV格式:一种颜色编码方式,可以转化成我们常用的RGB色值。Y代表亮度,UV代表色值,Y可以显示一张完整的黑白图像。这样的设计解决了黑白电视和彩色电视的兼容,并且YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。
基本概念整理:
DTS:Decode Time Stamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.在display的时候使用.在没有B frame的情况下.DTS和PTS的输出顺序是一样的.
SPS(序列的参数集):包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
PPS(图像的参数集):包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)