Commit 231fe424 authored by Fangwen Fu's avatar Fangwen Fu
Browse files

Extend delta q to have delta lf

This is the second patch.
* Add delta loop filter level at super block level.
* Add symbol coding for delta lf syntax
* Allow delta lf to work with segments

Change-Id: I393a021a875d03c6e113127cbb3543fc077308e4
parent c756e4d0
...@@ -294,7 +294,42 @@ static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) { ...@@ -294,7 +294,42 @@ static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) {
SIMD_WIDTH); SIMD_WIDTH);
} }
} }
#if CONFIG_EXT_DELTA_Q
static uint8_t get_filter_level(const AV1_COMMON *cm,
const loop_filter_info_n *lfi_n,
const MB_MODE_INFO *mbmi) {
#if CONFIG_SUPERTX
const int segment_id = AOMMIN(mbmi->segment_id, mbmi->segment_id_supertx);
assert(
IMPLIES(supertx_enabled(mbmi), mbmi->segment_id_supertx != MAX_SEGMENTS));
assert(IMPLIES(supertx_enabled(mbmi),
mbmi->segment_id_supertx <= mbmi->segment_id));
#else
const int segment_id = mbmi->segment_id;
#endif // CONFIG_SUPERTX
if (cm->delta_lf_present_flag) {
int lvl_seg = clamp(mbmi->current_delta_lf_from_base + cm->lf.filter_level,
0, MAX_LOOP_FILTER);
const int scale = 1 << (lvl_seg >> 5);
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_ALT_LF)) {
const int data = get_segdata(&cm->seg, segment_id, SEG_LVL_ALT_LF);
lvl_seg =
clamp(cm->seg.abs_delta == SEGMENT_ABSDATA ? data : lvl_seg + data, 0,
MAX_LOOP_FILTER);
}
if (cm->lf.mode_ref_delta_enabled) {
lvl_seg += cm->lf.ref_deltas[mbmi->ref_frame[0]] * scale;
if (mbmi->ref_frame[0] > INTRA_FRAME)
lvl_seg += cm->lf.mode_deltas[mode_lf_lut[mbmi->mode]] * scale;
lvl_seg = clamp(lvl_seg, 0, MAX_LOOP_FILTER);
}
return lvl_seg;
} else {
return lfi_n->lvl[segment_id][mbmi->ref_frame[0]][mode_lf_lut[mbmi->mode]];
}
}
#else
static uint8_t get_filter_level(const loop_filter_info_n *lfi_n, static uint8_t get_filter_level(const loop_filter_info_n *lfi_n,
const MB_MODE_INFO *mbmi) { const MB_MODE_INFO *mbmi) {
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
...@@ -308,6 +343,7 @@ static uint8_t get_filter_level(const loop_filter_info_n *lfi_n, ...@@ -308,6 +343,7 @@ static uint8_t get_filter_level(const loop_filter_info_n *lfi_n,
#endif // CONFIG_SUPERTX #endif // CONFIG_SUPERTX
return lfi_n->lvl[segment_id][mbmi->ref_frame[0]][mode_lf_lut[mbmi->mode]]; return lfi_n->lvl[segment_id][mbmi->ref_frame[0]][mode_lf_lut[mbmi->mode]];
} }
#endif
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0])) #define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
...@@ -763,9 +799,12 @@ static void highbd_filter_selectively_horiz( ...@@ -763,9 +799,12 @@ static void highbd_filter_selectively_horiz(
// block we are currently looking at. Shift is used to position the // block we are currently looking at. Shift is used to position the
// 1's we produce. // 1's we produce.
// TODO(JBB) Need another function for different resolution color.. // TODO(JBB) Need another function for different resolution color..
static void build_masks(const loop_filter_info_n *const lfi_n, static void build_masks(
const MODE_INFO *mi, const int shift_y, #if CONFIG_EXT_DELTA_Q
const int shift_uv, LOOP_FILTER_MASK *lfm) { AV1_COMMON *const cm,
#endif
const loop_filter_info_n *const lfi_n, const MODE_INFO *mi,
const int shift_y, const int shift_uv, LOOP_FILTER_MASK *lfm) {
const MB_MODE_INFO *mbmi = &mi->mbmi; const MB_MODE_INFO *mbmi = &mi->mbmi;
const BLOCK_SIZE block_size = mbmi->sb_type; const BLOCK_SIZE block_size = mbmi->sb_type;
// TODO(debargha): Check if masks can be setup correctly when // TODO(debargha): Check if masks can be setup correctly when
...@@ -779,7 +818,11 @@ static void build_masks(const loop_filter_info_n *const lfi_n, ...@@ -779,7 +818,11 @@ static void build_masks(const loop_filter_info_n *const lfi_n,
txsize_horz_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]]; txsize_horz_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
const TX_SIZE tx_size_uv_above = const TX_SIZE tx_size_uv_above =
txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]]; txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
#if CONFIG_EXT_DELTA_Q
const int filter_level = get_filter_level(cm, lfi_n, mbmi);
#else
const int filter_level = get_filter_level(lfi_n, mbmi); const int filter_level = get_filter_level(lfi_n, mbmi);
#endif
uint64_t *const left_y = &lfm->left_y[tx_size_y_left]; uint64_t *const left_y = &lfm->left_y[tx_size_y_left];
uint64_t *const above_y = &lfm->above_y[tx_size_y_above]; uint64_t *const above_y = &lfm->above_y[tx_size_y_above];
uint64_t *const int_4x4_y = &lfm->int_4x4_y; uint64_t *const int_4x4_y = &lfm->int_4x4_y;
...@@ -851,12 +894,16 @@ static void build_masks(const loop_filter_info_n *const lfi_n, ...@@ -851,12 +894,16 @@ static void build_masks(const loop_filter_info_n *const lfi_n,
// This function does the same thing as the one above with the exception that // This function does the same thing as the one above with the exception that
// it only affects the y masks. It exists because for blocks < 16x16 in size, // it only affects the y masks. It exists because for blocks < 16x16 in size,
// we only update u and v masks on the first block. // we only update u and v masks on the first block.
static void build_y_mask(const loop_filter_info_n *const lfi_n, static void build_y_mask(
const MODE_INFO *mi, const int shift_y, #if CONFIG_EXT_DELTA_Q
AV1_COMMON *const cm,
#endif
const loop_filter_info_n *const lfi_n, const MODE_INFO *mi,
const int shift_y,
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
int supertx_enabled, int supertx_enabled,
#endif // CONFIG_SUPERTX #endif // CONFIG_SUPERTX
LOOP_FILTER_MASK *lfm) { LOOP_FILTER_MASK *lfm) {
const MB_MODE_INFO *mbmi = &mi->mbmi; const MB_MODE_INFO *mbmi = &mi->mbmi;
const TX_SIZE tx_size_y = txsize_sqr_map[mbmi->tx_size]; const TX_SIZE tx_size_y = txsize_sqr_map[mbmi->tx_size];
const TX_SIZE tx_size_y_left = txsize_horz_map[mbmi->tx_size]; const TX_SIZE tx_size_y_left = txsize_horz_map[mbmi->tx_size];
...@@ -867,7 +914,11 @@ static void build_y_mask(const loop_filter_info_n *const lfi_n, ...@@ -867,7 +914,11 @@ static void build_y_mask(const loop_filter_info_n *const lfi_n,
#else #else
const BLOCK_SIZE block_size = mbmi->sb_type; const BLOCK_SIZE block_size = mbmi->sb_type;
#endif #endif
#if CONFIG_EXT_DELTA_Q
const int filter_level = get_filter_level(cm, lfi_n, mbmi);
#else
const int filter_level = get_filter_level(lfi_n, mbmi); const int filter_level = get_filter_level(lfi_n, mbmi);
#endif
uint64_t *const left_y = &lfm->left_y[tx_size_y_left]; uint64_t *const left_y = &lfm->left_y[tx_size_y_left];
uint64_t *const above_y = &lfm->above_y[tx_size_y_above]; uint64_t *const above_y = &lfm->above_y[tx_size_y_above];
uint64_t *const int_4x4_y = &lfm->int_4x4_y; uint64_t *const int_4x4_y = &lfm->int_4x4_y;
...@@ -971,27 +1022,48 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col, ...@@ -971,27 +1022,48 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
// loop and storing lfm in the mbmi structure so that we don't have to go // loop and storing lfm in the mbmi structure so that we don't have to go
// through the recursive loop structure multiple times. // through the recursive loop structure multiple times.
switch (mip[0]->mbmi.sb_type) { switch (mip[0]->mbmi.sb_type) {
#if CONFIG_EXT_DELTA_Q
case BLOCK_64X64: build_masks(cm, lfi_n, mip[0], 0, 0, lfm); break;
case BLOCK_64X32: build_masks(cm, lfi_n, mip[0], 0, 0, lfm);
#else
case BLOCK_64X64: build_masks(lfi_n, mip[0], 0, 0, lfm); break; case BLOCK_64X64: build_masks(lfi_n, mip[0], 0, 0, lfm); break;
case BLOCK_64X32: build_masks(lfi_n, mip[0], 0, 0, lfm); case BLOCK_64X32: build_masks(lfi_n, mip[0], 0, 0, lfm);
#endif
#if CONFIG_SUPERTX && CONFIG_TX64X64 #if CONFIG_SUPERTX && CONFIG_TX64X64
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif // CONFIG_SUPERTX && CONFIG_TX64X64 #endif // CONFIG_SUPERTX && CONFIG_TX64X64
mip2 = mip + mode_info_stride * 4; mip2 = mip + mode_info_stride * 4;
if (4 >= max_rows) break; if (4 >= max_rows) break;
#if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip2[0], 32, 8, lfm);
#else
build_masks(lfi_n, mip2[0], 32, 8, lfm); build_masks(lfi_n, mip2[0], 32, 8, lfm);
#endif
break; break;
#if CONFIG_EXT_DELTA_Q
case BLOCK_32X64: build_masks(cm, lfi_n, mip[0], 0, 0, lfm);
#else
case BLOCK_32X64: build_masks(lfi_n, mip[0], 0, 0, lfm); case BLOCK_32X64: build_masks(lfi_n, mip[0], 0, 0, lfm);
#endif
#if CONFIG_SUPERTX && CONFIG_TX64X64 #if CONFIG_SUPERTX && CONFIG_TX64X64
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif // CONFIG_SUPERTX && CONFIG_TX64X64 #endif // CONFIG_SUPERTX && CONFIG_TX64X64
mip2 = mip + 4; mip2 = mip + 4;
if (4 >= max_cols) break; if (4 >= max_cols) break;
#if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip2[0], 4, 2, lfm);
#else
build_masks(lfi_n, mip2[0], 4, 2, lfm); build_masks(lfi_n, mip2[0], 4, 2, lfm);
#endif
break; break;
default: default:
#if CONFIG_SUPERTX && CONFIG_TX64X64 #if CONFIG_SUPERTX && CONFIG_TX64X64
if (mip[0]->mbmi.tx_size == TX_64X64) { if (mip[0]->mbmi.tx_size == TX_64X64) {
#if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], 0, 0, lfm);
#else
build_masks(lfi_n, mip[0], 0, 0, lfm); build_masks(lfi_n, mip[0], 0, 0, lfm);
#endif
} else { } else {
#endif // CONFIG_SUPERTX && CONFIG_TX64X64 #endif // CONFIG_SUPERTX && CONFIG_TX64X64
for (idx_32 = 0; idx_32 < 4; mip += offset_32[idx_32], ++idx_32) { for (idx_32 = 0; idx_32 < 4; mip += offset_32[idx_32], ++idx_32) {
...@@ -1003,31 +1075,56 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col, ...@@ -1003,31 +1075,56 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
continue; continue;
switch (mip[0]->mbmi.sb_type) { switch (mip[0]->mbmi.sb_type) {
case BLOCK_32X32: case BLOCK_32X32:
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#endif
break; break;
case BLOCK_32X16: case BLOCK_32X16:
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#endif
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif #endif
if (mi_32_row_offset + 2 >= max_rows) continue; if (mi_32_row_offset + 2 >= max_rows) continue;
mip2 = mip + mode_info_stride * 2; mip2 = mip + mode_info_stride * 2;
build_masks(lfi_n, mip2[0], shift_y_32 + 16, shift_uv_32 + 4, #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip2[0], shift_y_32 + 16, shift_uv_32 + 4,
lfm); lfm);
#else
build_masks(lfi_n, mip2[0], shift_y_32 + 16, shift_uv_32 + 4, lfm);
#endif
break; break;
case BLOCK_16X32: case BLOCK_16X32:
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#endif
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif #endif
if (mi_32_col_offset + 2 >= max_cols) continue; if (mi_32_col_offset + 2 >= max_cols) continue;
mip2 = mip + 2; mip2 = mip + 2;
build_masks(lfi_n, mip2[0], shift_y_32 + 2, shift_uv_32 + 1, lfm); #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip2[0], shift_y_32 + 2, shift_uv_32 + 1,
lfm);
#else
build_masks(lfi_n, mip2[0], shift_y_32 + 2, shift_uv_32 + 1, lfm);
#endif
break; break;
default: default:
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (mip[0]->mbmi.tx_size == TX_32X32) { if (mip[0]->mbmi.tx_size == TX_32X32) {
#if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm);
#endif
break; break;
} }
#endif #endif
...@@ -1045,49 +1142,82 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col, ...@@ -1045,49 +1142,82 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
switch (mip[0]->mbmi.sb_type) { switch (mip[0]->mbmi.sb_type) {
case BLOCK_16X16: case BLOCK_16X16:
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16, #if CONFIG_EXT_DELTA_Q
lfm); build_masks(cm, lfi_n, mip[0], shift_y_32_16,
shift_uv_32_16, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16,
lfm);
#endif
break; break;
case BLOCK_16X8: case BLOCK_16X8:
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif #endif
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16, #if CONFIG_EXT_DELTA_Q
lfm); build_masks(cm, lfi_n, mip[0], shift_y_32_16,
shift_uv_32_16, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16,
lfm);
#endif
if (mi_16_row_offset + 1 >= max_rows) continue; if (mi_16_row_offset + 1 >= max_rows) continue;
mip2 = mip + mode_info_stride; mip2 = mip + mode_info_stride;
build_y_mask(lfi_n, mip2[0], shift_y_32_16 + 8, build_y_mask(
#if CONFIG_EXT_DELTA_Q
cm,
#endif
lfi_n, mip2[0], shift_y_32_16 + 8,
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
0, 0,
#endif #endif
lfm); lfm);
break; break;
case BLOCK_8X16: case BLOCK_8X16:
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (supertx_enabled(&mip[0]->mbmi)) break; if (supertx_enabled(&mip[0]->mbmi)) break;
#endif #endif
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16, #if CONFIG_EXT_DELTA_Q
lfm); build_masks(cm, lfi_n, mip[0], shift_y_32_16,
shift_uv_32_16, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32_16, shift_uv_32_16,
lfm);
#endif
if (mi_16_col_offset + 1 >= max_cols) continue; if (mi_16_col_offset + 1 >= max_cols) continue;
mip2 = mip + 1; mip2 = mip + 1;
build_y_mask(lfi_n, mip2[0], shift_y_32_16 + 1, build_y_mask(
#if CONFIG_EXT_DELTA_Q
cm,
#endif
lfi_n, mip2[0], shift_y_32_16 + 1,
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
0, 0,
#endif #endif
lfm); lfm);
break; break;
default: { default: {
const int shift_y_32_16_8_zero = const int shift_y_32_16_8_zero =
shift_y_32_16 + shift_8_y[0]; shift_y_32_16 + shift_8_y[0];
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
if (mip[0]->mbmi.tx_size == TX_16X16) { if (mip[0]->mbmi.tx_size == TX_16X16) {
#if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32_16_8_zero,
shift_uv_32_16, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32_16_8_zero, build_masks(lfi_n, mip[0], shift_y_32_16_8_zero,
shift_uv_32_16, lfm); shift_uv_32_16, lfm);
#endif
break; break;
} }
#endif #endif
build_masks(lfi_n, mip[0], shift_y_32_16_8_zero, #if CONFIG_EXT_DELTA_Q
build_masks(cm, lfi_n, mip[0], shift_y_32_16_8_zero,
shift_uv_32_16, lfm); shift_uv_32_16, lfm);
#else
build_masks(lfi_n, mip[0], shift_y_32_16_8_zero,
shift_uv_32_16, lfm);
#endif
mip += offset[0]; mip += offset[0];
for (idx_8 = 1; idx_8 < 4; mip += offset[idx_8], ++idx_8) { for (idx_8 = 1; idx_8 < 4; mip += offset[idx_8], ++idx_8) {
const int shift_y_32_16_8 = const int shift_y_32_16_8 =
...@@ -1100,11 +1230,15 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col, ...@@ -1100,11 +1230,15 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
if (mi_8_col_offset >= max_cols || if (mi_8_col_offset >= max_cols ||
mi_8_row_offset >= max_rows) mi_8_row_offset >= max_rows)
continue; continue;
build_y_mask(lfi_n, mip[0], shift_y_32_16_8, build_y_mask(
#if CONFIG_EXT_DELTA_Q
cm,
#endif
lfi_n, mip[0], shift_y_32_16_8,
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
supertx_enabled(&mip[0]->mbmi), supertx_enabled(&mip[0]->mbmi),
#endif #endif
lfm); lfm);
} }
break; break;
} }
...@@ -1380,8 +1514,13 @@ void av1_filter_block_plane_non420_ver(AV1_COMMON *cm, ...@@ -1380,8 +1514,13 @@ void av1_filter_block_plane_non420_ver(AV1_COMMON *cm,
: mb_tx_size; : mb_tx_size;
#endif #endif
// Filter level can vary per MI // Filter level can vary per MI
#if CONFIG_EXT_DELTA_Q
if (!(lfl[r][c_step] = get_filter_level(cm, &cm->lf_info, mbmi)))
continue;
#else
if (!(lfl[r][c_step] = get_filter_level(&cm->lf_info, mbmi))) continue; if (!(lfl[r][c_step] = get_filter_level(&cm->lf_info, mbmi))) continue;
#endif
#if CONFIG_VAR_TX #if CONFIG_VAR_TX
tx_size_r = AOMMIN(tx_size, cm->above_txfm_context[mi_col + c]); tx_size_r = AOMMIN(tx_size, cm->above_txfm_context[mi_col + c]);
...@@ -1574,8 +1713,13 @@ void av1_filter_block_plane_non420_hor(AV1_COMMON *cm, ...@@ -1574,8 +1713,13 @@ void av1_filter_block_plane_non420_hor(AV1_COMMON *cm,
} }
#endif #endif
// Filter level can vary per MI // Filter level can vary per MI
#if CONFIG_EXT_DELTA_Q
if (!(lfl[r][c_step] = get_filter_level(cm, &cm->lf_info, mbmi)))
continue;
#else
if (!(lfl[r][c_step] = get_filter_level(&cm->lf_info, mbmi))) continue; if (!(lfl[r][c_step] = get_filter_level(&cm->lf_info, mbmi))) continue;
#endif
#if CONFIG_VAR_TX #if CONFIG_VAR_TX
tx_size_r = AOMMIN(tx_size, cm->above_txfm_context[mi_col + c]); tx_size_r = AOMMIN(tx_size, cm->above_txfm_context[mi_col + c]);
...@@ -2400,6 +2544,9 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, ...@@ -2400,6 +2544,9 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
MACROBLOCKD *xd, int frame_filter_level, int y_only, MACROBLOCKD *xd, int frame_filter_level, int y_only,
int partial_frame) { int partial_frame) {
int start_mi_row, end_mi_row, mi_rows_to_filter; int start_mi_row, end_mi_row, mi_rows_to_filter;
#if CONFIG_EXT_DELTA_Q
int orig_filter_level = cm->lf.filter_level;
#endif
if (!frame_filter_level) return; if (!frame_filter_level) return;
start_mi_row = 0; start_mi_row = 0;
mi_rows_to_filter = cm->mi_rows; mi_rows_to_filter = cm->mi_rows;
...@@ -2410,7 +2557,13 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, ...@@ -2410,7 +2557,13 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
} }
end_mi_row = start_mi_row + mi_rows_to_filter; end_mi_row = start_mi_row + mi_rows_to_filter;
av1_loop_filter_frame_init(cm, frame_filter_level); av1_loop_filter_frame_init(cm, frame_filter_level);
#if CONFIG_EXT_DELTA_Q
cm->lf.filter_level = frame_filter_level;
#endif
av1_loop_filter_rows(frame, cm, xd->plane, start_mi_row, end_mi_row, y_only); av1_loop_filter_rows(frame, cm, xd->plane, start_mi_row, end_mi_row, y_only);
#if CONFIG_EXT_DELTA_Q
cm->lf.filter_level = orig_filter_level;
#endif
} }
void av1_loop_filter_data_reset( void av1_loop_filter_data_reset(
......
...@@ -389,6 +389,9 @@ typedef struct { ...@@ -389,6 +389,9 @@ typedef struct {
int8_t cdef_strength; int8_t cdef_strength;
#if CONFIG_DELTA_Q #if CONFIG_DELTA_Q
int current_q_index; int current_q_index;
#if CONFIG_EXT_DELTA_Q
int current_delta_lf_from_base;
#endif
#endif #endif
#if CONFIG_RD_DEBUG #if CONFIG_RD_DEBUG
RD_STATS rd_stats; RD_STATS rd_stats;
...@@ -617,6 +620,16 @@ typedef struct macroblockd { ...@@ -617,6 +620,16 @@ typedef struct macroblockd {
int prev_qindex; int prev_qindex;
int delta_qindex; int delta_qindex;
int current_qindex; int current_qindex;
#if CONFIG_EXT_DELTA_Q
// Since actual frame level loop filtering level value is not available
// at the beginning of the tile (only available during actual filtering)
// at encoder side.we record the delta_lf (against the frame level loop
// filtering level) and code the delta between previous superblock's delta
// lf and current delta lf. It is equivalent to the delta between previous
// superblock's actual lf and current lf.
int prev_delta_lf_from_base;
int current_delta_lf_from_base;
#endif
#endif #endif
#if CONFIG_ADAPT_SCAN #if CONFIG_ADAPT_SCAN
const EobThresholdMD *eob_threshold_md; const EobThresholdMD *eob_threshold_md;
......
...@@ -6327,6 +6327,9 @@ void av1_average_tile_intra_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[], ...@@ -6327,6 +6327,9 @@ void av1_average_tile_intra_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
#if CONFIG_DELTA_Q #if CONFIG_DELTA_Q
AVERAGE_TILE_CDFS(delta_q_cdf) AVERAGE_TILE_CDFS(delta_q_cdf)
#if CONFIG_EXT_DELTA_Q
AVERAGE_TILE_CDFS(delta_lf_cdf)
#endif
#endif #endif
#if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP #if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
AVERAGE_TILE_CDFS(intra_filter_cdf) AVERAGE_TILE_CDFS(intra_filter_cdf)
......
...@@ -909,6 +909,15 @@ static const aom_cdf_prob default_delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)] = { ...@@ -909,6 +909,15 @@ 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
}; };
#endif #endif
#if CONFIG_EXT_DELTA_Q
static const aom_prob default_delta_lf_probs[DELTA_LF_PROBS] = { 220, 220,
220 };
#if CONFIG_EC_MULTISYMBOL
static const aom_cdf_prob default_delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)] = {
28160, 32120, 32677, 32768, 0
};
#endif
#endif
#endif #endif
#if CONFIG_EC_MULTISYMBOL #if CONFIG_EC_MULTISYMBOL
int av1_intra_mode_ind[INTRA_MODES]; int av1_intra_mode_ind[INTRA_MODES];
...@@ -3279,6 +3288,12 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -3279,6 +3288,12 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#if CONFIG_EC_MULTISYMBOL #if CONFIG_EC_MULTISYMBOL
av1_copy(fc->delta_q_cdf, default_delta_q_cdf); av1_copy(fc->delta_q_cdf, default_delta_q_cdf);
#endif // CONFIG_EC_MULTISYMBOL #endif // CONFIG_EC_MULTISYMBOL
#if CONFIG_EXT_DELTA_Q
av1_copy(fc->delta_lf_prob, default_delta_lf_probs);
#if CONFIG_EC_MULTISYMBOL
av1_copy(fc->delta_lf_cdf, default_delta_lf_cdf);
#endif // CONFIG_EC_MULTISYMBOL
#endif