Merge "Loop filter code cleanup."
This commit is contained in:
commit
2824048a56
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user