NALU格式

音视频编码在流媒体和网络领域占有重要地位;流媒体编解码流程大致如下图所示:

NALU格式_第1张图片
image

x264原理解析

参考链接: x264百度词条;H264基本原理;

H264简介

H.264从1999年开始,到2003年形成草案,最后在2007年定稿有待核实。在ITU的标准里称为H.264,在MPEG的标准里是MPEG-4的一个组成部分–MPEG-4 Part 10,又叫Advanced Video Codec,因此常常称为MPEG-4 AVC或直接叫AVC。x264主要使用算法为H264编解码算法,下面对H264算法进行解析;

H264 编解码解析

参考链接: H264 编解码协议详解;深入浅出理解视频编码H264结构;详细文档;H264编解码框图;

H264编码原理:

在音视频传输过程中,视频文件的传输是一个极大的问题;一段分辨率为19201080,帧率是25的视频,对于传输带宽的要求是:1920108025/8/1024/1024=6.179MB,意味着视频每秒带宽为6.179MB这基本是不肯能的。因此视频压缩和编码技术应运而生。
对于视频文件来说,视频由单张图片帧所组成,每秒25/32帧,但是图片帧的像素块之间存在相似性,因此视频帧图像可以进行图像压缩;H264采用了16
16的分块大小对,视频帧图像进行相似比较和压缩编码。如下图所示:

NALU格式_第2张图片
image

除此之外,对于一段连续的帧图像来说,前一帧和后一帧之间的关联度和相似性很高,只记录当前帧和下一帧与当前帧之间的帧数据差,能够快速的帮助我们实现视频压缩编解码。为了方便图像之间的压缩,将原图像当前帧设置为Fn,下一帧设置为Fn-1;对Fn进行帧内相似压缩编码,使用估计函数进行重新映射(图像还原);再利用当前帧对图和帧差信息对下一帧图片进行估计和还原。具体编码框架如下图:

NALU格式_第3张图片
image

在上图中,输入的帧或场Fn以宏块为单位被编码器处理。首先,按帧内或者帧间预測编码的方法进行处理。假设採用帧间预測编码,其预測值PRED是由当前片中前面已编码的參考图像经运动补偿(MC)后得到,当中參考图像用F’n-1表示。预測值PRED和当前块相减后,产生一个残差块Dn,经块变换、量化后产生一组量化后的变换系数X,再经熵编码,与解码所需的一些头信息一起组成压缩后的码流,经NAL(网络自适应层)供传输和存储用。

在进行编码过后H264也提供了相应的解码方式,解码流程如下图:

NALU格式_第4张图片
image

将编码器的NAL输出的H264比特流经熵解码得到量化后的一组变换系数X,再经反量化、反变换,得到残差D’n。利用从该比特流中解码出的头信息,解码器就产生一个预測块PRED,它和编码器中的原始PRED是同样的。当该解码器产生的PRED与残差D’n相加后,就得到了uF’n,再经滤波后,最后就得到滤波后的解码输出图像F’n

H264中的I帧、P帧和B帧

正如上文所说;H264除了使用帧内压缩之外,还使用了帧间压缩;H264采用了独特的I帧、P帧和B帧策略来实现,连续帧之间的压缩;

[图片上传失败...(image-381d84-1564739618983)]

如上图所示;

  • I帧:自身可以通过视频解压算法解压成一张单独的完整的图片。
  • P帧:需要参考前面的I帧或P帧,还原成完整的图片。
  • B帧:需要同时参考前面和后面的I帧或P帧,来实现图片的还原。
    H.264基准类中,仅使用I帧和P帧以实现低延时,因此是网络摄像机和视频编码器的理想选择。
    注意:每当读取到一个新的I帧时,解码器会更新残差信息,删除之前的东西,防止错误。

H264编码结构解析

H264除了实现了对视频的压缩处理之外,为了方便网络传输,提供了对应的视频编码和分片策略;类似于网络数据封装成IP帧,在H264中将其称为组(gop)、片(slice)、宏块(Macroblock)这些一起组成了H264的码流分层结构;H264将其组织成为序列(GOP)、图片(pictrue)、片(Slice)、宏块(Macroblock)、子块(subblock)五个层次。

NALU格式_第5张图片
image

H264将视频分为连续的帧进行传输,在连续的帧之间使用I帧、P帧和B帧。同时对于帧内而言,将图像分块为片、宏块和字块进行分片传输;通过这个过程实现对视频文件的压缩包装。

NALU格式_第6张图片
image

在进行H264分包策略解析之前,我们需要先来了解一下H264的原始码流结构

