视频基础知识

2019-09-22  本文已影响0人  saltcc
视频胶片

视频

视频采集装置一秒钟会捕捉几十帧数据,动画一般25帧以上,一般视频文件30帧数据,对于捕捉一些清晰动作的甚至要达到60帧以上,但是对于一组帧,帧和帧之间的变化很小,为了压缩数据,我们将第一帧(I帧)完整保存下来,没有关键帧,后面数据帧无法解码。接下来章节主要着重介绍我们经常在视频编码当中用到的 H.264编码

常用的视频编解码器

x264/x265:x265压缩比更高,占用CPU也更高
openH264:支持SVC(会将图分层,小中大,根据网络情况发送,缺点是移动端很多硬件不支持,只能使用软编,cpu消耗高)
vp8/vp9:vpx系列,vp8对应x264,vp9对应x265

H.264背景

H.264是[国际标准化组织]([ISO])和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式。H.264是在MPEG-4技术的基础之上建立起来的,其编解码流程主要包括5个部分:帧间和帧内预测、变换(Transform)和反变换、量化(Quantization)和反量化、环路滤波(Loop Filter)、熵编码(Entropy Coding)。与其它现有的视频编码标准相比,在相同的带宽下提供更加优秀的图象质量。通过该标准,在同等图象质量下的压缩效率比以前的标准(MPEG2)提高了2倍左右

H.264中的基本概念

H.264原理与结构

主要使用压缩技术
H.264码流

H.264原始码流是由一个接一个NALU组成,它的功能分为两层,VCL(视频编码层)和 NAL(网络提取层).
VCL(Video Coding Layer) + NAL(Network Abstraction Layer)
VCL:Video Coding Layer 视频数据编码层,包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码
NAL:Network Abstraction Layer 视频数据网络抽象层,负责将VCL产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别

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

H.264结构

整体结构参考如下图


H264码流结构 H264码流分层
NALU单元详解
NAL Header
F:forbidden_zero_bit,在H.264规范中规定该位必须为0
NRI:指示重要性
Type:NALU单元类型
nal_unit_type 说明
0 没有定义
1-23 NAL单元 单个 NAL 单元包
1 非IDR图像中不采用数据划分的片段
2 非IDR图像中A类数据划分片段
3 非IDR图像中B类数据划分片段
4 非IDR图像中C类数据划分片段
5 IDR图像分片
6 补充增强信息单元(SEI)
7 序列参数集(SPS)
8 图像参数集(PPS)
9 分解符
10 序列结束
11 码流结束
12 填充
13-23 保留
24 STAP-A 单一时间的组合包
25 STAP-B 单一时间的组合包
26 MTAP16 多个时间的组合包
27 MTAP24 多个时间的组合包
28 FU-A 分片的单元
29 FU-B 分片的单元
30-31 没有定义
Slice片详解

由H264码流分层图可得知,NALU的主体就是Slice(片),片是H.264提出的新概念,通过编码图片后切分通过高效的方式整合出来的概念。一张图片有一个或者多个片,而片由NALU装载并进行网络传输的。一个Slice包含一帧图像的部分或全部数据,换言之,一帧视频图像可以编码为一个或若干个Slice。一个Slice最少包含一个宏块,最多包含整帧图像的数据。在不同的编码实现中,同一帧图像中所构成的Slice数目不一定相同。设置片的目的是为了限制误码的扩散和传输,应使编码片相互间是独立的。某片的预测不能以其他片中的宏块为参考图像,这样某一片中的预测误差才不会传播到其他片中。

一个Slice由Slice Header + Slice Data构成,如下图所示:


slice
slice类型 说明
I slice 帧内编码的条带(只包含I宏块)
P slice 单向帧间编码的条带(包含P和I宏块)
B slice 双向帧间编码的条带(包含B和I宏块)
SI slice 切换I条带,用于扩展档次中码流切换使用(一种特殊类型的编码宏块)
SP slice 切换P条带,用于扩展档次中码流切换使用(包含P 和I或 I宏块,用于不同码流之间的切换)
slice header参数 说明
first_mb_in_slice 第一个宏块在slice的位置
slice_type slice的类型
pic_parameter_set_id 当前slice所依赖的pps的id;范围 0 到 255
colour_plane_id 当标识位separate_colour_plane_flag为true时,colour_plane_id表示当前的颜色分量,0、1、2分别表示Y、U、V分量
frame_num 表示当前帧序号的一种计量方式
field_pic_flag 场编码标识位。当该标识位为1时表示当前slice按照场进行编码;该标识位为0时表示当前slice按照帧进行编码
bottom_field_flag 底场标识位。该标志位为1表示当前slice是某一帧的底场;为0表示当前slice为某一帧的顶场
idr_pic_id 表示IDR帧的序号。某一个IDR帧所属的所有slice,其idr_pic_id应保持一致。该值的取值范围为[0,65535]
pic_order_cnt_lsb 表示当前帧序号的另一种计量方式
delta_pic_order_cnt_bottom 表示顶场与底场POC差值的计算方法,不存在则默认为0
slice_qp_delta 用于计算当前slice内所使用的初始qp值

slice_type

slice_type值 说明
0 P (P slice)
1 B (B slice)
2 I (I slice)
3 SP (SP slice)
4 SI (SI slice)
5 P (P slice)
6 B (B slice)
7 I (I slice)
8 SP (SP slice)
9 SI (SI slice)
宏块详解

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

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

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


宏块结构

宏块结构

宏块结构 说明
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 量化参数的改变值
YUV(YCbCr)

YUV是从电视系统衍生出来的一种颜色编码方法,Y表示明亮度,也就是灰阶值,它是基础信号,U和V表示的则是色度,UV的作用是描述影像色彩及饱和度,它们用于指定像素的颜色。YUV亮度信息(Y)与色彩信息(UV)分离,没有 UV 信息一样可以显示完整的图像,没有UV分量,则只是黑白显示,YUV 不像RGB 那样要求三个独立的视频信号同时传输,而且用 YUV 数据占用的内容更少。

YCbCr 中,Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量

像素构成

RGB转YUV:
Y = 0.299R + 0.587G + 0.114B
Cb = 0.564(B - Y)
Cr = 0.713(R - Y)

YUV转RGB:
R = Y + 1.402Cr
G = Y - 0.344Cb - 0.714Cr
B = Y + 1.772Cb

  1. YUV4:2:0:
    YUV4:2:0并不意味着只有Y和Cb两个分量,而没有Cr分量。它实际指的是对每行扫描线来说,只有一种色度分量,它以2:1的抽样率存储。例如相邻的扫描行存储不同的色度分量,也就是说,如果一行时4:2:0的话,下一行就是4:0:2,在下一行就是4:0:2,在下一行就是4:2:0进行以此类推
  2. YUV4:2:2
  3. YUV4:4:4

举例一副图片假设像素矩阵如下:



上图中每个像素的 3 个分量的信息是完整的,Y : Cb : Cr = 4 : 4 : 4,属于 YUV444 格式。
人类视觉系统对亮度信号比色度信号敏感的原理,我们可以省略图片的一些信息,对图片的质量影响却不会太大,比如将该像素矩阵存储为:



此时,每两个 Y 共用一组 UV 分量,Y : Cb : Cr = 4 : 2 : 2,属于 YUV422 格式。
同理我们进一步得出YUV420格式如下:

每四个 Y 共用一组 UV 分量,Cb、Cr 交替出现,在第一行数据里 Y : Cb : Cr = 4 : 2 : 0;而在第二行数据,Y : Cb : Cr = 4 : 0 : 2,这就是最常见的 YUV420 格式。

  1. planar平面存储
    I420(YUV420P): YYYYYYYY UU VV
    YV12(YUV420P):YYYYYYYY VV UU
  2. packed打包存储
    NV12(YUV420SP):YYYYYYYY UVUV
    NV21(YUV420SP):YYYYYYYY VUVU

planar 先存储所有 Y,紧接着存储所有 U,最后是 V;而 packed 则是每个像素点的 Y、U、V 连续交叉存储。

现在我们不管是移动端(安卓和IOS)也好,PC端也好,在转成YUV之后可能出现图像倒置或反转,可能和平台支持的YUV存储格式不同有关,例如安卓默认的是NV21,ios默认是NV12,PC端是I420,屏幕倒置旋转主要原因还是存储格式不一样,要让他们一样就是要做成一个统一的格式

上一篇 下一篇

猜你喜欢

热点阅读