[SilkyBible] XviD系列-16

来源:互联网 发布:java 获取ip 端口号 编辑:程序博客网 时间:2024/04/29 20:09
 因为会有数日无法上网,怕说明得不够清楚,再举个例子
假设现在是 4fps,一秒四个 frameframe size:
1. 50k
2. 50k
3. 100K
4. 1000k

码率 1200kbps
码率平移一半 -> 600kbps
每个 frame 要 linear-scaling,线性的乘一比例下降
1. 50*0.5=25k
2. 50*0.5=25k
3. 100*0.5=50K
4. 1000*0.5=500k
=>600kbps

而不是每个 frame 均等的减去一定 size
1200-600=600k
600/4=150k
1. 50-150= -100k
2. 50-150= -100k
3. 100-150= -50k
4. 1000-150= 850k
=>850kbps,有些 frame size 是 0k

这样象话吗?
观察 XviD 2nd-pass 的 log 文件,你会发现
[Virtuald] 2nd-pass: stats1:13970 scaled:8373 actual:34697 overflow:-14801 movie
[Virtuald] 2nd-pass: stats1:62264 scaled:37314 actual:6461 overflow:16054 movie

stats1 也就是 1st-pass 13970 bytes,我们预计要 scale 到 8373
8373/13970 = 0.599355762347888332140300644237652

stats1 62264 bytes -> scale 37314
37314/62264 = 0.599286907362199665938584093537196

linear-scaling 是对每个 frame size 依一定的比例缩减。 
引用 09-29-2003
引用h.263, chroma optimizer, b-frame都是降低psnr的啊,尤其是b-frame降得更厉害

我手头没有helix dna 9.2(哈哈,听起来似乎源自"dna double stranded helix", 跟我的专业到似乎有联系 ), 要不然一定会捍卫XviD作为最强codec的圣地!!
当然罗, 大家都在努力, silky说dvix 5.1也有很大的进步,所以xvid要加油罗。
XviD 最强?蛮难的吧 :P
我这边测,api-3 SSE 很难赢 DivX 5.1。
winsen 测出来,在码率是 1st-pass 的 30~40% 这个区间,api-3 居然只输 RV9-EHQ 这样一点点,其实已经令我大感惊讶了 :P
所以我猜 winsen 兄用的 CPU 是 AMD 的,api-3 在有 3DNow! 的机器上,PSNR 会提升 0.3~0.4dB,分数甚至比 api-4 SSE 更高,和 RV9-EHQ 的差距会缩小。

甚至,不用提 RV9-EHQ,现在 api-3 连要赢 DivX 5.1 都有困难,DivX 5.1 是个超强的对手。
虽然不想这么说,但是我还是不得不承认 DivX 5.1 非常厉害。

关闭 chroma optimizer 会提升 "UV" 的 PSNR。
MPEG quant 目前不支持 Trellis Quantization,如果量化矩阵没有特制最佳矩阵,在这种码率区间 PSNR 可能会输 H.263 0.5dB 以上,比 H.263 更惨 ^^;
B-frame 不一定都会降低 PSNR,即使是动画,也有使用 B-frame 后 PSNR 大幅提升的例子。

我不用 RV9-EHQ 的原因
1. 因为我没有做网络串流的需求,不压中低码率
2. 上到高码率,RV9-EHQ 还是"洗掉"太多细节,以动画来比喻,就像是"水彩画"变成"油画"

我不用 DivX 5.1 的原因
1. 因为愚蠢的心理的因素作祟,就是不喜欢 DXN 这间公司
2. 高码率 XviD 用 MPEG quant,有现今 MPEG-4 的最高画质,DivX 5.1 还是比不上

我之所以不用 WMV9 的原因
1. 没有原因,就是不用
2. 除了低码率以外,其它码率我测出来好像每一部 WMV9 都是敬陪末座,很奇怪,我觉得 WMV9 不应该会这么差才对,原因不明

抛开奇怪的感情因素,以比较公正的角度来分析
a) 网络流传、给别人随便看看就算了的东西、中低码率用 RV9-EHQ/WMV9
b) 中高码率用 RV9-EHQ/DivX 5.1/XviD
c) 个人收藏、想拿到客厅去看,期待将来对应 MPEG-4 家电播放机、高码率用 XviD

