summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2010-12-01 15:50:14 -0800
committerYaowu Xu <yaowu@google.com>2011-01-19 13:22:35 -0800
commit5b42ae09aeecedfdff1dae9d59be9fbb2aba3392 (patch)
tree7e6bb870fbb3130fc8a45c953d755cd0f42396e5
parentae4db164e5ece4ffdf8d2f460940244763e5052d (diff)
downloadlibvpx-5b42ae09aeecedfdff1dae9d59be9fbb2aba3392.tar
libvpx-5b42ae09aeecedfdff1dae9d59be9fbb2aba3392.tar.gz
libvpx-5b42ae09aeecedfdff1dae9d59be9fbb2aba3392.tar.bz2
libvpx-5b42ae09aeecedfdff1dae9d59be9fbb2aba3392.zip
experiment extending the quantizer range
Prior to this change, VP8 min quantizer is 4, which caps the highest quality around 51DB. This experimental change extends the min quantizer to 1, removes the cap and allows the highest quality to be around ~73DB, consistent with the fdct/idct round trip error. To test this change, at configure time use options: --enable-experimental --enable-extend_qrange The following is a brief log of changes in each of the patch sets patch set 1: In this commit, the quantization/dequantization constants are kept unchanged, instead scaling factor 4 is rolled into fdct/idct. Fixed Q0 encoding tests on mobile: Before: 9560.567kbps Overall PSNR:50.255DB VPXSSIM:98.288 Now: 18035.774kbps Overall PSNR:73.022DB VPXSSIM:99.991 patch set 2: regenerated dc/ac quantizer lookup tables based on the scaling factor rolled in the fdct/idct. Also slightly extended the range towards the high quantizer end. patch set 3: slightly tweaked the quantizer tables and generated bits_per_mb table based on Paul's suggestions. patch set 4: fix a typo in idct, re-calculated tables relating active max Q to active min Q patch set 5: added rdmult lookup table based on Q patch set 6: fix rdmult scale: dct coefficient has scaled up by 4 patch set 7: make transform coefficients to be within 16bits patch set 8: normalize 2nd order quantizers patch set 9: fix mis-spellings patch set 10: change the configure script and macros to allow experimental code to be enabled at configure time with --enable-extend_qrange patch set 11: rebase for merge Change-Id: Ib50641ddd44aba2a52ed890222c309faa31cc59c
-rwxr-xr-xconfigure1
-rw-r--r--vp8/common/generic/systemdependent.c10
-rw-r--r--vp8/common/idctllm.c33
-rw-r--r--vp8/common/quant_common.c45
-rw-r--r--vp8/decoder/generic/dsystemdependent.c9
-rw-r--r--vp8/encoder/dct.c28
-rw-r--r--vp8/encoder/encodeframe.c2
-rw-r--r--vp8/encoder/encodemb.c4
-rw-r--r--vp8/encoder/firstpass.c2
-rw-r--r--vp8/encoder/generic/csystemdependent.c8
-rw-r--r--vp8/encoder/onyx_if.c109
-rw-r--r--vp8/encoder/ratectrl.c49
-rw-r--r--vp8/encoder/rdopt.c79
13 files changed, 349 insertions, 30 deletions
diff --git a/configure b/configure
index 744bd4dad..b79aee4e3 100755
--- a/configure
+++ b/configure
@@ -214,6 +214,7 @@ HAVE_LIST="
sys_mman_h
"
EXPERIMENT_LIST="
+ extend_qrange
"
CONFIG_LIST="
external_build
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index b3eadaf27..6ba0cfb87 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -83,8 +83,18 @@ void vp8_machine_specific_config(VP8_COMMON *ctx)
vp8_arch_x86_common_init(ctx);
#endif
+
#if ARCH_ARM
vp8_arch_arm_common_init(ctx);
#endif
+#if CONFIG_EXTEND_QRANGE
+ rtcd->idct.idct1 = vp8_short_idct4x4llm_1_c;
+ rtcd->idct.idct16 = vp8_short_idct4x4llm_c;
+ rtcd->idct.idct1_scalar_add = vp8_dc_only_idct_add_c;
+ rtcd->idct.iwalsh1 = vp8_short_inv_walsh4x4_1_c;
+ rtcd->idct.iwalsh16 = vp8_short_inv_walsh4x4_c;
+
+#endif
+
}
diff --git a/vp8/common/idctllm.c b/vp8/common/idctllm.c
index 196062df6..c65d35adc 100644
--- a/vp8/common/idctllm.c
+++ b/vp8/common/idctllm.c
@@ -22,6 +22,8 @@
* so
* x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1).
**************************************************************************/
+#include "vpx_ports/config.h"
+
static const int cospi8sqrt2minus1 = 20091;
static const int sinpi8sqrt2 = 35468;
static const int rounding = 0;
@@ -75,11 +77,19 @@ void vp8_short_idct4x4llm_c(short *input, short *output, int pitch)
d1 = temp1 + temp2;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a1 + d1 + 4) >> 3;
op[3] = (a1 - d1 + 4) >> 3;
op[1] = (b1 + c1 + 4) >> 3;
op[2] = (b1 - c1 + 4) >> 3;
+#else
+ op[0] = (a1 + d1 + 16) >> 5;
+ op[3] = (a1 - d1 + 16) >> 5;
+
+ op[1] = (b1 + c1 + 16) >> 5;
+ op[2] = (b1 - c1 + 16) >> 5;
+#endif
ip += shortpitch;
op += shortpitch;
@@ -92,8 +102,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
int a1;
short *op = output;
int shortpitch = pitch >> 1;
+#if !CONFIG_EXTEND_QRANGE
a1 = ((input[0] + 4) >> 3);
-
+#else
+ a1 = ((input[0] + 16) >> 5);
+#endif
for (i = 0; i < 4; i++)
{
op[0] = a1;
@@ -106,7 +119,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
void vp8_dc_only_idct_add_c(short input_dc, unsigned char *pred_ptr, unsigned char *dst_ptr, int pitch, int stride)
{
+#if !CONFIG_EXTEND_QRANGE
int a1 = ((input_dc + 4) >> 3);
+#else
+ int a1 = ((input_dc + 16) >> 5);
+#endif
int r, c;
for (r = 0; r < 4; r++)
@@ -168,11 +185,17 @@ void vp8_short_inv_walsh4x4_c(short *input, short *output)
c2 = a1 - b1;
d2 = d1 - c1;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a2 + 3) >> 3;
op[1] = (b2 + 3) >> 3;
op[2] = (c2 + 3) >> 3;
op[3] = (d2 + 3) >> 3;
-
+#else
+ op[0] = (a2 + 1) >> 2;
+ op[1] = (b2 + 1) >> 2;
+ op[2] = (c2 + 1) >> 2;
+ op[3] = (d2 + 1) >> 2;
+#endif
ip += 4;
op += 4;
}
@@ -184,7 +207,11 @@ void vp8_short_inv_walsh4x4_1_c(short *input, short *output)
int a1;
short *op = output;
- a1 = ((input[0] + 3) >> 3);
+#if !CONFIG_EXTEND_QRANGE
+ a1 = (input[0] + 3 )>> 3;
+#else
+ a1 = (input[0] + 1 )>> 2;
+#endif
for (i = 0; i < 4; i++)
{
diff --git a/vp8/common/quant_common.c b/vp8/common/quant_common.c
index e9833fe33..b8e6e2972 100644
--- a/vp8/common/quant_common.c
+++ b/vp8/common/quant_common.c
@@ -11,6 +11,8 @@
#include "quant_common.h"
+
+#if !CONFIG_EXTEND_QRANGE
static const int dc_qlookup[QINDEX_RANGE] =
{
4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17,
@@ -34,7 +36,32 @@ static const int ac_qlookup[QINDEX_RANGE] =
155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209,
213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284,
};
+#else
+
+static const int dc_qlookup[QINDEX_RANGE] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, 40, 42,
+ 44, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88,
+ 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
+ 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 205, 210, 215, 220,
+ 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300,
+ 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460,
+ 472, 484, 496, 508, 520, 532, 544, 556, 572, 588, 608, 628, 648, 668, 692, 720,
+};
+static const int ac_qlookup[QINDEX_RANGE] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51,
+ 54, 57, 60, 63, 66, 69, 72, 76, 80, 84, 88, 92, 96, 100, 105, 110,
+ 115, 120, 125, 130, 135, 140, 146, 152, 158, 164, 170, 176, 182, 188, 194, 200,
+ 206, 212, 218, 224, 232, 240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320,
+ 330, 340, 350, 360, 370, 380, 392, 404, 416, 428, 440, 454, 468, 482, 496, 510,
+ 524, 540, 556, 572, 588, 604, 622, 640, 658, 676, 696, 716, 736, 756, 776, 796,
+ 820, 844, 868, 892, 916, 944, 972, 1000, 1032, 1064, 1096, 1128, 1168, 1208, 1252, 1300
+};
+#endif
int vp8_dc_quant(int QIndex, int Delta)
{
@@ -62,7 +89,11 @@ int vp8_dc2quant(int QIndex, int Delta)
else if (QIndex < 0)
QIndex = 0;
+#if !CONFIG_EXTEND_QRANGE
retval = dc_qlookup[ QIndex ] * 2;
+#else
+ retval = dc_qlookup[ QIndex ];
+#endif
return retval;
}
@@ -72,16 +103,13 @@ int vp8_dc_uv_quant(int QIndex, int Delta)
QIndex = QIndex + Delta;
- if (QIndex > 127)
- QIndex = 127;
+ if (QIndex > 117)
+ QIndex = 117;
else if (QIndex < 0)
QIndex = 0;
retval = dc_qlookup[ QIndex ];
- if (retval > 132)
- retval = 132;
-
return retval;
}
@@ -108,12 +136,13 @@ int vp8_ac2quant(int QIndex, int Delta)
QIndex = 127;
else if (QIndex < 0)
QIndex = 0;
-
+#if !CONFIG_EXTEND_QRANGE
retval = (ac_qlookup[ QIndex ] * 155) / 100;
-
if (retval < 8)
retval = 8;
-
+#else
+ retval = ac_qlookup[ QIndex ];
+#endif
return retval;
}
int vp8_ac_uv_quant(int QIndex, int Delta)
diff --git a/vp8/decoder/generic/dsystemdependent.c b/vp8/decoder/generic/dsystemdependent.c
index 2e284729b..ed7504bfc 100644
--- a/vp8/decoder/generic/dsystemdependent.c
+++ b/vp8/decoder/generic/dsystemdependent.c
@@ -39,7 +39,16 @@ void vp8_dmachine_specific_config(VP8D_COMP *pbi)
vp8_arch_x86_decode_init(pbi);
#endif
+
#if ARCH_ARM
vp8_arch_arm_decode_init(pbi);
#endif
+
+#if CONFIG_EXTEND_QRANGE
+ pbi->dequant.idct_add = vp8_dequant_idct_add_c;
+ pbi->dequant.dc_idct_add = vp8_dequant_dc_idct_add_c;
+ pbi->dequant.dc_idct_add_y_block = vp8_dequant_dc_idct_add_y_block_c;
+ pbi->dequant.idct_add_y_block = vp8_dequant_idct_add_y_block_c;
+ pbi->dequant.idct_add_uv_block = vp8_dequant_idct_add_uv_block_c;
+#endif
}
diff --git a/vp8/encoder/dct.c b/vp8/encoder/dct.c
index b5a11ae34..69a882c89 100644
--- a/vp8/encoder/dct.c
+++ b/vp8/encoder/dct.c
@@ -10,7 +10,7 @@
#include <math.h>
-
+#include "vpx_ports/config.h"
void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
{
int i;
@@ -20,11 +20,17 @@ void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if CONFIG_EXTEND_QRANGE
+ a1 = ((ip[0] + ip[3])<<5);
+ b1 = ((ip[1] + ip[2])<<5);
+ c1 = ((ip[1] - ip[2])<<5);
+ d1 = ((ip[0] - ip[3])<<5);
+#else
a1 = ((ip[0] + ip[3])<<3);
b1 = ((ip[1] + ip[2])<<3);
c1 = ((ip[1] - ip[2])<<3);
d1 = ((ip[0] - ip[3])<<3);
-
+#endif
op[0] = a1 + b1;
op[2] = a1 - b1;
@@ -72,12 +78,22 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if !CONFIG_EXTEND_QRANGE
a1 = ((ip[0] + ip[2])<<2);
d1 = ((ip[1] + ip[3])<<2);
c1 = ((ip[1] - ip[3])<<2);
b1 = ((ip[0] - ip[2])<<2);
op[0] = a1 + d1 + (a1!=0);
+#else
+ a1 = ((ip[0] + ip[2]));
+ d1 = ((ip[1] + ip[3]));
+ c1 = ((ip[1] - ip[3]));
+ b1 = ((ip[0] - ip[2]));
+
+
+ op[0] = a1 + d1;
+#endif
op[1] = b1 + c1;
op[2] = b1 - c1;
op[3] = a1 - d1;
@@ -105,11 +121,17 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
c2 += c2<0;
d2 += d2<0;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a2+3) >> 3;
op[4] = (b2+3) >> 3;
op[8] = (c2+3) >> 3;
op[12]= (d2+3) >> 3;
-
+#else
+ op[0] = (a2+1) >> 2;
+ op[4] = (b2+1) >> 2;
+ op[8] = (c2+1) >> 2;
+ op[12]= (d2+1) >> 2;
+#endif
ip++;
op++;
}
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 4c95f28d6..59ccb5530 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -709,7 +709,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
vp8_auto_select_speed(cpi);
}
- vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+ vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
vp8cx_initialize_me_consts(cpi, cm->base_qindex);
// Copy data over into macro block data sturctures.
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index efcea745b..aa2beacde 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -245,7 +245,11 @@ struct vp8_token_state{
// TODO: experiments to find optimal multiple numbers
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
+#if !CONFIG_EXTEND_QRANGE
#define Y2_RD_MULT 16
+#else
+#define Y2_RD_MULT 4
+#endif
static const int plane_rd_mult[4]=
{
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 32a39c5f2..a78048153 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -578,7 +578,7 @@ void vp8_first_pass(VP8_COMP *cpi)
//if ( 0 )
{
int flag[2] = {1, 1};
- vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+ vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q);
vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
}
diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c
index 4738a5b28..b6de95b8d 100644
--- a/vp8/encoder/generic/csystemdependent.c
+++ b/vp8/encoder/generic/csystemdependent.c
@@ -111,4 +111,12 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi)
vp8_arch_arm_encoder_init(cpi);
#endif
+#if CONFIG_EXTEND_QRANGE
+ cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.walsh_short4x4 = vp8_short_walsh4x4_c;
+#endif
+
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 77fbb29b1..e494b6635 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -151,7 +151,7 @@ extern const int qrounding_factors[129];
extern const int qzbin_factors[129];
extern void vp8cx_init_quantizer(VP8_COMP *cpi);
extern const int vp8cx_base_skip_false_prob[128];
-
+#if !CONFIG_EXTEND_QRANGE
// Tables relating active max Q to active min Q
static const int kf_low_motion_minq[QINDEX_RANGE] =
{
@@ -219,7 +219,76 @@ static const int inter_minq[QINDEX_RANGE] =
71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
};
+#else
+static const int kf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
+ 9, 9, 9, 10,10,11,11,12,12,13,13,14,14,15,15,16,
+ 16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24,
+ 25,25,26,27,28,29,30,30,31,32,33,34,35,35,36,36,
+ 38,38,39,40,40,41,42,42,43,44,44,45,46,46,47,48,
+ 49,49,50,50,51,52,52,53,54,55,56,57,58,59,60,61,
+};
+static const int kf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,
+ 11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,24,
+ 25,26,27,28,28,29,29,30,30,31,31,32,33,33,34,34,
+ 35,36,37,38,39,39,40,41,41,42,43,44,45,45,46,46,
+ 47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,
+ 55,55,56,56,57,58,59,60,61,62,63,64,65,67,69,70,
+};
+static const int gf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,
+ 10,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,
+ 17,18,18,19,19,20,21,22,23,24,25,26,27,29,29,30,
+ 31,32,33,34,35,36,37,38,39,40,41,41,42,42,43,43,
+ 44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51,
+ 52,52,53,53,54,54,55,55,56,56,57,57,58,59,60,61,
+ 62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,
+};
+static const int gf_mid_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,10,
+ 10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,
+ 18,19,19,20,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,35,36,36,37,37,38,38,39,39,40,40,41,
+ 41,42,42,43,43,44,44,45,45,46,46,47,48,49,50,51,
+ 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,
+ 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,
+};
+static const int gf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4,
+ 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,10,10,
+ 11,11,12,12,13,14,15,16,17,18,18,19,19,20,20,21,
+ 22,23,24,25,26,26,27,28,29,30,31,32,33,34,35,36,
+ 37,38,39,39,40,40,40,41,41,41,42,42,43,43,44,44,
+ 44,45,45,45,46,46,47,47,47,48,48,48,49,49,49,50,
+ 50,50,51,51,52,53,54,54,55,56,57,57,58,59,60,61,
+ 62,63,64,66,68,69,72,74,77,80,82,85,87,89,91,93,
+};
+
+static const int inter_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 8, 9,10,11,12,13,14,15,16,17,18,18,19,19,20,21,
+ 21,22,23,23,24,25,26,26,27,28,29,30,31,32,32,33,
+ 34,35,36,36,37,38,39,40,40,41,41,42,43,44,44,45,
+ 46,46,47,47,48,49,49,50,50,51,52,52,53,54,54,55,
+ 55,56,57,57,58,59,60,60,61,62,63,63,64,65,66,67,
+ 68,68,69,70,71,72,72,73,74,75,76,77,78,79,80,81,
+ 81,82,83,84,85,86,87,88,89,90,90,91,92,93,94,95,
+};
+#endif
void vp8_initialize()
{
static int init_done = 0;
@@ -3466,6 +3535,12 @@ static int decide_key_frame(VP8_COMP *cpi)
return code_key_frame;
}
+#if !CONFIG_EXTEND_QRANGE
+#define FIRSTPASS_QINDEX 26
+#else
+#define FIRSTPASS_QINDEX 49
+#endif
+
#if !(CONFIG_REALTIME_ONLY)
static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
@@ -4107,6 +4182,17 @@ static void encode_frame_to_data_rate
vp8_clear_system_state(); //__asm emms;
+#if 0
+ if (cpi->pass != 1)
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%4d, %4d, %8d\n", cpi->common.current_video_frame,
+ cpi->common.base_qindex, cpi->projected_frame_size);
+ fclose(f);
+ }
+#endif
+
+
// Test to see if the stats generated for this frame indicate that we should have coded a key frame
// (assuming that we didn't)!
if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
@@ -4843,10 +4929,15 @@ static void encode_frame_to_data_rate
fclose(recon_file);
}
#endif
-
+#if 0
// DEBUG
- //vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show);
-
+ if(cm->current_video_frame>173 && cm->current_video_frame<178)
+ {
+ char filename[512];
+ sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);
+ vp8_write_yuv_frame(filename, cm->frame_to_show);
+ }
+#endif
}
@@ -5416,7 +5507,15 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
cpi->totalp_v += v2;
cpi->totalp += frame_psnr2;
cpi->total_sq_error2 += sq_error;
-
+#if 0
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
+ cpi->common.current_video_frame,y2, u2, v2,
+ frame_psnr2, frame_ssim2);
+ fclose(f);
+ }
+#endif
}
}
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index b69a1965e..c38cf4c74 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -48,6 +48,7 @@ extern int inter_b_modes[10];
// Work in progress recalibration of baseline rate tables based on
// the assumption that bits per mb is inversely proportional to the
// quantizer value.
+#if !CONFIG_EXTEND_QRANGE
const int vp8_bits_per_mb[2][QINDEX_RANGE] =
{
// Intra case 450000/Qintra
@@ -89,10 +90,54 @@ const int vp8_bits_per_mb[2][QINDEX_RANGE] =
11445, 11220, 11003, 10795, 10594, 10401, 10215, 10035,
}
};
+#else
+const int vp8_bits_per_mb[2][QINDEX_RANGE] =
+{
+ // (Updated DEC 2010) Baseline estimate of Bits Per MB at each Q:
+ // 4500000/Qintra
+ {
+ 4500000,3600000,3000000,2571428,2250000,2000000,1800000,1636363,
+ 1500000,1384615,1285714,1200000,1125000,1058823,1000000, 947368,
+ 900000, 818181, 750000, 692307, 642857, 600000, 562500, 529411,
+ 500000, 473684, 450000, 428571, 409090, 391304, 375000, 352941,
+ 333333, 315789, 300000, 285714, 272727, 260869, 250000, 236842,
+ 225000, 214285, 204545, 195652, 187500, 180000, 171428, 163636,
+ 156521, 150000, 144000, 138461, 133333, 128571, 123287, 118421,
+ 113924, 109756, 105882, 102272, 98901, 95744, 92783, 90000,
+ 87378, 84905, 82568, 80357, 77586, 75000, 72580, 70312,
+ 68181, 66176, 64285, 62500, 60810, 59210, 57692, 56250,
+ 54545, 52941, 51428, 50000, 48648, 47368, 45918, 44554,
+ 43269, 42056, 40909, 39647, 38461, 37344, 36290, 35294,
+ 34351, 33333, 32374, 31468, 30612, 29801, 28938, 28125,
+ 27355, 26627, 25862, 25139, 24456, 23809, 23195, 22613,
+ 21951, 21327, 20737, 20179, 19650, 19067, 18518, 18000,
+ 17441, 16917, 16423, 15957, 15410, 14900, 14376, 13846,
+ },
+ //2850000/Qinter
+ {
+ 2850000,2280000,1900000,1628571,1425000,1266666,1140000,1036363,
+ 950000, 876923, 814285, 760000, 712500, 670588, 633333, 600000,
+ 570000, 518181, 475000, 438461, 407142, 380000, 356250, 335294,
+ 316666, 300000, 285000, 271428, 259090, 247826, 237500, 223529,
+ 211111, 200000, 190000, 180952, 172727, 165217, 158333, 150000,
+ 142500, 135714, 129545, 123913, 118750, 114000, 108571, 103636,
+ 99130, 95000, 91200, 87692, 84444, 81428, 78082, 75000,
+ 72151, 69512, 67058, 64772, 62637, 60638, 58762, 57000,
+ 55339, 53773, 52293, 50892, 49137, 47500, 45967, 44531,
+ 43181, 41911, 40714, 39583, 38513, 37500, 36538, 35625,
+ 34545, 33529, 32571, 31666, 30810, 30000, 29081, 28217,
+ 27403, 26635, 25909, 25110, 24358, 23651, 22983, 22352,
+ 21755, 21111, 20503, 19930, 19387, 18874, 18327, 17812,
+ 17325, 16863, 16379, 15921, 15489, 15079, 14690, 14321,
+ 13902, 13507, 13133, 12780, 12445, 12076, 11728, 11400,
+ 11046, 10714, 10401, 10106, 9760, 9437, 9105, 8769,
+ }
+ };
+ #endif
const int vp8_kf_boost_qadjustment[QINDEX_RANGE] =
-{
- 128, 129, 130, 131, 132, 133, 134, 135,
+ {
+ 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159,
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index b2a3e117f..66c7a538a 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -158,6 +158,48 @@ static int rd_iifactor [ 32 ] = { 4, 4, 3, 2, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
+// 3* dc_qlookup[Q]*dc_qlookup[Q];
+#if !CONFIG_EXTEND_QRANGE
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 48,75,108,147,192,243,300,300,
+ 363,432,507,588,675,768,867,867,
+ 972,1083,1200,1200,1323,1323,1452,1452,
+ 1587,1587,1728,1875,1875,2028,2187,2352,
+ 2523,2700,2883,3072,3267,3468,3675,3888,
+ 4107,4107,4332,4563,4800,5043,5292,5547,
+ 5808,6075,6348,6348,6627,6912,7203,7500,
+ 7803,8112,8427,8748,9075,9408,9747,10092,
+ 10443,10800,11163,11532,11907,12288,12675,13068,
+ 13467,13872,14283,14700,15123,15552,15987,16428,
+ 16875,17328,17328,17787,18252,18723,19200,19683,
+ 20172,20667,21168,21675,22188,22707,23232,23763,
+ 24843,25947,27075,27648,28812,30000,30603,31212,
+ 32448,33708,34992,36300,37632,38988,40368,41772,
+ 44652,46128,47628,49152,50700,52272,53868,55488,
+ 57132,58800,61347,63075,65712,68403,71148,73947,
+};
+#else
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 3,5,7,9,12,15,19,23,
+ 27,32,37,42,48,54,61,68,
+ 75,83,91,99,108,117,127,137,
+ 147,169,192,217,243,271,300,331,
+ 363,397,450,507,567,631,698,768,
+ 842,919,999,1083,1170,1261,1355,1452,
+ 1587,1728,1875,2028,2187,2352,2523,2700,
+ 2883,3072,3267,3468,3675,3888,4107,4332,
+ 4563,4800,5043,5292,5547,5808,6075,6348,
+ 6627,6912,7203,7500,7880,8269,8667,9075,
+ 9492,9919,10355,10800,11255,11719,12192,12675,
+ 13167,13669,14180,14700,15230,15769,16317,16875,
+ 18019,19200,20419,21675,22969,24300,25669,27075,
+ 28519,30000,31519,33075,34669,36300,37969,39675,
+ 41772,43923,46128,48387,50700,53067,55488,57963,
+ 61347,64827,69312,73947,78732,83667,89787,97200,
+};
+#endif
/* values are now correlated to quantizer */
static int sad_per_bit16lut[QINDEX_RANGE] =
@@ -205,12 +247,16 @@ void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex];
}
-void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
+
+
+
+
+void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
{
int q;
int i;
- double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0;
- double rdconst = 3.00;
+ int *thresh;
+ int threshmult;
vp8_clear_system_state(); //__asm emms;
@@ -218,7 +264,8 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
// for key frames, golden frames and arf frames.
// if (cpi->common.refresh_golden_frame ||
// cpi->common.refresh_alt_ref_frame)
- cpi->RDMULT = (int)(rdconst * (capped_q * capped_q));
+ QIndex=(QIndex<0)? 0 : ((QIndex>127)?127 : QIndex);
+ cpi->RDMULT = rdmult_lut[QIndex];
// Extend rate multiplier along side quantizer zbin increases
if (cpi->zbin_over_quant > 0)
@@ -229,8 +276,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
// Experimental code using the same basic equation as used for Q above
// The units of cpi->zbin_over_quant are 1/128 of Q bin size
oq_factor = 1.0 + ((double)0.0015625 * cpi->zbin_over_quant);
- modq = (int)((double)capped_q * oq_factor);
- cpi->RDMULT = (int)(rdconst * (modq * modq));
+ cpi->RDMULT = (int)((double)cpi->RDMULT * oq_factor * oq_factor);
}
if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME))
@@ -241,20 +287,35 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->next_iiratio]) >> 4;
}
+#if !CONFIG_EXTEND_QRANGE
if (cpi->RDMULT < 125)
cpi->RDMULT = 125;
+#else
+ if (cpi->RDMULT < 7)
+ cpi->RDMULT = 7;
+#endif
cpi->mb.errorperbit = (cpi->RDMULT / 100);
+#if CONFIG_EXTEND_QRANGE
+ if(cpi->mb.errorperbit<1)
+ cpi->mb.errorperbit=1;
+#endif
vp8_set_speed_features(cpi);
if (cpi->common.simpler_lpf)
cpi->common.filter_type = SIMPLE_LOOPFILTER;
- q = (int)pow(Qvalue, 1.25);
+ q = (int)pow(vp8_dc_quant(QIndex,0), 1.25);
if (q < 8)
q = 8;
+
+
+#if CONFIG_EXTEND_QRANGE
+ cpi->RDMULT *= 16;
+#endif
+
if (cpi->RDMULT > 1000)
{
cpi->RDDIV = 1;
@@ -972,7 +1033,11 @@ static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion, const vp
// Distortion
d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
+#if CONFIG_EXTEND_QRANGE
+ d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff)<<2;
+#else
d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
+#endif
*Distortion = (d >> 4);