ref: 2824048a566a88d37f02d477b6480211986efa43
parent: d3d6ddcee5c2a18aa532e04aa41f97117dccf3e7
parent: 92a9eaef5078dde1bc4fc35eabca4d987dc6fddb
author: Dmitry Kovalev <[email protected]>
date: Tue Jul 9 14:56:19 EDT 2013
Merge "Loop filter code cleanup."
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -35,17 +35,13 @@
void vp9_loop_filter_update_sharpness(loop_filter_info_n *lfi,
int sharpness_lvl) {
- int i;
+ int lvl;
- /* 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;
+ // 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));
- /* Set loop filter paramaeters that control sharpness. */
- block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
- block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
-
if (sharpness_lvl > 0) {
if (block_inside_limit > (9 - sharpness_lvl))
block_inside_limit = (9 - sharpness_lvl);
@@ -54,11 +50,10 @@
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),
+ 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);
- vpx_memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit),
- SIMD_WIDTH);
}
}
@@ -78,23 +73,16 @@
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;
@@ -101,75 +89,52 @@
}
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];
+ 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) {
- const int hev_index = filter_level >> 4;
+ 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,
--- 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 @@
#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 */
--- 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,