diff --git a/configure b/configure
index 744bd4dad5bdd1f5b6e6809af39f196d2ad3451e..b79aee4e31cc59eaed4df772665956a11b9535bd 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 b3eadaf2705e70ebdb802401289204ff7de22784..6ba0cfb87ce8285890afa46b5dfa53c4fc756e37 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 196062df67b6af1a91ef8eafc1ef89611e73b3f5..c65d35adc94dfd0a669889ac0060a1f83aaae2c3 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 e9833fe33b4aa658c855a490842c8deb5a6103e7..b8e6e29720d84d080200b78b469cd36594e43f38 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 2e284729bc9e86351011075764d9326ddd92af63..ed7504bfca7cecec7c5aa40bd8b61dd545f04c92 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 b5a11ae34f9b8bfe3197117fdd7b9389017ade3d..69a882c898d904615da708465107e47e6fad6e6f 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 4c95f28d64ca54504eab688a836d51bbe856fc1d..59ccb5530d8efd9f9802b0c02a655eda930e228b 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 efcea745ba5781d930ab3ecb8ad85b48f07c4391..aa2beacded32c99c2338ed7594b5793990106a2c 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 32a39c5f27852e6190f89cbe53dd8dafa0b53a70..a78048153c602d2190b955e28854fefac12c768c 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 4738a5b286d8254959646adb9954906a76e3da55..b6de95b8d07d7e44b9c8625acb590cb8ed049efc 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 77fbb29b130cd50fa51cf71f18122e889a4927b6..e494b66356398675f544cbb5f28c8ca889bf92b1 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 b69a1965e60411b3e0dac5c3886c124691f247da..c38cf4c74567636debe19e1f8ba84e321d026ccd 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 b2a3e117f832a6421fe5e1aab2e165ad9cc573cc..66c7a538a54ff5a208172651753616d276c645b2 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);