summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/common/av1_loopfilter.c
diff options
context:
space:
mode:
authortrav90 <travawine@palemoon.org>2018-10-18 21:53:44 -0500
committertrav90 <travawine@palemoon.org>2018-10-18 21:53:44 -0500
commitec910d81405c736a4490383a250299a7837c2e64 (patch)
tree4f27cc226f93a863121aef6c56313e4153a69b3e /third_party/aom/av1/common/av1_loopfilter.c
parent01eb57073ba97b2d6cbf20f745dfcc508197adc3 (diff)
downloadUXP-ec910d81405c736a4490383a250299a7837c2e64.tar
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.gz
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.lz
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.xz
UXP-ec910d81405c736a4490383a250299a7837c2e64.zip
Update aom to commit id e87fb2378f01103d5d6e477a4ef6892dc714e614
Diffstat (limited to 'third_party/aom/av1/common/av1_loopfilter.c')
-rw-r--r--third_party/aom/av1/common/av1_loopfilter.c1060
1 files changed, 804 insertions, 256 deletions
diff --git a/third_party/aom/av1/common/av1_loopfilter.c b/third_party/aom/av1/common/av1_loopfilter.c
index 10df7fa91..95f7a8687 100644
--- a/third_party/aom/av1/common/av1_loopfilter.c
+++ b/third_party/aom/av1/common/av1_loopfilter.c
@@ -13,15 +13,28 @@
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
-#include "av1/common/av1_loopfilter.h"
-#include "av1/common/onyxc_int.h"
-#include "av1/common/reconinter.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"
-
+#include "av1/common/av1_loopfilter.h"
+#include "av1/common/onyxc_int.h"
+#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
+#if CONFIG_LOOPFILTER_LEVEL
+static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = {
+ { SEG_LVL_ALT_LF_Y_V, SEG_LVL_ALT_LF_Y_H },
+ { SEG_LVL_ALT_LF_U, SEG_LVL_ALT_LF_U },
+ { 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
+
#if CONFIG_LPF_DIRECT
static void pick_filter_pixel_left(uint8_t *const src, uint8_t *const line,
int *const orig_pos, int length, int row,
@@ -278,6 +291,29 @@ static int pick_min_grad_direct(uint8_t *const src, int length, int row,
#define PARALLEL_DEBLOCKING_15TAPLUMAONLY 1
#define PARALLEL_DEBLOCKING_DISABLE_15TAP 0
+#if CONFIG_DEBLOCK_13TAP
+#define PARALLEL_DEBLOCKING_5_TAP_CHROMA 1
+#else
+#define PARALLEL_DEBLOCKING_5_TAP_CHROMA 0
+#endif
+
+#if PARALLEL_DEBLOCKING_5_TAP_CHROMA
+extern void aom_lpf_vertical_6_c(uint8_t *s, int pitch, const uint8_t *blimit,
+ const uint8_t *limit, const uint8_t *thresh);
+
+extern void aom_lpf_horizontal_6_c(uint8_t *s, int p, const uint8_t *blimit,
+ const uint8_t *limit, const uint8_t *thresh);
+
+extern void aom_highbd_lpf_horizontal_6_c(uint16_t *s, int p,
+ const uint8_t *blimit,
+ const uint8_t *limit,
+ const uint8_t *thresh, int bd);
+
+extern void aom_highbd_lpf_vertical_6_c(uint16_t *s, int pitch,
+ const uint8_t *blimit,
+ const uint8_t *limit,
+ const uint8_t *thresh, int bd);
+#endif
// 64 bit masks for left transform size. Each 1 represents a position where
// we should apply a loop filter across the left border of an 8x8 block
@@ -376,7 +412,9 @@ static const uint64_t left_prediction_mask[BLOCK_SIZES_ALL] = {
0x0000000000000101ULL, // BLOCK_4X16,
0x0000000000000001ULL, // BLOCK_16X4,
0x0000000001010101ULL, // BLOCK_8X32,
- 0x0000000000000001ULL, // BLOCK_32X8
+ 0x0000000000000001ULL, // BLOCK_32X8,
+ 0x0101010101010101ULL, // BLOCK_16X64,
+ 0x0000000000000101ULL, // BLOCK_64X16
};
// 64 bit mask to shift and set for each prediction size.
@@ -402,7 +440,9 @@ static const uint64_t above_prediction_mask[BLOCK_SIZES_ALL] = {
0x0000000000000001ULL, // BLOCK_4X16,
0x0000000000000003ULL, // BLOCK_16X4,
0x0000000000000001ULL, // BLOCK_8X32,
- 0x000000000000000fULL, // BLOCK_32X8
+ 0x000000000000000fULL, // BLOCK_32X8,
+ 0x0000000000000003ULL, // BLOCK_16X64,
+ 0x00000000000000ffULL, // BLOCK_64X16
};
// 64 bit mask to shift and set for each prediction size. A bit is set for
// each 8x8 block that would be in the top left most block of the given block
@@ -429,7 +469,9 @@ static const uint64_t size_mask[BLOCK_SIZES_ALL] = {
0x0000000000000101ULL, // BLOCK_4X16,
0x0000000000000003ULL, // BLOCK_16X4,
0x0000000001010101ULL, // BLOCK_8X32,
- 0x000000000000000fULL, // BLOCK_32X8
+ 0x000000000000000fULL, // BLOCK_32X8,
+ 0x0303030303030303ULL, // BLOCK_16X64,
+ 0x000000000000ffffULL, // BLOCK_64X16
};
// These are used for masking the left and above 32x32 borders.
@@ -486,7 +528,9 @@ static const uint16_t left_prediction_mask_uv[BLOCK_SIZES_ALL] = {
0x0001, // BLOCK_4X16,
0x0001, // BLOCK_16X4,
0x0011, // BLOCK_8X32,
- 0x0001, // BLOCK_32X8
+ 0x0001, // BLOCK_32X8,
+ 0x1111, // BLOCK_16X64,
+ 0x0001, // BLOCK_64X16,
};
// 16 bit above mask to shift and set for uv each prediction size.
@@ -512,7 +556,9 @@ static const uint16_t above_prediction_mask_uv[BLOCK_SIZES_ALL] = {
0x0001, // BLOCK_4X16,
0x0001, // BLOCK_16X4,
0x0001, // BLOCK_8X32,
- 0x0003, // BLOCK_32X8
+ 0x0003, // BLOCK_32X8,
+ 0x0001, // BLOCK_16X64,
+ 0x000f, // BLOCK_64X16
};
// 64 bit mask to shift and set for each uv prediction size
@@ -538,28 +584,26 @@ static const uint16_t size_mask_uv[BLOCK_SIZES_ALL] = {
0x0001, // BLOCK_4X16,
0x0001, // BLOCK_16X4,
0x0011, // BLOCK_8X32,
- 0x0003, // BLOCK_32X8
+ 0x0003, // BLOCK_32X8,
+ 0x1111, // BLOCK_16X64,
+ 0x000f, // BLOCK_64X16
};
static const uint16_t left_border_uv = 0x1111;
static const uint16_t above_border_uv = 0x000f;
static const int mode_lf_lut[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
-#if CONFIG_ALT_INTRA
0,
#if CONFIG_SMOOTH_HV
0, 0,
#endif // CONFIG_SMOOTH_HV
-#endif // CONFIG_ALT_INTRA
1, 1, 0, 1, // INTER_MODES (ZEROMV == 0)
-#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
// 1, 1, 1, 1, 1, // INTER_SINGLEREF_COMP_MODES
// NOTE(zoeliu): Remove SR_NEAREST_NEWMV
1, 1, 1, 1, // INTER_SINGLEREF_COMP_MODES
#endif // CONFIG_COMPOUND_SINGLEREF
1, 1, 1, 1, 1, 1, 0, 1 // INTER_COMPOUND_MODES (ZERO_ZEROMV == 0)
-#endif // CONFIG_EXT_INTER
};
static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) {
@@ -585,7 +629,17 @@ static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) {
#if CONFIG_EXT_DELTA_Q
static uint8_t get_filter_level(const AV1_COMMON *cm,
const loop_filter_info_n *lfi_n,
+#if CONFIG_LOOPFILTER_LEVEL
+ const int dir_idx, int plane,
+#endif
+#if CONFIG_LPF_SB
+ int mi_row, int mi_col,
+#endif
const MB_MODE_INFO *mbmi) {
+#if CONFIG_LPF_SB
+ return cm->mi[mi_row * cm->mi_stride + mi_col].mbmi.filt_lvl;
+#endif
+
#if CONFIG_SUPERTX
const int segment_id = AOMMIN(mbmi->segment_id, mbmi->segment_id_supertx);
assert(
@@ -596,15 +650,38 @@ static uint8_t get_filter_level(const AV1_COMMON *cm,
const int segment_id = mbmi->segment_id;
#endif // CONFIG_SUPERTX
if (cm->delta_lf_present_flag) {
+#if CONFIG_LOOPFILTER_LEVEL
+ int delta_lf;
+ if (cm->delta_lf_multi) {
+ const int delta_lf_idx = delta_lf_id_lut[plane][dir_idx];
+ delta_lf = mbmi->curr_delta_lf[delta_lf_idx];
+ } else {
+ delta_lf = mbmi->current_delta_lf_from_base;
+ }
+ int lvl_seg =
+ clamp(delta_lf + cm->lf.filter_level[dir_idx], 0, MAX_LOOP_FILTER);
+#else
int lvl_seg = clamp(mbmi->current_delta_lf_from_base + cm->lf.filter_level,
0, MAX_LOOP_FILTER);
+#endif
const int scale = 1 << (lvl_seg >> 5);
+#if CONFIG_LOOPFILTER_LEVEL
+ assert(plane >= 0 && plane <= 2);
+ const int seg_lf_feature_id = seg_lvl_lf_lut[plane][dir_idx];
+ if (segfeature_active(&cm->seg, segment_id, seg_lf_feature_id)) {
+ const int data = get_segdata(&cm->seg, segment_id, seg_lf_feature_id);
+ lvl_seg =
+ clamp(cm->seg.abs_delta == SEGMENT_ABSDATA ? data : lvl_seg + data, 0,
+ MAX_LOOP_FILTER);
+ }
+#else
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);
}
+#endif // CONFIG_LOOPFILTER_LEVEL
if (cm->lf.mode_ref_delta_enabled) {
lvl_seg += cm->lf.ref_deltas[mbmi->ref_frame[0]] * scale;
@@ -614,7 +691,12 @@ static uint8_t get_filter_level(const AV1_COMMON *cm,
}
return lvl_seg;
} else {
+#if CONFIG_LOOPFILTER_LEVEL
+ return lfi_n
+ ->lvl[segment_id][dir_idx][mbmi->ref_frame[0]][mode_lf_lut[mbmi->mode]];
+#else
return lfi_n->lvl[segment_id][mbmi->ref_frame[0]][mode_lf_lut[mbmi->mode]];
+#endif
}
}
#else
@@ -648,12 +730,39 @@ void av1_loop_filter_init(AV1_COMMON *cm) {
memset(lfi->lfthr[lvl].hev_thr, (lvl >> 4), SIMD_WIDTH);
}
-void av1_loop_filter_frame_init(AV1_COMMON *cm, int default_filt_lvl) {
+#if CONFIG_LPF_SB
+void av1_loop_filter_sb_level_init(AV1_COMMON *cm, int mi_row, int mi_col,
+ int lvl) {
+ const int mi_row_start = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET);
+ const int mi_col_start = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
+ const int mi_row_range = mi_row - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
+ const int mi_col_range = mi_col - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
+ const int mi_row_end = AOMMIN(mi_row_range, cm->mi_rows);
+ const int mi_col_end = AOMMIN(mi_col_range, cm->mi_cols);
+
+ int row, col;
+ for (row = mi_row_start; row < mi_row_end; ++row) {
+ for (col = mi_col_start; col < mi_col_end; ++col) {
+ // Note: can't use cm->mi_grid_visible. Because for each partition,
+ // all visible pointers will point to the first of the partition.
+ cm->mi[row * cm->mi_stride + col].mbmi.filt_lvl = lvl;
+ }
+ }
+}
+#endif // CONFIG_LPF_SB
+
+void av1_loop_filter_frame_init(AV1_COMMON *cm, int default_filt_lvl,
+ int default_filt_lvl_r
+#if CONFIG_LOOPFILTER_LEVEL
+ ,
+ int plane
+#endif
+ ) {
int seg_id;
// n_shift is the multiplier for lf_deltas
// the multiplier is 1 for when filter_lvl is between 0 and 31;
// 2 when filter_lvl is between 32 and 63
- const int scale = 1 << (default_filt_lvl >> 5);
+ int scale = 1 << (default_filt_lvl >> 5);
loop_filter_info_n *const lfi = &cm->lf_info;
struct loopfilter *const lf = &cm->lf;
const struct segmentation *const seg = &cm->seg;
@@ -665,29 +774,64 @@ void av1_loop_filter_frame_init(AV1_COMMON *cm, int default_filt_lvl) {
}
for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) {
- int lvl_seg = default_filt_lvl;
- if (segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) {
- const int data = get_segdata(seg, seg_id, SEG_LVL_ALT_LF);
- lvl_seg = clamp(
- seg->abs_delta == SEGMENT_ABSDATA ? data : default_filt_lvl + data, 0,
- MAX_LOOP_FILTER);
- }
+ for (int dir = 0; dir < 2; ++dir) {
+ int lvl_seg = (dir == 0) ? default_filt_lvl : default_filt_lvl_r;
+#if CONFIG_LOOPFILTER_LEVEL
+ assert(plane >= 0 && plane <= 2);
+ const int seg_lf_feature_id = seg_lvl_lf_lut[plane][dir];
+ if (segfeature_active(seg, seg_id, seg_lf_feature_id)) {
+ const int data = get_segdata(&cm->seg, seg_id, seg_lf_feature_id);
+ lvl_seg = clamp(
+ seg->abs_delta == SEGMENT_ABSDATA ? data : default_filt_lvl + data,
+ 0, MAX_LOOP_FILTER);
+ }
+#else
+ if (segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) {
+ const int data = get_segdata(seg, seg_id, SEG_LVL_ALT_LF);
+ lvl_seg = clamp(
+ seg->abs_delta == SEGMENT_ABSDATA ? data : default_filt_lvl + data,
+ 0, MAX_LOOP_FILTER);
+ }
+#endif // CONFIG_LOOPFILTER_LEVEL
- if (!lf->mode_ref_delta_enabled) {
- // we could get rid of this if we assume that deltas are set to
- // zero when not in use; encoder always uses deltas
- memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id]));
- } else {
- int ref, mode;
- const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale;
- lfi->lvl[seg_id][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER);
-
- for (ref = LAST_FRAME; ref < TOTAL_REFS_PER_FRAME; ++ref) {
- for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) {
- const int inter_lvl = lvl_seg + lf->ref_deltas[ref] * scale +
- lf->mode_deltas[mode] * scale;
- lfi->lvl[seg_id][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER);
+ if (!lf->mode_ref_delta_enabled) {
+// we could get rid of this if we assume that deltas are set to
+// zero when not in use; encoder always uses deltas
+#if CONFIG_LOOPFILTER_LEVEL
+ memset(lfi->lvl[seg_id][dir], lvl_seg, sizeof(lfi->lvl[seg_id][dir]));
+#else
+ memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id]));
+#endif // CONFIG_LOOPFILTER_LEVEL
+ } else {
+ int ref, mode;
+#if CONFIG_LOOPFILTER_LEVEL
+ scale = 1 << (lvl_seg >> 5);
+
+ const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale;
+ lfi->lvl[seg_id][dir][INTRA_FRAME][0] =
+ clamp(intra_lvl, 0, MAX_LOOP_FILTER);
+
+ for (ref = LAST_FRAME; ref < TOTAL_REFS_PER_FRAME; ++ref) {
+ for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) {
+ const int inter_lvl = lvl_seg + lf->ref_deltas[ref] * scale +
+ lf->mode_deltas[mode] * scale;
+ lfi->lvl[seg_id][dir][ref][mode] =
+ clamp(inter_lvl, 0, MAX_LOOP_FILTER);
+ }
}
+#else
+ (void)default_filt_lvl_r;
+ const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale;
+ lfi->lvl[seg_id][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER);
+
+ for (ref = LAST_FRAME; ref < TOTAL_REFS_PER_FRAME; ++ref) {
+ for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) {
+ const int inter_lvl = lvl_seg + lf->ref_deltas[ref] * scale +
+ lf->mode_deltas[mode] * scale;
+ lfi->lvl[seg_id][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER);
+ }
+ }
+#endif
}
}
}
@@ -1384,7 +1528,15 @@ static void build_masks(AV1_COMMON *const cm,
const TX_SIZE tx_size_uv_above =
txsize_vert_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#else
+#if CONFIG_LPF_SB
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#else
const int filter_level = get_filter_level(cm, lfi_n, mbmi);
+#endif // CONFIG_LPF_SB
+#endif
#else
const int filter_level = get_filter_level(lfi_n, mbmi);
(void)cm;
@@ -1478,7 +1630,15 @@ static void build_y_mask(AV1_COMMON *const cm,
const BLOCK_SIZE block_size = mbmi->sb_type;
#endif
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#else
+#if CONFIG_LPF_SB
+ const int filter_level = get_filter_level(cm, lfi_n, 0, 0, mbmi);
+#else
const int filter_level = get_filter_level(cm, lfi_n, mbmi);
+#endif // CONFIG_LPF_SB
+#endif
#else
const int filter_level = get_filter_level(lfi_n, mbmi);
(void)cm;
@@ -1548,6 +1708,9 @@ static void update_tile_boundary_filter_mask(AV1_COMMON *const cm,
void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
MODE_INFO **mi, const int mode_info_stride,
LOOP_FILTER_MASK *lfm) {
+#if CONFIG_EXT_PARTITION
+ assert(0 && "Not yet updated");
+#endif // CONFIG_EXT_PARTITION
int idx_32, idx_16, idx_8;
const loop_filter_info_n *const lfi_n = &cm->lf_info;
MODE_INFO **mip = mi;
@@ -1575,9 +1738,6 @@ void av1_setup_mask(AV1_COMMON *const cm, const int mi_row, const int mi_col,
int i;
const int max_rows = AOMMIN(cm->mi_rows - mi_row, MAX_MIB_SIZE);
const int max_cols = AOMMIN(cm->mi_cols - mi_col, MAX_MIB_SIZE);
-#if CONFIG_EXT_PARTITION
- assert(0 && "Not yet updated");
-#endif // CONFIG_EXT_PARTITION
av1_zero(*lfm);
assert(mip[0] != NULL);
@@ -1898,8 +2058,8 @@ static void filter_selectively_vert(
orig_pos[i] = -1;
}
- int direct = pick_min_grad_direct(src, left_filt_len, row, col, width,
- height, pitch, 1, 0);
+ const int direct = pick_min_grad_direct(src, left_filt_len, row, col,
+ width, height, pitch, 1, 0);
pick_filter_block_vert(src, block, orig_pos, left_filt_len, row, col,
width, height, pitch, pivot, line_length, 1,
@@ -1928,8 +2088,8 @@ static void filter_selectively_vert(
orig_pos[i] = -1;
}
- int direct = pick_min_grad_direct(src, 4, row, col + 4, width, height,
- pitch, 1, 0);
+ const int direct = pick_min_grad_direct(src, 4, row, col + 4, width,
+ height, pitch, 1, 0);
pick_filter_block_vert(src, block, orig_pos, 4, row, col + 4, width,
height, pitch, pivot, line_length, 1, direct);
@@ -2083,7 +2243,18 @@ static void get_filter_level_and_masks_non420(
// Filter level can vary per MI
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ if (!(lfl_r[c_step] = get_filter_level(cm, &cm->lf_info, 0, 0, mbmi)))
+ continue;
+#else
+#if CONFIG_LPF_SB
+ if (!(lfl_r[c_step] =
+ get_filter_level(cm, &cm->lf_info, mi_row, mi_col, mbmi)))
+ continue;
+#else
if (!(lfl_r[c_step] = get_filter_level(cm, &cm->lf_info, mbmi))) continue;
+#endif // CONFIG_LPF_SB
+#endif
#else
if (!(lfl_r[c_step] = get_filter_level(&cm->lf_info, mbmi))) continue;
#endif
@@ -2249,7 +2420,7 @@ void av1_filter_block_plane_non420_ver(AV1_COMMON *const cm,
&col_masks);
// Disable filtering on the leftmost column or tile boundary
- unsigned int border_mask = ~(mi_col == 0);
+ unsigned int border_mask = ~(mi_col == 0 ? 1 : 0);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
MODE_INFO *const mi = cm->mi + (mi_row + idx_r) * cm->mi_stride + mi_col;
if (av1_disable_loopfilter_on_tile_boundary(cm) &&
@@ -2588,7 +2759,13 @@ static const uint32_t av1_prediction_masks[NUM_EDGE_DIRS][BLOCK_SIZES_ALL] = {
4 - 1, // BLOCK_4X16,
16 - 1, // BLOCK_16X4,
8 - 1, // BLOCK_8X32,
- 32 - 1 // BLOCK_32X8
+ 32 - 1, // BLOCK_32X8,
+ 16 - 1, // BLOCK_16X64,
+ 64 - 1, // BLOCK_64X16
+#if CONFIG_EXT_PARTITION
+ 32 - 1, // BLOCK_32X128
+ 128 - 1, // BLOCK_128X32
+#endif // CONFIG_EXT_PARTITION
},
// mask for horizontal edges filtering
{
@@ -2618,7 +2795,13 @@ static const uint32_t av1_prediction_masks[NUM_EDGE_DIRS][BLOCK_SIZES_ALL] = {
16 - 1, // BLOCK_4X16,
4 - 1, // BLOCK_16X4,
32 - 1, // BLOCK_8X32,
- 8 - 1 // BLOCK_32X8
+ 8 - 1, // BLOCK_32X8,
+ 64 - 1, // BLOCK_16X64,
+ 16 - 1, // BLOCK_64X16
+#if CONFIG_EXT_PARTITION
+ 128 - 1, // BLOCK_32X128
+ 32 - 1, // BLOCK_128X32
+#endif // CONFIG_EXT_PARTITION
},
};
@@ -2640,6 +2823,10 @@ static const uint32_t av1_transform_masks[NUM_EDGE_DIRS][TX_SIZES_ALL] = {
16 - 1, // TX_16X8
16 - 1, // TX_16X32
32 - 1, // TX_32X16
+#if CONFIG_TX64X64
+ 32 - 1, // TX_32X64
+ 64 - 1, // TX_64X32
+#endif // CONFIG_TX64X64
4 - 1, // TX_4X16
16 - 1, // TX_16X4
8 - 1, // TX_8X32
@@ -2662,6 +2849,10 @@ static const uint32_t av1_transform_masks[NUM_EDGE_DIRS][TX_SIZES_ALL] = {
8 - 1, // TX_16X8
32 - 1, // TX_16X32
16 - 1, // TX_32X16
+#if CONFIG_TX64X64
+ 64 - 1, // TX_32X64
+ 32 - 1, // TX_64X32
+#endif // CONFIG_TX64X64
16 - 1, // TX_4X16
4 - 1, // TX_16X4
32 - 1, // TX_8X32
@@ -2669,15 +2860,16 @@ static const uint32_t av1_transform_masks[NUM_EDGE_DIRS][TX_SIZES_ALL] = {
}
};
-static TX_SIZE av1_get_transform_size(const MODE_INFO *const pCurr,
- const EDGE_DIR edgeDir, const int mi_row,
+static TX_SIZE av1_get_transform_size(const MODE_INFO *const mi,
+ const EDGE_DIR edge_dir, const int mi_row,
const int mi_col, const int plane,
- const struct macroblockd_plane *pPlane,
- const uint32_t scaleHorz,
- const uint32_t scaleVert) {
- const MB_MODE_INFO *mbmi = &pCurr->mbmi;
- TX_SIZE tx_size = (plane == PLANE_TYPE_Y) ? mbmi->tx_size
- : av1_get_uv_tx_size(mbmi, pPlane);
+ const struct macroblockd_plane *plane_ptr,
+ const uint32_t scale_horz,
+ const uint32_t scale_vert) {
+ const MB_MODE_INFO *mbmi = &mi->mbmi;
+ TX_SIZE tx_size = (plane == AOM_PLANE_Y)
+ ? mbmi->tx_size
+ : av1_get_uv_tx_size(mbmi, plane_ptr);
assert(tx_size < TX_SIZES_ALL);
#if CONFIG_VAR_TX
@@ -2690,7 +2882,7 @@ static TX_SIZE av1_get_transform_size(const MODE_INFO *const pCurr,
const int idx_r = mi_row & MAX_MIB_MASK;
const int c = idx_c >> mi_width_log2_lookup[BLOCK_8X8];
const int r = idx_r >> mi_height_log2_lookup[BLOCK_8X8];
- const BLOCK_SIZE sb_type = pCurr->mbmi.sb_type;
+ const BLOCK_SIZE sb_type = mi->mbmi.sb_type;
const int blk_row = r & (num_8x8_blocks_high_lookup[sb_type] - 1);
const int blk_col = c & (num_8x8_blocks_wide_lookup[sb_type] - 1);
@@ -2702,40 +2894,40 @@ static TX_SIZE av1_get_transform_size(const MODE_INFO *const pCurr,
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
const BLOCK_SIZE bsize =
- AOMMAX(BLOCK_4X4, ss_size_lookup[sb_type][scaleHorz][scaleVert]);
+ AOMMAX(BLOCK_4X4, ss_size_lookup[sb_type][scale_horz][scale_vert]);
#else
- const BLOCK_SIZE bsize = ss_size_lookup[sb_type][scaleHorz][scaleVert];
+ const BLOCK_SIZE bsize = ss_size_lookup[sb_type][scale_horz][scale_vert];
#endif
const TX_SIZE mb_tx_size = mbmi->inter_tx_size[tx_row_idx][tx_col_idx];
assert(mb_tx_size < TX_SIZES_ALL);
- tx_size = (plane == PLANE_TYPE_UV)
- ? uv_txsize_lookup[bsize][mb_tx_size][0][0]
- : mb_tx_size;
+ tx_size = (plane == AOM_PLANE_Y)
+ ? mb_tx_size
+ : uv_txsize_lookup[bsize][mb_tx_size][0][0];
assert(tx_size < TX_SIZES_ALL);
}
#else
(void)mi_row;
(void)mi_col;
- (void)scaleHorz;
- (void)scaleVert;
+ (void)scale_horz;
+ (void)scale_vert;
#endif // CONFIG_VAR_TX
// since in case of chrominance or non-square transorm need to convert
// transform size into transform size in particular direction.
// for vertical edge, filter direction is horizontal, for horizontal
// edge, filter direction is vertical.
- tx_size = (VERT_EDGE == edgeDir) ? txsize_horz_map[tx_size]
- : txsize_vert_map[tx_size];
+ tx_size = (VERT_EDGE == edge_dir) ? txsize_horz_map[tx_size]
+ : txsize_vert_map[tx_size];
return tx_size;
}
typedef struct AV1_DEBLOCKING_PARAMETERS {
// length of the filter applied to the outer edge
- uint32_t filterLength;
+ uint32_t filter_length;
// length of the filter applied to the inner edge
- uint32_t filterLengthInternal;
+ uint32_t filter_length_internal;
// deblocking limits
const uint8_t *lim;
const uint8_t *mblim;
@@ -2743,291 +2935,595 @@ typedef struct AV1_DEBLOCKING_PARAMETERS {
} AV1_DEBLOCKING_PARAMETERS;
static void set_lpf_parameters(
- AV1_DEBLOCKING_PARAMETERS *const pParams, const MODE_INFO **const ppCurr,
- const ptrdiff_t modeStep, const AV1_COMMON *const cm,
- const EDGE_DIR edgeDir, const uint32_t x, const uint32_t y,
- const uint32_t width, const uint32_t height, const int plane,
- const struct macroblockd_plane *const pPlane, const uint32_t scaleHorz,
- const uint32_t scaleVert) {
+ AV1_DEBLOCKING_PARAMETERS *const params, const ptrdiff_t mode_step,
+ const AV1_COMMON *const cm, const EDGE_DIR edge_dir, const uint32_t x,
+ const uint32_t y, const int plane,
+ const struct macroblockd_plane *const plane_ptr) {
// reset to initial values
- pParams->filterLength = 0;
- pParams->filterLengthInternal = 0;
+ params->filter_length = 0;
+ params->filter_length_internal = 0;
+
// no deblocking is required
+ const uint32_t width = plane_ptr->dst.width;
+ const uint32_t height = plane_ptr->dst.height;
if ((width <= x) || (height <= y)) {
return;
}
- const int mi_row = (y << scaleVert) >> MI_SIZE_LOG2;
- const int mi_col = (x << scaleHorz) >> MI_SIZE_LOG2;
- const MB_MODE_INFO *mbmi = &ppCurr[0]->mbmi;
+ const uint32_t scale_horz = plane_ptr->subsampling_x;
+ const uint32_t scale_vert = plane_ptr->subsampling_y;
+ const int mi_row = (y << scale_vert) >> MI_SIZE_LOG2;
+ const int mi_col = (x << scale_horz) >> MI_SIZE_LOG2;
+ MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride + mi_col;
+ const MB_MODE_INFO *mbmi = &mi[0]->mbmi;
{
const TX_SIZE ts =
- av1_get_transform_size(ppCurr[0], edgeDir, mi_row, mi_col, plane,
- pPlane, scaleHorz, scaleVert);
+ av1_get_transform_size(mi[0], edge_dir, mi_row, mi_col, plane,
+ plane_ptr, scale_horz, scale_vert);
#if CONFIG_EXT_DELTA_Q
- const uint32_t currLevel = get_filter_level(cm, &cm->lf_info, mbmi);
+#if CONFIG_LOOPFILTER_LEVEL
+ const uint32_t curr_level =
+ get_filter_level(cm, &cm->lf_info, edge_dir, plane, mbmi);
#else
- const uint32_t currLevel = get_filter_level(&cm->lf_info, mbmi);
+#if CONFIG_LPF_SB
+ const uint32_t curr_level =
+ get_filter_level(cm, &cm->lf_info, mi_row, mi_col, mbmi);
+#else
+ const uint32_t curr_level = get_filter_level(cm, &cm->lf_info, mbmi);
+#endif // CONFIG_LPF_SB
+#endif
+#else
+ const uint32_t curr_level = get_filter_level(&cm->lf_info, mbmi);
#endif // CONFIG_EXT_DELTA_Q
- const int currSkipped = mbmi->skip && is_inter_block(mbmi);
- const uint32_t coord = (VERT_EDGE == edgeDir) ? (x) : (y);
- uint32_t level = currLevel;
+ const int curr_skipped = mbmi->skip && is_inter_block(mbmi);
+ const uint32_t coord = (VERT_EDGE == edge_dir) ? (x) : (y);
+ uint32_t level = curr_level;
// prepare outer edge parameters. deblock the edge if it's an edge of a TU
if (coord) {
#if CONFIG_LOOPFILTERING_ACROSS_TILES
- MODE_INFO *const mi = cm->mi + mi_row * cm->mi_stride + mi_col;
+ MODE_INFO *const mi_bound = cm->mi + mi_row * cm->mi_stride + mi_col;
if (!av1_disable_loopfilter_on_tile_boundary(cm) ||
- ((VERT_EDGE == edgeDir) &&
- (0 == (mi->mbmi.boundary_info & TILE_LEFT_BOUNDARY))) ||
- ((HORZ_EDGE == edgeDir) &&
- (0 == (mi->mbmi.boundary_info & TILE_ABOVE_BOUNDARY))))
+ ((VERT_EDGE == edge_dir) &&
+ (0 == (mi_bound->mbmi.boundary_info & TILE_LEFT_BOUNDARY))) ||
+ ((HORZ_EDGE == edge_dir) &&
+ (0 == (mi_bound->mbmi.boundary_info & TILE_ABOVE_BOUNDARY))))
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
{
- const int32_t tuEdge =
- (coord & av1_transform_masks[edgeDir][ts]) ? (0) : (1);
- if (tuEdge) {
- const MODE_INFO *const pPrev = *(ppCurr - modeStep);
- const int pvRow =
- (VERT_EDGE == edgeDir) ? (mi_row) : (mi_row - (1 << scaleVert));
- const int pvCol =
- (VERT_EDGE == edgeDir) ? (mi_col - (1 << scaleHorz)) : (mi_col);
- const TX_SIZE pvTs =
- av1_get_transform_size(pPrev, edgeDir, pvRow, pvCol, plane,
- pPlane, scaleHorz, scaleVert);
+ const int32_t tu_edge =
+ (coord & av1_transform_masks[edge_dir][ts]) ? (0) : (1);
+ if (tu_edge) {
+ const MODE_INFO *const mi_prev = *(mi - mode_step);
+ const int pv_row =
+ (VERT_EDGE == edge_dir) ? (mi_row) : (mi_row - (1 << scale_vert));
+ const int pv_col =
+ (VERT_EDGE == edge_dir) ? (mi_col - (1 << scale_horz)) : (mi_col);
+ const TX_SIZE pv_ts =
+ av1_get_transform_size(mi_prev, edge_dir, pv_row, pv_col, plane,
+ plane_ptr, scale_horz, scale_vert);
#if CONFIG_EXT_DELTA_Q
- const uint32_t pvLvl =
- get_filter_level(cm, &cm->lf_info, &pPrev->mbmi);
+#if CONFIG_LOOPFILTER_LEVEL
+ const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, edge_dir,
+ plane, &mi_prev->mbmi);
+#else
+#if CONFIG_LPF_SB
+ const uint32_t pv_lvl = get_filter_level(cm, &cm->lf_info, pv_row,
+ pv_col, &mi_prev->mbmi);
+#else
+ const uint32_t pv_lvl =
+ get_filter_level(cm, &cm->lf_info, &mi_prev->mbmi);
+#endif // CONFIG_LPF_SB
+#endif
#else
- const uint32_t pvLvl = get_filter_level(&cm->lf_info, &pPrev->mbmi);
+ const uint32_t pv_lvl =
+ get_filter_level(&cm->lf_info, &mi_prev->mbmi);
#endif // CONFIG_EXT_DELTA_Q
- const int pvSkip = pPrev->mbmi.skip && is_inter_block(&pPrev->mbmi);
- const int32_t puEdge =
+ const int pv_skip =
+ mi_prev->mbmi.skip && is_inter_block(&mi_prev->mbmi);
+ const int32_t pu_edge =
(coord &
- av1_prediction_masks[edgeDir]
- [ss_size_lookup[mbmi->sb_type][scaleHorz]
- [scaleVert]])
+ av1_prediction_masks[edge_dir]
+ [ss_size_lookup[mbmi->sb_type][scale_horz]
+ [scale_vert]])
? (0)
: (1);
// if the current and the previous blocks are skipped,
// deblock the edge if the edge belongs to a PU's edge only.
- if ((currLevel || pvLvl) && (!pvSkip || !currSkipped || puEdge)) {
- const TX_SIZE minTs = AOMMIN(ts, pvTs);
- if (TX_4X4 >= minTs) {
- pParams->filterLength = 4;
- } else if (TX_8X8 == minTs) {
- pParams->filterLength = 8;
+ if ((curr_level || pv_lvl) &&
+ (!pv_skip || !curr_skipped || pu_edge)) {
+ const TX_SIZE min_ts = AOMMIN(ts, pv_ts);
+ if (TX_4X4 >= min_ts) {
+ params->filter_length = 4;
+ } else if (TX_8X8 == min_ts) {
+ params->filter_length = 8;
} else {
- pParams->filterLength = 16;
+ params->filter_length = 16;
#if PARALLEL_DEBLOCKING_15TAPLUMAONLY
// No wide filtering for chroma plane
if (plane != 0) {
- pParams->filterLength = 8;
+#if PARALLEL_DEBLOCKING_5_TAP_CHROMA
+ params->filter_length = 6;
+#else
+ params->filter_length = 8;
+#endif
}
#endif
}
#if PARALLEL_DEBLOCKING_DISABLE_15TAP
- pParams->filterLength = (TX_4X4 >= AOMMIN(ts, pvTs)) ? (4) : (8);
+ params->filter_length = (TX_4X4 >= AOMMIN(ts, pv_ts)) ? (4) : (8);
#endif // PARALLEL_DEBLOCKING_DISABLE_15TAP
// update the level if the current block is skipped,
// but the previous one is not
- level = (currLevel) ? (currLevel) : (pvLvl);
+ level = (curr_level) ? (curr_level) : (pv_lvl);
}
}
}
#if !CONFIG_CB4X4
// prepare internal edge parameters
- if (currLevel && !currSkipped) {
- pParams->filterLengthInternal = (TX_4X4 >= ts) ? (4) : (0);
+ if (curr_level && !curr_skipped) {
+ params->filter_length_internal = (TX_4X4 >= ts) ? (4) : (0);
}
#endif
// prepare common parameters
- if (pParams->filterLength || pParams->filterLengthInternal) {
+ if (params->filter_length || params->filter_length_internal) {
const loop_filter_thresh *const limits = cm->lf_info.lfthr + level;
- pParams->lim = limits->lim;
- pParams->mblim = limits->mblim;
- pParams->hev_thr = limits->hev_thr;
+ params->lim = limits->lim;
+ params->mblim = limits->mblim;
+ params->hev_thr = limits->hev_thr;
}
}
}
}
-static void av1_filter_block_plane_vert(const AV1_COMMON *const cm,
- const int plane,
- const MACROBLOCKD_PLANE *const pPlane,
- const MODE_INFO **ppModeInfo,
- const uint32_t cuX,
- const uint32_t cuY) {
+static void av1_filter_block_plane_vert(
+ const AV1_COMMON *const cm, const int plane,
+ const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row,
+ const uint32_t mi_col) {
const int col_step = MI_SIZE >> MI_SIZE_LOG2;
const int row_step = MI_SIZE >> MI_SIZE_LOG2;
- const uint32_t scaleHorz = pPlane->subsampling_x;
- const uint32_t scaleVert = pPlane->subsampling_y;
- const uint32_t width = pPlane->dst.width;
- const uint32_t height = pPlane->dst.height;
- uint8_t *const pDst = pPlane->dst.buf;
- const int dstStride = pPlane->dst.stride;
- for (int y = 0; y < (MAX_MIB_SIZE >> scaleVert); y += row_step) {
- uint8_t *p = pDst + y * MI_SIZE * dstStride;
- for (int x = 0; x < (MAX_MIB_SIZE >> scaleHorz); x += col_step) {
+ const uint32_t scale_horz = plane_ptr->subsampling_x;
+ const uint32_t scale_vert = plane_ptr->subsampling_y;
+ uint8_t *const dst_ptr = plane_ptr->dst.buf;
+ const int dst_stride = plane_ptr->dst.stride;
+#if CONFIG_LPF_SB
+ int y_range = mi_row ? MAX_MIB_SIZE : MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET;
+ y_range = AOMMIN(y_range, cm->mi_rows);
+ y_range >>= scale_vert;
+
+ int x_range = mi_col ? MAX_MIB_SIZE : MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET;
+ x_range = AOMMIN(x_range, cm->mi_cols);
+ x_range >>= scale_horz;
+#else
+ const int y_range = (MAX_MIB_SIZE >> scale_vert);
+ const int x_range = (MAX_MIB_SIZE >> scale_horz);
+#endif // CONFIG_LPF_SB
+ for (int y = 0; y < y_range; y += row_step) {
+ uint8_t *p = dst_ptr + y * MI_SIZE * dst_stride;
+ for (int x = 0; x < x_range; x += col_step) {
// inner loop always filter vertical edges in a MI block. If MI size
// is 8x8, it will filter the vertical edge aligned with a 8x8 block.
// If 4x4 trasnform is used, it will then filter the internal edge
// aligned with a 4x4 block
- const MODE_INFO **const pCurr =
- ppModeInfo + (y << scaleVert) * cm->mi_stride + (x << scaleHorz);
+ const uint32_t curr_x = ((mi_col * MI_SIZE) >> scale_horz) + x * MI_SIZE;
+ const uint32_t curr_y = ((mi_row * MI_SIZE) >> scale_vert) + y * MI_SIZE;
AV1_DEBLOCKING_PARAMETERS params;
memset(&params, 0, sizeof(params));
- set_lpf_parameters(&params, pCurr, ((ptrdiff_t)1 << scaleHorz), cm,
- VERT_EDGE, cuX + x * MI_SIZE, cuY + y * MI_SIZE, width,
- height, plane, pPlane, scaleHorz, scaleVert);
+ set_lpf_parameters(&params, ((ptrdiff_t)1 << scale_horz), cm, VERT_EDGE,
+ curr_x, curr_y, plane, plane_ptr);
+
+#if CONFIG_LPF_DIRECT
+ uint8_t *const src = plane_ptr->dst.buf0;
+ const int width = cm->width >> scale_horz;
+ const int height = cm->height >> scale_vert;
+ const int pivot = 8;
+ const int line_length = 16;
+ uint8_t block[128];
+ int orig_pos[128];
+ const int vert_or_horz = 0; // 0: vertical
+ const int unit = 1;
+ int i;
+ for (i = 0; i < 128; ++i) {
+ block[i] = 0;
+ orig_pos[i] = -1;
+ }
+
+ if (params.filter_length) {
+ const int filt_len = params.filter_length == 16 ? 8 : 4;
+ const int direct =
+ pick_min_grad_direct(src, filt_len, curr_y, curr_x, width, height,
+ dst_stride, unit, vert_or_horz);
+
+ pick_filter_block_vert(src, block, orig_pos, filt_len, curr_y, curr_x,
+ width, height, dst_stride, pivot, line_length,
+ unit, direct);
+ uint8_t *const filt_start = block + pivot;
+ switch (params.filter_length) {
+ // apply 4-tap filtering
+ case 4:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_vertical_4(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_vertical_4(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // apply 8-tap filtering
+ case 8:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_vertical_8(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_vertical_8(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // apply 16-tap filtering
+ case 16:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_vertical_16(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_vertical_16(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // no filtering
+ default: break;
+ }
+
+ for (i = 0; i < 128; ++i) {
+ if (orig_pos[i] >= 0) src[orig_pos[i]] = block[i];
+ }
+ }
+
+ if (params.filter_length_internal) {
+ for (i = 0; i < 128; ++i) {
+ block[i] = 0;
+ orig_pos[i] = -1;
+ }
+
+ const int direct =
+ pick_min_grad_direct(src, 4, curr_y, curr_x + 4, width, height,
+ dst_stride, unit, vert_or_horz);
- switch (params.filterLength) {
+ pick_filter_block_vert(src, block, orig_pos, 4, curr_y, curr_x + 4,
+ width, height, dst_stride, pivot, line_length,
+ unit, direct);
+
+ uint8_t *const filt_start = block + pivot;
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_vertical_4(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_vertical_4(filt_start, line_length, params.mblim, params.lim,
+ params.hev_thr);
+
+ for (i = 0; i < 128; ++i) {
+ if (orig_pos[i] >= 0) src[orig_pos[i]] = block[i];
+ }
+ }
+#else // !CONFIG_LPF_DIRECT
+ switch (params.filter_length) {
// apply 4-tap filtering
case 4:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_vertical_4_c(CONVERT_TO_SHORTPTR(p), dstStride,
+ aom_highbd_lpf_vertical_4(CONVERT_TO_SHORTPTR(p), dst_stride,
+ params.mblim, params.lim, params.hev_thr,
+ cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_vertical_4(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
+ break;
+#if PARALLEL_DEBLOCKING_5_TAP_CHROMA
+ case 6: // apply 6-tap filter for chroma plane only
+ assert(plane != 0);
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_vertical_6_c(CONVERT_TO_SHORTPTR(p), dst_stride,
params.mblim, params.lim,
params.hev_thr, cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_vertical_4_c(p, dstStride, params.mblim, params.lim,
+ aom_lpf_vertical_6_c(p, dst_stride, params.mblim, params.lim,
params.hev_thr);
break;
+#endif
// apply 8-tap filtering
case 8:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_vertical_8_c(CONVERT_TO_SHORTPTR(p), dstStride,
- params.mblim, params.lim,
- params.hev_thr, cm->bit_depth);
+ aom_highbd_lpf_vertical_8(CONVERT_TO_SHORTPTR(p), dst_stride,
+ params.mblim, params.lim, params.hev_thr,
+ cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_vertical_8_c(p, dstStride, params.mblim, params.lim,
- params.hev_thr);
+ aom_lpf_vertical_8(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
break;
// apply 16-tap filtering
case 16:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_vertical_16_c(CONVERT_TO_SHORTPTR(p), dstStride,
+#if CONFIG_DEBLOCK_13TAP
+ // TODO(olah): Remove _c once SIMD for 13-tap is available
+ aom_highbd_lpf_vertical_16_c(CONVERT_TO_SHORTPTR(p), dst_stride,
params.mblim, params.lim,
params.hev_thr, cm->bit_depth);
+#else
+ aom_highbd_lpf_vertical_16(CONVERT_TO_SHORTPTR(p), dst_stride,
+ params.mblim, params.lim, params.hev_thr,
+ cm->bit_depth);
+#endif
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_vertical_16_c(p, dstStride, params.mblim, params.lim,
+#if CONFIG_DEBLOCK_13TAP
+ aom_lpf_vertical_16_c(p, dst_stride, params.mblim, params.lim,
params.hev_thr);
+#else
+ aom_lpf_vertical_16(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
+#endif
break;
// no filtering
default: break;
}
// process the internal edge
- if (params.filterLengthInternal) {
+ if (params.filter_length_internal) {
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_vertical_4_c(CONVERT_TO_SHORTPTR(p + 4), dstStride,
- params.mblim, params.lim, params.hev_thr,
- cm->bit_depth);
+ aom_highbd_lpf_vertical_4(CONVERT_TO_SHORTPTR(p + 4), dst_stride,
+ params.mblim, params.lim, params.hev_thr,
+ cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_vertical_4_c(p + 4, dstStride, params.mblim, params.lim,
- params.hev_thr);
+ aom_lpf_vertical_4(p + 4, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
}
+#endif // CONFIG_LPF_DIRECT
// advance the destination pointer
p += MI_SIZE;
}
}
}
-static void av1_filter_block_plane_horz(const AV1_COMMON *const cm,
- const int plane,
- const MACROBLOCKD_PLANE *const pPlane,
- const MODE_INFO **ppModeInfo,
- const uint32_t cuX,
- const uint32_t cuY) {
+static void av1_filter_block_plane_horz(
+ const AV1_COMMON *const cm, const int plane,
+ const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row,
+ const uint32_t mi_col) {
const int col_step = MI_SIZE >> MI_SIZE_LOG2;
const int row_step = MI_SIZE >> MI_SIZE_LOG2;
- const uint32_t scaleHorz = pPlane->subsampling_x;
- const uint32_t scaleVert = pPlane->subsampling_y;
- const uint32_t width = pPlane->dst.width;
- const uint32_t height = pPlane->dst.height;
- uint8_t *const pDst = pPlane->dst.buf;
- const int dstStride = pPlane->dst.stride;
- for (int y = 0; y < (MAX_MIB_SIZE >> scaleVert); y += row_step) {
- uint8_t *p = pDst + y * MI_SIZE * dstStride;
- for (int x = 0; x < (MAX_MIB_SIZE >> scaleHorz); x += col_step) {
+ const uint32_t scale_horz = plane_ptr->subsampling_x;
+ const uint32_t scale_vert = plane_ptr->subsampling_y;
+ uint8_t *const dst_ptr = plane_ptr->dst.buf;
+ const int dst_stride = plane_ptr->dst.stride;
+#if CONFIG_LPF_SB
+ int y_range = mi_row ? MAX_MIB_SIZE : MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET;
+ y_range = AOMMIN(y_range, cm->mi_rows);
+ y_range >>= scale_vert;
+
+ int x_range = mi_col ? MAX_MIB_SIZE : MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET;
+ x_range = AOMMIN(x_range, cm->mi_cols);
+ x_range >>= scale_horz;
+#else
+ const int y_range = (MAX_MIB_SIZE >> scale_vert);
+ const int x_range = (MAX_MIB_SIZE >> scale_horz);
+#endif // CONFIG_LPF_SB
+ for (int y = 0; y < y_range; y += row_step) {
+ uint8_t *p = dst_ptr + y * MI_SIZE * dst_stride;
+ for (int x = 0; x < x_range; x += col_step) {
// inner loop always filter vertical edges in a MI block. If MI size
// is 8x8, it will first filter the vertical edge aligned with a 8x8
// block. If 4x4 trasnform is used, it will then filter the internal
// edge aligned with a 4x4 block
- const MODE_INFO **const pCurr =
- ppModeInfo + (y << scaleVert) * cm->mi_stride + (x << scaleHorz);
+ const uint32_t curr_x = ((mi_col * MI_SIZE) >> scale_horz) + x * MI_SIZE;
+ const uint32_t curr_y = ((mi_row * MI_SIZE) >> scale_vert) + y * MI_SIZE;
AV1_DEBLOCKING_PARAMETERS params;
memset(&params, 0, sizeof(params));
- set_lpf_parameters(&params, pCurr, (cm->mi_stride << scaleVert), cm,
- HORZ_EDGE, cuX + x * MI_SIZE, cuY + y * MI_SIZE, width,
- height, plane, pPlane, scaleHorz, scaleVert);
- switch (params.filterLength) {
+
+ set_lpf_parameters(&params, (cm->mi_stride << scale_vert), cm, HORZ_EDGE,
+ curr_x, curr_y, plane, plane_ptr);
+
+#if CONFIG_LPF_DIRECT
+ uint8_t *const src = plane_ptr->dst.buf0;
+ const int width = cm->width >> scale_horz;
+ const int height = cm->height >> scale_vert;
+ const int pivot = 8;
+ const int line_length = 16;
+ uint8_t block[256];
+ int orig_pos[256];
+ const int vert_or_horz = 1; // 1: horizontal
+ const int unit = 1;
+ int i;
+ for (i = 0; i < 256; ++i) {
+ block[i] = 0;
+ orig_pos[i] = -1;
+ }
+
+ if (params.filter_length) {
+ const int filt_len = params.filter_length == 16 ? 8 : 4;
+ const int direct =
+ pick_min_grad_direct(src, filt_len, curr_y, curr_x, width, height,
+ dst_stride, unit, vert_or_horz);
+
+ pick_filter_block_horz(src, block, orig_pos, filt_len, curr_y, curr_x,
+ width, height, dst_stride, pivot, line_length,
+ unit, direct);
+ uint8_t *const filt_start = block + pivot * line_length;
+ switch (params.filter_length) {
+ // apply 4-tap filtering
+ case 4:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_horizontal_4(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_horizontal_4(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // apply 8-tap filtering
+ case 8:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_horizontal_8(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_horizontal_8(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // apply 16-tap filtering
+ case 16:
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_horizontal_edge_16(
+ CONVERT_TO_SHORTPTR(filt_start), line_length, params.mblim,
+ params.lim, params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_horizontal_edge_16(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+ break;
+ // no filtering
+ default: break;
+ }
+
+ for (i = 0; i < 256; ++i) {
+ if (orig_pos[i] >= 0) src[orig_pos[i]] = block[i];
+ }
+ }
+ if (params.filter_length_internal) {
+ for (i = 0; i < 256; ++i) {
+ block[i] = 0;
+ orig_pos[i] = -1;
+ }
+
+ const int direct =
+ pick_min_grad_direct(src, 4, curr_y + 4, curr_x, width, height,
+ dst_stride, unit, vert_or_horz);
+
+ pick_filter_block_horz(src, block, orig_pos, 4, curr_y + 4, curr_x,
+ width, height, dst_stride, pivot, line_length,
+ unit, direct);
+
+ uint8_t *const filt_start = block + pivot * line_length;
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_horizontal_4(CONVERT_TO_SHORTPTR(filt_start),
+ line_length, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_horizontal_4(filt_start, line_length, params.mblim,
+ params.lim, params.hev_thr);
+
+ for (i = 0; i < 256; ++i) {
+ if (orig_pos[i] >= 0) src[orig_pos[i]] = block[i];
+ }
+ }
+#else // !CONFIG_LPF_DIRECT
+ switch (params.filter_length) {
// apply 4-tap filtering
case 4:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_horizontal_4_c(CONVERT_TO_SHORTPTR(p), dstStride,
+ aom_highbd_lpf_horizontal_4(CONVERT_TO_SHORTPTR(p), dst_stride,
+ params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+ else
+#endif // CONFIG_HIGHBITDEPTH
+ aom_lpf_horizontal_4(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
+ break;
+#if PARALLEL_DEBLOCKING_5_TAP_CHROMA
+ // apply 6-tap filtering
+ case 6: assert(plane != 0);
+#if CONFIG_HIGHBITDEPTH
+ if (cm->use_highbitdepth)
+ aom_highbd_lpf_horizontal_6_c(CONVERT_TO_SHORTPTR(p), dst_stride,
params.mblim, params.lim,
params.hev_thr, cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_horizontal_4_c(p, dstStride, params.mblim, params.lim,
+ aom_lpf_horizontal_6_c(p, dst_stride, params.mblim, params.lim,
params.hev_thr);
break;
+#endif
// apply 8-tap filtering
case 8:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_horizontal_8_c(CONVERT_TO_SHORTPTR(p), dstStride,
- params.mblim, params.lim,
- params.hev_thr, cm->bit_depth);
+ aom_highbd_lpf_horizontal_8(CONVERT_TO_SHORTPTR(p), dst_stride,
+ params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_horizontal_8_c(p, dstStride, params.mblim, params.lim,
- params.hev_thr);
+ aom_lpf_horizontal_8(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
break;
// apply 16-tap filtering
case 16:
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
+#if CONFIG_DEBLOCK_13TAP
+ // TODO(olah): Remove _c once SIMD for 13-tap is available
aom_highbd_lpf_horizontal_edge_16_c(
- CONVERT_TO_SHORTPTR(p), dstStride, params.mblim, params.lim,
+ CONVERT_TO_SHORTPTR(p), dst_stride, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
+#else
+ aom_highbd_lpf_horizontal_edge_16(
+ CONVERT_TO_SHORTPTR(p), dst_stride, params.mblim, params.lim,
params.hev_thr, cm->bit_depth);
+#endif
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_horizontal_edge_16_c(p, dstStride, params.mblim, params.lim,
- params.hev_thr);
+#if CONFIG_DEBLOCK_13TAP
+ aom_lpf_horizontal_edge_16_c(p, dst_stride, params.mblim,
+ params.lim, params.hev_thr);
+#else
+ aom_lpf_horizontal_edge_16(p, dst_stride, params.mblim, params.lim,
+ params.hev_thr);
+#endif
break;
// no filtering
default: break;
}
// process the internal edge
- if (params.filterLengthInternal) {
+ if (params.filter_length_internal) {
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth)
- aom_highbd_lpf_horizontal_4_c(CONVERT_TO_SHORTPTR(p + 4 * dstStride),
- dstStride, params.mblim, params.lim,
- params.hev_thr, cm->bit_depth);
+ aom_highbd_lpf_horizontal_4(CONVERT_TO_SHORTPTR(p + 4 * dst_stride),
+ dst_stride, params.mblim, params.lim,
+ params.hev_thr, cm->bit_depth);
else
#endif // CONFIG_HIGHBITDEPTH
- aom_lpf_horizontal_4_c(p + 4 * dstStride, dstStride, params.mblim,
- params.lim, params.hev_thr);
+ aom_lpf_horizontal_4(p + 4 * dst_stride, dst_stride, params.mblim,
+ params.lim, params.hev_thr);
}
+#endif // CONFIG_LPF_DIRECT
// advance the destination pointer
p += MI_SIZE;
}
@@ -3036,9 +3532,12 @@ static void av1_filter_block_plane_horz(const AV1_COMMON *const cm,
#endif // CONFIG_PARALLEL_DEBLOCKING
void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
- struct macroblockd_plane planes[MAX_MB_PLANE],
- int start, int stop, int y_only) {
-#if CONFIG_UV_LVL
+ struct macroblockd_plane *planes, int start, int stop,
+#if CONFIG_LPF_SB
+ int col_start, int col_end,
+#endif
+ int y_only) {
+#if CONFIG_LOOPFILTER_LEVEL
// y_only no longer has its original meaning.
// Here it means which plane to filter
// when y_only = {0, 1, 2}, it means we are searching for filter level for
@@ -3047,8 +3546,15 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
const int plane_end = plane_start + 1;
#else
const int num_planes = y_only ? 1 : MAX_MB_PLANE;
-#endif // CONFIG_UV_LVL
+ const int plane_start = 0;
+ const int plane_end = num_planes;
+#endif // CONFIG_LOOPFILTER_LEVEL
+#if !CONFIG_LPF_SB
+ const int col_start = 0;
+ const int col_end = cm->mi_cols;
+#endif // CONFIG_LPF_SB
int mi_row, mi_col;
+ int plane;
#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION || CONFIG_EXT_PARTITION_TYPES || \
CONFIG_CB4X4
@@ -3062,19 +3568,13 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
#if CONFIG_VAR_TX
for (int i = 0; i < MAX_MB_PLANE; ++i)
- memset(cm->left_txfm_context[i], TX_32X32, MAX_MIB_SIZE
- << TX_UNIT_HIGH_LOG2);
+ memset(cm->left_txfm_context[i], TX_32X32,
+ MAX_MIB_SIZE << TX_UNIT_HIGH_LOG2);
#endif // CONFIG_VAR_TX
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += cm->mib_size) {
- int plane;
-
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
-#if CONFIG_UV_LVL
for (plane = plane_start; plane < plane_end; ++plane) {
-#else
- for (plane = 0; plane < num_planes; ++plane) {
-#endif // CONFIG_UV_LVL
av1_filter_block_plane_non420_ver(cm, &planes[plane], mi + mi_col,
mi_row, mi_col, plane);
av1_filter_block_plane_non420_hor(cm, &planes[plane], mi + mi_col,
@@ -3086,38 +3586,20 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
// filter all vertical edges in every 64x64 super block
for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) {
- MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
- for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
+ for (mi_col = col_start; mi_col < col_end; mi_col += MAX_MIB_SIZE) {
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
-#if CONFIG_UV_LVL
- for (int planeIdx = plane_start; planeIdx < plane_end; ++planeIdx) {
-#else
- for (int planeIdx = 0; planeIdx < num_planes; planeIdx += 1) {
-#endif // CONFIG_UV_LVL
- const int32_t scaleHorz = planes[planeIdx].subsampling_x;
- const int32_t scaleVert = planes[planeIdx].subsampling_y;
- av1_filter_block_plane_vert(
- cm, planeIdx, &planes[planeIdx], (const MODE_INFO **)(mi + mi_col),
- (mi_col * MI_SIZE) >> scaleHorz, (mi_row * MI_SIZE) >> scaleVert);
+ for (plane = plane_start; plane < plane_end; ++plane) {
+ av1_filter_block_plane_vert(cm, plane, &planes[plane], mi_row, mi_col);
}
}
}
// filter all horizontal edges in every 64x64 super block
for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) {
- MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
- for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
+ for (mi_col = col_start; mi_col < col_end; mi_col += MAX_MIB_SIZE) {
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
-#if CONFIG_UV_LVL
- for (int planeIdx = plane_start; planeIdx < plane_end; ++planeIdx) {
-#else
- for (int planeIdx = 0; planeIdx < num_planes; planeIdx += 1) {
-#endif // CONFIG_UV_LVL
- const int32_t scaleHorz = planes[planeIdx].subsampling_x;
- const int32_t scaleVert = planes[planeIdx].subsampling_y;
- av1_filter_block_plane_horz(
- cm, planeIdx, &planes[planeIdx], (const MODE_INFO **)(mi + mi_col),
- (mi_col * MI_SIZE) >> scaleHorz, (mi_row * MI_SIZE) >> scaleVert);
+ for (plane = plane_start; plane < plane_end; ++plane) {
+ av1_filter_block_plane_horz(cm, plane, &planes[plane], mi_row, mi_col);
}
}
}
@@ -3127,30 +3609,20 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
#if CONFIG_PARALLEL_DEBLOCKING
for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) {
- MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
// filter all vertical edges in every 64x64 super block
- for (int planeIdx = 0; planeIdx < num_planes; planeIdx += 1) {
- const int32_t scaleHorz = planes[planeIdx].subsampling_x;
- const int32_t scaleVert = planes[planeIdx].subsampling_y;
- av1_filter_block_plane_vert(
- cm, planeIdx, planes + planeIdx, (const MODE_INFO **)(mi + mi_col),
- (mi_col * MI_SIZE) >> scaleHorz, (mi_row * MI_SIZE) >> scaleVert);
+ for (plane = plane_start; plane < plane_end; plane += 1) {
+ av1_filter_block_plane_vert(cm, plane, &planes[plane], mi_row, mi_col);
}
}
}
for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) {
- MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
// filter all horizontal edges in every 64x64 super block
- for (int planeIdx = 0; planeIdx < num_planes; planeIdx += 1) {
- const int32_t scaleHorz = planes[planeIdx].subsampling_x;
- const int32_t scaleVert = planes[planeIdx].subsampling_y;
- av1_filter_block_plane_horz(
- cm, planeIdx, planes + planeIdx, (const MODE_INFO **)(mi + mi_col),
- (mi_col * MI_SIZE) >> scaleHorz, (mi_row * MI_SIZE) >> scaleVert);
+ for (plane = plane_start; plane < plane_end; plane += 1) {
+ av1_filter_block_plane_horz(cm, plane, &planes[plane], mi_row, mi_col);
}
}
}
@@ -3170,8 +3642,6 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) {
MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
- int plane;
-
av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col);
// TODO(JBB): Make setup_mask work for non 420.
@@ -3205,13 +3675,60 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm,
}
void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
- MACROBLOCKD *xd, int frame_filter_level, int y_only,
- int partial_frame) {
+ MACROBLOCKD *xd, int frame_filter_level,
+#if CONFIG_LOOPFILTER_LEVEL
+ int frame_filter_level_r,
+#endif
+ int y_only, int partial_frame
+#if CONFIG_LPF_SB
+ ,
+ int mi_row, int mi_col
+#endif
+ ) {
int start_mi_row, end_mi_row, mi_rows_to_filter;
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ int orig_filter_level[2] = { cm->lf.filter_level[0], cm->lf.filter_level[1] };
+#else
int orig_filter_level = cm->lf.filter_level;
#endif
+#endif
+
+#if CONFIG_LPF_SB
+ if (partial_frame && !frame_filter_level) return;
+#else
+#if CONFIG_LOOPFILTER_LEVEL
+ if (!frame_filter_level && !frame_filter_level_r) return;
+#else
if (!frame_filter_level) return;
+#endif
+#endif // CONFIG_LPF_SB
+#if CONFIG_LPF_SB
+ int start_mi_col;
+ int end_mi_col;
+
+ // In the experiment of deblocking filtering per superblock.
+ // When partial_frame is 1, it indicates we are searching for the best filter
+ // level for current superblock. We reuse frame_filter_level as filter level
+ // for superblock, no longer for the whole frame.
+ // When partial_frame is 0, it's in the actual filtering stage for the frame
+ if (partial_frame) {
+ start_mi_row = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET);
+ start_mi_col = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
+ const int mi_row_range = mi_row - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
+ const int mi_col_range = mi_col - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
+ end_mi_row = AOMMIN(mi_row_range, cm->mi_rows);
+ end_mi_col = AOMMIN(mi_col_range, cm->mi_cols);
+
+ av1_loop_filter_sb_level_init(cm, mi_row, mi_col, frame_filter_level);
+ } else {
+ start_mi_row = 0;
+ mi_rows_to_filter = cm->mi_rows;
+ end_mi_row = start_mi_row + mi_rows_to_filter;
+ start_mi_col = 0;
+ end_mi_col = cm->mi_cols;
+ }
+#else
start_mi_row = 0;
mi_rows_to_filter = cm->mi_rows;
if (partial_frame && cm->mi_rows > 8) {
@@ -3220,19 +3737,46 @@ void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
mi_rows_to_filter = AOMMAX(cm->mi_rows / 8, 8);
}
end_mi_row = start_mi_row + mi_rows_to_filter;
- av1_loop_filter_frame_init(cm, frame_filter_level);
+#if CONFIG_LOOPFILTER_LEVEL
+ // TODO(chengchen): refactor the code such that y_only has its matching
+ // meaning. Now it means the plane to be filtered in this experiment.
+ av1_loop_filter_frame_init(cm, frame_filter_level, frame_filter_level_r,
+ y_only);
+#else
+ av1_loop_filter_frame_init(cm, frame_filter_level, frame_filter_level);
+#endif
+#endif // CONFIG_LPF_SB
+
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ cm->lf.filter_level[0] = frame_filter_level;
+ cm->lf.filter_level[1] = frame_filter_level_r;
+#else
cm->lf.filter_level = frame_filter_level;
#endif
+#endif
+
+#if CONFIG_LPF_SB
+ av1_loop_filter_rows(frame, cm, xd->plane, start_mi_row, end_mi_row,
+ start_mi_col, end_mi_col, y_only);
+#else
av1_loop_filter_rows(frame, cm, xd->plane, start_mi_row, end_mi_row, y_only);
+#endif // CONFIG_LPF_SB
+
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ cm->lf.filter_level[0] = orig_filter_level[0];
+ cm->lf.filter_level[1] = orig_filter_level[1];
+#else
cm->lf.filter_level = orig_filter_level;
#endif
+#endif
}
-void av1_loop_filter_data_reset(
- LFWorkerData *lf_data, YV12_BUFFER_CONFIG *frame_buffer,
- struct AV1Common *cm, const struct macroblockd_plane planes[MAX_MB_PLANE]) {
+void av1_loop_filter_data_reset(LFWorkerData *lf_data,
+ YV12_BUFFER_CONFIG *frame_buffer,
+ struct AV1Common *cm,
+ const struct macroblockd_plane *planes) {
lf_data->frame_buffer = frame_buffer;
lf_data->cm = cm;
lf_data->start = 0;
@@ -3243,7 +3787,11 @@ void av1_loop_filter_data_reset(
int av1_loop_filter_worker(LFWorkerData *const lf_data, void *unused) {
(void)unused;
+#if !CONFIG_LPF_SB
av1_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes,
lf_data->start, lf_data->stop, lf_data->y_only);
+#else
+ (void)lf_data;
+#endif // CONFIG_LPF_SB
return 1;
}