H264码流分析和打包RTP过程

目录

    • 播放视频文件流程图
    • H264概述
    • 封装格式
          • 视频文件封装格式
    • H264基本单元
    • H264帧类型
    • H264中的 I帧、P帧和B帧
    • GOP(画面组)
    • IDR 帧
    • H264压缩方式
    • H264编码层次
    • H264压缩方式说明
    • H264分层结构
          • VLC层(Video Coding Layer)
          • NAL层(Network Abstraction Layer)
    • RBSP(Raw Byte Sequence Payload))
    • RBSP和SODB
    • H264的RTP打包过程
    • 单一NALU单元模式
    • 组合封包模式—STAP-A
    • 分片模式—FU-A
    • 举例解析RTP包数据
    • H264 局限性
    • h265和h264视频编码区别

播放视频文件流程图

H264码流分析和打包RTP过程_第1张图片

H264概述

         对摄像头采集的每一帧视频需要进行编码,由于视频中存在空间和时间的冗余,需要用算法来去除这些冗余。H264是专门去除这些冗余的算法,我们把这种算法称为H264编码。视频压缩算法来压缩视频的占用空间,提高存储和传输的效率,在获得有效的压缩效果的同时,使得压缩过程引起的失真最小。
         视频压缩算法是通过去除时间、空间的冗余来实现的。在一段时间内,相邻的图像的像素、亮度与色温的差别很小,我们没比要对每一个图像进行完成的编码,而是可以选取这段时间的第一张图(也就是第一帧)作为完整的编码,而后面一段时间的图像只需要记录与第一张图(第一帧)在像素、亮度、色温等方面的差别数据即可。通过去除不同类型的冗余,可以明显的压缩数据,代价就是一部分信息失真。

封装格式

         封装格式(也叫容器),就是将已经编码压缩好的视频轨和音频轨按照一定的格式放到一个文件中,也就是说仅仅是一个外壳,或者把它当成一个放视频轨和音频轨的文件夹也可以。说得通俗点,视频轨相当于饭,而音频轨相当于菜,封装格式就是一个碗,或者一个锅,用来盛放饭菜的容器。 下面是几种常用的视频文件后缀类型与其相对应的封装格式。

视频文件封装格式

H264码流分析和打包RTP过程_第2张图片

H264基本单元

         在H.264定义的结构中,一个视频图像编码后的数据叫做一帧。 一帧是由一个或多个片(slice)组成的,一个片是由一个或多个宏块(MB)组成的(宏块是H264编码的基本单位),一个宏块是由16x16的yuv数据组成的。

H264帧类型

         在H.264的协议中,定义了三类帧,分别是I帧、B帧和P帧。其中I帧就是一个完整的图像帧,而B帧和P帧对应的就是之前说的不对全部图像做编码的帧。B帧和P帧的差别在于,P帧是参考之前的I帧生成的,B帧是参考前后的图像帧生成的。
         在视频画面播放过程中,若I帧丢失了,则后面的P帧也就随着解不出来,就会出现视频画面黑屏的现象;若P帧丢失了,则视频画面会出现花屏、马赛克等现象。

H264中的 I帧、P帧和B帧

         H264 使用帧内压缩和帧间压缩的方式提高编码压缩率;H264采用了独特的 I帧,P帧和B帧策略来实现,连续帧之间的压缩。
H264码流分析和打包RTP过程_第3张图片
I帧:可以看成是一个图像经过压缩后的产物。自身可以通过视频解压算法解压成一张单独的完整的图片。
P帧:需要参考其前面的一个I frame 或者P frame来生成一张完整的图片。
B帧:要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。

GOP(画面组)

         一个GOP(Group Of Picture)就是一组连续的画面。GOP结构一般有两个数字,其中一个是GOP的长度(即两个I帧之间的B帧和P帧数),另一个数字为I帧和P帧之间的间隔距离(即B帧数)。在一个GOP内I帧解码不依赖任何的其它帧,P帧解码则依赖前面的I帧或P帧,B帧解码依赖前面的I帧或P帧及其后最近的一个P帧。
例子:
格式设置GOP:M = 1 , N = 30;
         M值表示I帧或者P帧之间的帧数目,N值表示GOP的长度。如上图所示M = 1,则表示两个P帧相差1帧(无B帧),N = 30, 则表示GOP长度为30.
H264码流分析和打包RTP过程_第4张图片

