[SilkyBible] XviD系列-5

来源:互联网 发布:java模拟借书系统 编辑:程序博客网 时间:2024/04/23 16:26
 
引用 12-31-2002譬如说我们目前要压缩的 2x2 方块,数值是
25 25
35 30

在参考画面上搜寻,找到最接近的整数方块是

10 20
40 30

这样压缩,要记录差值
-15 -05
05 00

但是如果我们将参考画面先做内插,补出 Pixel 和 Pixel 之间的 1/2-Pixel

10 xx 20
xx yy xx
40 xx 30

xx = 相邻两点相加除以二,四舍五入
yy = 相邻四点相加除以四,四舍五入
==>

10 15 20
25 25 25
40 35 30

这样我们便可以找到完全一样的参考方块,右下角的
25 25
35 30

所需记录的差值为 0,动作矢量的精度要提高为 1/2 Pixel(能指向 1/2 Pixel 的位置)
解压缩时一样,先将参考画面内插补出 1/2 Pixel,根据矢量找出要参考的位置(右下角),
得到参考方块的数值为
25 25
35 30

加上差值 0,便可还原现在的真正数值
25 25
35 30


1/4 Pixel 也是一样,只是补出的点更多,更精细而已。
(提高找到误差最小的参考方块的机率)

不知道这样解释有没有回答到您想问的问题?
引用 12-31-2002所以我们知道,次像素(sub-pixel)的动作估计、补偿可以提高压缩率,因为:
1. 如前所述,物体的移动和像素的位置无关,物体不会按照像素的格子,一格一格的移动,
每次都移动整数的格子点,刚好落在像素上。
更接近的数值可能在像素之间,藉由内插补出次像素的数值,我们可以得到更接近的参考方块。

2. 次像素的内插,可以柔化画面上的奇异点,减小噪讯增加的压缩困难度
目前的方块
10 10
10 10

最接近的参考方块
10 10
10 50 <-- 这个 50 和其它点都不一样,而且差距很大,可能这个奇异点是一个混入的噪讯

经过内插
10 10 10
10 20 30
10 30 50

左上角的
10 10
10 20

可以提供更小的误差,让噪讯的影响减低。

3. 当画面的分办率很低的时候,例如 352x288,Pixel 的数目很少,能够带来的讯息量不够,
往往画面和画面之间的差距一下就很大,此时多内插补出一些 Pixel,可以多补充一些隐含的讯息,
减低压缩的困难度。
引用 01-05-2003XviD 的 interlace 功能不是做去交错(de-interlace),
而是做 interlace 模式的压缩。
交错画面因为复杂度增加,奇、偶扫瞄线的差异性大,非常难压缩。
interlace 模式压缩时,动作估计会以场画面(Field)为单位,
将交错画面拆成奇数扫瞄线组成的奇数场(Odd Field)和偶数扫瞄线组成的偶数场(Even Field)
,分别做估计。因为同 Field 内的扫瞄线属同一个画面,画面无交错,彼此关联性大,
所以交错画面用 Field 做参考画面,用 Field 做动作估计,用 Filed 做单位压缩,
会比以 Frame 为单位压缩的效果更好。
场画面的动作估计又有好几种模式,一般场画面估计,目前要编码画面的第一个场画面
可以参考前一个画面的两个场做动作估计。而目前的第二个场画面则可以参考刚刚编码好的,
属同一个 Frame 的第一个场,或者是前一个画面的第二个场作为参考画面。
其它还有 16x8 模式,16x16 的巨方块拆成上下两个 16x8 的矩形,分别做动作估计,
这样就有两个向量,B 画面会有四个向量。以及用在 I/P 画面的 Dual Prime 动作补偿模式。

做 DCT 的时候,也是以 Field 为单位作 DCT,16x16 中的四个 DCT 方块,
拆成奇数场两个,偶数场两个,分开做 DCT。然后扫瞄读出系数排成一列的时候,
使用特别的 Alternate scan,而不用原本的 Zig-zag scan。
(交错画面使用 Alternate scan,压缩效率较高。有许多 MPEG 压缩软件在使用
interlace 模式压缩时,竟然不用自动改为 Alternate scan,需要手动更改,
这点必须注意。TMPGEnc 是一旦使用 interlace 模式,便会自动改成 Alternate scan)

