From 5b42ae09aeecedfdff1dae9d59be9fbb2aba3392 Mon Sep 17 00:00:00 2001
From: Yaowu Xu <yaowu@google.com>
Date: Wed, 1 Dec 2010 15:50:14 -0800
Subject: [PATCH] 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
---
 configure                              |   1 +
 vp8/common/generic/systemdependent.c   |  10 +++
 vp8/common/idctllm.c                   |  33 +++++++-
 vp8/common/quant_common.c              |  45 ++++++++--
 vp8/decoder/generic/dsystemdependent.c |   9 ++
 vp8/encoder/dct.c                      |  28 ++++++-
 vp8/encoder/encodeframe.c              |   2 +-
 vp8/encoder/encodemb.c                 |   4 +
 vp8/encoder/firstpass.c                |   2 +-
 vp8/encoder/generic/csystemdependent.c |   8 ++
 vp8/encoder/onyx_if.c                  | 109 +++++++++++++++++++++++--
 vp8/encoder/ratectrl.c                 |  49 ++++++++++-
 vp8/encoder/rdopt.c                    |  79 ++++++++++++++++--
 13 files changed, 349 insertions(+), 30 deletions(-)

diff --git a/configure b/configure
index 744bd4dad5..b79aee4e31 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 b3eadaf270..6ba0cfb87c 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 196062df67..c65d35adc9 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 e9833fe33b..b8e6e29720 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 2e284729bc..ed7504bfca 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 b5a11ae34f..69a882c898 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 4c95f28d64..59ccb5530d 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 efcea745ba..aa2beacded 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 32a39c5f27..a78048153c 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 4738a5b286..b6de95b8d0 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 77fbb29b13..e494b66356 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 b69a1965e6..c38cf4c745 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 b2a3e117f8..66c7a538a5 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);
 
-- 
GitLab