美文网首页Android技术知识Android开发
音视频开发——H264码流学习

音视频开发——H264码流学习

作者: 谁动了我的代码 | 来源:发表于2022-12-23 16:08 被阅读0次

    概述

    H.264是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为H.264/AVC。

    H.264标准的主要目标是:与其它现有的视频编码标准相比,在相同的带宽下提供更加优秀的图象质量。通过该标准,在同等图象质量下的压缩效率比以前的标准(MPEG2)提高了2倍左右。

    H.264特点:

    (1)码率低:在同等图像质量下,采用H.264技术压缩后的数据量约有MPEG-2的1/2。 (2)计算复杂度高:H.264获得优越性能的代价是计算复杂度高,相当于MPEG-2的2~3倍,大大增加了H.264编码器的实现难度。 (3)容错能力强:H.264码流具有较强的抗误码特性,可适应丢包率高、干扰严重的信道中的视频传输,如IP和无线网络的应用。 (4)网络适应性强:H.264提供的网络适应层,使得H.264文件可在不同网络上传输。

    H264编码分层

    NAL层:(Network Abstraction Layer,视频数据网络抽象层): 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。 VCL层:(Video Coding Layer,视频数据编码层): 对视频原始数据进行压缩

    上图中我们可以看到视频帧序列每一帧图像是由slice构成的,每一个slice是由多个宏块构成的,在实际传输的过程中,一般一帧图像就是一个slice,没有分那么细。

    码流的基本概念

    SODB:(String of Data Bits,原始数据比特流):由VCL层产生,数据长度不一定是8的倍数,所以处理起来比较麻烦 RBSP:(Raw Byte Sequence Payload,SODB+trailing bits,编码后的数据流):算法是在SODB最后一位补1,不按字节对齐补0,如果补齐0,不知道在哪里结束,所以补1,如果不够8位则按位补0 EBSP:(Encapsulate Byte Sequence Payload):生成编码后的数据流之后,我们还要在每个帧之前加一个起始位,需要开发者人为添加。起始位一般是十六进制的0001。但是在整个编码后的数据里,可能会出来连续的2个0x00。那这样就与起始位产生了冲突.那怎么处理了? H264规范里说明如果处理2个连续的0x00,就额外增加一个0x03 。这样就能预防压缩后的数据与起始位产生冲突 NALU: (NAL Header(1B)+EBSP).NALU就是在EBSP的基础上加1B的网络头. 下图展示了NAL单元的结构组成

    H264切片与宏块:

    在上述的VCL层中,切片与宏块划分的具体情况如下,对于slice是由header和data组成,data中由很多的宏块(MacroBlock)组成,在宏块中存储的包括宏块的类型 mb_type,宏块的预测值mb_pred 和残差值 codec residual

    码流分层

    整个H264的码流结构如下图所示

    将整个结构串起来,就很明白了。 我们在网上观看的时候,实际上H264码流包含了两种格式,Annexb和RTP格式的。 在文件中保存的,每一个NAL单元前面都有一个startcode,00开头的起始码,这样由Startcode和NAL单元构成的就是Annexb格式。 如果只是在网上传输,不包含startcode,直接传输NAL单元叫RTP码流。

    以上就对H264的码流做了一些介绍,但是我们不能只停留于表面,还需要进一步地去了解码流里面包含的一些重要的参数信息。

    SPS和PPS

    SPS:SPS即Sequence Paramater Set,又称作序列参数集。SPS中保存了一组编码视频序列(Coded video sequence)的全局参数。所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。在H.264标准协议中规定了多种不同的NAL Unit类型,其中类型7表示该NAL Unit内保存的数据为Sequence Paramater Set。在H.264的各种语法元素中,SPS中的信息至关重要。如果其中的数据丢失或出现错误,那么解码过程很可能会失败。

    PPS:除了序列参数集SPS之外,H.264中另一重要的参数集合为图像参数集Picture Paramater Set(PPS)。通常情况下,PPS类似于SPS,在H.264的裸码流中单独保存在一个NAL Unit中,只是PPS NAL Unit的nal_unit_type值为8;而在封装格式中,PPS通常与SPS一起,保存在视频文件的文件头中。

    SPS及PPS在某些平台的视频处理框架(比如iOS的VideoToolBox等)还通常作为解码器实例的初始化信息使用。而每一帧的编码后数据所依赖的参数保存于图像参数集中。一般情况SPS和PPS的NAL Unit通常位于整个码流的起始位置。

    通常情况下: H.264码流第一个 NALU是 SPS(序列参数集Sequence Parameter Set)

    H.264码流第二个 NALU是 PPS(图像参数集Picture Parameter Set)

    H.264码流第三个 NALU 是 IDR(即时解码器刷新)

    在对SPS PPS有基本了解以后我们来具体看一下SPS和PPS保存了哪些参数。

    4.1SPS

    SPS中两个重要的参数

    H264 Profile:对视频压缩特性的描述,Profile越高,说明采用了越高级的压缩特性

    H264 Level:Level是对视频的描述,Level越高,视频的码率、分辨率、fps越高。

    下图展示了H264 Profile的发展过程

    Profile主要分成了两极,第一极以CONSTRAINTS BASELINE为核心发展而来的是MAIN PROFILE,第二极是以CONSTARINT BASELINE发展而来的BASELINE和EXTEND。

    核心CONSTARINT BASELINE中包含一些核心的P帧,I帧的压缩技术,以及比较老的CAVLC的无损压缩技术,发展到MAINPROFILE出现了B帧,和新的无损压缩技术CABAC,也使得压缩率进一步提高。

    第二极不常见,所以我们具体阐释常见的第一极,在第一极发展的过程中,出现了更多的更高压缩比的压缩特性。

    下图展示了H264 Level比较好理解,拍视频买电子设备的时候都会研究这些参数

    SPS中与分辨率有关的参数

    SPS中与帧有关的参数

    最大帧数:log2_max_frame_num_minus4 通过此参数可以了解到一个GOP中有多少帧 最大参考帧数:max_num_ref_frames 表示了解码器中参考帧的缓冲队列的大小,如果该值是5,解码器缓冲队列参考帧就是5帧的大小。 显示帧序号:pic_order_cnt_type 可以通过不同的type计算具体的帧是哪一号显示

    4.2 PPS

    PPS相较于SPS要简单很多,下面列出PPS中较为重要的参数,不作具体阐述了。

    4.3 Slice-Header

    Slice Header中保存的信息较少,主要包括帧类型,GOP中的解码帧序号,预测权重,滤波相关信息。如果PPS中没有开启预测权重和滤波,这里就没有对应的信息。

    以上就是有关H264码流的学习,有关更多H264的学习或者音视频开发知识进阶的;可以参考《音视频开发基础精通》这份学习笔记。里面记录了从最基础的C++语言学起。

    文末

    编码器示意图:

    解码器示意图:

    相关文章

      网友评论

        本文标题:音视频开发——H264码流学习

        本文链接:https://www.haomeiwen.com/subject/dwivqdtx.html