diff --git a/vp9/common/vp9_quant_common.c b/vp9/common/vp9_quant_common.c index 3332e58e6a7c7d9db661a77ba4d7cad0dee91b70..564a3eb0ce3d255389301a3b829f663d225d4289 100644 --- a/vp9/common/vp9_quant_common.c +++ b/vp9/common/vp9_quant_common.c @@ -47,6 +47,78 @@ static const int16_t dc_qlookup[QINDEX_RANGE] = { 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336, }; +#if CONFIG_VP9_HIGHBITDEPTH +static const int16_t dc_qlookup_10[QINDEX_RANGE] = { + 4, 9, 10, 13, 15, 17, 20, 22, + 25, 28, 31, 34, 37, 40, 43, 47, + 50, 53, 57, 60, 64, 68, 71, 75, + 78, 82, 86, 90, 93, 97, 101, 105, + 109, 113, 116, 120, 124, 128, 132, 136, + 140, 143, 147, 151, 155, 159, 163, 166, + 170, 174, 178, 182, 185, 189, 193, 197, + 200, 204, 208, 212, 215, 219, 223, 226, + 230, 233, 237, 241, 244, 248, 251, 255, + 259, 262, 266, 269, 273, 276, 280, 283, + 287, 290, 293, 297, 300, 304, 307, 310, + 314, 317, 321, 324, 327, 331, 334, 337, + 343, 350, 356, 362, 369, 375, 381, 387, + 394, 400, 406, 412, 418, 424, 430, 436, + 442, 448, 454, 460, 466, 472, 478, 484, + 490, 499, 507, 516, 525, 533, 542, 550, + 559, 567, 576, 584, 592, 601, 609, 617, + 625, 634, 644, 655, 666, 676, 687, 698, + 708, 718, 729, 739, 749, 759, 770, 782, + 795, 807, 819, 831, 844, 856, 868, 880, + 891, 906, 920, 933, 947, 961, 975, 988, + 1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105, + 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, + 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, + 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, + 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, + 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, + 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, + 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, + 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, + 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, + 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, +}; + +static const int16_t dc_qlookup_12[QINDEX_RANGE] = { + 4, 12, 18, 25, 33, 41, 50, 60, + 70, 80, 91, 103, 115, 127, 140, 153, + 166, 180, 194, 208, 222, 237, 251, 266, + 281, 296, 312, 327, 343, 358, 374, 390, + 405, 421, 437, 453, 469, 484, 500, 516, + 532, 548, 564, 580, 596, 611, 627, 643, + 659, 674, 690, 706, 721, 737, 752, 768, + 783, 798, 814, 829, 844, 859, 874, 889, + 904, 919, 934, 949, 964, 978, 993, 1008, + 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, + 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, + 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, + 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, + 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, + 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, + 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, + 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, + 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, + 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, + 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, + 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, + 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, + 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, + 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517, + 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, + 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, + 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, + 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788, + 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, + 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, + 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, + 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387, +}; +#endif + static const int16_t ac_qlookup[QINDEX_RANGE] = { 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, @@ -82,15 +154,116 @@ static const int16_t ac_qlookup[QINDEX_RANGE] = { 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, }; -int16_t vp9_dc_quant(int qindex, int delta) { +#if CONFIG_VP9_HIGHBITDEPTH +static const int16_t ac_qlookup_10[QINDEX_RANGE] = { + 4, 9, 11, 13, 16, 18, 21, 24, + 27, 30, 33, 37, 40, 44, 48, 51, + 55, 59, 63, 67, 71, 75, 79, 83, + 88, 92, 96, 100, 105, 109, 114, 118, + 122, 127, 131, 136, 140, 145, 149, 154, + 158, 163, 168, 172, 177, 181, 186, 190, + 195, 199, 204, 208, 213, 217, 222, 226, + 231, 235, 240, 244, 249, 253, 258, 262, + 267, 271, 275, 280, 284, 289, 293, 297, + 302, 306, 311, 315, 319, 324, 328, 332, + 337, 341, 345, 349, 354, 358, 362, 367, + 371, 375, 379, 384, 388, 392, 396, 401, + 409, 417, 425, 433, 441, 449, 458, 466, + 474, 482, 490, 498, 506, 514, 523, 531, + 539, 547, 555, 563, 571, 579, 588, 596, + 604, 616, 628, 640, 652, 664, 676, 688, + 700, 713, 725, 737, 749, 761, 773, 785, + 797, 809, 825, 841, 857, 873, 889, 905, + 922, 938, 954, 970, 986, 1002, 1018, 1038, + 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, + 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, + 1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, + 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, + 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, + 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, + 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, + 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, + 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, + 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, + 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, + 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, + 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, +}; + +static const int16_t ac_qlookup_12[QINDEX_RANGE] = { + 4, 13, 19, 27, 35, 44, 54, 64, + 75, 87, 99, 112, 126, 139, 154, 168, + 183, 199, 214, 230, 247, 263, 280, 297, + 314, 331, 349, 366, 384, 402, 420, 438, + 456, 475, 493, 511, 530, 548, 567, 586, + 604, 623, 642, 660, 679, 698, 716, 735, + 753, 772, 791, 809, 828, 846, 865, 884, + 902, 920, 939, 957, 976, 994, 1012, 1030, + 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, + 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, + 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, + 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, + 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, + 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, + 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, + 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, + 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, + 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, + 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, + 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, + 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, + 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, + 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, + 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, + 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, + 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, + 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, + 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, + 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, + 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, + 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, + 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247, +}; +#endif + +int16_t vp9_dc_quant(int qindex, int delta, vpx_bit_depth_t bit_depth) { +#if CONFIG_VP9_HIGHBITDEPTH + switch (bit_depth) { + case VPX_BITS_8: + return dc_qlookup[clamp(qindex + delta, 0, MAXQ)]; + case VPX_BITS_10: + return dc_qlookup_10[clamp(qindex + delta, 0, MAXQ)]; + case VPX_BITS_12: + return dc_qlookup_12[clamp(qindex + delta, 0, MAXQ)]; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1; + } +#else + (void) bit_depth; return dc_qlookup[clamp(qindex + delta, 0, MAXQ)]; +#endif } -int16_t vp9_ac_quant(int qindex, int delta) { +int16_t vp9_ac_quant(int qindex, int delta, vpx_bit_depth_t bit_depth) { +#if CONFIG_VP9_HIGHBITDEPTH + switch (bit_depth) { + case VPX_BITS_8: + return ac_qlookup[clamp(qindex + delta, 0, MAXQ)]; + case VPX_BITS_10: + return ac_qlookup_10[clamp(qindex + delta, 0, MAXQ)]; + case VPX_BITS_12: + return ac_qlookup_12[clamp(qindex + delta, 0, MAXQ)]; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1; + } +#else + (void) bit_depth; return ac_qlookup[clamp(qindex + delta, 0, MAXQ)]; +#endif } - int vp9_get_qindex(const struct segmentation *seg, int segment_id, int base_qindex) { if (vp9_segfeature_active(seg, segment_id, SEG_LVL_ALT_Q)) { diff --git a/vp9/common/vp9_quant_common.h b/vp9/common/vp9_quant_common.h index d1545d93c245a0a2d8424e6b98fff5ab41c236a5..b6266059de812345e0e6d523d1091bb8c4029574 100644 --- a/vp9/common/vp9_quant_common.h +++ b/vp9/common/vp9_quant_common.h @@ -11,6 +11,7 @@ #ifndef VP9_COMMON_VP9_QUANT_COMMON_H_ #define VP9_COMMON_VP9_QUANT_COMMON_H_ +#include "vpx/vpx_codec.h" #include "vp9/common/vp9_blockd.h" #ifdef __cplusplus @@ -22,8 +23,8 @@ extern "C" { #define QINDEX_RANGE (MAXQ - MINQ + 1) #define QINDEX_BITS 8 -int16_t vp9_dc_quant(int qindex, int delta); -int16_t vp9_ac_quant(int qindex, int delta); +int16_t vp9_dc_quant(int qindex, int delta, vpx_bit_depth_t bit_depth); +int16_t vp9_ac_quant(int qindex, int delta, vpx_bit_depth_t bit_depth); int vp9_get_qindex(const struct segmentation *seg, int segment_id, int base_qindex); diff --git a/vp9/common/vp9_rtcd_defs.pl b/vp9/common/vp9_rtcd_defs.pl index c695a5dc075bab75b73bfe65520497c1713f01b7..9733d475030babc741cd8886fd8137cbfd4f323e 100644 --- a/vp9/common/vp9_rtcd_defs.pl +++ b/vp9/common/vp9_rtcd_defs.pl @@ -445,61 +445,60 @@ if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") { specialize qw/vp9_iwht4x4_16_add/; } - # High bitdepth functions if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") { -# -# dct -# -add_proto qw/void vp9_high_idct4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct4x4_1_add/; + # + # dct + # + add_proto qw/void vp9_high_idct4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct4x4_1_add/; -add_proto qw/void vp9_high_idct4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct4x4_16_add/; + add_proto qw/void vp9_high_idct4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct4x4_16_add/; -add_proto qw/void vp9_high_idct8x8_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct8x8_1_add/; + add_proto qw/void vp9_high_idct8x8_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct8x8_1_add/; -add_proto qw/void vp9_high_idct8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct8x8_64_add/; + add_proto qw/void vp9_high_idct8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct8x8_64_add/; -add_proto qw/void vp9_high_idct8x8_10_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct8x8_10_add/; + add_proto qw/void vp9_high_idct8x8_10_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct8x8_10_add/; -add_proto qw/void vp9_high_idct16x16_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct16x16_1_add/; + add_proto qw/void vp9_high_idct16x16_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct16x16_1_add/; -add_proto qw/void vp9_high_idct16x16_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct16x16_256_add/; + add_proto qw/void vp9_high_idct16x16_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct16x16_256_add/; -add_proto qw/void vp9_high_idct16x16_10_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct16x16_10_add/; + add_proto qw/void vp9_high_idct16x16_10_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct16x16_10_add/; -add_proto qw/void vp9_high_idct32x32_1024_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct32x32_1024_add/; + add_proto qw/void vp9_high_idct32x32_1024_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct32x32_1024_add/; -add_proto qw/void vp9_high_idct32x32_34_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct32x32_34_add/; + add_proto qw/void vp9_high_idct32x32_34_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct32x32_34_add/; -add_proto qw/void vp9_high_idct32x32_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_idct32x32_1_add/; + add_proto qw/void vp9_high_idct32x32_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_idct32x32_1_add/; -add_proto qw/void vp9_high_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd"; -specialize qw/vp9_high_iht4x4_16_add/; + add_proto qw/void vp9_high_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd"; + specialize qw/vp9_high_iht4x4_16_add/; -add_proto qw/void vp9_high_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd"; -specialize qw/vp9_high_iht8x8_64_add/; + add_proto qw/void vp9_high_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd"; + specialize qw/vp9_high_iht8x8_64_add/; -add_proto qw/void vp9_high_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type, int bd"; -specialize qw/vp9_high_iht16x16_256_add/; + add_proto qw/void vp9_high_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type, int bd"; + specialize qw/vp9_high_iht16x16_256_add/; -# dct and add + # dct and add -add_proto qw/void vp9_high_iwht4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_iwht4x4_1_add/; + add_proto qw/void vp9_high_iwht4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_iwht4x4_1_add/; -add_proto qw/void vp9_high_iwht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; -specialize qw/vp9_high_iwht4x4_16_add/; + add_proto qw/void vp9_high_iwht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd"; + specialize qw/vp9_high_iwht4x4_16_add/; } # diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 7615cddda3d34f25d20be1a104df2feaff00c7bb..f99fa7a5806d1e41d4339c8d160af140f3494348 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -1366,11 +1366,11 @@ void vp9_init_dequantizer(VP9_COMMON *cm) { int q; for (q = 0; q < QINDEX_RANGE; q++) { - cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q); - cm->y_dequant[q][1] = vp9_ac_quant(q, 0); + cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth); + cm->y_dequant[q][1] = vp9_ac_quant(q, 0, cm->bit_depth); - cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q); - cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q); + cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth); + cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth); } } diff --git a/vp9/encoder/vp9_aq_complexity.c b/vp9/encoder/vp9_aq_complexity.c index 33f92393c94169bc7e8f841b5487aa904bc3639f..f7fca0cde0a1711ee3f486a4243b2c9d17d5d2d4 100644 --- a/vp9/encoder/vp9_aq_complexity.c +++ b/vp9/encoder/vp9_aq_complexity.c @@ -23,9 +23,9 @@ static const double aq_c_q_adj_factor[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = {{1.0, 1.0, 1.0}, {1.0, 0.25, 0.0}, {1.0, 0.5, 0.25}}; -static int get_aq_c_strength(int q_index) { +static int get_aq_c_strength(int q_index, vpx_bit_depth_t bit_depth) { // Approximate base quatizer (truncated to int) - int base_quant = vp9_ac_quant(q_index, 0) / 4; + const int base_quant = vp9_ac_quant(q_index, 0, bit_depth) / 4; return (base_quant > 20) + (base_quant > 45); } @@ -40,7 +40,7 @@ void vp9_setup_in_frame_q_adj(VP9_COMP *cpi) { cpi->refresh_alt_ref_frame || (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { int segment; - const int aq_strength = get_aq_c_strength(cm->base_qindex); + const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); const int active_segments = aq_c_active_segments[aq_strength]; // Clear down the segment map. @@ -70,7 +70,8 @@ void vp9_setup_in_frame_q_adj(VP9_COMP *cpi) { for (segment = 1; segment < active_segments; ++segment) { int qindex_delta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, - aq_c_q_adj_factor[aq_strength][segment]); + aq_c_q_adj_factor[aq_strength][segment], + cm->bit_depth); // For AQ complexity mode, we dont allow Q0 in a segment if the base // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment @@ -115,7 +116,7 @@ void vp9_select_in_frame_q_segment(VP9_COMP *cpi, // It is converted to bits * 256 units. const int target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / (bw * bh); - const int aq_strength = get_aq_c_strength(cm->base_qindex); + const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); const int active_segments = aq_c_active_segments[aq_strength]; // The number of segments considered and the transition points used to diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index e7f0daac3ae6081e322b1f8edf9752dd13242e56..514ff7a52ad202da03a93dcf67d0095799c36f15 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -200,7 +200,7 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { // Rate target ratio to set q delta. const float rate_ratio_qdelta = 2.0; - const double q = vp9_convert_qindex_to_q(cm->base_qindex); + const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); vp9_clear_system_state(); // Some of these parameters may be set via codec-control function later. cr->max_sbs_perframe = 10; @@ -242,7 +242,8 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { // Set the q delta for segment 1. qindex_delta = vp9_compute_qdelta_by_rate(rc, cm->frame_type, cm->base_qindex, - rate_ratio_qdelta); + rate_ratio_qdelta, + cm->bit_depth); // TODO(marpan): Incorporate the actual-vs-target rate over/undershoot from // previous encoded frame. if (-qindex_delta > cr->max_qdelta_perc * cm->base_qindex / 100) diff --git a/vp9/encoder/vp9_aq_variance.c b/vp9/encoder/vp9_aq_variance.c index 56db95eb78b65f1d357c6145787a4e5a7968184b..b96f00fd19cd15c2336c00149671cc0c7047b3ef 100644 --- a/vp9/encoder/vp9_aq_variance.c +++ b/vp9/encoder/vp9_aq_variance.c @@ -75,7 +75,7 @@ void vp9_vaq_init() { void vp9_vaq_frame_setup(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; struct segmentation *seg = &cm->seg; - const double base_q = vp9_convert_qindex_to_q(cm->base_qindex); + const double base_q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); const int base_rdmult = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q); int i; @@ -99,7 +99,8 @@ void vp9_vaq_frame_setup(VP9_COMP *cpi) { continue; } - qindex_delta = vp9_compute_qdelta(&cpi->rc, base_q, base_q * Q_RATIO(i)); + qindex_delta = vp9_compute_qdelta(&cpi->rc, base_q, base_q * Q_RATIO(i), + cm->bit_depth); vp9_set_segdata(seg, SEGMENT_ID(i), SEG_LVL_ALT_Q, qindex_delta); vp9_enable_segfeature(seg, SEGMENT_ID(i), SEG_LVL_ALT_Q); diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index e16b0b356c59f6a241db72fbb8997aee6120117c..9545ba0f3b02c297ffce58e048e3d49ee63687c6 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -330,7 +330,8 @@ static void configure_static_seg_features(VP9_COMP *cpi) { seg->update_map = 1; seg->update_data = 1; - qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875); + qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, + cm->bit_depth); vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2); vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); @@ -351,7 +352,8 @@ static void configure_static_seg_features(VP9_COMP *cpi) { seg->update_data = 1; seg->abs_delta = SEGMENT_DELTADATA; - qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125); + qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, + cm->bit_depth); vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2); vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 54b57cf88abe6a2ba42e09d96bf4a397de60175a..df82be5eca3a36f6261c4b39ef72dd3d82b08e52 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -62,8 +62,8 @@ static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { *b = temp; } -static int gfboost_qadjust(int qindex) { - const double q = vp9_convert_qindex_to_q(qindex); +static int gfboost_qadjust(int qindex, vpx_bit_depth_t bit_depth) { + const double q = vp9_convert_qindex_to_q(qindex, bit_depth); return (int)((0.00000828 * q * q * q) + (-0.0055 * q * q) + (1.32 * q) + 79.3); @@ -360,11 +360,11 @@ static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) { } } -static int find_fp_qindex() { +static int find_fp_qindex(vpx_bit_depth_t bit_depth) { int i; for (i = 0; i < QINDEX_RANGE; ++i) - if (vp9_convert_qindex_to_q(i) >= 30.0) + if (vp9_convert_qindex_to_q(i, bit_depth) >= 30.0) break; if (i == QINDEX_RANGE) @@ -434,7 +434,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) { vp9_clear_system_state(); set_first_pass_params(cpi); - vp9_set_quantizer(cm, find_fp_qindex()); + vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth)); if (lc != NULL) { twopass = &lc->twopass; @@ -935,12 +935,13 @@ static double calc_correction_factor(double err_per_mb, double err_divisor, double pt_low, double pt_high, - int q) { + int q, + vpx_bit_depth_t bit_depth) { const double error_term = err_per_mb / err_divisor; // Adjustment based on actual quantizer to power term. - const double power_term = MIN(vp9_convert_qindex_to_q(q) * 0.0125 + pt_low, - pt_high); + const double power_term = + MIN(vp9_convert_qindex_to_q(q, bit_depth) * 0.0125 + pt_low, pt_high); // Calculate correction factor. if (power_term < 1.0) @@ -975,9 +976,11 @@ static int get_twopass_worst_quality(const VP9_COMP *cpi, const double factor = calc_correction_factor(err_per_mb, ERR_DIVISOR, is_svc_upper_layer ? SVC_FACTOR_PT_LOW : - FACTOR_PT_LOW, FACTOR_PT_HIGH, q); + FACTOR_PT_LOW, FACTOR_PT_HIGH, q, + cpi->common.bit_depth); const int bits_per_mb = vp9_rc_bits_per_mb(INTER_FRAME, q, - factor * speed_term); + factor * speed_term, + cpi->common.bit_depth); if (bits_per_mb <= target_norm_bits_per_mb) break; } @@ -1594,7 +1597,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // At high Q when there are few bits to spare we are better with a longer // interval to spread the cost of the GF. active_max_gf_interval = - 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5); + 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME], + cpi->common.bit_depth) >> 5); if (active_max_gf_interval > rc->max_gf_interval) active_max_gf_interval = rc->max_gf_interval; @@ -1736,7 +1740,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Calculate the extra bits to be used for boosted frame(s) { int q = rc->last_q[INTER_FRAME]; - int boost = (rc->gfu_boost * gfboost_qadjust(q)) / 100; + int boost = + (rc->gfu_boost * gfboost_qadjust(q, cpi->common.bit_depth)) / 100; // Set max and minimum boost and hence minimum allocation. boost = clamp(boost, 125, (rc->baseline_gf_interval + 1) * 200); @@ -2227,7 +2232,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { section_target_bandwidth); twopass->active_worst_quality = tmp_q; rc->ni_av_qi = tmp_q; - rc->avg_q = vp9_convert_qindex_to_q(tmp_q); + rc->avg_q = vp9_convert_qindex_to_q(tmp_q, cm->bit_depth); } vp9_zero(this_frame); if (EOF == input_stats(twopass, &this_frame)) diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index 5557d7fe7ecd0d23b5f2a8e1dbf34b5edc84f4a2..2fc05e7fe2041c202a49dbaace16a52c1cd98207 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -142,7 +142,7 @@ void vp9_pick_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, } else if (method >= LPF_PICK_FROM_Q) { const int min_filter_level = 0; const int max_filter_level = get_max_filter_level(cpi); - const int q = vp9_ac_quant(cm->base_qindex, 0); + const int q = vp9_ac_quant(cm->base_qindex, 0, cm->bit_depth); // These values were determined by linear fitting the result of the // searched level, filt_guess = q * 0.316206 + 3.87252 int filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index a97d77831dcba50b54fb92650f8f73be8aff2694..2edd52baee8ee21b684cffb98c22a280cbeac38a 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -440,7 +440,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, unsigned int sse_y = UINT_MAX; const int intra_cost_penalty = - 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); + 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth); const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv, intra_cost_penalty, 0); const int intra_mode_cost = 50; diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c index d49eb956f0df4723716289c9ca8d94ec102ebfd6..2f225d74e3c344fe34d54e35c18a54f3978466ec 100644 --- a/vp9/encoder/vp9_quantize.c +++ b/vp9/encoder/vp9_quantize.c @@ -40,6 +40,31 @@ void vp9_quantize_dc(const tran_low_t *coeff_ptr, int skip_block, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_dc(const tran_low_t *coeff_ptr, int skip_block, + const int16_t *round_ptr, const int16_t quant, + tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, + const int16_t dequant_ptr, uint16_t *eob_ptr) { + int eob = -1; + + if (!skip_block) { + const int rc = 0; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + + const int64_t tmp = + (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) * + quant) >> 16; + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr; + if (tmp) + eob = 0; + } + *eob_ptr = eob + 1; +} +#endif + void vp9_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block, const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, @@ -62,6 +87,31 @@ void vp9_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block, + const int16_t *round_ptr, const int16_t quant, + tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, + const int16_t dequant_ptr, uint16_t *eob_ptr) { + int eob = -1; + + if (!skip_block) { + const int rc = 0; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + + const int64_t tmp = + (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) * + quant) >> 15; + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2; + if (tmp) + eob = 0; + } + *eob_ptr = eob + 1; +} +#endif + void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, @@ -103,6 +153,51 @@ void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count, + int skip_block, const int16_t *zbin_ptr, + const int16_t *round_ptr, const int16_t *quant_ptr, + const int16_t *quant_shift_ptr, + tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, + const int16_t *dequant_ptr, + int zbin_oq_value, uint16_t *eob_ptr, + const int16_t *scan, const int16_t *iscan) { + int i; + int eob = -1; + // TODO(jingning) Decide the need of these arguments after the + // quantization process is completed. + (void)zbin_ptr; + (void)quant_shift_ptr; + (void)zbin_oq_value; + (void)iscan; + + vpx_memset(qcoeff_ptr, 0, count * sizeof(*qcoeff_ptr)); + vpx_memset(dqcoeff_ptr, 0, count * sizeof(*dqcoeff_ptr)); + + if (!skip_block) { + // Quantization pass: All coefficients with index >= zero_flag are + // skippable. Note: zero_flag can be zero. + for (i = 0; i < count; i++) { + const int rc = scan[i]; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + + const int64_t tmp = + (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) * + quant_ptr[rc != 0]) >> 16; + + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; + + if (tmp) + eob = i; + } + } + *eob_ptr = eob + 1; +} +#endif + // TODO(jingning) Refactor this file and combine functions with similar // operations. void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, @@ -146,6 +241,51 @@ void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, + intptr_t n_coeffs, int skip_block, + const int16_t *zbin_ptr, + const int16_t *round_ptr, + const int16_t *quant_ptr, + const int16_t *quant_shift_ptr, + tran_low_t *qcoeff_ptr, + tran_low_t *dqcoeff_ptr, + const int16_t *dequant_ptr, + int zbin_oq_value, uint16_t *eob_ptr, + const int16_t *scan, const int16_t *iscan) { + int i, eob = -1; + (void)zbin_ptr; + (void)quant_shift_ptr; + (void)zbin_oq_value; + (void)iscan; + + vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); + vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); + + if (!skip_block) { + for (i = 0; i < n_coeffs; i++) { + const int rc = scan[i]; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + int64_t tmp = 0; + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + + if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) { + tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1), + INT32_MIN, INT32_MAX); + tmp = (tmp * quant_ptr[rc != 0]) >> 15; + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; + } + + if (tmp) + eob = i; + } + } + *eob_ptr = eob + 1; +} +#endif + void vp9_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, @@ -199,6 +339,62 @@ void vp9_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, + int skip_block, const int16_t *zbin_ptr, + const int16_t *round_ptr, const int16_t *quant_ptr, + const int16_t *quant_shift_ptr, + tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, + const int16_t *dequant_ptr, int zbin_oq_value, + uint16_t *eob_ptr, const int16_t *scan, + const int16_t *iscan) { + int i, non_zero_count = (int)n_coeffs, eob = -1; + const int zbins[2] = { zbin_ptr[0] + zbin_oq_value, + zbin_ptr[1] + zbin_oq_value }; + const int nzbins[2] = { zbins[0] * -1, + zbins[1] * -1 }; + (void)iscan; + + vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); + vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); + + if (!skip_block) { + // Pre-scan pass + for (i = (int)n_coeffs - 1; i >= 0; i--) { + const int rc = scan[i]; + const int coeff = coeff_ptr[rc]; + + if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) + non_zero_count--; + else + break; + } + + // Quantization pass: All coefficients with index >= zero_flag are + // skippable. Note: zero_flag can be zero. + for (i = 0; i < non_zero_count; i++) { + const int rc = scan[i]; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + + if (abs_coeff >= zbins[rc != 0]) { + int64_t tmp = clamp(abs_coeff + round_ptr[rc != 0], + INT32_MIN, INT32_MAX); + tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * + quant_shift_ptr[rc != 0]) >> 16; // quantization + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; + + if (tmp) + eob = i; + } + } + } + *eob_ptr = eob + 1; +} +#endif + void vp9_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, @@ -255,12 +451,84 @@ void vp9_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, *eob_ptr = eob + 1; } +#if CONFIG_VP9_HIGHBITDEPTH +void vp9_high_quantize_b_32x32_c(const tran_low_t *coeff_ptr, + intptr_t n_coeffs, int skip_block, + const int16_t *zbin_ptr, + const int16_t *round_ptr, + const int16_t *quant_ptr, + const int16_t *quant_shift_ptr, + tran_low_t *qcoeff_ptr, + tran_low_t *dqcoeff_ptr, + const int16_t *dequant_ptr, + int zbin_oq_value, uint16_t *eob_ptr, + const int16_t *scan, const int16_t *iscan) { + const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value, 1), + ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value, 1) }; + const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 }; + + int idx = 0; + int idx_arr[1024]; + int i, eob = -1; + (void)iscan; + + vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); + vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); + + if (!skip_block) { + // Pre-scan pass + for (i = 0; i < n_coeffs; i++) { + const int rc = scan[i]; + const int coeff = coeff_ptr[rc]; + + // If the coefficient is out of the base ZBIN range, keep it for + // quantization. + if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) + idx_arr[idx++] = i; + } + + // Quantization pass: only process the coefficients selected in + // pre-scan pass. Note: idx can be zero. + for (i = 0; i < idx; i++) { + const int rc = scan[idx_arr[i]]; + const int coeff = coeff_ptr[rc]; + const int coeff_sign = (coeff >> 31); + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; + int64_t tmp = clamp(abs_coeff + + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1), + INT32_MIN, INT32_MAX); + tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * + quant_shift_ptr[rc != 0]) >> 15; + + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; + + if (tmp) + eob = idx_arr[i]; + } + } + *eob_ptr = eob + 1; +} +#endif + void vp9_regular_quantize_b_4x4(MACROBLOCK *x, int plane, int block, const int16_t *scan, const int16_t *iscan) { MACROBLOCKD *const xd = &x->e_mbd; struct macroblock_plane *p = &x->plane[plane]; struct macroblockd_plane *pd = &xd->plane[plane]; +#if CONFIG_VP9_HIGHBITDEPTH + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { + vp9_high_quantize_b(BLOCK_OFFSET(p->coeff, block), + 16, x->skip_block, + p->zbin, p->round, p->quant, p->quant_shift, + BLOCK_OFFSET(p->qcoeff, block), + BLOCK_OFFSET(pd->dqcoeff, block), + pd->dequant, p->zbin_extra, &p->eobs[block], + scan, iscan); + return; + } +#endif vp9_quantize_b(BLOCK_OFFSET(p->coeff, block), 16, x->skip_block, p->zbin, p->round, p->quant, p->quant_shift, @@ -281,9 +549,23 @@ static void invert_quant(int16_t *quant, int16_t *shift, int d) { } static int get_qzbin_factor(int q, vpx_bit_depth_t bit_depth) { - int quant = vp9_dc_quant(q, 0); + const int quant = vp9_dc_quant(q, 0, bit_depth); +#if CONFIG_VP9_HIGHBITDEPTH + switch (bit_depth) { + case VPX_BITS_8: + return q == 0 ? 64 : (quant < 148 ? 84 : 80); + case VPX_BITS_10: + return q == 0 ? 64 : (quant < 592 ? 84 : 80); + case VPX_BITS_12: + return q == 0 ? 64 : (quant < 2368 ? 84 : 80); + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1; + } +#else (void) bit_depth; return q == 0 ? 64 : (quant < 148 ? 84 : 80); +#endif } void vp9_init_quantizer(VP9_COMP *cpi) { @@ -301,8 +583,8 @@ void vp9_init_quantizer(VP9_COMP *cpi) { qrounding_factor_fp = 64; // y - quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q) - : vp9_ac_quant(q, 0); + quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth) + : vp9_ac_quant(q, 0, cm->bit_depth); invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant); quants->y_quant_fp[q][i] = (1 << 16) / quant; quants->y_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7; @@ -311,8 +593,8 @@ void vp9_init_quantizer(VP9_COMP *cpi) { cm->y_dequant[q][i] = quant; // uv - quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q) - : vp9_ac_quant(q, cm->uv_ac_delta_q); + quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth) + : vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth); invert_quant(&quants->uv_quant[q][i], &quants->uv_quant_shift[q][i], quant); quants->uv_quant_fp[q][i] = (1 << 16) / quant; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index b607c8559eb5933198697ea86539ff7a668200e2..94c0b64dd882f174dc398a57d8f1bd8823a6fa95 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -42,13 +42,56 @@ #define FRAME_OVERHEAD_BITS 200 +#if CONFIG_VP9_HIGHBITDEPTH +#define ASSIGN_MINQ_TABLE(bit_depth, name) \ + do { \ + switch (bit_depth) { \ + case VPX_BITS_8: \ + name = name##_8; \ + break; \ + case VPX_BITS_10: \ + name = name##_10; \ + break; \ + case VPX_BITS_12: \ + name = name##_12; \ + break; \ + default: \ + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10" \ + " or VPX_BITS_12"); \ + name = NULL; \ + } \ + } while (0) +#else +#define ASSIGN_MINQ_TABLE(bit_depth, name) \ + do { \ + (void) bit_depth; \ + name = name##_8; \ + } while (0) +#endif + // Tables relating active max Q to active min Q -static int kf_low_motion_minq[QINDEX_RANGE]; -static int kf_high_motion_minq[QINDEX_RANGE]; -static int arfgf_low_motion_minq[QINDEX_RANGE]; -static int arfgf_high_motion_minq[QINDEX_RANGE]; -static int inter_minq[QINDEX_RANGE]; -static int rtc_minq[QINDEX_RANGE]; +static int kf_low_motion_minq_8[QINDEX_RANGE]; +static int kf_high_motion_minq_8[QINDEX_RANGE]; +static int arfgf_low_motion_minq_8[QINDEX_RANGE]; +static int arfgf_high_motion_minq_8[QINDEX_RANGE]; +static int inter_minq_8[QINDEX_RANGE]; +static int rtc_minq_8[QINDEX_RANGE]; + +#if CONFIG_VP9_HIGHBITDEPTH +static int kf_low_motion_minq_10[QINDEX_RANGE]; +static int kf_high_motion_minq_10[QINDEX_RANGE]; +static int arfgf_low_motion_minq_10[QINDEX_RANGE]; +static int arfgf_high_motion_minq_10[QINDEX_RANGE]; +static int inter_minq_10[QINDEX_RANGE]; +static int rtc_minq_10[QINDEX_RANGE]; +static int kf_low_motion_minq_12[QINDEX_RANGE]; +static int kf_high_motion_minq_12[QINDEX_RANGE]; +static int arfgf_low_motion_minq_12[QINDEX_RANGE]; +static int arfgf_high_motion_minq_12[QINDEX_RANGE]; +static int inter_minq_12[QINDEX_RANGE]; +static int rtc_minq_12[QINDEX_RANGE]; +#endif + static int gf_high = 2000; static int gf_low = 400; static int kf_high = 5000; @@ -58,7 +101,8 @@ static int kf_low = 400; // formulaic approach to facilitate easier adjustment of the Q tables. // The formulae were derived from computing a 3rd order polynomial best // fit to the original data (after plotting real maxq vs minq (not q index)) -static int get_minq_index(double maxq, double x3, double x2, double x1) { +static int get_minq_index(double maxq, double x3, double x2, double x1, + vpx_bit_depth_t bit_depth) { int i; const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq, maxq); @@ -68,38 +112,69 @@ static int get_minq_index(double maxq, double x3, double x2, double x1) { if (minqtarget <= 2.0) return 0; - for (i = 0; i < QINDEX_RANGE; i++) - if (minqtarget <= vp9_convert_qindex_to_q(i)) + for (i = 0; i < QINDEX_RANGE; i++) { + if (minqtarget <= vp9_convert_qindex_to_q(i, bit_depth)) return i; + } return QINDEX_RANGE - 1; } -void vp9_rc_init_minq_luts() { +static void init_minq_luts(int *kf_low_m, int *kf_high_m, + int *arfgf_low, int *arfgf_high, + int *inter, int *rtc, vpx_bit_depth_t bit_depth) { int i; - for (i = 0; i < QINDEX_RANGE; i++) { - const double maxq = vp9_convert_qindex_to_q(i); - kf_low_motion_minq[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.125); - kf_high_motion_minq[i] = get_minq_index(maxq, 0.000002, -0.0012, 0.50); - arfgf_low_motion_minq[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30); - arfgf_high_motion_minq[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.50); - inter_minq[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.90); - rtc_minq[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70); + const double maxq = vp9_convert_qindex_to_q(i, bit_depth); + kf_low_m[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.125, bit_depth); + kf_high_m[i] = get_minq_index(maxq, 0.000002, -0.0012, 0.50, bit_depth); + arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth); + arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.50, bit_depth); + inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.90, bit_depth); + rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth); } } +void vp9_rc_init_minq_luts() { + init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8, + arfgf_low_motion_minq_8, arfgf_high_motion_minq_8, + inter_minq_8, rtc_minq_8, VPX_BITS_8); +#if CONFIG_VP9_HIGHBITDEPTH + init_minq_luts(kf_low_motion_minq_10, kf_high_motion_minq_10, + arfgf_low_motion_minq_10, arfgf_high_motion_minq_10, + inter_minq_10, rtc_minq_10, VPX_BITS_10); + init_minq_luts(kf_low_motion_minq_12, kf_high_motion_minq_12, + arfgf_low_motion_minq_12, arfgf_high_motion_minq_12, + inter_minq_12, rtc_minq_12, VPX_BITS_12); +#endif +} + // These functions use formulaic calculations to make playing with the // quantizer tables easier. If necessary they can be replaced by lookup // tables if and when things settle down in the experimental bitstream -double vp9_convert_qindex_to_q(int qindex) { +double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth) { // Convert the index to a real Q value (scaled down to match old Q values) - return vp9_ac_quant(qindex, 0) / 4.0; +#if CONFIG_VP9_HIGHBITDEPTH + switch (bit_depth) { + case VPX_BITS_8: + return vp9_ac_quant(qindex, 0, bit_depth) / 4.0; + case VPX_BITS_10: + return vp9_ac_quant(qindex, 0, bit_depth) / 16.0; + case VPX_BITS_12: + return vp9_ac_quant(qindex, 0, bit_depth) / 64.0; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1.0; + } +#else + return vp9_ac_quant(qindex, 0, bit_depth) / 4.0; +#endif } int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, - double correction_factor) { - const double q = vp9_convert_qindex_to_q(qindex); + double correction_factor, + vpx_bit_depth_t bit_depth) { + const double q = vp9_convert_qindex_to_q(qindex, bit_depth); int enumerator = frame_type == KEY_FRAME ? 3300000 : 2250000; // q based adjustment to baseline enumerator @@ -108,8 +183,10 @@ int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, } static int estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs, - double correction_factor) { - const int bpm = (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor)); + double correction_factor, + vpx_bit_depth_t bit_depth) { + const int bpm = (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor, + bit_depth)); return ((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS; } @@ -227,7 +304,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { rc->ni_frames = 0; rc->tot_q = 0.0; - rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q); + rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q, oxcf->bit_depth); for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { rc->rate_correction_factors[i] = 1.0; @@ -330,7 +407,8 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { // Stay in double to avoid int overflow when values are large projected_size_based_on_q = estimate_bits_at_q(cm->frame_type, cm->base_qindex, cm->MBs, - rate_correction_factor); + rate_correction_factor, + cm->bit_depth); // Work out a size correction factor. if (projected_size_based_on_q > 0) correction_factor = (100 * cpi->rc.projected_frame_size) / @@ -392,7 +470,8 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, do { const int bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(cm->frame_type, i, - correction_factor); + correction_factor, + cm->bit_depth); if (bits_per_mb_at_this_q <= target_bits_per_mb) { if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error) @@ -424,12 +503,22 @@ static int get_active_quality(int q, int gfu_boost, int low, int high, } } -static int get_kf_active_quality(const RATE_CONTROL *const rc, int q) { +static int get_kf_active_quality(const RATE_CONTROL *const rc, int q, + vpx_bit_depth_t bit_depth) { + int *kf_low_motion_minq; + int *kf_high_motion_minq; + ASSIGN_MINQ_TABLE(bit_depth, kf_low_motion_minq); + ASSIGN_MINQ_TABLE(bit_depth, kf_high_motion_minq); return get_active_quality(q, rc->kf_boost, kf_low, kf_high, kf_low_motion_minq, kf_high_motion_minq); } -static int get_gf_active_quality(const RATE_CONTROL *const rc, int q) { +static int get_gf_active_quality(const RATE_CONTROL *const rc, int q, + vpx_bit_depth_t bit_depth) { + int *arfgf_low_motion_minq; + int *arfgf_high_motion_minq; + ASSIGN_MINQ_TABLE(bit_depth, arfgf_low_motion_minq); + ASSIGN_MINQ_TABLE(bit_depth, arfgf_high_motion_minq); return get_active_quality(q, rc->gfu_boost, gf_low, gf_high, arfgf_low_motion_minq, arfgf_high_motion_minq); } @@ -516,6 +605,8 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, int active_best_quality; int active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi); int q; + int *rtc_minq; + ASSIGN_MINQ_TABLE(cm->bit_depth, rtc_minq); if (frame_is_intra_only(cm)) { active_best_quality = rc->best_quality; @@ -524,9 +615,10 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, // based on the ambient Q to reduce the risk of popping. if (rc->this_key_frame_forced) { int qindex = rc->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex); + double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, - (last_boosted_q * 0.75)); + (last_boosted_q * 0.75), + cm->bit_depth); active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); } else if (cm->current_video_frame > 0) { // not first frame of one pass and kf_boost is set @@ -534,7 +626,8 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, double q_val; active_best_quality = - get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME]); + get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME], + cm->bit_depth); // Allow somewhat lower kf minq with small image formats. if ((cm->width * cm->height) <= (352 * 288)) { @@ -543,9 +636,10 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, // Convert the adjustment factor to a qindex delta // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality); + q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); active_best_quality += vp9_compute_qdelta(rc, q_val, - q_val * q_adj_factor); + q_val * q_adj_factor, + cm->bit_depth); } } else if (!rc->is_src_frame_alt_ref && !cpi->use_svc && @@ -559,7 +653,7 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, } else { q = active_worst_quality; } - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } else { // Use the lower of active_worst_quality and recent/average Q. if (cm->current_video_frame > 1) { @@ -592,7 +686,8 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, int qdelta = 0; vp9_clear_system_state(); qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, - active_worst_quality, 2.0); + active_worst_quality, 2.0, + cm->bit_depth); *top_index = active_worst_quality + qdelta; *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; } @@ -644,6 +739,8 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, int active_best_quality; int active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi); int q; + int *inter_minq; + ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); if (frame_is_intra_only(cm)) { @@ -652,9 +749,10 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, // based on the ambient Q to reduce the risk of popping. if (rc->this_key_frame_forced) { int qindex = rc->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex); + double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 0.75); + last_boosted_q * 0.75, + cm->bit_depth); active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); } else { // not first frame of one pass and kf_boost is set @@ -662,7 +760,8 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, double q_val; active_best_quality = - get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME]); + get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME], + cm->bit_depth); // Allow somewhat lower kf minq with small image formats. if ((cm->width * cm->height) <= (352 * 288)) { @@ -671,9 +770,10 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, // Convert the adjustment factor to a qindex delta // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality); + q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); active_best_quality += vp9_compute_qdelta(rc, q_val, - q_val * q_adj_factor); + q_val * q_adj_factor, + cm->bit_depth); } } else if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { @@ -691,7 +791,7 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, if (q < cq_level) q = cq_level; - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); // Constrained quality use slightly lower active best. active_best_quality = active_best_quality * 15 / 16; @@ -700,10 +800,10 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, if (!cpi->refresh_alt_ref_frame) { active_best_quality = cq_level; } else { - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { if (oxcf->rc_mode == VPX_Q) { @@ -742,11 +842,13 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, !rc->this_key_frame_forced && !(cm->current_video_frame == 0)) { qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, - active_worst_quality, 2.0); + active_worst_quality, 2.0, + cm->bit_depth); } else if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, - active_worst_quality, 1.75); + active_worst_quality, 1.75, + cm->bit_depth); } *top_index = active_worst_quality + qdelta; *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; @@ -788,6 +890,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int active_best_quality; int active_worst_quality = cpi->twopass.active_worst_quality; int q; + int *inter_minq; + ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) { // Handle the special case for key frames forced when we have75 reached @@ -795,16 +899,18 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, // based on the ambient Q to reduce the risk of popping. if (rc->this_key_frame_forced) { int qindex = rc->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex); + double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 0.75); + last_boosted_q * 0.75, + cm->bit_depth); active_best_quality = MAX(qindex + delta_qindex, rc->best_quality); } else { // Not forced keyframe. double q_adj_factor = 1.0; double q_val; // Baseline value derived from cpi->active_worst_quality and kf boost. - active_best_quality = get_kf_active_quality(rc, active_worst_quality); + active_best_quality = get_kf_active_quality(rc, active_worst_quality, + cm->bit_depth); // Allow somewhat lower kf minq with small image formats. if ((cm->width * cm->height) <= (352 * 288)) { @@ -816,9 +922,10 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, // Convert the adjustment factor to a qindex delta // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality); + q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); active_best_quality += vp9_compute_qdelta(rc, q_val, - q_val * q_adj_factor); + q_val * q_adj_factor, + cm->bit_depth); } } else if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { @@ -836,7 +943,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, if (q < cq_level) q = cq_level; - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); // Constrained quality use slightly lower active best. active_best_quality = active_best_quality * 15 / 16; @@ -845,10 +952,10 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, if (!cpi->refresh_alt_ref_frame) { active_best_quality = cq_level; } else { - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { - active_best_quality = get_gf_active_quality(rc, q); + active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { if (oxcf->rc_mode == VPX_Q) { @@ -888,7 +995,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, const double rate_factor = rate_factor_deltas[gf_group->rf_level[gf_group->index]]; int qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, - active_worst_quality, rate_factor); + active_worst_quality, rate_factor, + cm->bit_depth); *top_index = active_worst_quality + qdelta; *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; } @@ -1038,7 +1146,7 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { rc->avg_frame_qindex[INTER_FRAME] = ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2); rc->ni_frames++; - rc->tot_q += vp9_convert_qindex_to_q(qindex); + rc->tot_q += vp9_convert_qindex_to_q(qindex, cm->bit_depth); rc->avg_q = rc->tot_q / rc->ni_frames; // Calculate the average Q for normal inter frames (not key or GFU // frames). @@ -1294,7 +1402,8 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { rc->baseline_gf_interval = INT_MAX; } -int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget) { +int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget, + vpx_bit_depth_t bit_depth) { int start_index = rc->worst_quality; int target_index = rc->worst_quality; int i; @@ -1302,14 +1411,14 @@ int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget) { // Convert the average q value to an index. for (i = rc->best_quality; i < rc->worst_quality; ++i) { start_index = i; - if (vp9_convert_qindex_to_q(i) >= qstart) + if (vp9_convert_qindex_to_q(i, bit_depth) >= qstart) break; } // Convert the q target to an index for (i = rc->best_quality; i < rc->worst_quality; ++i) { target_index = i; - if (vp9_convert_qindex_to_q(i) >= qtarget) + if (vp9_convert_qindex_to_q(i, bit_depth) >= qtarget) break; } @@ -1317,12 +1426,14 @@ int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget) { } int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, - int qindex, double rate_target_ratio) { + int qindex, double rate_target_ratio, + vpx_bit_depth_t bit_depth) { int target_index = rc->worst_quality; int i; // Look up the current projected bits per block for the base index - const int base_bits_per_mb = vp9_rc_bits_per_mb(frame_type, qindex, 1.0); + const int base_bits_per_mb = vp9_rc_bits_per_mb(frame_type, qindex, 1.0, + bit_depth); // Find the target bits per mb based on the base value and given ratio. const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb); @@ -1330,7 +1441,7 @@ int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, // Convert the q target to an index for (i = rc->best_quality; i < rc->worst_quality; ++i) { target_index = i; - if (vp9_rc_bits_per_mb(frame_type, i, 1.0) <= target_bits_per_mb ) + if (vp9_rc_bits_per_mb(frame_type, i, 1.0, bit_depth) <= target_bits_per_mb) break; } diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index 456daf48d032bc569bee95ae9c9150938ffd6daf..2ced8e6dd355c825268f687126b4b39573659857 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -12,6 +12,7 @@ #ifndef VP9_ENCODER_VP9_RATECTRL_H_ #define VP9_ENCODER_VP9_RATECTRL_H_ +#include "vpx/vpx_codec.h" #include "vpx/vpx_integer.h" #include "vp9/common/vp9_blockd.h" @@ -104,7 +105,7 @@ struct VP9EncoderConfig; void vp9_rc_init(const struct VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc); -double vp9_convert_qindex_to_q(int qindex); +double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth); void vp9_rc_init_minq_luts(); @@ -167,7 +168,7 @@ int vp9_rc_regulate_q(const struct VP9_COMP *cpi, int target_bits_per_frame, // Estimates bits per mb for a given qindex and correction factor. int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, - double correction_factor); + double correction_factor, vpx_bit_depth_t bit_depth); // Clamping utilities for bitrate targets for iframes and pframes. int vp9_rc_clamp_iframe_target_size(const struct VP9_COMP *const cpi, @@ -180,12 +181,14 @@ void vp9_rc_set_frame_target(struct VP9_COMP *cpi, int target); // Computes a q delta (in "q index" terms) to get from a starting q value // to a target q value -int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget); +int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget, + vpx_bit_depth_t bit_depth); // Computes a q delta (in "q index" terms) to get from a starting q value // to a value that should equate to the given rate ratio. int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, - int qindex, double rate_target_ratio); + int qindex, double rate_target_ratio, + vpx_bit_depth_t bit_depth); void vp9_rc_update_framerate(struct VP9_COMP *cpi); diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c index 1dd44b4aafdc04c8bcf271c96cecb88370d71839..8b7066b13357b55ceb44a256703ea3a03aec06ae 100644 --- a/vp9/encoder/vp9_rd.c +++ b/vp9/encoder/vp9_rd.c @@ -93,34 +93,69 @@ static void fill_token_costs(vp9_coeff_cost *c, } // Values are now correlated to quantizer. -static int sad_per_bit16lut[QINDEX_RANGE]; -static int sad_per_bit4lut[QINDEX_RANGE]; - -void vp9_init_me_luts() { +static int sad_per_bit16lut_8[QINDEX_RANGE]; +static int sad_per_bit4lut_8[QINDEX_RANGE]; + +#if CONFIG_VP9_HIGHBITDEPTH +static int sad_per_bit16lut_10[QINDEX_RANGE]; +static int sad_per_bit4lut_10[QINDEX_RANGE]; +static int sad_per_bit16lut_12[QINDEX_RANGE]; +static int sad_per_bit4lut_12[QINDEX_RANGE]; +#endif + +static void init_me_luts_bd(int *bit16lut, int *bit4lut, int range, + vpx_bit_depth_t bit_depth) { int i; - // Initialize the sad lut tables using a formulaic calculation for now. // This is to make it easier to resolve the impact of experimental changes // to the quantizer tables. - for (i = 0; i < QINDEX_RANGE; ++i) { - const double q = vp9_convert_qindex_to_q(i); - sad_per_bit16lut[i] = (int)(0.0418 * q + 2.4107); - sad_per_bit4lut[i] = (int)(0.063 * q + 2.742); + for (i = 0; i < range; i++) { + const double q = vp9_convert_qindex_to_q(i, bit_depth); + bit16lut[i] = (int)(0.0418 * q + 2.4107); + bit4lut[i] = (int)(0.063 * q + 2.742); } } +void vp9_init_me_luts() { + init_me_luts_bd(sad_per_bit16lut_8, sad_per_bit4lut_8, QINDEX_RANGE, + VPX_BITS_8); +#if CONFIG_VP9_HIGHBITDEPTH + init_me_luts_bd(sad_per_bit16lut_10, sad_per_bit4lut_10, QINDEX_RANGE, + VPX_BITS_10); + init_me_luts_bd(sad_per_bit16lut_12, sad_per_bit4lut_12, QINDEX_RANGE, + VPX_BITS_12); +#endif +} + static const int rd_boost_factor[16] = { 64, 32, 32, 32, 24, 16, 12, 12, 8, 8, 4, 4, 2, 2, 1, 0 }; static const int rd_frame_type_factor[FRAME_UPDATE_TYPES] = { -128, 144, 128, 128, 144 + 128, 144, 128, 128, 144 }; int vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) { - const int q = vp9_dc_quant(qindex, 0); + const int q = vp9_dc_quant(qindex, 0, cpi->common.bit_depth); +#if CONFIG_VP9_HIGHBITDEPTH + int rdmult = 0; + switch (cpi->common.bit_depth) { + case VPX_BITS_8: + rdmult = 88 * q * q / 24; + break; + case VPX_BITS_10: + rdmult = ROUND_POWER_OF_TWO(88 * q * q / 24, 4); + break; + case VPX_BITS_12: + rdmult = ROUND_POWER_OF_TWO(88 * q * q / 24, 8); + break; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1; + } +#else int rdmult = 88 * q * q / 24; - +#endif if (cpi->oxcf.pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; const FRAME_UPDATE_TYPE frame_type = gf_group->update_type[gf_group->index]; @@ -132,15 +167,53 @@ int vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) { return rdmult; } -static int compute_rd_thresh_factor(int qindex) { +static int compute_rd_thresh_factor(int qindex, vpx_bit_depth_t bit_depth) { + double q; +#if CONFIG_VP9_HIGHBITDEPTH + switch (bit_depth) { + case VPX_BITS_8: + q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0; + break; + case VPX_BITS_10: + q = vp9_dc_quant(qindex, 0, VPX_BITS_10) / 16.0; + break; + case VPX_BITS_12: + q = vp9_dc_quant(qindex, 0, VPX_BITS_12) / 64.0; + break; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + return -1; + } +#else + (void) bit_depth; + q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0; +#endif // TODO(debargha): Adjust the function below. - const int q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12); - return MAX(q, 8); + return MAX((int)(pow(q, RD_THRESH_POW) * 5.12), 8); } void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) { - cpi->mb.sadperbit16 = sad_per_bit16lut[qindex]; - cpi->mb.sadperbit4 = sad_per_bit4lut[qindex]; +#if CONFIG_VP9_HIGHBITDEPTH + switch (cpi->common.bit_depth) { + case VPX_BITS_8: + cpi->mb.sadperbit16 = sad_per_bit16lut_8[qindex]; + cpi->mb.sadperbit4 = sad_per_bit4lut_8[qindex]; + break; + case VPX_BITS_10: + cpi->mb.sadperbit16 = sad_per_bit16lut_10[qindex]; + cpi->mb.sadperbit4 = sad_per_bit4lut_10[qindex]; + break; + case VPX_BITS_12: + cpi->mb.sadperbit16 = sad_per_bit16lut_12[qindex]; + cpi->mb.sadperbit4 = sad_per_bit4lut_12[qindex]; + break; + default: + assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); + } +#else + cpi->mb.sadperbit16 = sad_per_bit16lut_8[qindex]; + cpi->mb.sadperbit4 = sad_per_bit4lut_8[qindex]; +#endif } static void set_block_thresholds(const VP9_COMMON *cm, RD_OPT *rd) { @@ -149,9 +222,8 @@ static void set_block_thresholds(const VP9_COMMON *cm, RD_OPT *rd) { for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) { const int qindex = clamp(vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex) + - cm->y_dc_delta_q, - 0, MAXQ); - const int q = compute_rd_thresh_factor(qindex); + cm->y_dc_delta_q, 0, MAXQ); + const int q = compute_rd_thresh_factor(qindex, cm->bit_depth); for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) { // Threshold here seems unnecessarily harsh but fine given actual diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 7be557df9e566fee722c9512ae395db5200dce66..bf27ba68264af53b1efcdf2509b2f817ab4723ba 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2582,7 +2582,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int64_t dist_uv[TX_SIZES]; int skip_uv[TX_SIZES]; PREDICTION_MODE mode_uv[TX_SIZES]; - int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); + const int intra_cost_penalty = + 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth); int best_skip2 = 0; uint8_t ref_frame_skip_mask[2] = { 0 }; uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 }; @@ -3312,7 +3313,8 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int64_t dist_uv; int skip_uv; PREDICTION_MODE mode_uv = DC_PRED; - int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); + const int intra_cost_penalty = + 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth); int_mv seg_mvs[4][MAX_REF_FRAMES]; b_mode_info best_bmodes[4]; int best_skip2 = 0; diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index 51d6f766be798022b4c141e5eea2b04bd8f82b51..ff026666b3120f276a19a76e06d181e0eae63f56 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -389,10 +389,10 @@ static void adjust_arnr_filter(VP9_COMP *cpi, // Adjust the strength based on active max q. if (cpi->common.current_video_frame > 1) q = ((int)vp9_convert_qindex_to_q( - cpi->rc.avg_frame_qindex[INTER_FRAME])); + cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth)); else q = ((int)vp9_convert_qindex_to_q( - cpi->rc.avg_frame_qindex[KEY_FRAME])); + cpi->rc.avg_frame_qindex[KEY_FRAME], cpi->common.bit_depth)); if (q > 16) { strength = oxcf->arnr_strength; } else {