虽然不是悲观的说 XviD 在低码率一定不行,只是还要调整设定好久才能赢人家,好麻烦,干脆用适合低码率的 codec 压缩岂不是更轻松愉快?
引用片源是动画片吗?
我想看非动画片的用PSNR4AVI测出的YUV各量的结果
我有测过非动画类的讯源,XviD 的 chroma PSNR 也不低,一样很高
我觉得 PSNR4AVI 内部是怎么计算的我们不清楚,说不定它接收的是各个 codec 解码输出的 RGB,而不是 YV12,然后再做 RGB -> YUV,计算 YUV 的 PSNR。这样会犯了我说的那两个缺点,一个是经过 YUV -> RGB -> YUV 的多次转换,另一个是 YUV 4:2:0 -> YUV 4:4:4 upsampling 的问题,这个两个问题影响非常巨大,可以差到数 dB,所以要准确的测定 PSNR,我觉得还是用 Avisynth 的 compareyv12 较好。
compareyv12 测定的是 Overall PSNR,可信度比较高,同时它也很方便,你测试 YUV 三个 channel 的总和平均,它同时会把 Y/U/V 三个 channel 分开的 PSNR 一起列出来,不用反复测试很多次,和 PSNR4AVI 一样方便。
http://web.etel.ru/~shalcker/CompareYV12.zip
引用 11-25-2003
引用我搜了一下帖子, 没有发现几贴讨论trellis的, 还请Silky兄讲解一下trellis是怎么回事 .
thx!
这个,上面 winsen 兄有贴,或者,这几天 xvid-mailing-list 不是正在讨论,大家可以看,还是要我把它翻成中文?

trellis-based RD optimal quantization 就是找一个 block 的 optimal。
这个 optimal 的定义是从 RD(Rate-Distortion) 的观点来看,最小的 cost。
也就是说 trellis 是在量化一个 block 的时候,改变一些量化后的系数,使得量化的结果,这个 block 的 cost 会最小,这样我们称为 optimal。
一个 block 的大小是 8x8,里面有 64 个系数,最左上角叫做 DC,其它 63 个叫做 AC 系数。
那么什么是 cost 呢?
一般我们只要求一个 block 的 error 误差最小就好了,现在我们改用 cost 作为评量的标准。
cost 会考虑求得的最小误差和所要花费的 bits 代价,所以说它是从 Rate vs. Distortion 的观点来考量。
这个 cost 我们用一个 bits 对 distortion 的权重公式计算:
cost = error + lambda*bits

error(distortion) 用 SSE(Sum of Squared Error) 计算。
SSE 的计算方式是,将动作搜寻找到的参考方块和目前方块中的每个像素相减,得到每个像素的误差(Error),然后把误差值平方(Squared),将每个像素的误差值平方全部加起来(Sum)得到的数字就是 SSE。
一般我们找到的是 SSE 最小的方块。
现在我们改找 cost 最小的状态。

上式中的 bits 是编码这个方块所需的 bits 数。
lambda 则是一个参数,调节 bits 的权重,这个参数通常用下面的算式计算:
lambda = 0.85*quant*quant

也就是让 lambda 可以随 quantizer 做变化。
我举个例子,大家就可以了解这个算式的作用,假设现在 quantizer 是 10,lambda 就会等于
0.85*10*10 = 85

假设我们现在减少编码所需的 bits 数 1-bit,但是 error 会增加 85,这样划不划算呢?
根据 cost 算式
原本 cost = error + 85*bits
现在 cost = (error+85) + 85*(bits-1) => error+85 + 85bits-85

加 85 减 85 刚好打平。
也就是说,在 quantizer = 10 的时候,减少 1-bit 但是会增加 85 的 error,这样的代价我们是可以接受的。
同理在 quantizer = 2 的时候,lambda = 3.4,1-bit 可以换 3.4 的 error 增加。

这样我们就了解,trellis 会改变一些系数,譬如说把 1 这种很小的系数 skip 掉,使得 error 增加,但是所花费的 bits 减少,只要最后 cost 减小,我们就选择 cost 最小的结果。