IDR 帧

         GOP中的I帧又分为普通I帧和IDR帧,IDR帧可以认为是首个I帧(但是很多场景I帧都是IDR帧),这样区分视为了方便控制编码和解码的流程。 IDR帧一定是I帧,但是I帧不一定是IDR帧。
         IDR帧因为附带SPS、PPS等信息,解码器在收到 IDR 帧时,需要做的工作就是:把所有的 PPS 和 SPS 参数进行更新。
         SPS是序列参数集,包含的是针对一连续编码视频序列的参数,如标识符 seq_parameter_set_id、帧数及 POC 的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等等。
         PPS是图像参数集,对应的是一个序列中某一幅图像或者某几幅图像,其参数如标识符 pic_parameter_set_id、可选的 seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等等。
可以看出来IDR帧的作用是让解码器立刻刷新相关数据信息,避免出现较大的解码错误问题。
         引入IDR帧机制是为了解码的重同步,当解码器解码到 IDR帧时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现错误,在这里可以获得重新同步的机会。IDR帧之后的帧永远不会使用IDR帧之前的数据来解码。

H264压缩方式

         H264 的核心压缩算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。
         帧内(Intraframe)压缩的原理是:当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩率一般不高。
         帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。
而帧间压缩也称为时间压缩(Temporalcompression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩是无损的,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。

H264编码层次

         H264除了实现对视频的压缩处理外,为了方便网络传输,还提供了对应的视频编码和分片策略。类似网络数据帧封装成IP帧,在H264中将其称为组(GOP,group of picture)、片(slice)、宏块(Macroblock),它们一起组成了H264的码流分层结构。H264将其组织成为序列(GOP)、图片(pictrue)、片(Slice)、宏块(Macroblock)、子块(subblock)五个层次。
H264码流分析和打包RTP过程_第5张图片

H264压缩方式说明

1、分组,也就是将一系列变换不大的图像归为一个组,即一个GOP;
2、定义帧,将每组的图像帧归分为I帧、P帧和B帧三种类型;
3、预测帧, 以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;
4、数据传输, 最后将I帧数据与预测的差值信息进行存储和传输。

H264分层结构

         H264的主要目标是为了有高的视频压缩比和良好的网络亲和性,H264将系统框架分为两个层面,分别是视频编码层面(VCL)和网络抽象层面(NAL)

VLC层(Video Coding Layer)

VLC层:包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码;

NAL层(Network Abstraction Layer)

         NAL层:负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。
NALU(NAL Unit)
         H.264原始码流(裸流)是由一个接一个NALU组成, 每个NALU之间都使用start code(起始码)分隔,NALU单元通常由[StartCode] [NALU Header] [NALU Payload] 三部分组成,其中 Start Code 用于标示这是一个NALU 单元的开始,必须是"00 00 00 01" 或"00 00 01"。每个 NALU包括一个头部信息(NAL header)和一个原始字节序列负荷(RBSP)。
H264码流分析和打包RTP过程_第6张图片
Start Code(1字节)
         Start Code 用于标示这是一个NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”。就是一个完整的帧被编为多个slice(片)的时候StartCode是00 00 01, 否则都是00 00 00 01。
NAL Header(1字节)
         NAL Header由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。
H264码流分析和打包RTP过程_第7张图片
forbidden_bit
         禁止位,初始为0,当网络发现NAL单元有比特错误时可设置该比特为1,以便接受方纠错或丢掉该单元。
nal_reference_bit
         NAL重要性,值越大,越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU。
nal_unit_type:NALU类型取值如下表所示:
在这里插入图片描述

RBSP(Raw Byte Sequence Payload))

下图是一个NAL由多个类型的NALU(RBSP)组成的序列样式和相关类型参数描述表:
H264码流分析和打包RTP过程_第8张图片
         RBSP根据NALU头中的nal_unit_type判断数据类型进行解析比如7是SPS,8是PPS,1是非IDR的片。

RBSP和SODB

         原始编码数据SODB(String Of Data Bits)他们2个的关系是:
RBSP = SODB + RBSP尾部

H264的RTP打包过程

H264码流分析和打包RTP过程_第9张图片
         打包的时候,我们将RBSP作为作为负载数据放到RTP包中,我们根据NAL头来确定Slice头放到负载数据的头部供我们作为标识,如果是单一NALU一般直接用NAL的头来作为标识,如果是组合获取其他模式的,我们利用Slice的值来辨识。其Slice片数据就是数据(一系列的宏块和一些不变吗数据)。
         Slice header中主要保存了当前slice的一些全局的信息,和片的类型。
H264码流分析和打包RTP过程_第10张图片

单一NALU单元模式

H264码流分析和打包RTP过程_第11张图片
如有一个 H.264 的 NALU 是这样的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F … ]
封装成 RTP 包将如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]

组合封包模式—STAP-A

