[SilkyBible] XviD系列-3
来源:互联网 发布:软件开发 税种 编辑:程序博客网 时间:2024/04/26 05:34
参数太过复杂,使用者根本不知道要怎么调整,而且调整的效果也不是非常理想。
像 DivX 5 的 2-pass 多轻松,使用者根本不需要去修改什么设定,反复实验最佳的结果。
通常来说,只要用默认值就可以得到不错的码率分配,这对初学者来说,容易上手得多。
所以他在设计 XviD 的 2-pass 的时候,就采用了和 Nandub 一样的 stats 檔格式,
所以 GKnot 也可以读取 XviD 生成的 stats 檔。
不过如前所述,两者的参数有些不相同,像 XviD 的 stats 档就没有 Luma noise
这个参数,所以 GKnot 读取显示的 Luma noise 的数值都是错的。
基本上是不能用 GKnot 来做 XviD 的 scaling 的,所以我以前也从没这样做过。
最近是一时无聊,试试看用 GKnot 乱搞出来的 stats 檔拿给 XviD 压会压出什么结果,
结果效果非常好!我自己也很惊讶,我原来以为会压出乱七八糟的东西....
XviD 我现在最不满意的就是 2-pass 的算法不像 DivX 5 那么好,
而使用 linear-scaling 时如果码率太低,静态画面的画质会不够好,
导致明明 XviD 的压缩效率已经大幅超越 DivX 5,但是做 2-pass 的时候总是觉得某些画面
还是不如 DivX 5(因为分配码率的问题,要分配得恰到好处,才能在有限的码率下隐藏压缩
的缺点,增进表面上看起来的视觉品质)。
现在用 GKnot scaling 出来的 stats,我觉得已经接近 DivX 5 VBR 的水准,
让 XviD 的 2-pass 明显超越同码率下的 DivX 5。
不过再重申一次,我只有做了两三个 clip 的压缩测试,无法确定每一部电影使用 GKnot 都会有
相同的优异效果,毕竟现在的 GKnot 理论上根本不支持判断、分析、计算 XviD 的 stats 檔。
我也是担心 GKnot 会自己加入 Key-Frame,导致不正确的结果,所以在 Key-Frames 的设定那边
指定 GKnot 使用原本 stats 档内的 Frame Type 不要变更(按 Stats 那个按钮),
同时 ""不能"" 勾选 F.-Size、Motion、Luma 这三个 Correction 的校正,
然后才按 Calculate 计算 scale 的 Frame 大小,然后存盘。
压出来 Key-Frames 的数目是对的,没有乱增加。
不过说实在的,用得心理毛毛的 ^^;
看起很不错就是了 :)
XviD 的 B-frame 的 quantizer 设定是用 B-frame quantizer ratio 和 B-frame quantizer offset
这两个参数来控制的。
因为 B-frame 不能拿来做为参考画面,也就是说 B-frame 不会再被其它画面参考到,所以 B-frame
可以压得比较差一点,通常 quantizer 会设得比较高。
这是因为 MPEG 压缩的时候 I-frame 和 P-frame 会被其它画面拿来做为参考画面,
其它画面会参考这两种 frame 来压缩,只纪录和参考画面之间的差异。
参考的时候参考的是压缩过的画面,举例:
I P P P ...
首先第一张 I 独立压缩,压缩完以后再解压缩,还原一张经过压缩过的画面 I'。
第二张 P 要参考前一张画面压缩,此时要参考的是未压缩过的、原本的画面 I,
还是压缩过,再解压缩回来的 I' 画面?
答案是压缩过,再解压缩回来的 I' 画面。
因为 P 纪录的是和前一个画面的差异,解压缩时用前一张画面补上这个差异便能得到正确的画面。
然而解压缩的时候的前一张画面是什么?是经过压缩过的 I',不是原本的 I。
原本的 I 在压缩档里面已经不存在了(当然,不然怎么叫有损压缩 :D )。
所以我们可以了解,P 要参考的画面必须是压缩过的 I' 画面,要记录的是未压缩的目前的画面,
和前一张压缩过的参考画面之间的差异。
所以,如果前一张 I' 压缩得很烂,它和目前的画面的差异必然很大,必然很不像现在的这张画面。
这样这张 P 就必须提高码率才能记录这么大的差异,如果码率不够用,这张 P 就无法压得很好。
接着后面的 P 又要参考这张前面压得不好的 P..... 如此恶性循环,结果所有的 frame 都无法压得好。
所以会被参考的 I-frame/P-frame 必须要压好一点(或者说要压得正确一点),
尤其是 I-frame是独立压缩,比较不好压缩,需要的码率要大,所以才会有 I-frame boost 这种选项。
(不过要做到 linear-scaling 便不能使用 I-frame boost,前一次忘了提,这里补充)
反过来说,B-frame 不会被参考到,所以可以压得比较不精确一点,所以通常我们会提高
B-frame 的 quantizer 达到高压缩率。
例如 TMPGEnc 的 VBR 和 CQ 压缩模式当中的设定选项「B picture spoilage」
(英文版,中文版我不知道是怎么翻译),就是让你设定 B Frame 相较于 I/P Frame 所要减少的品质。
回过来说 XviD 的 B-frame quantizer 设定。本来只有一个选项「B-frame quantizer ratio」,
用的算式是:
((前面参考画面的 quantizer + 后面参考画面的 quantizer)/2 * ratio)/100
例如前面参考画面的 quant 是 4,后面是 6,ratio 设 200,则 B-frame 的 quant 就是
((4+6)/2*200)/100 = 10
也就是「前后画面的 quant 平均,然后乘上 2」。
不过这种设计你可以看出来很不理想,如果前后的平均 quant 为 10,
中间的 B-frame 的 quant 一下子就会跳到 20。
我们知道 10 和 20 压出来的品质差很多,这种设计 quant 一下跳太快,比较没有弹性,
容易造成某些画面突然发生劣化,出现明显的瑕疵。
所以后来有人建议,才又加上了 offset 这个参数,整个 B-frame 的 quant 算式变成:
b_quant =
(AVG(prev vop quant, future vop quant) * bquant_ratio +
bquant_offset) / 100
也就是
((前面参考画面的 quantizer + 后面参考画面的 quantizer)/2 * ratio + "offset")/100
例如 ratio 设 150,offset 设 50,前后平均 5,则 B-frame 的 quant 就是
(5*150 + 50)/100 = 5*1.5 + 0.5 = 7.5 + 0.5 = 8
这样比较有弹性,前后画面是高 quant 的时候 B-frame 也不会一下劣化太快。
那么为什么 debug view 里面回报的 B-frame 的 quant 数目和算出来的不一样?
因为目前 B-frame 回报的那个数值是错的 :p
(那个只是压缩时 Codec 丢出来的讯息,本来只有设计显示 I/P Frame 讯息的部分,
没有考虑到 B-frame。反正对压缩没有影响,目前也没有人去修改这个输出的讯息。
开发人员都很忙,有更重要的 bug 要去修正 :D )
除了这个 quant 的数目,1st pass B-frame 显示出来的 k-blocks, m-blocks, u-blocks
这些数字也都是错的 -_-;;
等开发完成,应该会做个选项让使用者决定要不要开启吧。
从理论上来说,这样编码器的码率控制器(bitrate control)才能准确的工作。
码率控制器根据 1st-pass 压出来的每个 frame 的 size 做 scaling 调整大小,
也就是 2nd-pass 压缩的时候调整 quantizer 控制每个 frame 的 size 接近 scaled 后的大小,
如果因为 2nd-pass 的设定不一样,造成压出来的 frame size 和预测的差很多,
码率控制器就无法准确的预测使用的 bit 超出(overflow)的情形,
做出适当的补偿(payback),这样便可能会发生无法预期的结果。
当然这是从理论上来说,实际压出来不一定会有不好的结果,因为实际的情况可能是很复杂的,
小弟只是提供一点理论面的说法,大家参考看看,如果有时间的话可以反复多压几次,
做做实验
另外建议如果是要保存用的影片,最好不要在最终的生成结果使用 qpel。
目前 XviD 的 qpel 使用 XviD 自己的 xvid.dll 这个 vfw codec 播放是正常的,
不过这是理所当然的
如果用 ffdshow,也就是 libavcodec 这个译码器播放,水平/垂直/水平加垂直 三种 interpolation
都不正确,DivX 5 的译码器播放 水平/垂直 看起来好像没有问题,但是 水平加垂直 还是不正确。
这种错误一开始并不明显,但是如果一直参考同一个位置,连续 100 个 frame 以后就会变得很明显。
(因为各家译码器对 qpel interpolation 内插补值的作法不一样,造成补偿加上去的差值不一样,
这个错误会一直累积,连续 100 frames 之后就会变成非常明显的错误瑕疵)
因为 DivX 5 的 qpel 的作法本来就不正确,不符合标准 ISO MPEG-4 的规范,
所以 DivX 5 不能正确解碼 XviD 的 qpel 无所谓。
但是使用 MS MPEG-4 FADM 这个 MS 作的 100% 标准的 MPEG-4 软件来译码也不正确,
这个问题就很严重了,这代表目前 XviD 的 qpel 可能有兼容性(正确性)的问题。
凄惨的是,目前几个 MPEG-4 译码软件 XviD/ffdshow/DivX 5/Envivio TV 对 qpel 的 interpolation
作法都不一样,到底是谁做错?难道大家都做错?还要再研究。
(也许根本没人看懂 ISO 的标准说明文件到底在写什么 )
XviD 的开发人员之一 Isibaar(Michael Militzer)目前还在研究,寻找到底是哪里有问题。
XviD 的目标是要作出完全标准的 MPEG-4 视讯编译码器,「不标准的 MPEG-4 编译码器
有 DivX 5 一个就够了」他笑着说。
所以如果你考虑到将来播放、兼容性的问题,最好不要在保存用的影片上使用 qpel。
不过 1st-pass 的时候使用 qpel 倒是没有关系,因为并不是 qpel 有错误,
只是各家的作法不一样,造成在不同译码器上播放有不同的结果,这对 1st-pass 使用 qpel
不会造成任何影响。
(虽然我还是建议 1st-pass 的设定要和 2nd-pass 一致 )
再次提醒,Koepi/Nic/uManiac 提供的最新的 binary 是开发中的版本(development, unstable),
任何新加入的功能都可能有着错误、兼容性问题的危险,这些新功能不见得能够提高压缩率,
带来高画质,相反的它可能会制造充满错误的压缩结果,所以如果您是想用它来压缩要保存的影片,
在勾选这些功能之前请确定你知道你在做什么。
XviD 的主要开发人员之一 gruel 很担忧的说,GMC 现在充满了 bug,甚至无法正确的译码,
但是已经有人使用 GMC 来压缩要保存的影片,他可以想见将来这些使用者发现过去压缩的影片
无法正确译码的时候,将会是多么的愤怒,论坛上将会充斥着这些使用者抱怨的声音。
到时候开发小组的回答恐怕只能是:
「既然你知道这是 unstable、开发中的版本,既然你根本不晓得那些选项是做什么用的,
那你为什么还用它?」
目前已知比较安全应该没有问题的新功能:
1. Chroma Motion
实际上就是动作估计(ME)的时候多做色彩平面上的动作向量搜寻,让 ME 的结果更精确,
找到更小的误差,可以视为是 Motion Search - 7,完全没有规格上的争议,不会有错误,
所以相当安全。
2. B-frame
应该已经很稳定了,测试过各家译码器解碼大致上都正确,视情况动态插入 B-frame 的设计更是
XviD 的首创。B-frame 功能是目前能提供最大压缩率的利器,但是要注意的是 "一定" 要勾选
"DX50 B-VOP compatibility" 这个选项,禁止 B-VOP(B-frame)的下一张参考画面是 I-VOP,
否则这个 B-VOP 会出现一堆错误的方块。这个错误虽然只有一个 frame,画面一闪而过,
但是注意看的话还是会发现,所以请 "一定" 要勾选 "DX50 B-VOP compatibility"。
比较有争议的新功能:
1. Qpel
理由如上所述。
如果你不在意兼容性的问题,不在乎压出来的东西是否合于标准的 MPEG-4 规范,
不打算未来在家电产品上播放目前压的 MPEG-4 影片,并且只打算在计算机上使用 xvid.dll 播放,
那么可以使用这个功能。
2. GMC
开发中,功能简陋,完全没有实质上的压缩助益,并且还有错误需要修正,绝对不要使用。
DivX 5 的 GMC 也一样,功能简陋,不会比 XviD 好多少,XviD 的 GMC 很快的就会超越 DivX 5。
3. Modulated Quantization Type
动态切换 H.263/MPEG 的量化方式。这个 ISO 没有明文规定不可以,而且目前的译码器都支持
Modulated Quant,播放上完全没有问题,但是... 还是有隐忧,因为不保证将来的家电产品
一定都可以解 Modulated Quant,毕竟文件上没有要求要有这种规格。
如果你觉得将来太遥远,到时候可能都已经不用 MPEG-4 part 2(目前的 MPEG-4 视讯压缩法),
而改用压缩率更高,更强大,更先进的 MPEG-4 part 10(或者叫 MPEG-4 AVC,Advanced Visual
Coding,先进视讯编码法,也就是 ITU 的 H.264,旧名叫 H.26L)来编码,所以将来支不支持
旧的压缩法,对你来说都无关紧要,那么可以使用这个功能。
以上提供给大家做为参考。
这次写太短了,后面加一些不相关的讨论跟大家闲聊
最近 Doom9 有一篇在讨论如何压出最高品质的帖子,讨论到使用 quantizer 1 的问题,
为什么以前不建议使用 quantizer 1 呢?
quantizer 1 使用「非线性量化表」对应的量化倍数是 1x,
也就是 DCT 系数直接除量化矩阵。这样的失真应该最小,品质应该最好,
为什么反而不建议使用呢?
因为 XviD 使用的 iDCT(inverse DCT,反向 DCT 运算),会做舍弃小数,如果 quant = 1,
则矩阵中很可能会出现非常小的 DCT 系数(没有被除为零),
这些 DCT 系数在压缩时会经过 iDCT 转换回来当成参考画面。
(压缩器当中必须包含译码器才能将压缩过的画面解回来当作参考画面)
此时这些很小的系数会造成非零的 iDCT 输入,解出来却因为舍弃小数的关系而变成为零的输出。
这样子很浪费 bit,因为这些 iDCT 后为 0 的 block 本来应该 skip 掉,试想补偿时加上差值
为 0 的补偿要做什么?这样子不是等于没补偿?那花费 bit 去记录这些数据不是很浪费?
而且在 MPEG-4 规范中,这是不可以的。
如果播放的译码器使用的是和压缩器不同的 iDCT(iDCT 的算法有很多种,有的速度快,
有的算得很精确,没有规定译码器一定要用哪一种 iDCT 算法,所以不同译码器画质也可能不同),
播放端译码器的 iDCT 输出可能不为零,这样就惨了,原本压缩时,参考画面是输出为零的结果,
现在解压缩时,参考画面却不是为零,这个错误会一直累积,慢慢的画面上就会出现肉眼看得到的瑕疵。
这个叫做压缩器/译码器 iDCT mismatch 的问题。
解决这个 zero-iDCT 问题的方法,
1. 不要用 quantizer 1 (MS MPEG-4 和 DivX 5 都不用 quantizer 1)
2. 利用 TOO SMALL LIMIT 这个参数,当 block 中的 DCT 总和小于一定门坎就 skip 掉,
一般情况下是设为 1,遇到 quant =1 时调整为 2,防止 sum = 1,iDCT 后却变成 0 的情况。
XviD 已经用 2 的方法解决这个问题,不过以前说过 TOO SMALL LIMIT 太高,会损失细节。
所以到底用 quantizer 1 好不好?我试压了几个 clip,quantizer 1 的画质还是明显比较好,
不过压出来的档案非常非常大 ^^;
我们知道 resize 最强的计算方法是 lanzcos3,这个计算法转换后的画面既锐利、而且又没有
aliasing/ringing 的问题。压缩 lanzcos3 resize 的画面,锐利的线条、物体的边缘不容易
出现扩散的,斑斑点点的压缩噪讯。也就是虽然 lanzcos3 画面锐利,但是又不会增加太多的
压缩困难度。这是因为 lanzcos3 的计算法本身就等于一个完美的 Low Pass Filter,
不像其它的 resize 法为了要设计一个适当的 LPF 而伤透脑筋。
这个 resize 法本来是由一个很厉害的人实作在 AviUtl 这个软件上,做成 AviUtl 的 plug-in。
后来西方有人注意到这个好用、画面又漂亮的 resize 法,于是提议 Avisynth 加入这个 filter。
因为越来越多人使用,成为大家公认的最棒的 resize 法,所以 VD 的作者也在 1.4.13 版加入了
这个 resize。
我以前都是用 AviUtl 的 lanzcos3,不过因为 AviUtl 的速度实在太慢,所以想说改用 VD 内建的
来试试看,结果...
不知道 VD 的作者是怎么作的,VD 的 lanzcos3 aliasing 得非常严重,resize 后的画面锯齿得
很厉害,压出来的线条周围噪讯飞散,惨不忍睹,就像 bicubic 的算法如果设定成锐利化得太厉害,
压缩后的线条周围会都是噪讯一样。
所以,建议大家不要用 VD 的 lanzcos3
我没用过 Avisynth 的版本,不过我相信 Avisynth 作的应该是对的
- [SilkyBible] XviD系列-3
- [SilkyBible] XviD系列-1
- [SilkyBible] XviD系列-2
- [SilkyBible] XviD系列-4
- [SilkyBible] XviD系列-5
- [SilkyBible] XviD系列-6
- [SilkyBible] XviD系列-7
- [SilkyBible] XviD系列-8
- [SilkyBible] XviD系列-9
- [SilkyBible] XviD系列-10
- [SilkyBible] XviD系列-11
- [SilkyBible] XviD系列-12
- [SilkyBible] XviD系列-13
- [SilkyBible] XviD系列-14
- [SilkyBible] XviD系列-15
- [SilkyBible] XviD系列-16
- [SilkyBible] XviD系列-17
- [SilkyBible] XviD系列-18
- [VB.NET][求助]关于在vs.net2005中连接oracle数据库的问题
- pe_xscan 修正文件时间的一个bug
- 融会贯通Oracle数据库的25条基本知识
- [VB.NET]如何动态设置数据库访问方法
- [VB.NET]如何改变当前exe文件的运行路径?
- [SilkyBible] XviD系列-3
- 非正式测试用DDS写的“视频”传输程序
- [VB.NET]数据传递,绑定问题?
- [VB.NET]求助:关于取treeview父结点的问题.(在线...)
- [SilkyBible] XviD系列-4
- bnu1299 ZUMA C语言版
- bnu1054 杨辉三角 C语言版
- j2me 实现连连看的算法
- bnu1055 阶乘 C语言版