那么 trellis 是怎么决定要改变哪些系数的?
这几天在 mailing-list 上 skal 大神才举了一个例子,假设现在系数值是 1(level=1),MPEG 是用 VLC 的方式来编码 AC 系数,我们现在不讲 VLC 的编码方式,太麻烦了 ,总之最后要查表便知道这样的系数排列需要花费多少 bits,假设 AC 系数目前是像下面这样排列
[1 0 0 0 1 0 0 x...] (run=4, run=3)

因为没解释什么是 RLC,就这样想吧,run 代表 1 和 1 之间 0 隔开的间距。
查表 run=4, run=5, run=6 同样要花 6bits 编码,run=3 花费 5bits,run=2 花费 4bits。
所以上面的系数要花费 6+5bits。
如果我们移动第二个 1 的位置,把它移到后面(就是把原本的 1 变成 0,后面 0 的变成 1)
[1 0 0 0 0 1 0 x...] (run=5, run=2)

花费的 bits 变成 6+4bits,减少了 1bit,但是注意此时误差增加。
再往后移
[1 0 0 0 0 0 1 x...] (run=6, run=1)

总共 6+3bits。

所以我们把一些系数改变,让它的排列刚刚好符合最有效率的编码方式,就可以减少所需的 bits 数,但是此时会增加误差,怎样的 bits 节省 vs. 损失的 PSNR 是最划算的?用 cost 公式决定
cost = error + lambda*bits

例如刚刚举的例子,quantizer = 10 的时候,1-bit 可以换 85 的 SSE 误差增加。
利用寻找最小的 cost ,我们可以得到 RD optimal 最佳的结果。
很简单吧

那么 trellis 又是怎么增加 PSNR 的?
mailing-list 上 gruel 大神举了一种情况,我们知道 MPEG-4 用的量化器有 dead-zone,譬如说量化位阶 QP=6 的话,+6 到 -6 之间的数值都会被量化为 0,这个区间叫做 dead-zone,死亡区 :P
很明显的,如果原本的 DCT 数值是 +6 或 -6,被量化为 0,误差是 6。此时如果我们把量化后的系数从 0 变成 +1 或 -1,反量化回来得到 +9 或 -9,和原来的的误差是 3,误差反而变小。
所以我们把一些 0 变成 1,误差反而减少,这就是 trellis 增加 PSNR 的机会。

在固定 quantizer 的时候 trellis 会缩小文件大小,但是 PSNR 可能也免不了要降低。
但是由于它减少 bits 是根据 RD optimal,每一个 bit 减少都是有代价、值得的,用一定的 PSNR 损失换取最大的 bits 节省,所以比较 PSNR/size 比,trellis 会比较有效率,没有用 trellis 同样的 size 下达不到这样高的 PSNR。


和 alexheart 兄一样,我这边测出来 2-pass 开 trellis 也是 PSNR 降低,我想大概是 trellis 影响了 2-pass scaling 判断的结果。用了 trellis,quant 分散的情形好像更收敛了,不知道是不是这个原因影响,还要再研究。

关于 lambda 值的设定变化,一般是根据 quantizer 做改变,gruel 提过一个很有意思的想法,为什么不让 lambda 也随系数的频率位置做变化?我们知道低频比较重要,低频误差增加 1 视觉品质不等于高频误差增加 1,如果随系数的频率位置调整 lambda,让 lambda 在不同的频率有不同的权重,这样似乎比较符合 HVS(Human Visual System) 的概念,视觉品质可能会更好。

另外,在 Patch-109,XviD trellis 的灰色方块 bug 应该修掉了,感谢 skal 大神
引用 11-25-2003
引用请教S兄上面所用片源的长度和分辩率等参数
光看文件体积我是一头雾水
640x480, 23.976fps, 1min 30sec, 2168 frames, anime
我自订的量化矩阵质量离谱高,所以 MPEG-Custom q=4 压出来会和 H.263 q=2 差不多大。
文件大小差不多是 H.263 q=2 的大小程度。
所以这个文件质量很高,Overall PSNR 47dB 上下。
引用也跟钓一下:
在他坛争论过PSNR在YV12下测与在RGB下测到底有多大区别?
有意见认为RGB有足够的色彩空间来描述YV12色彩,应该是没有误差的
如同上面 winsen 兄说的,因为 MPEG 储存的是 YUV,要比较 RGB 要做 YUV -> RGB 转换,这个转换是有损失的。

