Commit a97394f7 authored by Cheng Chen's avatar Cheng Chen

Make LOOPFILTER_LEVEL support EXT_DELTA_Q

Before LOOPFILTER_LEVEL, there's one filter level,
now we have four filter levels for y plane vertical,
y plane horizontal, u plane and v plane.

This patch enables experiment LOOPFILTER_LEVEL to support per
superblock loop filter level update.

Change-Id: Ib11a1564471eb3076c26e73e5cdf7b5a3045ef97
parent e36b028e
...@@ -27,6 +27,12 @@ static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = { ...@@ -27,6 +27,12 @@ static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = {
{ SEG_LVL_ALT_LF_U, SEG_LVL_ALT_LF_U }, { SEG_LVL_ALT_LF_U, SEG_LVL_ALT_LF_U },
{ SEG_LVL_ALT_LF_V, SEG_LVL_ALT_LF_V } { SEG_LVL_ALT_LF_V, SEG_LVL_ALT_LF_V }
}; };
#if CONFIG_EXT_DELTA_Q
static const int delta_lf_id_lut[MAX_MB_PLANE][2] = {
{ 0, 1 }, { 2, 2 }, { 3, 3 }
};
#endif // CONFIG_EXT_DELTA_Q
#endif // CONFIG_LOOPFILTER_LEVEL #endif // CONFIG_LOOPFILTER_LEVEL
#if CONFIG_LPF_DIRECT #if CONFIG_LPF_DIRECT
...@@ -645,9 +651,10 @@ static uint8_t get_filter_level(const AV1_COMMON *cm, ...@@ -645,9 +651,10 @@ static uint8_t get_filter_level(const AV1_COMMON *cm,
#endif // CONFIG_SUPERTX #endif // CONFIG_SUPERTX
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL #if CONFIG_LOOPFILTER_LEVEL
const int delta_lf_idx = delta_lf_id_lut[plane][dir_idx];
const int delta_lf = mbmi->curr_delta_lf[delta_lf_idx];
int lvl_seg = int lvl_seg =
clamp(mbmi->current_delta_lf_from_base + cm->lf.filter_level[dir_idx], clamp(delta_lf + cm->lf.filter_level[dir_idx], 0, MAX_LOOP_FILTER);
0, MAX_LOOP_FILTER);
#else #else
int lvl_seg = clamp(mbmi->current_delta_lf_from_base + cm->lf.filter_level, int lvl_seg = clamp(mbmi->current_delta_lf_from_base + cm->lf.filter_level,
0, MAX_LOOP_FILTER); 0, MAX_LOOP_FILTER);
......
...@@ -445,6 +445,9 @@ typedef struct MB_MODE_INFO { ...@@ -445,6 +445,9 @@ typedef struct MB_MODE_INFO {
int current_q_index; int current_q_index;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
int current_delta_lf_from_base; int current_delta_lf_from_base;
#if CONFIG_LOOPFILTER_LEVEL
int curr_delta_lf[FRAME_LF_COUNT];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_RD_DEBUG #if CONFIG_RD_DEBUG
RD_STATS rd_stats; RD_STATS rd_stats;
...@@ -805,6 +808,23 @@ typedef struct macroblockd { ...@@ -805,6 +808,23 @@ typedef struct macroblockd {
// superblock's actual lf and current lf. // superblock's actual lf and current lf.
int prev_delta_lf_from_base; int prev_delta_lf_from_base;
int current_delta_lf_from_base; int current_delta_lf_from_base;
#if CONFIG_LOOPFILTER_LEVEL
// For this experiment, we have four frame filter levels for different plane
// and direction. So, to support the per superblock update, we need to add
// a few more params as below.
// 0: delta loop filter level for y plane vertical
// 1: delta loop filter level for y plane horizontal
// 2: delta loop filter level for u plane
// 3: delta loop filter level for v plane
// To make it consistent with the reference to each filter level in segment,
// we need to -1, since
// SEG_LVL_ALT_LF_Y_V = 1;
// SEG_LVL_ALT_LF_Y_H = 2;
// SEG_LVL_ALT_LF_U = 3;
// SEG_LVL_ALT_LF_V = 4;
int prev_delta_lf[FRAME_LF_COUNT];
int curr_delta_lf[FRAME_LF_COUNT];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_ADAPT_SCAN #if CONFIG_ADAPT_SCAN
const EobThresholdMD *eob_threshold_md; const EobThresholdMD *eob_threshold_md;
......
...@@ -1683,11 +1683,24 @@ static const aom_cdf_prob default_delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)] = { ...@@ -1683,11 +1683,24 @@ static const aom_cdf_prob default_delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)] = {
AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0
}; };
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
static const aom_prob default_delta_lf_probs[FRAME_LF_COUNT][DELTA_LF_PROBS] = {
{ 220, 220, 220 }, { 220, 220, 220 }, { 220, 220, 220 }, { 220, 220, 220 }
};
static const aom_cdf_prob
default_delta_lf_cdf[FRAME_LF_COUNT][CDF_SIZE(DELTA_LF_PROBS + 1)] = {
{ AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 },
{ AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 },
{ AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 },
{ AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 }
};
#else
static const aom_prob default_delta_lf_probs[DELTA_LF_PROBS] = { 220, 220, static const aom_prob default_delta_lf_probs[DELTA_LF_PROBS] = { 220, 220,
220 }; 220 };
static const aom_cdf_prob default_delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)] = { static const aom_cdf_prob default_delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)] = {
AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0 AOM_ICDF(28160), AOM_ICDF(32120), AOM_ICDF(32677), AOM_ICDF(32768), 0
}; };
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_SMOOTH_HV #if CONFIG_SMOOTH_HV
...@@ -5287,9 +5300,16 @@ void av1_adapt_intra_frame_probs(AV1_COMMON *cm) { ...@@ -5287,9 +5300,16 @@ void av1_adapt_intra_frame_probs(AV1_COMMON *cm) {
fc->delta_q_prob[i] = fc->delta_q_prob[i] =
mode_mv_merge_probs(pre_fc->delta_q_prob[i], counts->delta_q[i]); mode_mv_merge_probs(pre_fc->delta_q_prob[i], counts->delta_q[i]);
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
for (i = 0; i < FRAME_LF_COUNT; ++i)
for (int j = 0; j < DELTA_LF_PROBS; ++j)
fc->delta_lf_prob[i][j] = mode_mv_merge_probs(pre_fc->delta_lf_prob[i][j],
counts->delta_lf[i][j]);
#else
for (i = 0; i < DELTA_LF_PROBS; ++i) for (i = 0; i < DELTA_LF_PROBS; ++i)
fc->delta_lf_prob[i] = fc->delta_lf_prob[i] =
mode_mv_merge_probs(pre_fc->delta_lf_prob[i], counts->delta_lf[i]); mode_mv_merge_probs(pre_fc->delta_lf_prob[i], counts->delta_lf[i]);
#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
#if CONFIG_INTRA_INTERP #if CONFIG_INTRA_INTERP
......
...@@ -360,7 +360,11 @@ typedef struct frame_contexts { ...@@ -360,7 +360,11 @@ typedef struct frame_contexts {
[CDF_SIZE(MAX_TX_DEPTH + 1)]; [CDF_SIZE(MAX_TX_DEPTH + 1)];
aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)]; aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)];
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
aom_cdf_prob delta_lf_cdf[FRAME_LF_COUNT][CDF_SIZE(DELTA_LF_PROBS + 1)];
#else
aom_cdf_prob delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)]; aom_cdf_prob delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_EXT_TX #if CONFIG_EXT_TX
aom_cdf_prob intra_ext_tx_cdf[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES] aom_cdf_prob intra_ext_tx_cdf[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
...@@ -376,7 +380,11 @@ typedef struct frame_contexts { ...@@ -376,7 +380,11 @@ typedef struct frame_contexts {
#endif // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
aom_prob delta_q_prob[DELTA_Q_PROBS]; aom_prob delta_q_prob[DELTA_Q_PROBS];
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
aom_prob delta_lf_prob[FRAME_LF_COUNT][DELTA_LF_PROBS];
#else
aom_prob delta_lf_prob[DELTA_LF_PROBS]; aom_prob delta_lf_prob[DELTA_LF_PROBS];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_PVQ #if CONFIG_PVQ
// TODO(any): If PVQ is enabled, most of coefficient related cdf, // TODO(any): If PVQ is enabled, most of coefficient related cdf,
...@@ -507,7 +515,11 @@ typedef struct FRAME_COUNTS { ...@@ -507,7 +515,11 @@ typedef struct FRAME_COUNTS {
#endif #endif
unsigned int delta_q[DELTA_Q_PROBS][2]; unsigned int delta_q[DELTA_Q_PROBS][2];
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
unsigned int delta_lf[FRAME_LF_COUNT][DELTA_LF_PROBS][2];
#else
unsigned int delta_lf[DELTA_LF_PROBS][2]; unsigned int delta_lf[DELTA_LF_PROBS][2];
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
#if CONFIG_EXT_TX && CONFIG_RECT_TX #if CONFIG_EXT_TX && CONFIG_RECT_TX
unsigned int tx_size_implied[TX_SIZES][TX_SIZES]; unsigned int tx_size_implied[TX_SIZES][TX_SIZES];
......
...@@ -82,6 +82,12 @@ extern "C" { ...@@ -82,6 +82,12 @@ extern "C" {
#define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2) #define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2)
#if CONFIG_LOOPFILTER_LEVEL
// 4 frame filter levels: y plane vertical, y plane horizontal,
// u plane, and v plane
#define FRAME_LF_COUNT 4
#endif // CONFIG_LOOPFILTER_LEVEL
#if CONFIG_LPF_SB #if CONFIG_LPF_SB
#define LPF_DELTA_BITS 3 #define LPF_DELTA_BITS 3
#define LPF_STEP 2 #define LPF_STEP 2
......
...@@ -5069,6 +5069,10 @@ static size_t read_uncompressed_header(AV1Decoder *pbi, ...@@ -5069,6 +5069,10 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
assert(!segment_quantizer_active); assert(!segment_quantizer_active);
cm->delta_lf_present_flag = aom_rb_read_bit(rb); cm->delta_lf_present_flag = aom_rb_read_bit(rb);
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
xd->prev_delta_lf[lf_id] = 0;
#endif // CONFIG_LOOPFILTER_LEVEL
xd->prev_delta_lf_from_base = 0; xd->prev_delta_lf_from_base = 0;
cm->delta_lf_res = 1 << aom_rb_read_literal(rb, 2); cm->delta_lf_res = 1 << aom_rb_read_literal(rb, 2);
} }
......
...@@ -79,6 +79,9 @@ static int read_delta_qindex(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r, ...@@ -79,6 +79,9 @@ static int read_delta_qindex(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
} }
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r, static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
#if CONFIG_LOOPFILTER_LEVEL
int lf_id,
#endif
MB_MODE_INFO *const mbmi, int mi_col, MB_MODE_INFO *const mbmi, int mi_col,
int mi_row) { int mi_row) {
FRAME_COUNTS *counts = xd->counts; FRAME_COUNTS *counts = xd->counts;
...@@ -93,12 +96,22 @@ static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r, ...@@ -93,12 +96,22 @@ static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
(void)cm; (void)cm;
if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_lf_flag) { if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_lf_flag) {
#if CONFIG_LOOPFILTER_LEVEL
abs = aom_read_symbol(r, ec_ctx->delta_lf_cdf[lf_id], DELTA_LF_PROBS + 1,
ACCT_STR);
#else
abs = abs =
aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1, ACCT_STR); aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1, ACCT_STR);
#endif // CONFIG_LOOPFILTER_LEVEL
smallval = (abs < DELTA_LF_SMALL); smallval = (abs < DELTA_LF_SMALL);
if (counts) { if (counts) {
#if CONFIG_LOOPFILTER_LEVEL
for (i = 0; i < abs; ++i) counts->delta_lf[lf_id][i][1]++;
if (smallval) counts->delta_lf[lf_id][abs][0]++;
#else
for (i = 0; i < abs; ++i) counts->delta_lf[i][1]++; for (i = 0; i < abs; ++i) counts->delta_lf[i][1]++;
if (smallval) counts->delta_lf[abs][0]++; if (smallval) counts->delta_lf[abs][0]++;
#endif // CONFIG_LOOPFILTER_LEVEL
} }
if (!smallval) { if (!smallval) {
rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1; rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
...@@ -1102,11 +1115,21 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm, ...@@ -1102,11 +1115,21 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
xd->prev_qindex = xd->current_qindex; xd->prev_qindex = xd->current_qindex;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
mbmi->curr_delta_lf[lf_id] = xd->curr_delta_lf[lf_id] =
xd->prev_delta_lf[lf_id] +
read_delta_lflevel(cm, xd, r, lf_id, mbmi, mi_col, mi_row) *
cm->delta_lf_res;
xd->prev_delta_lf[lf_id] = xd->curr_delta_lf[lf_id];
}
#else
mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base = mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base =
xd->prev_delta_lf_from_base + xd->prev_delta_lf_from_base +
read_delta_lflevel(cm, xd, r, mbmi, mi_col, mi_row) * read_delta_lflevel(cm, xd, r, mbmi, mi_col, mi_row) *
cm->delta_lf_res; cm->delta_lf_res;
xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base; xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base;
#endif // CONFIG_LOOPFILTER_LEVEL
} }
#endif #endif
} }
...@@ -2853,11 +2876,21 @@ static void read_inter_frame_mode_info(AV1Decoder *const pbi, ...@@ -2853,11 +2876,21 @@ static void read_inter_frame_mode_info(AV1Decoder *const pbi,
xd->prev_qindex = xd->current_qindex; xd->prev_qindex = xd->current_qindex;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
mbmi->curr_delta_lf[lf_id] = xd->curr_delta_lf[lf_id] =
xd->prev_delta_lf[lf_id] +
read_delta_lflevel(cm, xd, r, lf_id, mbmi, mi_col, mi_row) *
cm->delta_lf_res;
xd->prev_delta_lf[lf_id] = xd->curr_delta_lf[lf_id];
}
#else
mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base = mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base =
xd->prev_delta_lf_from_base + xd->prev_delta_lf_from_base +
read_delta_lflevel(cm, xd, r, mbmi, mi_col, mi_row) * read_delta_lflevel(cm, xd, r, mbmi, mi_col, mi_row) *
cm->delta_lf_res; cm->delta_lf_res;
xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base; xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base;
#endif // CONFIG_LOOPFILTER_LEVEL
} }
#endif #endif
} }
......
...@@ -529,6 +529,9 @@ static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd, ...@@ -529,6 +529,9 @@ static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_LOOPFILTER_LEVEL
int lf_id,
#endif
int delta_lflevel, aom_writer *w) { int delta_lflevel, aom_writer *w) {
int sign = delta_lflevel < 0; int sign = delta_lflevel < 0;
int abs = sign ? -delta_lflevel : delta_lflevel; int abs = sign ? -delta_lflevel : delta_lflevel;
...@@ -537,8 +540,13 @@ static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, ...@@ -537,8 +540,13 @@ static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd,
FRAME_CONTEXT *ec_ctx = xd->tile_ctx; FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
(void)cm; (void)cm;
#if CONFIG_LOOPFILTER_LEVEL
aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf[lf_id],
DELTA_LF_PROBS + 1);
#else
aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf, aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf,
DELTA_LF_PROBS + 1); DELTA_LF_PROBS + 1);
#endif // CONFIG_LOOPFILTER_LEVEL
if (!smallval) { if (!smallval) {
rem_bits = OD_ILOG_NZ(abs - 1) - 1; rem_bits = OD_ILOG_NZ(abs - 1) - 1;
...@@ -1715,6 +1723,17 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, ...@@ -1715,6 +1723,17 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
write_delta_qindex(cm, xd, reduced_delta_qindex, w); write_delta_qindex(cm, xd, reduced_delta_qindex, w);
xd->prev_qindex = mbmi->current_q_index; xd->prev_qindex = mbmi->current_q_index;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
if (cm->delta_lf_present_flag) {
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
int reduced_delta_lflevel =
(mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
cm->delta_lf_res;
write_delta_lflevel(cm, xd, lf_id, reduced_delta_lflevel, w);
xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
}
}
#else
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
int reduced_delta_lflevel = int reduced_delta_lflevel =
(mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) / (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
...@@ -1722,6 +1741,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, ...@@ -1722,6 +1741,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
write_delta_lflevel(cm, xd, reduced_delta_lflevel, w); write_delta_lflevel(cm, xd, reduced_delta_lflevel, w);
xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base; xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
} }
#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
} }
} }
...@@ -2098,6 +2118,17 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd, ...@@ -2098,6 +2118,17 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd,
write_delta_qindex(cm, xd, reduced_delta_qindex, w); write_delta_qindex(cm, xd, reduced_delta_qindex, w);
xd->prev_qindex = mbmi->current_q_index; xd->prev_qindex = mbmi->current_q_index;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
if (cm->delta_lf_present_flag) {
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
int reduced_delta_lflevel =
(mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
cm->delta_lf_res;
write_delta_lflevel(cm, xd, lf_id, reduced_delta_lflevel, w);
xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
}
}
#else
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
int reduced_delta_lflevel = int reduced_delta_lflevel =
(mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) / (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
...@@ -2105,6 +2136,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd, ...@@ -2105,6 +2136,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd,
write_delta_lflevel(cm, xd, reduced_delta_lflevel, w); write_delta_lflevel(cm, xd, reduced_delta_lflevel, w);
xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base; xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
} }
#endif // CONFIG_LOOPFILTER_LEVEL
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
} }
} }
...@@ -3223,6 +3255,10 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, ...@@ -3223,6 +3255,10 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile,
xd->prev_qindex = cpi->common.base_qindex; xd->prev_qindex = cpi->common.base_qindex;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
if (cpi->common.delta_lf_present_flag) { if (cpi->common.delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
xd->prev_delta_lf[lf_id] = 0;
#endif // CONFIG_LOOPFILTER_LEVEL
xd->prev_delta_lf_from_base = 0; xd->prev_delta_lf_from_base = 0;
} }
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
...@@ -4731,6 +4767,10 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi, ...@@ -4731,6 +4767,10 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi,
aom_wb_write_bit(wb, cm->delta_lf_present_flag); aom_wb_write_bit(wb, cm->delta_lf_present_flag);
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_lf_res) - 1, 2); aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_lf_res) - 1, 2);
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
xd->prev_delta_lf[lf_id] = 0;
#endif // CONFIG_LOOPFILTER_LEVEL
xd->prev_delta_lf_from_base = 0; xd->prev_delta_lf_from_base = 0;
} }
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
...@@ -5086,6 +5126,10 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi, ...@@ -5086,6 +5126,10 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
aom_wb_write_bit(wb, cm->delta_lf_present_flag); aom_wb_write_bit(wb, cm->delta_lf_present_flag);
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_lf_res) - 1, 2); aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_lf_res) - 1, 2);
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
xd->prev_delta_lf[lf_id] = 0;
#endif // CONFIG_LOOPFILTER_LEVEL
xd->prev_delta_lf_from_base = 0; xd->prev_delta_lf_from_base = 0;
} }
#endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_EXT_DELTA_Q
......
...@@ -1622,6 +1622,23 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row, ...@@ -1622,6 +1622,23 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++; if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
xd->prev_qindex = mbmi->current_q_index; xd->prev_qindex = mbmi->current_q_index;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
#if CONFIG_LOOPFILTER_LEVEL
if (cm->delta_lf_present_flag) {
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
const int delta_lf =
(mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
cm->delta_lf_res;
const int abs_delta_lf = abs(delta_lf);
for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
td->counts->delta_lf[lf_id][i][1]++;
}
if (abs_delta_lf < DELTA_LF_SMALL)
td->counts->delta_lf[lf_id][abs_delta_lf][0]++;
xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
}
xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
}
#else
if (cm->delta_lf_present_flag) { if (cm->delta_lf_present_flag) {
const int dlf = const int dlf =
(mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) / (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
...@@ -1633,6 +1650,7 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row, ...@@ -1633,6 +1650,7 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++; if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++;
xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base; xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
} }
#endif // CONFIG_LOOPFILTER_LEVEL
#endif #endif
} }
if (!frame_is_intra_only(cm)) { if (!frame_is_intra_only(cm)) {
...@@ -2141,6 +2159,10 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile, ...@@ -2141,6 +2159,10 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
mbmi = &xd->mi[0]->mbmi; mbmi = &xd->mi[0]->mbmi;
if (bsize == BLOCK_64X64 && mbmi->skip == 1 && if (bsize == BLOCK_64X64 && mbmi->skip == 1 &&
cpi->common.delta_lf_present_flag) { cpi->common.delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
mbmi->curr_delta_lf[lf_id] = xd->prev_delta_lf[lf_id];
#endif // CONFIG_LOOPFILTER_LEVEL
mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base; mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
} }
#endif #endif
...@@ -4604,8 +4626,14 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td, ...@@ -4604,8 +4626,14 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
if (cm->delta_q_present_flag) if (cm->delta_q_present_flag)
if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex; if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
#if CONFIG_EXT_DELTA_Q #if CONFIG_EXT_DELTA_Q
if (cm->delta_lf_present_flag) if (cm->delta_lf_present_flag) {
#if CONFIG_LOOPFILTER_LEVEL
if (mi_row == tile_info->mi_row_start)
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
xd->prev_delta_lf[lf_id] = 0;
#endif // CONFIG_LOOPFILTER_LEVEL
if (mi_row == tile_info->mi_row_start) xd->prev_delta_lf_from_base = 0; if (mi_row == tile_info->mi_row_start) xd->prev_delta_lf_from_base = 0;
}
#endif #endif
// Code each SB in the row // Code each SB in the row
...@@ -4702,6 +4730,12 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td, ...@@ -4702,6 +4730,12 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
for (k = 0; k < AOMMIN(cm->mib_size, cm->mi_cols - mi_col); k++) { for (k = 0; k < AOMMIN(cm->mib_size, cm->mi_cols - mi_col); k++) {
cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)] cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
.mbmi.current_delta_lf_from_base = current_delta_lf_from_base; .mbmi.current_delta_lf_from_base = current_delta_lf_from_base;
#if CONFIG_LOOPFILTER_LEVEL
for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
.mbmi.curr_delta_lf[lf_id] = current_delta_lf_from_base;
}
#endif // CONFIG_LOOPFILTER_LEVEL
} }
} }
} }
......
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