H264知识

作者: 一川烟草i蓑衣 | 来源:发表于2019-04-17 22:18 被阅读0次

    VideoToolbox基本数据结构:

    (1)CVPixelBuffer:编码前和解码后的图像数据结构。

    (2)CMTime、CMClock和CMTimebase:时间戳相关。时间以64-bit/32-bit的形式出现。

    (3)CMBlockBuffer:编码后,结果图像的数据结构。

    (4)CMVideoFormatDescription:图像存储方式,编解码器等格式描述。

    (5)CMSampleBuffer:存放编解码前后的视频图像的容器数据结构。

    1

    视频压缩知识:

    H264压缩技术主要采用了以下几种方法对视频数据进行压缩。包括:

    帧内预测压缩,解决的是空域数据冗余问题。

    帧间预测压缩(运动估计与补偿),解决的是时域数据冗徐问题。

    整数离散余弦变换(DCT),将空间上的相关性变为频域上无关的数据然后进行量化。

    CABAC压缩。

    经过压缩后的帧分为:I帧,P帧和B帧:

    I帧:关键帧,采用帧内压缩技术。

    P帧:向前参考帧,在压缩时,只参考前面已经处理的帧。采用帧音压缩技术。

    B帧:双向参考帧,在压缩时,它即参考前而的帧,又参考它后面的帧。采用帧间压缩技术。

    除了I/P/B帧外,还有图像序列GOP。

    GOP:两个I帧之间是一个图像序列,在一个图像序列中只有一个I帧。如下图所示:

    2

    NALU:(H264的码流,H264的实际数据传输)Network Abstract Layer,即网络抽象层

    H.264码流在网络中传输时实际是以NALU的形式进行传输的.

    H264的码流由NALU单元组成,NALU单元包含视频图像数据和H264的参数信息。其中视频图像数据就是CMBlockBuffer,而H264的参数信息则可以组合成FormatDesc。具体来说参数信息包含SPS(Sequence Parameter Set)和PPS(Picture Parameter Set)

    由NALU构成的H264NALUS数据码流

    (1)提取sps和pps生成format description。

    a,每个NALU的开始码是0x00 00 01,按照开始码定位NALU。

    b,通过类型信息找到sps和pps并提取,开始码后第一个byte的后5位,7代表sps,8代表pps。

    c,CMVideoFormatDescriptionCreateFromH264ParameterSets函数来构建CMVideoFormatDescriptionRef。具体代码可以见demo。

    (2)提取视频图像数据生成CMBlockBuffer。

    a,通过开始码,定位到NALU。

    b,确定类型为数据后,将开始码替换成NALU的长度信息(4 Bytes)。

    c,CMBlockBufferCreateWithMemoryBlock接口构造CMBlockBufferRef。具体代码可以见demo。

    (3)根据需要,生成CMTime信息。(实际测试时,加入time信息后,有不稳定的图像,不加入time信息反而没有,需要进一步研究,这里建议不加入time信息)

    根据上述得到CMVideoFormatDescriptionRef、CMBlockBufferRef和可选的时间信息,使用CMSampleBufferCreate接口得到CMSampleBuffer数据这个待解码的原始的数据。见下图的H264数据转换示意图。

    1

    NALU结构:长度-1byte

    NALU结构 NALU Header

    NAL header:

    forbidden_zero_bit:forbidden_zero_bit shall be equal to 0.

    nal_ref_idc:

    用于表示当前NALU的重要性,值越大,越重要.

    解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU.

    nal_ref_idc不等于0时, NAL unit的内容可能是SPS/PPS/参考图像的片等,nal_ref_idc等于0时,NAL unit的内容可能是非参考图像的片等.

    SPS/PPS时,nal_ref_idc不可为0,当某个图像的片的nal_ref_id等于0时,该图像的所有片均应等于0.

    1

    举例来说:

    00 00 00 01 06:  SEI信息

    00 00 00 01 67: 0x67&0x1f = 0x07 :SPS

    00 00 00 01 68: 0x68&0x1f= 0x08 :PPS

    00 00 00 01 65: 0x65&0x1f= 0x05 :IDR Slice

    RBSP


    2

    RBSP 序列举例:

    3

    SODB与RBSP:

    SODB 数据比特串 -> 是编码后的原始数据.

    RBSP 原始字节序列载荷 -> 在原始编码数据的后面添加了 结尾比特。一个 bit“1”若干比特“0”,以便字节对齐。

    3

    NALU架构:

    4

    1帧 = n个片

    1片 = n个宏块

    1宏块 =16x16yuv数据

    为什么要设置片呢?

    设置片的目的是为了限制误码的扩散和传输,应使编码片相互间是独立的。某片的预测不能以其他片中的宏块为参考图像,这样某一片中的预测误差才不会传播到其他片中。 

    可以看到上图中,每个图像中,若干宏块(Macroblock)被排列成片。一个视频图像可编程一个或更多个片,每片包含整数个宏块 (MB),每片至少包含一个宏块。

    片有一下五种类型:

    片     意义

    I       片只包含I宏块

    P      片包含P和I宏块

    B      片包含B和I宏块

    SP     片包含P 和/或 I宏块,用于不同码流之间的切换

    SI     片一种特殊类型的编码宏块

    SPS:

    h264文档 7.2章节描述了内存大小描述语法

    7.3.2.1.1描述了sps结构

    Sequence Parameter Set(序列参数集)

    nal_unit_type = 7

    包含H.264的profile_idc和level_idc等信息.

    还有图像的宽高:

    pic_width_in_mbs_minus1:pic_width_in_mbs_minus1 = 21 以宏块(16x16)为单位的值减1

    因此,实际的宽为 (21 + 1) * 16 = 352

    pic_height_in_map_units_minus1

    PPS:

    Picture Parameter Set(图像参数集)

    SEI:

    Supplementary Enhancement Information

    level和profile:

    profile:

    在H.264的SPS中,第一个字节表示profile_idc,根据profile_idc的值可以确定码流符合哪一种档次。判断规律为:

    profile_idc = 66 → baseline profile,基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;

    profile_idc = 77 → main profile, 进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;(用的少);

    profile_idc = 88 → extended profile,主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced), 也支持CAVLC 和CABAC 的支持;

    4、High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;

    在新版的标准中,还包括了High、High 10、High 4:2:2、High 4:4:4、High 10 Intra、High 4:2:2 Intra、High 4:4:4 Intra、CAVLC 4:4:4 Intra等,每一种都由不同的profile_idc表示。

    level:

    level由level_idc指定,编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数

    Level 主要参数:

    1

    如何查看H264码流数据?

    h264bitstream: https://sourceforge.net/projects/h264bitstream/files/latest/download

    H264Naked:https://github.com/shi-yan/H264Naked 可视化工具,H264Naked既可以识别.264,也可以还别.h264.但是使用live555MediaServer播放RTSP流,live555MediaServer只支持.264后缀。

    参考文章:https://www.jianshu.com/p/ea650344bafb

    如何查看H264裸流数据?

    相关文章

      网友评论

        本文标题:H264知识

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