我被钓上来了,好痛
引用請問 cartoon mode 放在 zone 裡面會不會不好呢? 因為 cartoon mode 跟 detect static scenes 要一起用,但是 detect static scenes 似乎不能放在 zone 裡面,所以如果有一個 zone 要使用 cartoon mode 就整個影片都要用 detect static scenes...
我觉得放到 zone 里面比较好,不过可能要考虑到 ME 部分结构设计的问题,所以.... 写信建议 Isibaar 看看
引用似乎dev-api-4的Qpel+bf连用时不能被devapi3的directshow decoder正常解码, 但4自己的没有问题...
ps.
E.G.跟Michael争的好厉害啊
是啊,看得我心惊胆跳。
Michael 就是 Isibaar,最早开发 XviD 的三巨头之一,现在大部分的 XviD code 都是由他们三位写的,gruel=Christoph Lampert , Isibaar, pete=suxen_drol。
当然还有总是会说「耶,这个东西,我这边已经有写好的 code,你要不要拿去试试看」的 skal 大神。skal 写的东西又快又好,是 XviD 强而有力的后援
这几个月来,确实整个 XviD team 除了 E.G. 和 sysKin=Radek Czyz 之外,其它人因为各自有事要忙,进度几乎陷入停摆。
所以不论结果如何,我都非常感谢他们抽出自己的空余时间,拿来做 coding 的工作,写出这么好、速度又快、又不用钱的 XviD 给我们用,谢谢
引用 12-17-2003
引用我压的是matrix reloaded,以下是DRF的分析,大家给提提意见,另外,压这部片子有什么需要注意的吗?谢谢。

DivX DRF Analyzer v0.9.5 Report!
File Name: E:/DVDRip/Reloaded/Reloaded.avi
FourCC: XVID
Codec: XviD0012
<-- 这个是哪一版的 XviD?
api-3 的版号是 0009,之前的 api-4 是 0021,目前的 beta2 是 0023。

DRF(Detail Reduction Factor) 是 Nandub 时代的称呼,现在叫做 quantizer,正式的名称也叫做 quantizer。
quantizer 是量化的倍数,quantizer 越高,代表量化时资料削减得越多,误差越大,品质越低。
例如 H.263 量化,intra block 每个系数 除的是 2 倍的 quantizer 数字


通常 quantizer 在 2.5~3.5 之间品质都不错。
引用 12-17-2003
引用不算太好也不算太坏,因为DRF值不能完全表述电影的质量。。。不过有那么多>9的,就很难说在很多场景下会出现什么结果。
正在讨论中的TDX2k4有人建议说以后要求全片Average DRF<4,呵呵,不知道怎么check.
关于 quantizer 的分布,XviD 的 2-pass 算法和 DivX 不一样。
DivX 1st-pass 的时候会用设定的码率压缩一次,得到大概的平均 quantizer,2nd-pass 会用这个平均 quantizer 为中心,在这个 quantizer 的上下切换量化,压出来的 quantizer 分布范围很小,码率够的话甚至只会在邻近的两个 quantizer 之间切换压缩。
例如 1st-pass 压出来平均 quantizer=4.85,2nd-pass 就只用 q=4 和 q=5 两个 quantizer 压缩。如果设定要分给 low-motion 的画面多一点 bit,那么为了平衡码率,high-motion 的画面就有可能会用到 q=6。但是最后的 quantizer 分布范围很小,不会一下跳得很高。以上是 I/P frame 的情况,B-frame 我们知道会依比例提高 quantizer,通常是两倍。

而 XviD 的算法则截然不同,XviD 是 1st-pass 用 q=2 压缩一次,所以 1st-pass 产生的文件相当大,压完后我们还是无法得知我们设定的码率,用在这个讯源上,压出来的平均 quantizer 大约会是多少。2nd-pass 时则会依 1st-pass size/2nd-pass size 的比例提高 quantizer 压缩,这个分散的范围很大,会出现很低和很高的 quantizer,例如会出现 q=2~q=8 的 quantizer。

