diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index ef8ed2b40f64cbdf9e85fe2c95d25fe621302790..9d2e2ea26a539bbc25f4ed7ed4e077441736b13c 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -35,16 +35,12 @@ static void lf_init_lut(loop_filter_info_n *lfi) { void vp9_loop_filter_update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) { - int i; - - /* For each possible value for the loop filter fill out limits */ - for (i = 0; i <= MAX_LOOP_FILTER; i++) { - int filt_lvl = i; - int block_inside_limit = 0; + int lvl; - /* Set loop filter paramaeters that control sharpness. */ - block_inside_limit = filt_lvl >> (sharpness_lvl > 0); - block_inside_limit = block_inside_limit >> (sharpness_lvl > 4); + // For each possible value for the loop filter fill out limits + for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) { + // Set loop filter paramaeters that control sharpness. + int block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4)); if (sharpness_lvl > 0) { if (block_inside_limit > (9 - sharpness_lvl)) @@ -54,10 +50,9 @@ void vp9_loop_filter_update_sharpness(loop_filter_info_n *lfi, if (block_inside_limit < 1) block_inside_limit = 1; - vpx_memset(lfi->lim[i], block_inside_limit, SIMD_WIDTH); - vpx_memset(lfi->blim[i], (2 * filt_lvl + block_inside_limit), - SIMD_WIDTH); - vpx_memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit), + vpx_memset(lfi->lim[lvl], block_inside_limit, SIMD_WIDTH); + vpx_memset(lfi->blim[lvl], (2 * lvl + block_inside_limit), SIMD_WIDTH); + vpx_memset(lfi->mblim[lvl], (2 * (lvl + 2) + block_inside_limit), SIMD_WIDTH); } } @@ -78,98 +73,68 @@ void vp9_loop_filter_init(VP9_COMMON *cm) { vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH); } -void vp9_loop_filter_frame_init(VP9_COMMON *cm, - MACROBLOCKD *xd, +void vp9_loop_filter_frame_init(VP9_COMMON *cm, MACROBLOCKD *xd, int default_filt_lvl) { - int seg, // segment number - ref, // index in ref_lf_deltas - mode; // index in mode_lf_deltas + int seg; // n_shift is the a 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 - int n_shift = default_filt_lvl >> 5; + const int n_shift = default_filt_lvl >> 5; + loop_filter_info_n *const lfi = &cm->lf_info; - loop_filter_info_n *lfi = &cm->lf_info; - - /* update limits if sharpness has changed */ - // printf("vp9_loop_filter_frame_init %d\n", default_filt_lvl); - // printf("sharpness level: %d [%d]\n", - // cm->sharpness_level, cm->last_sharpness_level); + // update limits if sharpness has changed if (cm->last_sharpness_level != cm->sharpness_level) { vp9_loop_filter_update_sharpness(lfi, cm->sharpness_level); cm->last_sharpness_level = cm->sharpness_level; } for (seg = 0; seg < MAX_MB_SEGMENTS; seg++) { - int lvl_seg = default_filt_lvl; - int lvl_ref, lvl_mode; - + int lvl_seg = default_filt_lvl, ref, mode, intra_lvl; // Set the baseline filter values for each segment if (vp9_segfeature_active(xd, seg, SEG_LVL_ALT_LF)) { - /* Abs value */ - if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) { - lvl_seg = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF); - } else { /* Delta Value */ - lvl_seg += vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF); - lvl_seg = clamp(lvl_seg, 0, 63); - } + const int data = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF); + lvl_seg = xd->mb_segment_abs_delta == SEGMENT_ABSDATA + ? data + : clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER); } if (!xd->mode_ref_lf_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 - */ + // we could get rid of this if we assume that deltas are set to + // zero when not in use; encoder always uses deltas vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4); continue; } - lvl_ref = lvl_seg; + intra_lvl = lvl_seg + (xd->ref_lf_deltas[INTRA_FRAME] << n_shift); + lfi->lvl[seg][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER); - /* INTRA_FRAME */ - ref = INTRA_FRAME; - - /* Apply delta for reference frame */ - lvl_ref += xd->ref_lf_deltas[ref] << n_shift; - - mode = 0; /* all the rest of Intra modes */ - lvl_mode = lvl_ref; - lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63); - - /* LAST, GOLDEN, ALT */ - for (ref = 1; ref < MAX_REF_FRAMES; ref++) { - int lvl_ref = lvl_seg; - - /* Apply delta for reference frame */ - lvl_ref += xd->ref_lf_deltas[ref] << n_shift; - - /* Apply delta for Inter modes */ - for (mode = 0; mode < MAX_MODE_LF_DELTAS; mode++) { - lvl_mode = lvl_ref + (xd->mode_lf_deltas[mode] << n_shift); - lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63); + for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) + for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { + const int inter_lvl = lvl_seg + (xd->ref_lf_deltas[ref] << n_shift) + + (xd->mode_lf_deltas[mode] << n_shift); + lfi->lvl[seg][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER); } - } } } static int build_lfi(const VP9_COMMON *cm, const MB_MODE_INFO *mbmi, struct loop_filter_info *lfi) { - const loop_filter_info_n *lfi_n = &cm->lf_info; - int mode = mbmi->mode; - int mode_index = lfi_n->mode_lf_lut[mode]; - int seg = mbmi->segment_id; - int ref_frame = mbmi->ref_frame[0]; - int filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - const int hev_index = filter_level >> 4; + const loop_filter_info_n *const lfi_n = &cm->lf_info; + const int seg = mbmi->segment_id; + const int ref = mbmi->ref_frame[0]; + const int mode = lfi_n->mode_lf_lut[mbmi->mode]; + const int filter_level = lfi_n->lvl[seg][ref][mode]; + + if (filter_level > 0) { lfi->mblim = lfi_n->mblim[filter_level]; lfi->blim = lfi_n->blim[filter_level]; lfi->lim = lfi_n->lim[filter_level]; - lfi->hev_thr = lfi_n->hev_thr[hev_index]; + lfi->hev_thr = lfi_n->hev_thr[filter_level >> 4]; return 1; + } else { + return 0; } - return 0; } static void filter_selectively_vert(uint8_t *s, int pitch, diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h index ce954c0c3c445d34c95c3a629c296adb1d2d9cc8..2582979f5e8c89d3155719e2ab53ff4f2dc6515c 100644 --- a/vp9/common/vp9_loopfilter.h +++ b/vp9/common/vp9_loopfilter.h @@ -16,34 +16,35 @@ #include "vp9/common/vp9_blockd.h" #define MAX_LOOP_FILTER 63 +#define MAX_SHARPNESS 7 + #define SIMD_WIDTH 16 -/* Need to align this structure so when it is declared and - * passed it can be loaded into vector registers. - */ +// Need to align this structure so when it is declared and +// passed it can be loaded into vector registers. typedef struct { - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, + DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, + DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, blim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, + DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, + DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[4][SIMD_WIDTH]); - unsigned char lvl[MAX_MB_SEGMENTS][4][4]; - unsigned char mode_lf_lut[MB_MODE_COUNT]; + uint8_t lvl[MAX_MB_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS]; + uint8_t mode_lf_lut[MB_MODE_COUNT]; } loop_filter_info_n; struct loop_filter_info { - const unsigned char *mblim; - const unsigned char *blim; - const unsigned char *lim; - const unsigned char *hev_thr; + const uint8_t *mblim; + const uint8_t *blim; + const uint8_t *lim; + const uint8_t *hev_thr; }; #define prototype_loopfilter(sym) \ - void sym(uint8_t *src, int pitch, const unsigned char *blimit, \ - const unsigned char *limit, const unsigned char *thresh, int count) + void sym(uint8_t *src, int pitch, const uint8_t *blimit, \ + const uint8_t *limit, const uint8_t *thresh, int count) #define prototype_loopfilter_block(sym) \ void sym(uint8_t *y, uint8_t *u, uint8_t *v, \ @@ -53,11 +54,10 @@ struct loop_filter_info { #include "x86/vp9_loopfilter_x86.h" #endif -typedef void loop_filter_uvfunction(uint8_t *u, /* source pointer */ - int p, /* pitch */ - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, +typedef void loop_filter_uvfunction(uint8_t *src, int pitch, + const uint8_t *blimit, + const uint8_t *limit, + const uint8_t *thresh, uint8_t *v); /* assorted loopfilter functions which get used elsewhere */ diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index df7747c909fdcadce64eb95d1fe9b76a703f4ca0..9bf2072514a4afd16f7cc30f40d8dc5d9dc718e1 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -13,7 +13,9 @@ #include "vp9/common/vp9_seg_common.h" static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 }; -static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, 63, 3, 0 }; + +static const int seg_feature_data_max[SEG_LVL_MAX] = { + MAXQ, MAX_LOOP_FILTER, 3, 0 }; // These functions provide access to new segment level features. // Eventually these function may be "optimized out" but for the moment,