所以使用 XviD 的 interlace 模式压缩,画面并不会去交错,交错还是会保留下来,
只是压缩的效果比较好。那这样有什么用?当然有用,因为不是所有人都在计算机上看影片,
如果你的成品是要在电视机上播放,电视机一次只显示一个场,
这些交错看不到(交错要一次显示一个完整画面才会看到,例如计算机屏幕)。
所以在电视上播放以 interlace 模式压缩即可,不用做 de-interlace 去交错,
去交错反而损失品质。

这是 XviD 设计 interlace 这个选项的目的。
去交错属于 pre-processing 前置处理的步骤,不是压缩软件应该作的功能。

那么用 XviD 要做去交错怎么办,我想采集的软件本身就有提供去交错的功能,
去交错完以后再交给 XviD 压缩。我知道许多采集软件都有提供这个功能,
而且效果比一般软件还好。不过我本身没有使用的经验,
相关软件的信息还要请其它前辈帮忙补充。
引用 02-15-2003
引用1)Maillist上讲的VHQ是什么东东?
简单的说,高品质模式,开了同码率下品质比较好,固定品质下档案比较小。

复杂的说... 真的要复杂的说吗? :P
(有人要看吗? ^^;)

我们知道压缩的时候会将画面切成好多个 16x16 大小的小方块作动作预测,每个方块称为 Macroblock。每个 Macroblock 压缩的时候要做好几个选择,首先我们要决定这个 Macroblock 是要独立压缩,压成一个 intra-block,或者是要参考其它画面压缩,压成一个 inter-block。
接下来如果是压成 inter-block,要参考其它画面作预测压缩,那么要使用哪种动作预测模式呢?例如 MPEG-4 有 INTER4V(4MV)模式,一个 Macroblock 可以有 4 个 Motion Vector(动作向量),内部 4 个 8x8 的小方块各自使用一个 MV,各自记录最接近的参考对象。使用 4MV 让内部的小方块各自参考误差最小的对象,可以缩小所需记录的误差值,但是同时需要记录的向量个数也会增加为 4 个,一来一往、此消彼长,到底能不能提高压缩效率并不一定,要看情况。那么是要使用一般的 16x16 方块共享一个 MV 的预测模式(INTER),还是要使用 8x8 方块的 4MV 预测模式(INTER4V),这个 encoder 必须要作决定。

最后 encoder 还要决定找到的参考对象误差是不是很小,如果小到一定程度,我们就可以视为没有误差,不用编码、记录这个 Macroblock 的误差(not coded)。此时如果 MV = (0,0),也就是参考的对象和目前的方块在画面上的同一位置,那么这个 Macroblock 就可以 skip 掉,完全不记录任何数据,显示的时候直接使用前一个画面相同位置的方块来显示。

Macroblock 要用上面哪种模式压缩,压出来所需的 bit 会最少,encoder 必须要作判断。判断的时候会根据理论上的算式作判断,例如如果 四个SAD8x8的总和 < SAD16x16,我们就把这个方块用 INTER4V 模式压缩。SAD 是 sum of absolute differences 的缩写,误差绝对值的总和,是一种计算、判断、寻找最少误差量的方法。
根据这些简单的计算判断,encoder 可以很快速的决定要用哪种模式压缩。但是这样压出来真的会最小,所需的 bit 真的会最少吗?答案是不一定。可能这个 Macroblock 用 INTER 压缩会比较有效率,压出来所需的 bit 会比较少,但是却被计算式判断为要使用 INTER4V 压缩,白白浪费了许多 bit。
所以 XviD 和 FFMPEG 的开发小组之前就发现,使用 4MV 模式的时候,压缩效率反而不好,就是因为 encoder 的判断太简陋,造成了 4MV 的使用没有效率,使得压出来的档案反而变大。

