———————–
H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论依据是:参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内。所以对于一段变化不大图像画面,我们可以先编码出一个完整的图像帧A,随后的B帧就不编码全部图像,只写入与A帧的差别,这样B帧的大小就只有完整帧的1/10或更小!B帧之后的C帧如果变化不大,我们可以继续以参考B的方式编码C帧,这样循环下去。这段图像我们称为一个序列(序列就是有相同特点的一段数据),当某个图像与之前的图像变化很大,无法参考前面的帧来生成,那我们就结束上一个序列,开始下一段序列,也就是对这个图像生成一个完整帧A1,随后的图像就参考A1生成,只写入与A1的差别内容。
在H264协议里定义了三种帧,完整编码的帧叫I帧,参考之前的I帧生成的只包含差异部分编码的帧叫P帧,还有一种参考前后的帧编码的帧叫B帧。
H264采用的核心算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。
———————-
序列的说明
———————-
在H264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开始,到下一个I帧结束。
一个序列的第一个图像叫做 IDR图像(立即刷新图像),IDR 图像都是 I 帧图像。H.264引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了,比如就包含一个I帧和3、4个P帧。
———————–
三种帧的说明
———————–
——————————–
压缩算法的说明
——————————–
h264的压缩方法:
帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。也即连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。帧间压缩也称为时间压缩(Temporalcompression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧差值(Framedifferencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。
顺便说下有损(Lossy )压缩和无损(Lossyless)压缩。无损压缩也即压缩前和解压缩后的数据完全一致。多数的无损压缩都采用RLE行程编码算法。有损压缩意味着解压缩后的数据与压缩前的数据不一致。在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复。几乎所有高压缩的算法都采用有损压缩,这样才能达到低数据率的目标。丢失的数据率与压缩比有关,压缩比越小,丢失的数据越多,解压缩后的效果一般越差。此外,某些有损压缩算法采用多次重复压缩的方式,这样还会引起额外的数据丢失。
H264层次构成
8.较高的复杂度:264性能的改进是以增加复杂性为代价而获得的。据估计,H.264编码的计算复杂度大约相当于H.263的3倍,解码复杂度大约相当于H.263的2倍。
H264标准各主要部分有Access Unit delimiter(访问单元分割符),SEI(附加增强信息),primary coded picture(基本图像编码),Redundant Coded Picture(冗余图像编码)。还有Instantaneous Decoding Refresh(IDR,即时解码刷新)、Hypothetical Reference Decoder(HRD,假想码流调度器)、Hypothetical Stream Scheduler(HSS,假想参考解码)。
主要部分结构如图3.18所示:
H.264的目标应用涵盖了目前大部分的视频服务,如有线电视远程监控、交互媒体、数字电视、视频会议、视频点播、流媒体服务等。H.264为解决不同应用中的网络传输的差异。定义了两层:视频编码层(VCL:Video Coding Layer)负责高效的视频内容表示,网络提取层(NAL:Network Abstraction Layer)负责以网络所要求的恰当的方式对数据进行打包和传送。如图3.19所示。
|
| 图3.19 标准的整体框架 |
|
|
其中A是变换核矩阵
a=1/2
|
|
|
|
|
|
反变换公式为:
|
(3)如图3.18所示,展示了宏块中的变换块及其传送顺序。编号为-1的块在采用Intra16x16模式编码时0-15号4×4子块经整数DCT变换后的DC系数在经4×4的哈达变换的结果。块16、17是色度块的DC系数进行2×2哈达码变换的结果。其余的24块则进行4×4整数变换。
|
| 图3.20 宏块中的变换及其传送顺序 |
|
|
| 图3.21 宏块划分方式 |
|
| 图3.22 亚像素采样点 |
半像素内插值分别由运动于水平和垂直方向的一维6阶滤波器产生。1/4像素值由整数像素和半像素点求均值取得。
例如:
b=round((E-5F+20G+20H-5I+J)/32) a=round((G+b)/2) e=round((b+h)/2) |
由于亮度分量中的1/4像素精度运动矢量将在色度分量中产生1/8像素精度。因此,采用线性内插法产生1/8像素采样点。
a=round(([(8-dx).(8-dy)A+dx.(8-dy)B+(8-dx).dyC+dx.dyD]/64) |
|
| 图3.23 可变宏块编码顺序 |
slice是一个类似于H.263中图像组(GOP)的概念,一个slice是由一系列按光栅扫描顺序排列的宏块组成。一般情况下每个宏块均包含一个16×16 的亮度阵列,当视频格式不是单色时,还包含和两个相应的色度阵列。如果没有使用宏块自适应帧/场解码,每个宏块代表图像中的一个空间矩形区域。例如,如图3.22所示,一幅图像被分为两个条带。
|
| 图3.24 slice对象 |
表3.11 P画面中的宏块类型及VLC编码
|
宏块类型 |
VLC码 |
INTRA |
MOTION FORWARD |
CODED PATTERN |
QUANT |
|
pred_mc |
1 |
0 |
1 |
1 |
0 |
|
pred_c |
01 |
0 |
0 |
1 |
0 |
|
pred_m |
001 |
0 |
1 |
0 |
0 |
|
intra_d |
0001 1 |
1 |
0 |
0 |
0 |
|
pred_mcq |
0001 0 |
0 |
1 |
1 |
1 |
|
pred_cq |
0000 1 |
0 |
0 |
1 |
1 |
|
intra_q |
0000 01 |
1 |
0 |
0 |
1 |
|
skipped |
无 |
|
|
|
|
表3.12 B画面中的宏块类型及VLC编码
|
宏块类型 |
VLC码 |
INTRA |
MOTION FORWARD |
MOTION BACKWARD |
CODED PATTERN |
QUANT |
|
pred_I |
10 |
0 |
1 |
1 |
0 |
0 |
|
pred_ic |
11 |
0 |
1 |
1 |
1 |
0 |
|
pred_b |
010 |
0 |
0 |
1 |
0 |
0 |
|
pred_bc |
011 |
0 |
0 |
1 |
1 |
0 |
|
pred_f |
0010 |
0 |
1 |
0 |
0 |
0 |
|
pred_fc |
0011 |
0 |
1 |
0 |
1 |
0 |
|
intra_d |
0001 1 |
1 |
0 |
0 |
0 |
0 |
|
pred_icq |
0001 0 |
0 |
1 |
1 |
0 |
1 |
|
pred_fcq |
0000 11 |
0 |
1 |
0 |
0 |
1 |
|
pred_bcq |
0000 10 |
1 |
0 |
1 |
1 |
1 |
|
intra_q |
0000 01 |
1 |
0 |
0 |
0 |
1 |
|
skippde |
无 |
|
|
|
|
|
表3.13 帧编码模式
|
帧类型 |
描述 |
支持的框架 |
|
I(Intra) |
只包含帧内预测的宏块(I) |
全部 |
|
P(Predicted) |
包含帧间预测宏块(P)和I型宏块 |
全部 |
|
B(Bi-Predictive) |
包含帧间双向预测宏块(B)和I型宏块 |
扩展和主 |
|
SP(Switching P) |
利于在编码的比特流中切换,包括I和P宏块 |
扩展 |
|
SI(Switching I) |
利于在编码的比特流中切换,包含SI宏块(一种特殊的帧内编码宏块) |
扩展 |
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229740.html原文链接:https://javaforall.net

