shithub: libvpx

Download patch

ref: 93d6b86cfd6891964de5d1061af45d8ce4671138
parent: 4dfcb129fdcab683644d667cf56d689e79fa7db3
author: Yaowu Xu <yaowu@google.com>
date: Wed Feb 13 09:22:15 EST 2013

Use lossless for Q0

The commit changes the coding mode to lossless whenever the lowest
quantizer is choosen.

As expected, test results showed no difference for cif and std-hd
set where Q0 is rarely used. For yt and yt-hd set, Q0 is used for
a number of clips, where this commit helped a lot in the high end.

Average over all clips in the sets:
yt: 2.391% 1.017% 1.066%
hd: 1.937%  .764%  .787%

Change-Id: I9fa9df8646fd70cb09ffe9e4202b86b67da16765

--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -140,7 +140,7 @@
 #define VP9_MVREFS (1 + SPLITMV - NEARESTMV)
 
 #if CONFIG_LOSSLESS
-#define WHT_UPSCALE_FACTOR 3
+#define WHT_UPSCALE_FACTOR 2
 #endif
 
 typedef enum {
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1673,8 +1673,8 @@
   pc->sb32_coded = get_binary_prob(cpi->sb32_count[0], cpi->sb32_count[1]);
   vp9_write_literal(&header_bc, pc->sb32_coded, 8);
 #if CONFIG_LOSSLESS
-  vp9_write_bit(&header_bc, cpi->oxcf.lossless);
-  if (cpi->oxcf.lossless) {
+  vp9_write_bit(&header_bc, cpi->mb.e_mbd.lossless);
+  if (cpi->mb.e_mbd.lossless) {
     pc->txfm_mode = ONLY_4X4;
   }
   else
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -30,7 +30,7 @@
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_tile_common.h"
 #include "vp9/encoder/vp9_tokenize.h"
-#include "vp9_rtcd.h"
+#include "./vp9_rtcd.h"
 #include <stdio.h>
 #include <math.h>
 #include <limits.h>
@@ -1225,6 +1225,25 @@
   if (cm->full_pixel)
     xd->fullpixel_mask = 0xfffffff8;
 }
+#if CONFIG_LOSSLESS
+static void switch_lossless_mode(VP9_COMP *cpi, int lossless) {
+  if (lossless) {
+    cpi->mb.fwd_txm8x4            = vp9_short_walsh8x4_x8;
+    cpi->mb.fwd_txm4x4            = vp9_short_walsh4x4_x8;
+    cpi->mb.e_mbd.inv_txm4x4_1    = vp9_short_inv_walsh4x4_1_x8;
+    cpi->mb.e_mbd.inv_txm4x4      = vp9_short_inv_walsh4x4_x8;
+    cpi->mb.optimize              = 0;
+    cpi->common.filter_level      = 0;
+    cpi->zbin_mode_boost_enabled  = FALSE;
+    cpi->common.txfm_mode         = ONLY_4X4;
+  } else {
+    cpi->mb.fwd_txm8x4            = vp9_short_fdct8x4;
+    cpi->mb.fwd_txm4x4            = vp9_short_fdct4x4;
+    cpi->mb.e_mbd.inv_txm4x4_1    = vp9_short_idct4x4llm_1;
+    cpi->mb.e_mbd.inv_txm4x4      = vp9_short_idct4x4llm;
+  }
+}
+#endif
 
 static void encode_frame_internal(VP9_COMP *cpi) {
   int mb_row;
@@ -1282,6 +1301,14 @@
   vp9_zero(cpi->mb_mv_ref_count);
 #endif
 
+#if CONFIG_LOSSLESS
+  // force lossless mode when Q0 is selected
+  cpi->mb.e_mbd.lossless = (cm->base_qindex == 0 &&
+                            cm->y1dc_delta_q == 0 &&
+                            cm->uvdc_delta_q == 0 &&
+                            cm->uvac_delta_q == 0);
+  switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
+#endif
   vp9_frame_init_quantizer(cpi);
 
   vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -847,7 +847,7 @@
   cpi->mb.fwd_txm4x4    = vp9_short_fdct4x4;
 
 #if CONFIG_LOSSLESS
-  if (cpi->oxcf.lossless) {
+  if (cpi->oxcf.lossless || cpi->mb.e_mbd.lossless) {
     cpi->mb.fwd_txm8x4    = vp9_short_walsh8x4_x8;
     cpi->mb.fwd_txm4x4    = vp9_short_walsh4x4_x8;
   }
@@ -2469,7 +2469,7 @@
     cm->filter_level = 0;
   }
 #if CONFIG_LOSSLESS
-  else if (cpi->oxcf.lossless) {
+  else if (cpi->mb.e_mbd.lossless) {
     cm->filter_level = 0;
   }
 #endif
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -411,15 +411,11 @@
 
   for (Q = 0; Q < QINDEX_RANGE; Q++) {
     int qzbin_factor = (vp9_dc_quant(Q, 0) < 148) ? 84 : 80;
-
     int qrounding_factor = 48;
-#if CONFIG_LOSSLESS
-    if (cpi->oxcf.lossless && Q == 0) {
+    if (Q == 0) {
       qzbin_factor = 64;
       qrounding_factor = 64;
     }
-#endif
-
     // dc values
     quant_val = vp9_dc_quant(Q, cpi->common.y1dc_delta_q);
     invert_quant(cpi->Y1quant[Q] + 0,