H.264编解码浅析
声明:本文是阅读《新一代视频压缩标准H.264_AVC》笔记总结
简介
H.264,又称为MPEG-4第10部分,高级视频编码(英语:MPEG-4 Part 10, Advanced Video Coding,缩写为MPEG-4 AVC)是一种面向块,基于运动补偿的视频编码标准。
视频压缩
预测编码
帧内预测
解决空间冗余,因为一帧的图片相邻位置的像素点一般是相似的,突变概率较小。
帧间预测
解决时间冗余,因为相邻帧的图片一般只是个别像素的移动改变。
- 单向预测
- 双向预测
H.264标准中参考帧可达16帧。
将图像分成若干块或者宏块,然后设法搜索出它们在临近帧中的位置,得到两者在空间位置的相对偏移量(运动矢量),这个过程就称为运动估计。
变换编码
视频信号中包含大量的直流和低频部分,还有少量高频部分。所以将图像进行某种数学变换后,得到变换域的图像。o表示低频,x表示高频,O表示零值,则可用较少的码来完成压缩编码。
- K-L变换:性能最好,但是缺乏快速算法。只是理想中的变换方法
- DCT(离散余弦变换):广泛使用
熵编码
根据变换系数量化后,高频有少量不大的值,低频直流有少量较大的值,系数大部分为0的特性,采用熵编码进一步压缩码率。
概念:利用信源的统计特效进行码率压缩的编码就叫熵编码(统计编码).
前置操作
- 锯齿形扫描:以8x8块为例:
- 游程编码:在变换域,量化后的系数用3个量来表示,即0的个数(称为游程),系数值,最后的位置(如果非0系数已经在最后或者后边全是0,则置1,否则置0)。
举个例子:锯齿扫描后的串行系数序列为15,0,0,-3,4,5,0,0,0,-7,0,0…
则游程编码后为:(0,15,0),(2,-3,0),(0,4,0),(0,5,0),(3,-7,1)
分类
变长编码(哈夫曼编码)
步骤:1.将信息符号按出现的概率从大到小排序
2.将两个最小的概率组成一组,并划分两个分支,大的标0,小的标1,然后计算两个分支的概率和。
3.依次类推,只到概率和为1,也剩最后一个分支
4.找到最后概率从1到信息符号的路径,从右到左记录路径上的0,1即为最终的编码序列。
算术编码
1.编码过程
采用一个浮点数(0<=x<1)编码表示一串输入符号。
比如:输入序列abaca,a出现的概率p(a)=0.5
,b出现的概率p(b)=0.25
,c出现的概率p(c)=0.25
。总范围为[0,1]
,则各字符可分割为对应的区间范围a[0,0.5],b[0.5,0.75],c[0.75,1]
。
然后对于输入的序列,核心就是重复将原区间根据abc的概率重新映射到新区间。
a:[0, 0.5] 新区间
b:[0+(0.5-0)*0.5 , 0+(0.5-0)*0.75] = [0.25, 0.375] 新区间
a:[0.25+(0.375-0.25)*0, 0.25+(0.375-0.25)*0.5] = [0.25, 0.3125] 新区间
…
依次类推。
总结一下:旧区间如果为[L0,H0][L_0, H_0][L0,H0],某一个符号的概率区间为[p0,p1][p_0, p_1][p0,p1],则编码后的新区间为:
[L0+(H0−L0)∗p0,L0+(H0−L0)∗p1][L_0+(H_0-L_0)*p_0,L_0+(H_0-L_0)*p_1][L0+(H0−L0)∗p0,L0+(H0−L0)∗p1]
最后会挑选一个该区间的一个浮点数,即是最后的编码结果。
2.解码过程
解码过程就是一个逆向的过程。比如上边的例子,如果序列为aba,则最终编码结果假设为0.3:
0.3在a的区间范围[0, 0.5],所以解码第一个字符为a
然后(0.3-0)/p(a) = 0.3/0.5 = 0.6
0.6在b的区间范围[0.5, 0.75],所以解码第二个字符为b
然后(0.6-0.5)/p(b) = 0.1/0.25 = 0.4
0.4在a的区间范围[0, 0.5],所以解码第三个字符为a
…
依次类推。
总结一下:编码结果如果为sss,判断sss的值处在符号概率区间[p0,p1][p_0, p_1][p0,p1]中,得到一个字符xxx,它对应的概率为p(x)p(x)p(x)
则下一个字符编码值为:(s−p0)/p(x)(s-p_0)/p(x)(s−p0)/p(x)
问题:可能会注意到这个解码过程会无限执行下去,实际上会有一个专门的终止符,当看到这个终止符的时候就不会再去解码。
H.264中的熵编码
- CAVLC(基于上下文自适应的可变长编码)
- CABAC(基于上下文自适应的二进制算术熵编码)
数字信号处理
对于输入的模拟信号转成输出的数字信号,需要进行取样,量化,编码三个步骤。
取样:将时间轴上连续变化的模拟信号变为离散量的过程。
一张隔行扫描的帧图像,由两个场组成(所有的奇数行构成顶场,所有的偶数行构成底场)量化:取样后的脉冲信号在时间上是离散的,但是在幅值上(空间)仍然是连续的。将信号幅值从连续量变为离散量的过程。
编码:对于量化后的信号用0,1二进制码表示,称之为脉冲编码调制-PCM。
颜色空间
关于yuv和取样格式的分析,可以参考:
移动端视频进阶(二):YUV数据编码格式的总结
编码参数
- 量化值:一般认为,每个取样值采用8bit表示,即256个灰度级。(但是HDR位深采用10,甚至12来获取更高的图像质量)
- 取样频率:单位时间内从连续信号中提取并组成离散信号的取样个数。
预处理
- 色彩插值:图像传感器一个像素只能给出纯白到纯黑单色的色调值,需要借助色彩滤镜阵列(CFA,Color Filter Array)获取彩色的图像。
- 色彩校正:减小传感器响应的图像与真实场景间的差异
- 伽马校正:显示器的输出光强度与显示器上加载的光束电压呈幂指数关系,这个幂指数被称之为gamma。对于阴极射线管显示器(CRT),gamma一般取值2.2。伽马校正就是在图像颜色显示在屏幕之前,将像素值做
1/γ
次幂,这样就将颜色变为线性关系。 - 图像增强:平滑滤波,中值滤波,图像锐化,直方图均衡,白平衡。
这里说一下白平衡,先了解一下色温,色温就是定量地以开尔文温度表示色彩,色温越高,蓝色成分越多,色温越低,红色成分越多。白平衡就是为了消除图像传感器在不同光线下输出的不平衡,导致图像偏红或者偏蓝的问题。
概念介绍
场(Field)和帧(Frame)
视频的一场或者一帧可以产生一个编码图像。视频帧通常分为两类:连续和隔行视频帧。对于隔行视频帧,又分为顶场和底场。
场内邻行间的时间相关性较强,帧内邻行空间相关性较强,所以活动量较小或者静止的图像适宜采用帧编码,而活动量较大的图像适宜采用场编码。
宏(Macro)和片(Slice)
一个编码图像通常划分成若干个宏块组成。一个宏块通常为16x16像素(16x16个亮度和一个8x8 cb,8x8 cr彩色像素块)。
每个图像中,若干个块又被排列成片的形式。I片只包含I宏块,P片可包含P宏块和I宏块,B片可包含B宏块和I宏块。片的作用:相互独立,可以防止误码的扩散和传输。
还有SP片和SI片,SP(Switch P)片用于不同码流之间的切换,它包含P宏块和/或I宏块。SI片包含一种特殊编码格式的宏块,叫SI宏块。这两个片都是拓展档次中的必备功能。
I宏块只能利用从当前片中解码出的像素作为参考进行帧内预测,P宏块利用前边已经编码的图像作为参考进行帧间预测,B宏块则利用前后双向的参考图像进行帧间预测。IDR图像
IDR:即时解码刷新(Instantaneous Decoding Refresh)图像,所有的IDR图像都是I图像,但是并不是所有的I图像都是IDR。H.264引入IDR时为了解码的重同步,当解码器解码到IDR图像时,会立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。IDR之后的图像永远不会引用IDR之前的图像数据来解码。档次
1.基础(Baseline Profile)
2.拓展(Extended Profile)
3.主要(Main Profile)
编码数据格式
分层结构
H.264分为两层:视频编码层(VCL,Video Coding Layer)和网络提取(抽象)层(NAL,Network Abstraction Layer)。
VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。在它传输或存储之前,会先被映射或封装到NAL单元中。
每个NAL单元包含一个原始字节序列负荷(RBSR,Raw Byte Sequence Payload)和一组对应视频编码数据的NAL头信息。
一个NAL单元的结构如下图所示:
然后继续往下,典型的RBSP序列结构:
- SPS:序列参数集,包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id,帧数及POC(picture order count,图像序列号)的约束,参考帧数据,解码图像尺寸和帧场编码模式选择等。
- PPS:图像参数集,对应的是一个序列中某一个图像或者某几幅图像。如标识符pic_parameter_set_id,熵编码模式选择标识,片组数目,初始量化参数和去方波滤波系数调整标识等。
- SEI:辅助增强信息(Supplemental Enhancement Information),属于码流范畴,它提供了向视频码流中加入额外信息的方法。
关于SEI更多内容,可以参考:FFmpeg从入门到精通——进阶篇,SEI那些事儿
然后是一个个的切片的数据结构:
包含一个片头和片数据。片头规定了片的类型,该片属于哪个图像,有关的参考图像等。片数据一系列的编码宏块(MB),跳编码数据(skip_run)。每个宏块(MB)包含头单元和残差数据。
什么是EBSP?
由于NAL是依次紧密排列的,解码器无法在数据流中分辨出每个NAL的起始位置和终止位置,所有在H.264草案的附录B,在每个NAL的起始位置前添加起始码0x000001,另外考虑到寻址的方便,要求数据流在长度上对齐,所以H.264建议在起始码前添加若干字节的0来填充,直到该NAL的长度符合要求。
这样一来,是解决了问题,H.264规定当检测出0x000000则表示当前NAL的结束,但是会有一个问题:如果在NALU的内部,出现了0x000001或0x000000时该怎么办?
于是H.264提出另一个机制,叫“防止竞争”,在编码器编码完一个NAL时,应该检测是否出现下边的4个字节序列,如果有,则在最后一个字节前插入一个字节0x03
当解码器在NAL内部发现有0x000003序列,则将0x03抛弃,恢复原始数据。
这个带有0x03的防止竞争字节的序列就是EBSP(扩展字节序列载荷,Encapsulated Byte Sequence Payload)
H.264标准升级拓展
高清拓展标准
2004年7月发布高清拓展标准FRExt(Fidelity Range Extension),包括了High Profile(HP),High10(Hi10p),High 4:2:2 Profile(Hi422p)和High 4:4:4 Profile(Hi444p),它们都基于Main Profile。
可伸缩编码
可伸缩编码(SVC,Scalable Video Coding),根据视频信息按照重要性分解,对分解的各个部分按照其自身的统计特性进行编码。
推荐阅读
https://zhuanlan.zhihu.com/p/31056455
H.264编解码浅析相关推荐
- 对于H.264编解码的探索
为什么需要视频编码 举个例子,如果摄像头输出分辨率为400*400的图像,那每一帧的大小就是400*400*8*3=3840000bit,折算下来一帧就需要468KB 一般情况下帧数都是30fps,那 ...
- H.264编解码标准的核心技术(提供相关流程图)
最近在学习H.264编解码知识,上网搜了不少资料看,发现大多数中文资料中都缺少相应的图片,例如编解码流程图.编码模板等,这对加深理解是很有帮助 的.木有办法,只好回去潜心阅读<H.264_MPE ...
- H.264编解码实验2020
1.将自行选择或老师给的两个264文件进行解码,得到相应的YUV文件 将上述两个视频序列编码为.264文件 将JM18.6下的ldecod.exe.decoder.cfg与要处理的.264文件放在同一 ...
- H.264编解码流程
编码: 蓝色的前向编码流程: 以宏块为输入单位介绍优于以帧为单位介绍. Fn为即将进行编码的宏块,由原始图像中16*16像素构成.每个宏块要么采用帧内模式编码,要么采用帧间模式编码.不管是哪种编码模式 ...
- Android音视频开发基础(六):学习MediaCodec API,完成视频H.264的解码
前言 在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了<Android 音视频从入门到提高 - 任务列表>.本文是Android音视 ...
- h.264并行解码算法分析
并行算法类型可以分为两类 Function-level Decomposition,按照功能模块进行并行 Data-level Decomposition,按照数据划分进行并行 Function-le ...
- php海思hi3531d,海思hi3531DV200 h.265编解码AI处理器
主要特点 处理器内核 ARM Cortex A53 四核@1.15GHz − 32KB L1 I-Cache, 32KB L1 D-Cache − 512KB L2 Cache − 支持NEON/ ...
- Android音视频--H.264视频流解码
1. 简介 H.264是比较多开发者使用较多的一种数字视频压缩格式,主要用于直播流的传输与视频网站的视频流传输,也有不少开发者开始使用H.265进行视频压缩,性能较H.264提升较大.本篇文章着重介绍 ...
- 基于ambarella安霸H.264编解码芯片的视频采集压缩系统
概述: 利用ADI视频采集芯片作为前端信号采集,视频压缩采用H.264标准,采用ambarella芯片,能达到高画质,低码率,低功耗三大特性,为目前最佳的H.264压缩方案. 适用于采集VGA/YPb ...
最新文章
- 金税接口调用实例 java_Java 常见面试题
- jsp 4种常用语法3个编译指令7个动作指令
- 云计算面试题及答案,云计算主要就业岗位
- SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)
- 武汉数字工程研究所计算机软件分数,武汉数字工程研究所2017考研成绩查询时间:2月16日...
- 使用IOUtils和FileUtils
- 产品经理没有做过成功的产品,该何去何从?
- Linux系统的各种安装方法与修复技巧
- Kafka 消息序列化反序列化
- 共建数据库软件全生态,新数科技宣布 ShinSight 开放共享!
- Windows下修改Git bash的HOME路径
- 绝对值编码器的调整方法有哪些?
- Linux升级ilo,利用HP iLO4安装系统
- 不解决产能低下的问题,直供模式也拯救不了小米
- MAXIMO部分AppBean类操作经验
- HTML读取xml文件的三种办法
- 干得漂亮!微信封禁大量色情账号
- java for class_Class forClass
- Linux文件导入gitee仓库中
- 4年美容师小姐姐,终转APP测试工程师,踏上职业正轨