H264 网络包

参考链接: 从零了解H264结构;H264码流结构分析;

H264在提出视频分片压缩策略的同时,也提出了网络分包发送策略。其详细分包发送策略如下:

NALU格式_第7张图片
image

下面我们从网络分包的角度对H264原始码流进行分析;

H.264原始码流(裸流)是由一个接一个NALU组成,它的功能分为两层,VCL(视频编码层)和 NAL(网络提取层);

  1. VCL:包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码;
  2. NAL:负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。

在VCL进行数据传输或存储之前,这些编码的VCL数据,被映射或封装进NAL单元。(NALU)

一个NALU = 一组对应于视频编码的NALU头部信息 + 一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload).

NALU结构单元的主体结构如下所示;一个原始的H.264 NALU单元常由[StartCode] [NALU Header] [NALU Payload]三部分组成,其中 Start Code 用于标示这是一个NALU 单元的开始,必须是"00 00 00 01" 或"00 00 01",除此之外基本相当于一个NAL header + RBSP;

[图片上传失败...(image-278870-1564739618983)]

NAL Header

由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)

[图片上传失败...(image-7f0e7f-1564739618983)]

NALU格式_第8张图片
image
NALU格式_第9张图片
image

举例如下:

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

NAL解码流程如下图

NALU格式_第10张图片
image
RBSP

NALU主体为RBSP;RBSP的主要结构如下:

[图片上传失败...(image-31d2b9-1564739618983)]

[图片上传失败...(image-7b427c-1564739618983)]

注意:SODB是RBSP的原始帧

  • SODB 数据比特串 -> 是编码后的原始数据
  • RBSP 原始字节序列载荷 -> 在原始编码数据的后面添加了 结尾比特。一个 bit“1”若干比特“0”,以便字节对齐。
    [图片上传失败...(image-d6e30a-1564739618981)]
再解H264中的分包策略

正如图3所示,NALU主体中包含了片头和片上数据


1帧 = n个片
1片 = n个宏块
1宏块 = 16x16yuv数据

片是H.264提出的新概念,通过编码图片后切分通过高效的方式整合出来的概念。一张图片有一个或者多个片,而片由NALU装载并进行网络传输的。但是NALU不一定是切片,这是充分不必要条件,因为 NALU 还有可能装载着其他用作描述视频的信息;片的种类如下表所示

意义
I 片 只包含I宏块
P 片 包含P和I宏块
B 片 包含B和I宏块
SP 片 包含P 和/或 I宏块,用于不同码流之间的切换
SI 片 一种特殊类型的编码宏块

宏块是视频信息的主要承载者。一个编码图像通常划分为多个宏块组成.包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中像素阵列。

一个宏块 = 一个16*16的亮度像素 + 一个8×8Cb + 一个8×8Cr彩色像素块组成。(YCbCr 是属于 YUV 家族的一员,在YCbCr 中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量)

宏块分类 意义
I 宏块 利用从当前片中已解码的像素作为参考进行帧内预测
P 宏块 利用前面已编码图像作为参考进行帧内预测,一个帧内编码的宏块可进一步作宏块的分割:即16×16.16×8.8×16.8×8亮度像素块。如果选了8×8的子宏块,则可再分成各种子宏块的分割,其尺寸为8×8,8×4,4×8,4×4
B 宏块 利用双向的参考图像(当前和未来的已编码图像帧)进行帧内预测

句法元素的分层结构有助于更有效地节省码流。例如,再一个图像中,经常会在各个片之间有相同的数据,如果每个片都同时携带这些数据,势必会造成码流的浪费。更为有效的做法是将该图像的公共信息抽取出来,形成图像一级的句法元素,而在片级只携带该片自身独有的句法元素。

NALU格式_第11张图片
image
NALU格式_第12张图片
image
宏块分类 意义
mb_type 确定该 MB 是帧内或帧间(P 或 B)编码模式,确定该 MB 分割的尺寸
mb_pred 确定帧内预测模式(帧内宏块)确定表 0 或表 1 参考图 像,和每一宏块分割的差分编码的运动矢量(帧间宏块,除 8×8 宏块分割的帧内 MB)
sub_mb_pred (只对 8×8MB 分割的帧内 MB)确定每一子宏块的子宏 块分割,每一宏块分割的表 0 和/或表 1 的参考图象;每一 宏块子分割的差分编码运动矢量。
coded_block_pattern 指出哪个 8×8 块(亮度和彩色)包 编码变换系数
mb_qp_delta 量化参数的改变值
residual 预测后对应于残差图象取样的编码变换系数
I,P,B帧与pts/dts
帧的分类 中文 意义
I帧 帧内编码帧,又称intra picture I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物
P帧 前向预测编码帧,又称predictive-frame 通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧
B帧 双向预测帧,又称bi-directional interpolated prediction frame 既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧

I,P,B帧的不同

  • I frame:自身可以通过视频解压算法解压成一张单独的完整的图片。
  • P frame:需要参考其前面的一个I frame 或者B frame来生成一张完整的图片。
  • B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。

pts/dts

名称 意义
PTS(Presentation Time Stamp) PTS主要用于度量解码后的视频帧什么时候被显示出来。
DTS(Decode Time Stamp) DTS主要是标识内存中的bit流再什么时候开始送入解码器中进行解码。
NALU格式_第13张图片
image

主要区别:DTS主要用户视频的解码,在解码阶段使用。PTS主要用于视频的同步和输出,在display的时候使用。再没有B frame的时候输出顺序一样。

IDR
一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。
I和IDR帧都使用帧内预测。I帧不用参考任何帧,但是之后的P帧和B帧是有可能参考这个I帧之前的帧的。IDR就不允许这样。
其核心作用是,是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

帧(frame)和场(filed)

参考链接: 帧编码与场编码的区别分析

视频的一场和一帧用来产生一个编码图像,一帧通常是一个完整的图像,当采集视频信号时,如果采用隔行扫描(奇、偶数行),则扫描下来的一帧图像就被分成了两个部分,这每一部分都被称为 [场],根据次序,分为 [顶场] 和 [底场]。
人眼可察觉到的电视视频图像刷新中的闪烁为 0.02 秒,即当电视系统的帧率低于 50 帧/秒,人眼可感觉得出画面的闪烁。常规如 PAL 制式电视系统帧率为 25 帧/秒、NTSC 制式的则为 30 帧/秒,如果采用逐行扫描将不可避免地在视频刷新时产生闪烁现象。而另一方面如果单纯的提高帧率达到避免闪烁刷新效果,则会增加系统的频带宽度。
隔行扫描中,每一帧包含两个场(top field)和(bottom field),其中每个 field 包含一帧中一半数量的水平线,top field 包含所有奇数线,bottom field 则包含所有偶数线。则在电视显示过程中,电子枪每发射一行隔一行—先发射奇数行13579…(top field)回头再发射2468…(bottom field)利用两次扫描来完成一幅图像,因为视觉的滞留性,我们看到的效果是差不多的。如在 NTSC 视频中 frame 的频率为30次/秒-àfield的频率则为 60 次/秒,大于了人眼可察觉闪烁的频率。

方式 作用域
帧编码方式 活动量较小或者静止的图像宜采用
场编码方式 活动量较大的运动图像
NALU格式_第14张图片
image

H264编解码编程

参考链接: x264源代码简单分析:概述;
开源的H264编码器有很多,JMVC,T264、X264,这里选择X264,因为网上关于X264源码分析资源很多。X264编码器是一个开源的经过优化的高性能H.264编码器,目前最新的源码在本人的I5处理器的PC机上,编码1920x1080分辨率的视频序列在使用ultrafast配置的情况下,可以实现160fps左右的编码速度。
H264编码规范,已经有了不错的编解码实现;其中承担编码任务的主要实现有:x264,解码主要实现有libavcodec;下面分别对这两个进行介绍。

x264说明和API详解

x264命令行使用和参数解析

参考链接: X264 01 命令行用法
使用linux 中使用x264时可以直接使用:

x264 --fullhelp //

查看x264帮助信息;显示内容如下


x264 core:148 r2643 5c65704
Syntax: x264 [options] -o outfile infile

Infile can be raw (in which case resolution is required),
  or YUV4MPEG (*.y4m),
  or Avisynth if compiled with support (yes).
  or libav* formats if compiled with lavf support (yes) or ffms support (yes).
Outfile type is selected by filename:
 .264 -> Raw bytestream
 .mkv -> Matroska
 .flv -> Flash Video
 .mp4 -> MP4 if compiled with GPAC or L-SMASH support (gpac)
Output bit depth: 8 (configured at compile time)

Options:

  -h, --help                  List basic options
      --longhelp              List more options
      --fullhelp              List all options

Example usage:

      Constant quality mode:
            x264 --crf 24 -o  

      Two-pass with a bitrate of 1000kbps:
            x264 --pass 1 --bitrate 1000 -o  
            x264 --pass 2 --bitrate 1000 -o  

      Lossless:
            x264 --qp 0 -o  

      Maximum PSNR at the cost of speed and visual quality:
            x264 --preset placebo --tune psnr -o  

      Constant bitrate at 1000kbps with a 2 second-buffer:
            x264 --vbv-bufsize 2000 --bitrate 1000 -o  

