Commit 93d6b86c authored by Yaowu Xu's avatar Yaowu Xu

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
parent 4dfcb129
......@@ -140,7 +140,7 @@ typedef enum {
#define VP9_MVREFS (1 + SPLITMV - NEARESTMV)
#if CONFIG_LOSSLESS
#define WHT_UPSCALE_FACTOR 3
#define WHT_UPSCALE_FACTOR 2
#endif
typedef enum {
......
......@@ -1673,8 +1673,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
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
......
......@@ -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 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
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 @@ static void encode_frame_internal(VP9_COMP *cpi) {
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);
......
......@@ -847,7 +847,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
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 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {
cm->filter_level = 0;
}
#if CONFIG_LOSSLESS
else if (cpi->oxcf.lossless) {
else if (cpi->mb.e_mbd.lossless) {
cm->filter_level = 0;
}
#endif
......
......@@ -411,15 +411,11 @@ void vp9_init_quantizer(VP9_COMP *cpi) {
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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment