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,
--
⑨