Presets:

      --profile       Force the limits of an H.264 profile
                                  Overrides all settings.
                                  - baseline:
                                    --no-8x8dct --bframes 0 --no-cabac
                                    --cqm flat --weightp 0
                                    No interlaced.
                                    No lossless.
                                  - main:
                                    --no-8x8dct --cqm flat
                                    No lossless.
                                  - high:
                                    No lossless.
                                  - high10:
                                    No lossless.
                                    Support for bit depth 8-10.
                                  - high422:
                                    No lossless.
                                    Support for bit depth 8-10.
                                    Support for 4:2:0/4:2:2 chroma subsampling.
                                  - high444:
                                    Support for bit depth 8-10.
                                    Support for 4:2:0/4:2:2/4:4:4 chroma subsampling.
      --preset        Use a preset to select encoding settings [medium]
                                  Overridden by user settings.
                                  - ultrafast:
                                    --no-8x8dct --aq-mode 0 --b-adapt 0
                                    --bframes 0 --no-cabac --no-deblock
                                    --no-mbtree --me dia --no-mixed-refs
                                    --partitions none --rc-lookahead 0 --ref 1
                                    --scenecut 0 --subme 0 --trellis 0
                                    --no-weightb --weightp 0
                                  - superfast:
                                    --no-mbtree --me dia --no-mixed-refs
                                    --partitions i8x8,i4x4 --rc-lookahead 0
                                    --ref 1 --subme 1 --trellis 0 --weightp 1
                                  - veryfast:
                                    --no-mixed-refs --rc-lookahead 10
                                    --ref 1 --subme 2 --trellis 0 --weightp 1
                                  - faster:
                                    --no-mixed-refs --rc-lookahead 20
                                    --ref 2 --subme 4 --weightp 1
                                  - fast:
                                    --rc-lookahead 30 --ref 2 --subme 6
                                    --weightp 1
                                  - medium:
                                    Default settings apply.
                                  - slow:
                                    --b-adapt 2 --direct auto --me umh
                                    --rc-lookahead 50 --ref 5 --subme 8
                                  - slower:
                                    --b-adapt 2 --direct auto --me umh
                                    --partitions all --rc-lookahead 60
                                    --ref 8 --subme 9 --trellis 2
                                  - veryslow:
                                    --b-adapt 2 --bframes 8 --direct auto
                                    --me umh --merange 24 --partitions all
                                    --ref 16 --subme 10 --trellis 2
                                    --rc-lookahead 60
                                  - placebo:
                                    --bframes 16 --b-adapt 2 --direct auto
                                    --slow-firstpass --no-fast-pskip
                                    --me tesa --merange 24 --partitions all
                                    --rc-lookahead 60 --ref 16 --subme 11
                                    --trellis 2
      --tune          Tune the settings for a particular type of source
                              or situation
                                  Overridden by user settings.
                                  Multiple tunings are separated by commas.
                                  Only one psy tuning can be used at a time.
                                  - film (psy tuning):
                                    --deblock -1:-1 --psy-rd :0.15
                                  - animation (psy tuning):
                                    --bframes {+2} --deblock 1:1
                                    --psy-rd 0.4: --aq-strength 0.6
                                    --ref {Double if >1 else 1}
                                  - grain (psy tuning):
                                    --aq-strength 0.5 --no-dct-decimate
                                    --deadzone-inter 6 --deadzone-intra 6
                                    --deblock -2:-2 --ipratio 1.1 
                                    --pbratio 1.1 --psy-rd :0.25
                                    --qcomp 0.8
                                  - stillimage (psy tuning):
                                    --aq-strength 1.2 --deblock -3:-3
                                    --psy-rd 2.0:0.7
                                  - psnr (psy tuning):
                                    --aq-mode 0 --no-psy
                                  - ssim (psy tuning):
                                    --aq-mode 2 --no-psy
                                  - fastdecode:
                                    --no-cabac --no-deblock --no-weightb
                                    --weightp 0
                                  - zerolatency:
                                    --bframes 0 --force-cfr --no-mbtree
                                    --sync-lookahead 0 --sliced-threads
                                    --rc-lookahead 0
      --slow-firstpass        Do not force these faster settings with --pass 1:
                                  --no-8x8dct --me dia --partitions none
                                  --ref 1 --subme {2 if >2 else unchanged}
                                  --trellis 0 --fast-pskip