这是两种不同的 2-pass 方法,我们知道 DivX 的做法接近 CQ 压缩(固定品质压缩),压出来的 quantizer 会在两个数字之间切换量化,等于 XviD 在 Zone 里面设定 quantizer=4.85 压缩,或者 DivX 本身的 1-pass quality 压缩。不过 1-pass quality 压缩无法事先预测压出来的文件大小,2-pass 可以,还有 2-pass 可以调整 bit 的分配,它所用的 quantizer 会更有弹性,不会完全只限制在两个 quantizer 切换量化,通常 DivX 会用到其它 quantizer 做适当的压缩。
这种 2-pass 方法的好处是质量比较稳定,不会出现太差的 frame,但是用这种方法压出来的品质不一定是最好的。

XviD 的方法缺点是分散得太开,容易出现烂掉的 frame,不过适当的压缩 quantizer 分布的范围,会大大提升画质。限制的方法一种是限制 I/P/B frame 的 quantizer 范围,另一种是改变 1st-pass 压缩的 quant。
例如,根据经验,我知道这样的码率设定压出来最终的平均 quantizer 大约会是 4.85 左右,所以我 1st-pass 改用 q=3 压缩一次(压 1st-pass 时,在 Zone 里面强制设定 quantizer=3),产生 q=3 的 1st-pass stats 文件。2nd-pass 用这个 stats 文件压缩,最低 quantizer 会变成只能用 q=3,因为少了 q=2 这种品质太好,size 太大,消耗太多 bit 的 frame,会让可用的码率更充裕,最高 quantizer 会下降,最后范围便会收缩在 q=3~6 之间。
这样测出来的 PSNR 会比较高,同时视觉品质也会大大改善,我测过 Harry Potter II Trailer,在低码率甚至可以赢过 WMV9。

所以根据设定的码率大小,讯源压缩的难易程度,适当调整 1st-pass 的 quantizer 会提高品质。
要压超高品质的时候,例如依照设定的码率,最后的平均 quantizer 大约会 =1.xx,这时也可以做 2-pass,把 1st-pass 的 q 强制设定为 1。


其实最大的问题是在 1st q=2 压缩和 2nd q=4 压缩 size 可能会差很多,不是成线性削减,造成码率控制误差太大。改用 q=3 的 1st,和最后的 avg. q=4.85 会比较接近,预测、控制会更准确。
如果 1st-pass 改用 q=4 压缩,那么 2nd-pass 最低只能用 q=4,quantizer 范围更小,上面的例子压出来 quantizer 只会在 4~5 之间切换,等于 CQ 压缩。
我们知道 CQ 压缩品质不一定是最好的,有几个 q=3 的 frame,会让后面比较好参考,最后整体品质反而提高。
所以 1st-pass q 值太靠近最后的平均 quantizer 会变成 CQ 压缩,不好;离得太远会造成 q 分散太广,不好;刚好接近又不会太接近,最好

XviD 的开发小组目前正在讨论,要收敛 2-pass 的 quant 分布,像 DivX 那种的,但是又不会限制得太严格的分散法。
引用 12-17-2003
引用正好silky大神在,问个问题,就是全片DRF<4有没有什么实际必要?我们要改进tdx2k4,要收集意见
小弟不是大神啦 ^^;
小弟是来入侵的使徒

由上面的说明,我们知道适当的分散 quantizer 范围,偶而出现少数一两个 q 值很高的 frame,对品质影响不大,因为前面的 frame 压得很好,例如 q=2,后面的 frame 如果和它差异不是很大,即使用 q=8 压缩,视觉看起来也不会有什么不妥。
但是如果有太多 >8 的 quantizer,就有必要考虑一下修正、或者限制 quantizer 范围。

规定全部 frame q<4 会有一些缺点
1. 我们知道 B-frame 的价值就在它的高 quantizer,B-frame quantizer 高,把码率分给它要参考的 I/P frame,使得参考对象的品质提高,这样 B-frame 参考他们压缩,虽然自身 quantizer 很高,但是品质并不会劣化太多。

所以 q<4 的规定最好是限制 I/P frame,B-frame 不要包括在其中。

2. 如果是用自订 MPEG Matrix,自订那种质量很高的 Matrix,q=4 的时候质量相等于 H.263 q=2,那么压出来全片 quantizer 一定会超过 4,这种情况也必须考虑进去。

q 的品质是会变化的,根据使用的量化方式的不同,例如 H.263 q=2 质量不等于 MPEG q=2,还有自订矩阵等等,所以单一的限制无法适合所有的情况。
原创粉丝点击