Merge "Loop filter code cleanup."

This commit is contained in:
Dmitry Kovalev 2013-07-09 18:56:19 -07:00 committed by Gerrit Code Review
commit 2824048a56
3 changed files with 59 additions and 92 deletions

View File

@ -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;
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;
/* 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];
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,

View File

@ -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 */

View File

@ -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,