H264码流分析和打包RTP过程_第12张图片
如有两个 H.264 的 NALU 是这样的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F … ]
[00 00 00 01 68 42 B0 12 58 6A D4 FF … ]
封装成 RTP 包将如下:
[ RTP Header ]
[F + NRI + TYPE24 (代表STAP-A)]
[第一个NALU长度 (占用两个字节)]
[67 42 A0 1E 23 56 0E 2F ]
[第二个NALU长度 (占用两个字节)]
[68 42 B0 12 58 6A D4 FF … ]

分片模式—FU-A

H264码流分析和打包RTP过程_第13张图片
S:1bit 当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始为设为0。
E:1bit当设置成1,结束位指示分片NAL单元的结束,即荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。
R:1bit保留位必须设置为0,接受者必须忽略该位。
例如:
0x7C85=01111100 10000101 (开始包)
0x7C05=01111100 00000101 (中间包)
0x7C45=01111100 01000101 (结束包)
如有一个 H.264 的 NALU 是这样的:
[00 00 00 01 65 42 A0 1E 23 56 0E 2F … 02 17 C8 FD F1 B9 C7 53 59 72 … CB FF FF F4 1A D5 C4 18 A8 … F1 B9 C7 1D A5 FA 13 0B …]
封装成 RTP 包将如下:
[ RTP Header ] [ 7C 85 42 A0 1E 23 56 0E 2F …]
[ RTP Header ] [ 7C 05 02 17 C8 FD F1 B9 C7 53 59 72 …]
[ RTP Header ] [ 7C 05 CB FF FF F4 1A D5 C4 18 A8 …]
[ RTP Header ] [ 7C 45 F1 B9 C7 1D A5 FA 13 0B …]
一段RTP包数据码流如下:

举例解析RTP包数据

H264码流分析和打包RTP过程_第14张图片

H264 局限性

         随着数字视频应用产业链的快速发展,视频应用向以下几个方向发展的趋势愈加明显:
(1) 高清晰度(HigherDefinition):数字视频的应用格式从720P向1080P全面升级,而且现在4K的数字视频格式也已经成为常见。
(2) 高帧率(Higherframe rate ):数字视频帧率从30fps向60fps、120fps甚至240fps的应用场景升级;
(3) 高压缩率(HigherCompression rate ):传输带宽和存储空间一直是视频应用中最为关键的资源,因此,在有限的空间和管道中获得最佳的视频体验一直是用户的不懈追求。
         但是面对视频应用不断向高清晰度、高帧率、高压缩率方向发展的趋势,当前主流的视频压缩标准协议H.264的局限性不断凸显。主要体现在:
(1) 宏块个数的爆发式增长,会导致用于编码宏块的预测模式、运动矢量、参考帧索引和量化级等宏块级参数信息所占用的码字过多,用于编码残差部分的码字明显减少。
(2) 由于分辨率的大大增加,单个宏块所表示的图像内容的信息大大减少,这将导致相邻的4 x 4或8 x 8块变换后的低频系数相似程度也大大提高,导致出现大量的冗余。
(3) 由于分辨率的大大增加,表示同一个运动的运动矢量的幅值将大大增加,H.264中采用一个运动矢量预测值,对运动矢量差编码使用的是哥伦布指数编码,该编码方式的特点是数值越小使用的比特数越少。因此,随着运动矢量幅值的大幅增加,H.264中用来对运动矢量进行预测以及编码的方法压缩率将逐渐降低。
(4) H.264的一些关键算法例如采用CAVLC和CABAC两种基于上下文的熵编码方法、deblock滤波等都要求串行编码,并行度比较低。针对GPU/DSP/FPGA/ASIC等并行化程度非常高的CPU,H.264的这种串行化处理越来越成为制约运算性能的瓶颈。
于是面向更高清晰度、更高帧率、更高压缩率视频应用的HEVC(H.265)协议标准应运而生。H.265在H.264标准2~4倍的复杂度基础上,将压缩效率提升一倍以上。

h265和h264视频编码区别

1、版本
         H.265是新的编码协议,也即是H.264的升bai级版。H.265标准保留duH.264原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。
2、储存空间与画质
         同样的画质和同样的码率,H.265比H2.64 占用的存储空间要少理论50%。如果存储空间一样大,那么意味着,在一样的码率下H.265会比H2.64 画质要高一些理论值是30%~40%。
3、降码率
         比起H.264/AVC,H.265/HEVC提供了更多不同的工具来降低码率,以编码单位来说,H.264中每个宏块(macroblock/MB)大小都是固定的16x16像素,而H.265的编码单位可以选择从最小的8x8到最大的64x64。

你可能感兴趣的:(音视频开发,音视频,实时音视频)