Frame-type options:

  -I, --keyint  Maximum GOP size [250]
  -i, --min-keyint   Minimum GOP size [auto]
      --no-scenecut           Disable adaptive I-frame decision
      --scenecut     How aggressively to insert extra I-frames [40]
      --intra-refresh         Use Periodic Intra Refresh instead of IDR frames
  -b, --bframes      Number of B-frames between I and P [3]
      --b-adapt      Adaptive B-frame decision method [1]
                                  Higher values may lower threading efficiency.
                                  - 0: Disabled
                                  - 1: Fast
                                  - 2: Optimal (slow with high --bframes)
      --b-bias       Influences how often B-frames are used [0]
      --b-pyramid     Keep some B-frames as references [normal]
                                  - none: Disabled
                                  - strict: Strictly hierarchical pyramid
                                  - normal: Non-strict (not Blu-ray compatible)
      --open-gop              Use recovery points to close GOPs
                              Only available with b-frames
      --no-cabac              Disable CABAC
  -r, --ref          Number of reference frames [3]
      --no-deblock            Disable loop filter
  -f, --deblock   Loop filter parameters [0:0]
      --slices       Number of slices per frame; forces rectangular
                              slices and is overridden by other slicing options
      --slices-max   Absolute maximum slices per frame; overrides
                              slice-max-size/slice-max-mbs when necessary
      --slice-max-size  Limit the size of each slice in bytes
      --slice-max-mbs  Limit the size of each slice in macroblocks (max)
      --slice-min-mbs  Limit the size of each slice in macroblocks (min)
      --tff                   Enable interlaced mode (top field first)
      --bff                   Enable interlaced mode (bottom field first)
      --constrained-intra     Enable constrained intra prediction.
      --pulldown      Use soft pulldown to change frame rate
                                  - none, 22, 32, 64, double, triple, euro (requires cfr input)
      --fake-interlaced       Flag stream as interlaced but encode progressive.
                              Makes it possible to encode 25p and 30p Blu-Ray
                              streams. Ignored in interlaced mode.
      --frame-packing  For stereoscopic videos define frame arrangement
                                  - 0: checkerboard - pixels are alternatively from L and R
                                  - 1: column alternation - L and R are interlaced by column
                                  - 2: row alternation - L and R are interlaced by row
                                  - 3: side by side - L is on the left, R on the right
                                  - 4: top bottom - L is on top, R on bottom
                                  - 5: frame alternation - one view per frame
                                  - 6: mono - 2D frame without any frame packing
                                  - 7: tile format - L is on top-left, R split across

Ratecontrol:

  -q, --qp           Force constant QP (0-69, 0=lossless)
  -B, --bitrate      Set bitrate (kbit/s)
      --crf            Quality-based VBR (0-51) [23.0]
      --rc-lookahead  Number of frames for frametype lookahead [40]
      --vbv-maxrate  Max local bitrate (kbit/s) [0]
      --vbv-bufsize  Set size of the VBV buffer (kbit) [0]
      --vbv-init       Initial VBV buffer occupancy [0.9]
      --crf-max        With CRF+VBV, limit RF to this value
                                  May cause VBV underflows!
      --qpmin        Set min QP [0]
      --qpmax        Set max QP [69]
      --qpstep       Set max QP step [4]
      --ratetol        Tolerance of ABR ratecontrol and VBV [1.0]
      --ipratio        QP factor between I and P [1.40]
      --pbratio        QP factor between P and B [1.30]
      --chroma-qp-offset   QP difference between chroma and luma [0]
      --aq-mode      AQ method [1]
                                  - 0: Disabled
                                  - 1: Variance AQ (complexity mask)
                                  - 2: Auto-variance AQ
                                  - 3: Auto-variance AQ with bias to dark scenes
      --aq-strength    Reduces blocking and blurring in flat and
                              textured areas. [1.0]

  -p, --pass         Enable multipass ratecontrol
                                  - 1: First pass, creates stats file
                                  - 2: Last pass, does not overwrite stats file
                                  - 3: Nth pass, overwrites stats file
      --stats         Filename for 2 pass stats ["x264_2pass.log"]
      --no-mbtree             Disable mb-tree ratecontrol.
      --qcomp          QP curve compression [0.60]
      --cplxblur       Reduce fluctuations in QP (before curve compression) [20.0]
      --qblur          Reduce fluctuations in QP (after curve compression) [0.5]
      --zones //...  Tweak the bitrate of regions of the video
                              Each zone is of the form
                                  ,,

你可能感兴趣的:(NALU格式)