FFMPEG 首先设计了一个 VHQ 模式,也就是高品质模式,也叫做 brute force。在这个模式底下,encoder 会把 Macroblock 各种可能的压缩模式都压一遍,INTRA/INTER/INTER4V... 都压一次,然后从里面选压出来最小,所需花费的 bit 数最少的一种模式来使用。这样就可以确定,我们选择的压缩模式是最有效率的压缩模式。实验结果证明,使用 4MV 的时候一定要搭配 VHQ 模式,压出来的品质才会最好,档案也会是最小的。不过当然,使用 VHQ 模式压缩的时间也需要比较久。

XviD 现在也设计了这个 VHQ 模式,第一件做的事情(VHQ 设定选项选 "1 - Mode Decision")就是上面说的 brute force,每种模式都压一次,选最好的。

XviD 的 VHQ 模式做的第二件事情,是 FFMPEG 里面没有的,但是这个功能还是要从 FFMPEG 谈起。
FFMPEG 可以让你自行选择动作估计(ME)的时候使用的「比对最小误差」的计算方法。当我们寻找误差最小的参考对象时,要怎么比较哪个参考位置的误差是最小的呢?一般我们是使用上面提到的 SAD,将两个方块的像素值相减,取绝对值,然后把 16x16 所有的点相减的结果加起来,作为总和的误差。这个计算的方法比较简单,速度很快,效果也很不错。但是 FFMPEG 还提供了其它各种的比较方法让你作测试,有
0. SAD: sum of absolute differences,计算法如上所述
1. SSE: sum of squared errors,和 SAD 差不多,但是不是取绝对值,而是平方,计算复杂度高一点
2. SATD: sum of absolute hadamard transformed differences,将像素值先作 hadamard 转换,然后再比较两个方块 hadamard 转换后系数的绝对值差值。这是 H.264 建议使用的做法,计算复杂度又比 SSE 高
3. DCT: sum of absolute dct transformed differences,先作 DCT 转换,然后比较 DCT 系数的绝对值差值,理论上是最精确的比较法,但是计算复杂度最高
4. PSNR: sum of the squared quantization errors,计算量化误差的平方总和
5. BIT: number of bits needed for the block,计算此方块实际所需的 bit 数
6. RD: rate distoration optimal,利用 Lagrangian 算式找出 rate-distortion 的最佳平衡点

实验证明,次像素的动作检索如果使用比较精确的比对方法,例如 SATD/DCT,品质会提高(这个同时是 H.264 建议的方法)。同时固定码率下,BIT/RD 的比对法也会提升品质。另外 SSE 似乎对动画类型的影片有最好的效果。

XviD 的开发人员看到 FFMPEG 不错的实验结果,也开始着手开发类似的高品质模式。sisKin 一开始是打算使用 DCT 比对法(因为他说虽然 DCT 比 SATD 复杂,但是他发现实际上压缩的时候最耗时的动作不是在 CPU 的计算上,而是在等待内存的存取上,所以使用 SATD/DCT 的速度应该不会差太多),结果后来是使用 BIT 比对法,比较实际上所需的 bit 数最小的。
以前曾说过 ME 的时候做次像素的动作检索,例如 Quarter Pixel,可以提高压缩率,但是那时没仔细说 Quarter Pixel 是怎么做的。如果我们一开始的时候就把整个画面内插,补出 1/4 的像素,然后在这个画面上作检索,这样一定会很慢很慢,因为要搜寻、比对的位置变得很多,范围很大,而且也很没有效率。所以实际上做的时候,我们是先做整数像素的搜寻,找出整数像素上误差最小的位置,然后再内插补出这个位置周围的 1/2 像素,订出八个新的搜寻位置,如下图
代码 (双击代码复制到粘贴板)
y x y x y
x x x x x
y x y x y
x x x x x
y x y x y

y: 整数像素
x: 1/2 像素
中间的 y: 找出来误差最小的整数像素位置,也就是误差最小方块的左上角顶点位置
红色: 新的次像素比对位置左上角顶点位置红色: 新的次像素比对位置
这样我们就只要比对这八个新位置和原来的整数像素位置哪个误差最小,就可以找出 1/2 像素精度误差最小的位置。这么一来就不用内插计算那么多的点,也不用比对那么多的次数,是不是比较有效率呢?
做完 1/2 Pixel 之后,我们可以继续再做 1/4 Pixel 精度的新位置比对,依此类推。

XviD 的 VHQ 功能做的第二件事,就是当确定好了 Macroblock 的压缩模式之后,我们可能会找到有很多位置的误差都相同。因为 SAD 找出来的误差经过量化以后,较小的误差值会被量化为 0。如果 quantizer 很高的话,那么就有可能误差都被量化为 0,这个方块就不需要 coded、记录误差值了,只需要记录 MV 即可。而当使用次像检索的时候,通常邻近周围位置的误差会很接近,经过量化之后,就可能有很多位置的误差结果都变成 0,那么我们就要从这些误差都是 0 的位置里面,找一个 MV 最小的位置,也就是最靠近目前方块的位置来使用,这样不是就可以更进一步的减少记录 MV 所需的 bit 数了吗?
所以 XviD 的 VHQ 模式的 2~4 选项,就是在多做这个额外的最小 MV 搜寻,搜寻范围由 "2 - Limited Search" 到 "4 - Wide Search" 增大,范围越大找到越小 MV 的机会越高,但是所花的时间越长。

但是但是,这个额外的搜寻可以保证找出来的参考位置所需花费的总 bit 数最少,压出来的档案会最小,但是 PSNR,也就是画质却会降低喔!!
为什么呢?因为当 Macroblock 不记录误差值,not coded 的时候,会直接显示 MV 所指向的参考画面中的那一个方块,而不需要再作动作补偿,补上差值(MC)。那么和原本方块误差最小的方块应该是哪一个呢?是我们原先用 SAD 找出来的那一个。不过后来我们又发现附近有其它位置因为 "经过量化" 以后,所需记录的误差 bit 数也变为 0,所以我们又改找其它 "量化后误差为 0",而 MV 较小的位置,使压出来的 bit 数更小。但是这样却会偏离了我们原先所找出来的最佳位置,其它 MV 较小的位置,其原本的误差是比较大的,所以显示的时候直接拿这个误差比较大的方块来显示,而不是我们原先用 SAD 所找到的误差最小的方块,这样画质就会下降啰。

不知道这样解释好不好懂 ^^;

其实不用理解这么深入,总之:
VHQ 模式 1 一定可以缩小档案、同时提高品质
VHQ 模式 2~4 固定品质(quantizer)压缩,可以让档案更小,但是品质(PSNR)却会下降大概 0.1dB
使用 quanity/2pass 模式压缩时,VHQ 2~4 通常能取得较好的档案大小和 PSNR 比。
引用2)丢失keyframe的问题是不是一直没解决?昨天我压一个10分钟的片断,竟然只有9个keyframe。哪个版本没有这个问题?
丢失 keyframe?应该解决了呀。如果压出来 keyframe 很少,代表 XviD 判断 Scene Change 场景变换的地方很少,所以不需要插入 keyframe。如果间隔太长造成搜寻段落播放时不方便,可以藉由设定 Maximum I-frame interval 来控制 I-frame 的间隔。MPEG-4 Standard 文件里面有提到,为了避免 iDCT mismatch 的问题,建议每 132 个 inter-block 之后就要强制更新为 intra-block 压缩。目前 XviD 和其它 MPEG-4 encoder 都没有实作这个限制,我们可以自行用 Maximum I-frame interval 这个选项设为 132 来做到这个要求。(I-frame 内的 Macroblock 一定全部以 intra-block 压缩,这样设定的话不管前面如何选择,一定最少每 132 次压缩中就会有一个 intra-block)
不过这个只是建议,不一定要照做,132 的 I-frame 间距对低码率的情况来说,太密集了一点,品质会下降。
引用3)压VCD的时候,运动物体周围的镶边很严重,怎么办?我试了一些filter都不管用。用Divx3.11压缩的时候,同样的码率,虽然图象质量不够完善,但镶边要少得多,什么道理?
因为 MPEG-4 压缩压缩效率比较高。
因为 VCD 是 CBR,DivX 3.11 是 VBR。
原创粉丝点击