最近两周时间的课余时间我做了一些有关x265 v2.4版本的测试,主要是两个新参数”–limit-tu”和”–limit-sao”。
昨天挂机测试加百列的堕落,发现在相近的参数下v2.4成品的体积异常的大。于是我开始寻找与体积变化有关的参数。我首先关闭limit-tu关闭SAO,统一v2.3与2.4的其他几项参数(CRF/PSY等)进行了5000帧长度的测试。
测试结果是这种条件下,x265 v2.4的成品体积达到了v2.3的131%。由于有部分参数是保持默认值的,因此我又将成品的mediainfo进行对比,确认差异。首先我注意到的一点是v2.4的mediainfo参数中多了一项–no-ssim-rd,且其他参数基本与v2.3相同。查询Release Note后发现这项参数实际上出现于v2.3版本。按照这项参数的描述,这个开关是对码率有明显影响的,因此我就做了一个测试。让v2.4版本启用–ssim-rd,最后成品体积降低了大约30%。但是测试v2.3版本后发现默认参数下,–ssim-rd是禁用的,也就是说这里都是未启用–ssim-rd参数的成品,因此在这里两个版本体积的差异与这项参数无关。
再次查看Release Note后我注意到”Lambda tables for 8, 10, and 12-bit encoding revised, resulting in significant enhancement to subjective visual quality.”这条变化,根据以往经验来看,增强感官优化这类涉及码率分配策略的参数往往会影响体积,于是我查看了一下x265的代码仓库。看到了以下变化:
在Tag2.4到2.3之间有一些对Lambda tables的修改(例如10bit):
-// lambda2 = pow(lambda, 2) * scale (0.85); +// lambda2 = 0.038 * EXP(0.234 * QP) * 256; double x265_lambda2_tab[QP_MAX_MAX + 1] = { - 13.6000, 17.1349, 21.5887, 27.2000, 34.2699, - 43.1773, 54.4000, 68.5397, 86.3546, 108.8000, - 137.0794, 172.7092, 217.6000, 274.1588, 345.4185, - 435.2000, 548.3176, 690.8369, 870.4000, 1096.6353, - 1381.6739, 1740.8000, 2193.2706, 2763.3478, 3481.6000, - 4386.5411, 5526.6955, 6963.2000, 8773.0822, 11053.3910, - 13926.4000, 17546.1645, 22106.7819, 27852.8000, 35092.3291, - 44213.5641, 55705.6000, 70184.6579, 88427.1282, 111411.2000, - 140369.3159, 176854.2563, 222822.4000, 280738.6324, 353708.5127, - 445644.8001, 561477.2648, 707417.0237, 891289.6000, 1122954.5277, - 1414834.0484, 1782579.2003, 2245909.0566, 2829668.0981, 3565158.4000, - 4491818.1146, 5659336.1938, 7130316.8013, 8983636.2264, 11318672.3923, - 14260633.6000, 17967272.4585, 22637344.7751, 28521267.1953, 35934544.9165, - 45274689.5567, 57042534.4000, 71869089.8338, 90549379.1181, 114085068.8008 + 9.7280, 12.2880, 15.5136, 19.6096, 24.7808, + 31.3344, 39.6032, 50.0480, 63.2320, 79.8976, + 100.9664, 127.5904, 161.2544, 203.7504, 257.4848, + 325.3760, 411.1616, 519.5520, 656.5376, 829.6448, + 1048.3712, 1324.7744, 1674.0608, 2115.4048, 2673.1264, + 3377.8944, 4268.4416, 5393.7920, 6815.8464, 8612.8128, + 10883.5328, 13752.9344, 17378.8160, 21960.6528, 27750.4768, + 35066.7264, 44311.8848, 55994.4704, 70757.0944, 89411.8144, + 112984.7552, 142772.5824, 180413.7728, 227978.8800, 288084.2496, + 364036.0960, 460012.2112, 581291.8784, 734546.3040, 928205.3888, + 1172921.6256, 1482155.9552, 1872918.2208, 2366702.7968, 2990670.9504, + 3779144.8832, 4775495.6288, 6034528.7424, 7625499.0080, 9635919.8464, + 12176377.0368, 15386611.7888, 19443207.2448, 24569301.7344, 31046862.8224, + 39232197.1968, 49575549.9264, 62645870.6176, 79162109.3632, 100032763.4688 }; #elif X265_DEPTH == 10
可以发现这张表格的参数差距还是相当明显的。我决定先暂且忽视这张表格在x265中的实际意义,直接进行替换测试。首先我找来v2.4的源码,并且找到”./source/common/constants.cpp”中间有关这张lambda的参数,修改回2.3版本的参数,然后进行了编译。尽管编译一开始遇到了点小问题,不过最终还算顺利的编译出了一个特殊的版本:使用v2.3 lambda tables的x265 v2.4。编译我也使用了和www.msystem.waw.pl相同的msvc版本,同时开启所有asm优化。
最后跑了一下同样的5000帧测试,结果如下:
x265 2.3+1-7e225aefd389 | x265 2.4+9-dccf02340c75 | x265 2.4 Special ver | |
Size(KB) | 137128 | 180286 | 137094 |
rate | 100.00% | 131.47% | 99.98% |
可以看出,在更换了lambda tables后,成品体积几乎等于v2.3,也就是说这里体积异常增大的主要理由就是由于lambda tables造成的码率分配策略发生了变化。接下去就是针对成品实际效果的比较了。
我将v2.4编码成品也控制到2.3相同的体积后发现,相比之下v2.4更加注重平面纹理的保护,也就是说,在相同参数下,平面会分配更多码率。那么显而易见的,psy以及一些prefix就应该进行相应的调节。首先是crf,若保持相同体积,则需要提高0.5~1.0,psy则是psy-rd基本不变,psy-rdoq相比之前需要略微降低,同时对于纹理的补偿锐化程度应该适当降低一些。那么这样调节后,能够有一个相对来说不错的体积质量比。