引用Okay, 的确。做了几道课后习题,遇到问题了前来请教
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
1. qm中的threshold是只考虑了亮度, 还是亮度(brightness or luminace)色调(hue,如区别于红色与蓝色,etc)及色度(chroma, 灰色含的成分, 如: 同是灰蓝, 但灰色越多看起越泛白灰一点)都被包含其中?抑或都包含,但对亮度的变化更敏感?
ex. 比如像少数派报告(Minority Report)那样的电影,电影普遍偏蓝(过滤了些hue?), 那么如果qm考虑色调的话,由于整个macroblock的平均值和其细节之间的差别小了,我们适当降低threshold是不是更能捕捉细节?
即使不考虑色度,我感觉影片的亮度的差别在这种处理下似乎也变小了。
而对于色彩专门处理得特别鲜艳但很柔和的影片我们是不是可以适当抬高threshold来增加压缩率?
请看下面两个截图(我手头没有Minority Report, 用另一个类似的MTV代替).
第一幅画面细节也很多(比如布赖恩的胡子,皮肤的瑕疵和牛仔服的质地),但大概编辑加了filter, 颜色与自然中不一样而显得更加单调(专辑叫Black & Blue嘛
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);"> ).
第二副细节倒被刷没了(都是同一个人),但色彩异常的鲜艳。
喔,你这些问题,不太好回答
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
首先,在 JPEG 里面,Luminance 和 Chrominance 有不同的量化矩阵,一个矩阵用在 Luminance 上,另一个矩阵用在 Chrominance 上。但是在 MPEG 里面,一般 Luminance 和 Chrominance 共享一个量化矩阵,不能分开设置,如果要分开设置不同的矩阵,MPEG-4 好像可以,在某个 profile 里面可以让你这样设,但是一般我们使用的 profile 是不行。
譬如说一般 MPEG-2 是用 YUV 4:2:0 格式,但是 High Profile 以上就可以用 4:2:2 格式,UV 的取样由 4:2:0 的 1/4 提升为 4:2:2 的 1/2,但是我们一般使用的 Main Profile & Main Level,MP@ML,也就是 DVD 使用的 Profile,不能用这个 4:2:2 的设置。
所以虽然 MPEG-4 规格有包含可以对 Luminance & Chrominance 设置不同的量化矩阵,但是我们一般没有办法用。
这样还算好的,更惨的是有的功能虽然有写在规格里,但是没有包含在任何一个 Profile 里面,所以根本没有人会去用,例如 MPEG-4 里面的 OBMC。
MPEG 可以设置两个矩阵,一个是 intra QM,给 intra-block 使用,另一个是 inter QM,给 inter-block 使用。
intra-block,独立压缩的 block,压缩的内容是画面的"材质",实际的画像像素。
inter-block,参考别人压缩的 block,压缩的内容是和参考对象之间的"差异",记录的是和参考对象的"误差"。
因为量化的对象不同,所以 intra QM 和 inter QM 设置的系数就不同,请不要把它两者设成一样
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
那么是不是 I-
frame 都用 intra QM,P/B-
frame 都用 inter QM 呢?
也不是。
I-
frame 里面都用 intra-block 压缩,所以全部都用 intra QM 没问题,但是 P/B-
frame 里面,有 inter-block 也有 intra-block,所以 P/B-
frame 也会用到 intra QM。
由于 intra/inter QM 会在同一个 inter
frame 内混合使用,所以两者之间的搭配就很奥妙。譬如说如果我把 intra QM 设得砍很多,数字很大,这在 I-
frame 内使用没问题,因为 I-
frame 都常 quantizer 低,最后除的数字还好,不算太大,但是在 P/B-
frame 中,quantizer 高,如果又遇上非用 intra-block 不可的时候,这个 intra QM 的设置就嫌太高,量化的结果这个在 P/B-
frame 中的 intra-block 就会压得太差。
所以 intra 和 inter QM 有微妙的搭配关系。
还有前面提到,inter QM 量化的是 inter-block,而 inter-block 里面记录的是"误差",所以 inter QM 量化的对象是误差,而不是真正画面上的材质像素,所以它的设置方法会和 intra QM 不一样。
在低流量的时候,我们可以看到许多软件预设的矩阵高频砍很多来缩减容量,例如 CCE SP 的 Ultra low bitrate 矩阵
inter
16 17 18 19 99 99 99 99
17 18 19 20 99 99 99 99
18 19 20 21 99 99 99 99
19 20 21 22 99 99 99 99
20 21 22 23 99 99 99 99
21 22 23 24 99 99 99 99
22 23 24 26 99 99 99 99
23 24 25 27 99 99 99 99
但是在高流量,这样的矩阵就不是很适合。
譬如说如果画面偏静态较多,前后画面的差异不大,假设 motion search 可以找到很接近的对象,这时如果我们用比较平坦的 inter 矩阵
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16
压出来的方块误差会很小,下一个画面用这个误差很小的方块做为参考对象,不但好压缩(因为差异小),而且画质高。
如果我们用一个比较陡峭的 inter 矩阵
16 17 18 19 20 21 22 23
17 18 19 20 21 22 23 24
18 19 20 21 22 23 24 25
19 20 21 22 23 24 26 27
20 21 22 23 25 26 27 28
21 22 23 24 26 27 28 30
22 23 24 26 27 28 30 31
23 24 25 27 28 30 31 33
虽然这个方块砍得多,压出来容量小,但是误差也随之扩大,下一个画面参考这个误差较大的方块,会变得不好压缩,最后虽然靠着削的数字多,容量还是压下来,和上面平坦矩阵一样大,但是误差却较大,画质就不如上面用平坦矩阵压缩的好。
如果反过来,现在是动态画面偏多,motion search 不容易找到接近的对象,可能找到的对象差异很大,误差的数字经 DCT 转换后,高频很多,这时如果再用平坦的 inter 矩阵,高频削太少,容量暴增,Encoder 为了维持一定容量,必须提高 quantizer 压缩,此时低频的量化系数会跟着一起被放大:
quantizer=2 量化矩阵系数 16 全部 *2
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
32 32 32 32 32 32 32 32
和 quantizer=1 的不平坦矩阵比较
16 17 18 19 20 21 22 23
17 18 19 20 21 22 23 24
18 19 20 21 22 23 24 25
19 20 21 22 23 24 26 27
20 21 22 23 25 26 27 28
21 22 23 24 26 27 28 30
22 23 24 26 27 28 30 31
23 24 25 27 28 30 31 33
用平坦矩阵量化为了保留高频,低频跟着一起完蛋,而不平坦矩阵高频砍较多,可以在 quantizer=1 的时候就缩小这个 block 的容量,不用提高 quantizer,反而保存了低频,结果在这种讯源下,陡峭的 inter 矩阵反而画质会比较好。
以上只是举例,和实际情况不一定相符
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
由上面的例子我们可以发现,量化矩阵的设置,如果全部的矩阵系数都乘或除同一个数字,有换等于没换:
32 32
32 32
换成
16 16
16 16
等于没换,因为全部 16 的矩阵,只要 quantizer 提高一倍,最后除的数字等于
16*2 16*2
16*2 16*2
=>
32 32
32 32
和原来一样,所以这样压缩的结果,和原来一样,只是压出来的 quantizer 提高一倍。
(其实是会有一点差异,因为 dc_scale 是 nonlinear scale,还有量化的算式会根据 quant_scale 的奇偶做正负加减变化,不过此处忽略不计)
所以更改量化矩阵,其实我们是在改高低频 scale 的速度
16 24
24 32
->
32 48
48 64
这样改等于没换
但是
16 24
24 32
->
16 48
48 83
高频放大的速度变快,这个矩阵的效果就和原来不一样。
总结以上的分析:
1. intra 和 inter 有相互搭配的关系
2. inter 不是削越多越好,常见到有许多矩阵 inter 削得很多,其实误差加大,后面反而不好压缩,有时质量高的 inter 矩阵,整体 PSNR 反而高
3. inter 量化的是"误差",设置方法和 intra 不同,不同比对方法的特性不同,误差数字的分布没有一定,造成 DCT 转换后的高低频分布也没有一定,此时高频的 DCT 系数,不像 intra 一样代表画面上实际像素的空间频率,所以不见得把 inter 的高频削多损失就比较少,要看讯源特性,陡峭的 inter 矩阵和平坦的 inter 矩阵各有其适用范围
4. 总归一句话,不要把 inter 当成 intra 来设,莫名其妙乱砍一堆高频系数
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
5. 设置矩阵,其实是在调整高低频量化倍数放大的"速度",全部同除或同乘一个倍数,矩阵等没有改变
以压动画来说,我们希望
1. 找到一个矩阵,可以防止锐利线条周围的量化 noise ,最少要让它比较不明显。原本 MPEG-4 预设的那个量化矩阵, noise 就太明显。
2. 不同 DCT 矩阵的量化,会造成特殊的视觉效果,通常来说会有几个共通的优点
a) 画面清晰锐利
b) 可见的细节增加
c) 暗部(画面上亮度较低的区域)H.263 量化 inter 低频砍太多,会有一块一块的方块感,即使到 quantizer=2 压缩也一样,暗色系的部分都是一块一块的色块。MPEG 量化方块感较轻微,取而代之的是扩散的点状 noise 。
我比较能接受点状 noise
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
但是 MPEG 矩阵设置错误也会造成反效果,甚至压出来比 H.263 还模糊。
我们希望能够找到一个有良好视觉特性的矩阵,能够发挥 MPEG 量化优点的矩阵。
3. 通常要压高画质,我们会用 q=2,开 B-
frame 压缩,B-
frame 的 q=4,但是这样并不是最高画质。
2-pass 压缩有一个特性,它会对较复杂,较难压缩的画面分给较高 q 值压缩,而这种画面通常是高动态的画面,人眼对这种画面的敏锐度较低,所以虽然压得较差,但是感觉不太出来。
如果用 CQ 固定品质压缩,譬如说固定用 q=2 压缩,遇到这些难压的画面,Encoder 还是用 q=2 压,压出来 size 很大,代价很高,但是增益很小,因为人眼根本感觉不出来这些画质提升。
同档案大小下,如果用 2-pass 压缩,静态、人眼较敏感的画面可以分到 q=1,画质好得不得了,而动态、人眼较不敏感的画面可以用 q=4 压缩,感觉差异不大,那么整体视觉品质来说,2-pass 就会优于 CQ。
所以对于静态画面较多的讯源用 2-pass 压缩有它的好处。
可是 XviD 1st-pass 就是只用 q=2 压一遍啊,要怎么样才能在平均质量 avg q=2,能用到 2-pass?
如果我们让 2-pass 压出来最后的平均 q 值 = 4.xx,可是这个 q=4.xx 的质量等于 预设 MPEG QM 的 q=2,这样不就可以用到 2-pass 了?
有兴趣的人可以研究看看
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
不过这样的做法有几个缺点要提醒大家
1. 目前 XviD 的 MPEG quant 没有 Trellis 功能,只有 H.263 才有,所以用 MPEG quant 压缩在低流量讨不到便宜。
2. 2-pass 不见得能赢 CQ,不同讯源有不同结果,不同量化矩阵也有不同结果。
3. 用上述方法,让 q=4 质量等于原本 q=2 做 2-pass 压缩的时候,要注意 B-
frame 的 q 会由 q=4(I/P 的两倍)升高为 q=8。由于 quant_scale 有 nonlinear scaling,quantizer 越高,dc 除的越多(参考前面提供的算式),所以要注意控制设置的 QM,不要让 B-
frame quantizer 不合理的高出太多,否则部分画面会因此急速劣化。
引用
09-27-2003我举一些测试做为例子,譬如说现在 DivX Pro 5.1 很强,真的很强,压出来的质量真的令我非常赞叹
1. 画面不像 5.0.5 的时候那么模糊,非常清晰,几乎看不出来用的是 H.263 量化
2. 细节保留得很多,虽然还是输 XviD MPEG 量化的细节,但是比以前 5.0.5 的时候多很多
3. PSNR 很高,可以赢过 XviD api-3,和 api-4 不相上下
不过要注意的是,PSNR 的数字,很容易改变:
a) 计算的是平均 PSNR 还是整体 PSNR(Overall PSNR)?
b) PSNR 在高流量时的可信度较高,测试的目标流量是多少?
c) 计算的是 YUY2 还是直接比较 YV12,中间有没有经过转换?
d) 不同讯源类型,Encoder 的表现就会不一样,不会一面倒的都是某个 Encoder 赢,所以测试的 sample 是否足够?
e) 一些细节的设定不同,例如 I-
frame 插入的个数不同,PSNR 就会变化
f) 甚至使用的 CPU 不同,PSNR 也会不同。例如 XviD 在 3DNow! 的机器上,PSNR 比 SSE 高 0.3~0.4dB,而 XviD 和 DivX 的差距通常在 0.02~0.1dB 之间,使用的 CPU 不同,就有决定性的胜负
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
所以 api-3 的 PSNR 就一定会输 DivX 5.1 吗?当然不一定
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
如果只比"账面上"的 PSNR 分数的话,我可以做到 XviD 压出来每一部 PSNR 都赢 DivX 5.1
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
例如用 MPEG quant,改改量化矩阵,结果就天差地远。
clip1 FFX-2 游戏里的动画,没有用 B-
frame,XviD 都用 MPEG quant
XviD 2-pass 档案大小 48,187,318 bytes
PSNR 47.1088dB
DivX Kaukura 2-pass 48,119,808 bytes 平均 quantizer 1.751 <- 作为指标,这些档案的品质大概是这样的水准
PSNR 47.0978dB (-0.0110)
WMV9 VCM 2-pass 48,508,928 bytes
PSNR 46.7516dB (-0.3572) <- 有关闭会降低 PSNR 的 Post Process
ps. XviD 的测试都有开 Chroma Optimizer,这个选项会降低 PSNR。
DivX 3-pass PSNR 反而下降,所以不用 3-pass 的数据。<- 这不是表示 3-pass 的视觉品质就一定会输 2-pass,而是前面提过的,multi-pass 会重新分配 bit 的分布,如果 Encoder 决定给静态画面较多 bit,而动态画面较少 bit,而讯源本身动态画面很多,这样较多而且较大的动态画面误差增加,就会使得最后整体 PSNR 下降。但是实际观看时,3-pass 的静态画面会赢 2-pass,而动态画面的劣化不见得能察觉出来,所以整体 PSNR 下降,不代表视觉品质跟着下降,要看讯源的特性。这里只是选"账面上"分数最漂亮的成绩来比较。当然如果差距很大(ex: 0.3~0.5dB 以上),那就另当别论了。
DivX 2-pass 的 modulation 设 low motion,PSNR 会较高,以上是用最高的成绩。
clip2 同样是 FFX-2 游戏里的动画,没有用 B-
frame
XviD 2-pass 档案大小 11,738,018 bytes
PSNR 46.1228dB
DivX Kaukura 2-pass 11,751,424 bytes 平均 quantizer 2.552
PSNR 46.3756dB (+0.2528)
WMV9 VCM 2-pass 10,954,752 bytes <-- 实在无法精确地控制档案大小,使之接近其它两个档案,不是太大就是太小
PSNR 46.0904dB (-0.0324)
clip3 OneTwins 的 OP,有用 B-
frame
XviD 2-pass 档案大小 29,777,920 bytes <- 有用 Cartoon mode
PSNR 45.8581dB
DivX Pro 5.1 2-pass 29,702,144 bytes 平均 quantizer 2.293
PSNR 44.9119dB (-0.9462)
2-pass modulation 设 low motion 档案大小 30,015,448 bytes
PSNR 45.7383dB (-0.1198)
WMV9 VCM 2-pass 30,662,656 bytes
PSNR 44.7818dB (-1.0763)
以上是不同讯源输入的结果。
针对单一讯源改变 QM,结果也会有很大的不同,例如
clip4 Tales of Destiny 2 的 OP
目标档案大小是 DivX Pro 5.1 H.263 q=2 压出来的档案大小
代码 (双击代码复制到粘贴板)
Minimum Average
矩阵 1 : 76,486,656 bytes 42.7555 46.2865 dB
矩阵 2 : 75,6xx,xxx bytes 42.6892 46.2616 dB <- 2-pass
矩阵 2 : 76,285,952 bytes 43.7924 46.3377 dB <- CQ=3.86
DivX5.1: 75,4xx,xxx bytes 43.5825 46.3928 dB <- CQ=2 据说 DivX 5.1 CQ 压出来 PSNR 比 2-pass 高
矩阵 3 : 76,382,208 bytes 43.2245 46.3220 dB <- 2-pass
矩阵 3 : 76,310,528 bytes 43.2638 46.3184 dB <- CQ=3.xx
矩阵 4 : 76,306,432 bytes 43.7644 46.4469 dB
矩阵 4 是最高的吗?
当然不是,还可以有更高的
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
不过比起 PSNR,我比较注意视觉的效果,不同 QM 会有不同视觉效果,有的会特别锐利,线条的锯齿特别清楚;有的会特别清晰,轮廓会特别清楚;有的会很柔和,看起来有点模糊;有的细节超多,会让你感动 MPEG-4 也有接近 MPEG-2 的高画质
screen.width-500)this.style.width=screen.width-500;" onclick="javascript:window.open(this.src);">
而不同矩阵会对画面造成什么影响?请看下面