New loop filter interface
Separate simple filter with reduced no. of parameters. MB filter level picking based on precalculated table. Level table updated for each frame. Inside and edge limits precalculated and updated just when sharpness changes. HEV threshhold is constant. ARM targets use scalars and others vectors. Change works only with --target=generic-gnu All other targets have to be updated! Change-Id: I6b73aca6b525075b20129a371699b2561bd4d51c
This commit is contained in:
parent
973a9c075d
commit
622958449b
@ -108,9 +108,9 @@ void vp8_machine_specific_config(VP8_COMMON *ctx)
|
||||
rtcd->loopfilter.normal_b_v = vp8_loop_filter_bv_c;
|
||||
rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_c;
|
||||
rtcd->loopfilter.normal_b_h = vp8_loop_filter_bh_c;
|
||||
rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_c;
|
||||
rtcd->loopfilter.simple_mb_v = vp8_loop_filter_simple_vertical_edge_c;
|
||||
rtcd->loopfilter.simple_b_v = vp8_loop_filter_bvs_c;
|
||||
rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_c;
|
||||
rtcd->loopfilter.simple_mb_h = vp8_loop_filter_simple_horizontal_edge_c;
|
||||
rtcd->loopfilter.simple_b_h = vp8_loop_filter_bhs_c;
|
||||
|
||||
#if CONFIG_POSTPROC || (CONFIG_VP8_ENCODER && CONFIG_INTERNAL_STATS)
|
||||
|
@ -9,152 +9,149 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "vpx_ports/config.h"
|
||||
#include "vpx_config.h"
|
||||
#include "loopfilter.h"
|
||||
#include "onyxc_int.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
typedef unsigned char uc;
|
||||
|
||||
|
||||
prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
|
||||
prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
|
||||
prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
|
||||
prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
|
||||
prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
|
||||
prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
|
||||
|
||||
prototype_simple_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
|
||||
prototype_simple_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
|
||||
|
||||
/* Horizontal MB filtering */
|
||||
void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr,
|
||||
unsigned char *v_ptr, int y_stride, int uv_stride,
|
||||
loop_filter_info *lfi)
|
||||
{
|
||||
vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
|
||||
vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
|
||||
|
||||
if (u_ptr)
|
||||
vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
|
||||
vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
|
||||
|
||||
if (v_ptr)
|
||||
vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
|
||||
}
|
||||
|
||||
void vp8_loop_filter_mbhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
{
|
||||
(void) u_ptr;
|
||||
(void) v_ptr;
|
||||
(void) uv_stride;
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
|
||||
vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
|
||||
}
|
||||
|
||||
/* Vertical MB Filtering */
|
||||
void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr,
|
||||
unsigned char *v_ptr, int y_stride, int uv_stride,
|
||||
loop_filter_info *lfi)
|
||||
{
|
||||
vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
|
||||
vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
|
||||
|
||||
if (u_ptr)
|
||||
vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
|
||||
vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
|
||||
|
||||
if (v_ptr)
|
||||
vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->mbflim, lfi->lim, lfi->thr, 1);
|
||||
}
|
||||
|
||||
void vp8_loop_filter_mbvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
{
|
||||
(void) u_ptr;
|
||||
(void) v_ptr;
|
||||
(void) uv_stride;
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->thr, 2);
|
||||
vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
|
||||
}
|
||||
|
||||
/* Horizontal B Filtering */
|
||||
void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr,
|
||||
unsigned char *v_ptr, int y_stride, int uv_stride,
|
||||
loop_filter_info *lfi)
|
||||
{
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
|
||||
if (u_ptr)
|
||||
vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
|
||||
vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
|
||||
|
||||
if (v_ptr)
|
||||
vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
|
||||
vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
|
||||
}
|
||||
|
||||
void vp8_loop_filter_bhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_bhs_c(unsigned char *y_ptr, int y_stride,
|
||||
const unsigned char *blimit)
|
||||
{
|
||||
(void) u_ptr;
|
||||
(void) v_ptr;
|
||||
(void) uv_stride;
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, blimit);
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, blimit);
|
||||
vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, blimit);
|
||||
}
|
||||
|
||||
/* Vertical B Filtering */
|
||||
void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr,
|
||||
unsigned char *v_ptr, int y_stride, int uv_stride,
|
||||
loop_filter_info *lfi)
|
||||
{
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
|
||||
|
||||
if (u_ptr)
|
||||
vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
|
||||
vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
|
||||
|
||||
if (v_ptr)
|
||||
vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->flim, lfi->lim, lfi->thr, 1);
|
||||
vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
|
||||
}
|
||||
|
||||
void vp8_loop_filter_bvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
|
||||
int y_stride, int uv_stride, loop_filter_info *lfi)
|
||||
void vp8_loop_filter_bvs_c(unsigned char *y_ptr, int y_stride,
|
||||
const unsigned char *blimit)
|
||||
{
|
||||
(void) u_ptr;
|
||||
(void) v_ptr;
|
||||
(void) uv_stride;
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, blimit);
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, blimit);
|
||||
vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, blimit);
|
||||
}
|
||||
|
||||
void vp8_init_loop_filter(VP8_COMMON *cm)
|
||||
static void lf_init_lut(loop_filter_info_n *lfi)
|
||||
{
|
||||
loop_filter_info *lfi = cm->lf_info;
|
||||
LOOPFILTERTYPE lft = cm->filter_type;
|
||||
int sharpness_lvl = cm->sharpness_level;
|
||||
int frame_type = cm->frame_type;
|
||||
int i, j;
|
||||
int filt_lvl;
|
||||
|
||||
int block_inside_limit = 0;
|
||||
int HEVThresh;
|
||||
|
||||
/* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
|
||||
for (i = 0; i <= MAX_LOOP_FILTER; i++)
|
||||
for (filt_lvl = 0; filt_lvl <= MAX_LOOP_FILTER; filt_lvl++)
|
||||
{
|
||||
int filt_lvl = i;
|
||||
|
||||
if (frame_type == KEY_FRAME)
|
||||
if (filt_lvl >= 40)
|
||||
{
|
||||
if (filt_lvl >= 40)
|
||||
HEVThresh = 2;
|
||||
else if (filt_lvl >= 15)
|
||||
HEVThresh = 1;
|
||||
else
|
||||
HEVThresh = 0;
|
||||
lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 2;
|
||||
lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 3;
|
||||
}
|
||||
else if (filt_lvl >= 20)
|
||||
{
|
||||
lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
|
||||
lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 2;
|
||||
}
|
||||
else if (filt_lvl >= 15)
|
||||
{
|
||||
lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1;
|
||||
lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filt_lvl >= 40)
|
||||
HEVThresh = 3;
|
||||
else if (filt_lvl >= 20)
|
||||
HEVThresh = 2;
|
||||
else if (filt_lvl >= 15)
|
||||
HEVThresh = 1;
|
||||
else
|
||||
HEVThresh = 0;
|
||||
lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 0;
|
||||
lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lfi->mode_lf_lut[DC_PRED] = 1;
|
||||
lfi->mode_lf_lut[V_PRED] = 1;
|
||||
lfi->mode_lf_lut[H_PRED] = 1;
|
||||
lfi->mode_lf_lut[TM_PRED] = 1;
|
||||
lfi->mode_lf_lut[B_PRED] = 0;
|
||||
|
||||
lfi->mode_lf_lut[ZEROMV] = 1;
|
||||
lfi->mode_lf_lut[NEARESTMV] = 2;
|
||||
lfi->mode_lf_lut[NEARMV] = 2;
|
||||
lfi->mode_lf_lut[NEWMV] = 2;
|
||||
lfi->mode_lf_lut[SPLITMV] = 3;
|
||||
|
||||
}
|
||||
|
||||
void vp8_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;
|
||||
|
||||
/* Set loop filter paramaeters that control sharpness. */
|
||||
block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
|
||||
@ -169,119 +166,120 @@ void vp8_init_loop_filter(VP8_COMMON *cm)
|
||||
if (block_inside_limit < 1)
|
||||
block_inside_limit = 1;
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
lfi[i].lim[j] = block_inside_limit;
|
||||
lfi[i].mbflim[j] = filt_lvl + 2;
|
||||
lfi[i].flim[j] = filt_lvl;
|
||||
lfi[i].thr[j] = HEVThresh;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Set up the function pointers depending on the type of loop filtering selected */
|
||||
if (lft == NORMAL_LOOPFILTER)
|
||||
{
|
||||
cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
|
||||
cm->lf_bv = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
|
||||
cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
|
||||
cm->lf_bh = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
|
||||
cm->lf_bv = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
|
||||
cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
|
||||
cm->lf_bh = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
|
||||
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),
|
||||
SIMD_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
|
||||
* each frame. Check last_frame_type to skip the function most of times.
|
||||
*/
|
||||
void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
|
||||
void vp8_loop_filter_init(VP8_COMMON *cm)
|
||||
{
|
||||
int HEVThresh;
|
||||
int i, j;
|
||||
loop_filter_info_n *lfi = &cm->lf_info;
|
||||
int i;
|
||||
|
||||
/* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
|
||||
for (i = 0; i <= MAX_LOOP_FILTER; i++)
|
||||
/* init limits for given sharpness*/
|
||||
vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level);
|
||||
cm->last_sharpness_level = cm->sharpness_level;
|
||||
|
||||
/* init LUT for lvl and hev thr picking */
|
||||
lf_init_lut(lfi);
|
||||
|
||||
/* init hev threshold const vectors */
|
||||
for(i = 0; i < 4 ; i++)
|
||||
{
|
||||
int filt_lvl = i;
|
||||
|
||||
if (frame_type == KEY_FRAME)
|
||||
{
|
||||
if (filt_lvl >= 40)
|
||||
HEVThresh = 2;
|
||||
else if (filt_lvl >= 15)
|
||||
HEVThresh = 1;
|
||||
else
|
||||
HEVThresh = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filt_lvl >= 40)
|
||||
HEVThresh = 3;
|
||||
else if (filt_lvl >= 20)
|
||||
HEVThresh = 2;
|
||||
else if (filt_lvl >= 15)
|
||||
HEVThresh = 1;
|
||||
else
|
||||
HEVThresh = 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
/*lfi[i].lim[j] = block_inside_limit;
|
||||
lfi[i].mbflim[j] = filt_lvl+2;*/
|
||||
/*lfi[i].flim[j] = filt_lvl;*/
|
||||
lfi[i].thr[j] = HEVThresh;
|
||||
}
|
||||
vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int filter_level)
|
||||
void vp8_loop_filter_frame_init(VP8_COMMON *cm,
|
||||
MACROBLOCKD *mbd,
|
||||
int default_filt_lvl,
|
||||
int sharpness_lvl)
|
||||
{
|
||||
MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
|
||||
int seg, /* segment number */
|
||||
ref, /* index in ref_lf_deltas */
|
||||
mode; /* index in mode_lf_deltas */
|
||||
|
||||
if (mbd->mode_ref_lf_delta_enabled)
|
||||
loop_filter_info_n *lfi = &cm->lf_info;
|
||||
|
||||
/* update limits if sharpness has changed */
|
||||
if(cm->last_sharpness_level != sharpness_lvl)
|
||||
{
|
||||
vp8_loop_filter_update_sharpness(lfi, sharpness_lvl);
|
||||
cm->last_sharpness_level = sharpness_lvl;
|
||||
}
|
||||
|
||||
for(seg = 0; seg < MAX_MB_SEGMENTS; seg++)
|
||||
{
|
||||
int lvl_seg = default_filt_lvl;
|
||||
int lvl_ref, lvl_mode;
|
||||
|
||||
/* Note the baseline filter values for each segment */
|
||||
if (mbd->segmentation_enabled)
|
||||
{
|
||||
/* Abs value */
|
||||
if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
|
||||
{
|
||||
lvl_seg = mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
|
||||
}
|
||||
else /* Delta Value */
|
||||
{
|
||||
lvl_seg += mbd->segment_feature_data[MB_LVL_ALT_LF][seg];
|
||||
lvl_seg = (lvl_seg > 0) ? ((lvl_seg > 63) ? 63: lvl_seg) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mbd->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
|
||||
*/
|
||||
vpx_memset(lfi->lvl[seg][0], lvl_seg, 4 * 4 );
|
||||
continue;
|
||||
}
|
||||
|
||||
lvl_ref = lvl_seg;
|
||||
|
||||
/* INTRA_FRAME */
|
||||
ref = INTRA_FRAME;
|
||||
|
||||
/* Apply delta for reference frame */
|
||||
filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
|
||||
lvl_ref += mbd->ref_lf_deltas[ref];
|
||||
|
||||
/* Apply delta for mode */
|
||||
if (mbmi->ref_frame == INTRA_FRAME)
|
||||
/* Apply delta for Intra modes */
|
||||
mode = 0; /* B_PRED */
|
||||
/* Only the split mode BPRED has a further special case */
|
||||
lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode];
|
||||
lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clamp */
|
||||
|
||||
lfi->lvl[seg][ref][mode] = lvl_mode;
|
||||
|
||||
mode = 1; /* all the rest of Intra modes */
|
||||
lvl_mode = (lvl_ref > 0) ? (lvl_ref > 63 ? 63 : lvl_ref) : 0; /* clamp */
|
||||
lfi->lvl[seg][ref][mode] = lvl_mode;
|
||||
|
||||
/* LAST, GOLDEN, ALT */
|
||||
for(ref = 1; ref < MAX_REF_FRAMES; ref++)
|
||||
{
|
||||
/* Only the split mode BPRED has a further special case */
|
||||
if (mbmi->mode == B_PRED)
|
||||
filter_level += mbd->mode_lf_deltas[0];
|
||||
int lvl_ref = lvl_seg;
|
||||
|
||||
/* Apply delta for reference frame */
|
||||
lvl_ref += mbd->ref_lf_deltas[ref];
|
||||
|
||||
/* Apply delta for Inter modes */
|
||||
for (mode = 1; mode < 4; mode++)
|
||||
{
|
||||
lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode];
|
||||
lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; /* clamp */
|
||||
|
||||
lfi->lvl[seg][ref][mode] = lvl_mode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Zero motion mode */
|
||||
if (mbmi->mode == ZEROMV)
|
||||
filter_level += mbd->mode_lf_deltas[1];
|
||||
|
||||
/* Split MB motion mode */
|
||||
else if (mbmi->mode == SPLITMV)
|
||||
filter_level += mbd->mode_lf_deltas[3];
|
||||
|
||||
/* All other inter motion modes (Nearest, Near, New) */
|
||||
else
|
||||
filter_level += mbd->mode_lf_deltas[2];
|
||||
}
|
||||
|
||||
/* Range check */
|
||||
if (filter_level > MAX_LOOP_FILTER)
|
||||
filter_level = MAX_LOOP_FILTER;
|
||||
else if (filter_level < 0)
|
||||
filter_level = 0;
|
||||
}
|
||||
return filter_level;
|
||||
}
|
||||
|
||||
|
||||
void vp8_loop_filter_frame
|
||||
(
|
||||
VP8_COMMON *cm,
|
||||
@ -290,49 +288,23 @@ void vp8_loop_filter_frame
|
||||
)
|
||||
{
|
||||
YV12_BUFFER_CONFIG *post = cm->frame_to_show;
|
||||
loop_filter_info *lfi = cm->lf_info;
|
||||
loop_filter_info_n *lfi_n = &cm->lf_info;
|
||||
loop_filter_info lfi;
|
||||
|
||||
FRAME_TYPE frame_type = cm->frame_type;
|
||||
|
||||
int mb_row;
|
||||
int mb_col;
|
||||
|
||||
|
||||
int baseline_filter_level[MAX_MB_SEGMENTS];
|
||||
int filter_level;
|
||||
int alt_flt_enabled = mbd->segmentation_enabled;
|
||||
|
||||
int i;
|
||||
unsigned char *y_ptr, *u_ptr, *v_ptr;
|
||||
|
||||
mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */
|
||||
|
||||
/* Note the baseline filter values for each segment */
|
||||
if (alt_flt_enabled)
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
{
|
||||
/* Abs value */
|
||||
if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
|
||||
baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
/* Delta Value */
|
||||
else
|
||||
{
|
||||
baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; /* Clamp to valid range */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
baseline_filter_level[i] = default_filt_lvl;
|
||||
}
|
||||
/* Point at base of Mb MODE_INFO list */
|
||||
const MODE_INFO *mode_info_context = cm->mi;
|
||||
|
||||
/* Initialize the loop filter for this frame. */
|
||||
if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
|
||||
vp8_init_loop_filter(cm);
|
||||
else if (frame_type != cm->last_frame_type)
|
||||
vp8_frame_init_loop_filter(lfi, frame_type);
|
||||
vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl, cm->sharpness_level);
|
||||
|
||||
/* Set up the buffer pointers */
|
||||
y_ptr = post->y_buffer;
|
||||
@ -344,51 +316,79 @@ void vp8_loop_filter_frame
|
||||
{
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
|
||||
{
|
||||
int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
|
||||
int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
mbd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mbd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
|
||||
mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
filter_level = baseline_filter_level[Segment];
|
||||
const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
|
||||
const int seg = mode_info_context->mbmi.segment_id;
|
||||
const int ref_frame = mode_info_context->mbmi.ref_frame;
|
||||
|
||||
/* Distance of Mb to the various image edges.
|
||||
* These specified to 8th pel as they are always compared to values that are in 1/8th pel units
|
||||
* Apply any context driven MB level adjustment
|
||||
*/
|
||||
filter_level = vp8_adjust_mb_lf_value(mbd, filter_level);
|
||||
filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
|
||||
|
||||
if (filter_level)
|
||||
{
|
||||
if (mb_col > 0)
|
||||
cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
|
||||
if (cm->filter_type == NORMAL_LOOPFILTER)
|
||||
{
|
||||
const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
|
||||
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];
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v)
|
||||
(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v)
|
||||
(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level]);
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h)
|
||||
(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h)
|
||||
(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
}
|
||||
}
|
||||
|
||||
y_ptr += 16;
|
||||
u_ptr += 8;
|
||||
v_ptr += 8;
|
||||
|
||||
mbd->mode_info_context++; /* step to next MB */
|
||||
mode_info_context++; /* step to next MB */
|
||||
}
|
||||
|
||||
y_ptr += post->y_stride * 16 - post->y_width;
|
||||
u_ptr += post->uv_stride * 8 - post->uv_width;
|
||||
v_ptr += post->uv_stride * 8 - post->uv_width;
|
||||
|
||||
mbd->mode_info_context++; /* Skip border mb */
|
||||
mode_info_context++; /* Skip border mb */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vp8_loop_filter_frame_yonly
|
||||
(
|
||||
VP8_COMMON *cm,
|
||||
@ -399,49 +399,28 @@ void vp8_loop_filter_frame_yonly
|
||||
{
|
||||
YV12_BUFFER_CONFIG *post = cm->frame_to_show;
|
||||
|
||||
int i;
|
||||
unsigned char *y_ptr;
|
||||
int mb_row;
|
||||
int mb_col;
|
||||
|
||||
loop_filter_info *lfi = cm->lf_info;
|
||||
int baseline_filter_level[MAX_MB_SEGMENTS];
|
||||
loop_filter_info_n *lfi_n = &cm->lf_info;
|
||||
loop_filter_info lfi;
|
||||
|
||||
int filter_level;
|
||||
int alt_flt_enabled = mbd->segmentation_enabled;
|
||||
FRAME_TYPE frame_type = cm->frame_type;
|
||||
|
||||
(void) sharpness_lvl;
|
||||
/* Point at base of Mb MODE_INFO list */
|
||||
const MODE_INFO *mode_info_context = cm->mi;
|
||||
|
||||
/*MODE_INFO * this_mb_mode_info = cm->mi;*/ /* Point at base of Mb MODE_INFO list */
|
||||
mbd->mode_info_context = cm->mi; /* Point at base of Mb MODE_INFO list */
|
||||
sharpness_lvl = cm->sharpness_level;
|
||||
|
||||
/* Note the baseline filter values for each segment */
|
||||
if (alt_flt_enabled)
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
{
|
||||
/* Abs value */
|
||||
if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
|
||||
baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
/* Delta Value */
|
||||
else
|
||||
{
|
||||
baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; /* Clamp to valid range */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
baseline_filter_level[i] = default_filt_lvl;
|
||||
}
|
||||
#if 0
|
||||
if(default_filt_lvl == 0) /* no filter applied */
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Initialize the loop filter for this frame. */
|
||||
if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
|
||||
vp8_init_loop_filter(cm);
|
||||
else if (frame_type != cm->last_frame_type)
|
||||
vp8_frame_init_loop_filter(lfi, frame_type);
|
||||
vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl, sharpness_lvl);
|
||||
|
||||
/* Set up the buffer pointers */
|
||||
y_ptr = post->y_buffer;
|
||||
@ -451,44 +430,75 @@ void vp8_loop_filter_frame_yonly
|
||||
{
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
|
||||
{
|
||||
int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
|
||||
int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
mbd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mbd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
|
||||
mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
filter_level = baseline_filter_level[Segment];
|
||||
const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode];
|
||||
const int seg = mode_info_context->mbmi.segment_id;
|
||||
const int ref_frame = mode_info_context->mbmi.ref_frame;
|
||||
|
||||
/* Apply any context driven MB level adjustment */
|
||||
filter_level = vp8_adjust_mb_lf_value(mbd, filter_level);
|
||||
filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
|
||||
|
||||
if (filter_level)
|
||||
{
|
||||
if (mb_col > 0)
|
||||
cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (cm->filter_type == NORMAL_LOOPFILTER)
|
||||
{
|
||||
const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
|
||||
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];
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
}
|
||||
}
|
||||
|
||||
y_ptr += 16;
|
||||
mbd->mode_info_context ++; /* step to next MB */
|
||||
mode_info_context ++; /* step to next MB */
|
||||
|
||||
}
|
||||
|
||||
y_ptr += post->y_stride * 16 - post->y_width;
|
||||
mbd->mode_info_context ++; /* Skip border mb */
|
||||
mode_info_context ++; /* Skip border mb */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void vp8_loop_filter_partial_frame
|
||||
(
|
||||
VP8_COMMON *cm,
|
||||
@ -500,25 +510,32 @@ void vp8_loop_filter_partial_frame
|
||||
{
|
||||
YV12_BUFFER_CONFIG *post = cm->frame_to_show;
|
||||
|
||||
int i;
|
||||
unsigned char *y_ptr;
|
||||
int mb_row;
|
||||
int mb_col;
|
||||
/*int mb_rows = post->y_height >> 4;*/
|
||||
int mb_cols = post->y_width >> 4;
|
||||
|
||||
int linestocopy;
|
||||
int linestocopy, i;
|
||||
|
||||
loop_filter_info_n *lfi_n = &cm->lf_info;
|
||||
loop_filter_info lfi;
|
||||
|
||||
loop_filter_info *lfi = cm->lf_info;
|
||||
int baseline_filter_level[MAX_MB_SEGMENTS];
|
||||
int filter_level;
|
||||
int alt_flt_enabled = mbd->segmentation_enabled;
|
||||
FRAME_TYPE frame_type = cm->frame_type;
|
||||
|
||||
(void) sharpness_lvl;
|
||||
const MODE_INFO *mode_info_context;
|
||||
|
||||
/*MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);*/ /* Point at base of Mb MODE_INFO list */
|
||||
mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1); /* Point at base of Mb MODE_INFO list */
|
||||
int lvl_seg[MAX_MB_SEGMENTS];
|
||||
|
||||
sharpness_lvl = cm->sharpness_level;
|
||||
|
||||
#if 0
|
||||
if(default_filt_lvl == 0) /* no filter applied */
|
||||
return;
|
||||
#endif
|
||||
|
||||
mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);
|
||||
|
||||
linestocopy = (post->y_height >> (4 + Fraction));
|
||||
|
||||
@ -531,29 +548,24 @@ void vp8_loop_filter_partial_frame
|
||||
if (alt_flt_enabled)
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
{
|
||||
/* Abs value */
|
||||
{ /* Abs value */
|
||||
if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
|
||||
baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
{
|
||||
lvl_seg[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
}
|
||||
/* Delta Value */
|
||||
else
|
||||
{
|
||||
baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; /* Clamp to valid range */
|
||||
lvl_seg[i] = default_filt_lvl
|
||||
+ mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
lvl_seg[i] = (lvl_seg[i] > 0) ?
|
||||
((lvl_seg[i] > 63) ? 63: lvl_seg[i]) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
baseline_filter_level[i] = default_filt_lvl;
|
||||
}
|
||||
lvl_seg[0] = default_filt_lvl;
|
||||
|
||||
/* Initialize the loop filter for this frame. */
|
||||
if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
|
||||
vp8_init_loop_filter(cm);
|
||||
else if (frame_type != cm->last_frame_type)
|
||||
vp8_frame_init_loop_filter(lfi, frame_type);
|
||||
|
||||
/* Set up the buffer pointers */
|
||||
y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
|
||||
@ -563,32 +575,64 @@ void vp8_loop_filter_partial_frame
|
||||
{
|
||||
for (mb_col = 0; mb_col < mb_cols; mb_col++)
|
||||
{
|
||||
int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
|
||||
int skip_lf = (mbd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
mbd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mbd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
int skip_lf = (mode_info_context->mbmi.mode != B_PRED &&
|
||||
mode_info_context->mbmi.mode != SPLITMV &&
|
||||
mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
filter_level = baseline_filter_level[Segment];
|
||||
if (alt_flt_enabled)
|
||||
filter_level = lvl_seg[mode_info_context->mbmi.segment_id];
|
||||
else
|
||||
filter_level = lvl_seg[0];
|
||||
|
||||
if (filter_level)
|
||||
{
|
||||
if (mb_col > 0)
|
||||
cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (cm->filter_type == NORMAL_LOOPFILTER)
|
||||
{
|
||||
const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
|
||||
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];
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level]);
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h)
|
||||
(y_ptr, 0, 0, post->y_stride, 0, &lfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h)
|
||||
(y_ptr, post->y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h)
|
||||
(y_ptr, post->y_stride, lfi_n->blim[filter_level]);
|
||||
}
|
||||
}
|
||||
|
||||
y_ptr += 16;
|
||||
mbd->mode_info_context += 1; /* step to next MB */
|
||||
mode_info_context += 1; /* step to next MB */
|
||||
}
|
||||
|
||||
y_ptr += post->y_stride * 16 - post->y_width;
|
||||
mbd->mode_info_context += 1; /* Skip border mb */
|
||||
mode_info_context += 1; /* Skip border mb */
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define loopfilter_h
|
||||
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_config.h"
|
||||
|
||||
#define MAX_LOOP_FILTER 63
|
||||
|
||||
@ -22,27 +23,46 @@ typedef enum
|
||||
SIMPLE_LOOPFILTER = 1
|
||||
} LOOPFILTERTYPE;
|
||||
|
||||
/* FRK
|
||||
* Need to align this structure so when it is declared and
|
||||
#if ARCH_ARM
|
||||
#define SIMD_WIDTH 1
|
||||
#else
|
||||
#define SIMD_WIDTH 16
|
||||
#endif
|
||||
|
||||
/* Need to align this structure so when it is declared and
|
||||
* passed it can be loaded into vector registers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
DECLARE_ALIGNED(16, signed char, lim[16]);
|
||||
DECLARE_ALIGNED(16, signed char, flim[16]);
|
||||
DECLARE_ALIGNED(16, signed char, thr[16]);
|
||||
DECLARE_ALIGNED(16, signed char, mbflim[16]);
|
||||
DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, mblim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
|
||||
DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, blim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
|
||||
DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, lim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
|
||||
DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, hev_thr[4][SIMD_WIDTH]);
|
||||
unsigned char lvl[4][4][4];
|
||||
unsigned char hev_thr_lut[2][MAX_LOOP_FILTER + 1];
|
||||
unsigned char mode_lf_lut[10];
|
||||
} loop_filter_info_n;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const unsigned char * mblim;
|
||||
const unsigned char * blim;
|
||||
const unsigned char * lim;
|
||||
const unsigned char * hev_thr;
|
||||
} loop_filter_info;
|
||||
|
||||
|
||||
#define prototype_loopfilter(sym) \
|
||||
void sym(unsigned char *src, int pitch, const signed char *flimit,\
|
||||
const signed char *limit, const signed char *thresh, int count)
|
||||
void sym(unsigned char *src, int pitch, const unsigned char *blimit,\
|
||||
const unsigned char *limit, const unsigned char *thresh, int count)
|
||||
|
||||
#define prototype_loopfilter_block(sym) \
|
||||
void sym(unsigned char *y, unsigned char *u, unsigned char *v,\
|
||||
void sym(unsigned char *y, unsigned char *u, unsigned char *v, \
|
||||
int ystride, int uv_stride, loop_filter_info *lfi)
|
||||
|
||||
#define prototype_simple_loopfilter(sym) \
|
||||
void sym(unsigned char *y, int ystride, const unsigned char *blimit)
|
||||
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
#include "x86/loopfilter_x86.h"
|
||||
#endif
|
||||
@ -71,38 +91,39 @@ extern prototype_loopfilter_block(vp8_lf_normal_mb_h);
|
||||
#endif
|
||||
extern prototype_loopfilter_block(vp8_lf_normal_b_h);
|
||||
|
||||
|
||||
#ifndef vp8_lf_simple_mb_v
|
||||
#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_c
|
||||
#define vp8_lf_simple_mb_v vp8_loop_filter_simple_vertical_edge_c
|
||||
#endif
|
||||
extern prototype_loopfilter_block(vp8_lf_simple_mb_v);
|
||||
extern prototype_simple_loopfilter(vp8_lf_simple_mb_v);
|
||||
|
||||
#ifndef vp8_lf_simple_b_v
|
||||
#define vp8_lf_simple_b_v vp8_loop_filter_bvs_c
|
||||
#endif
|
||||
extern prototype_loopfilter_block(vp8_lf_simple_b_v);
|
||||
extern prototype_simple_loopfilter(vp8_lf_simple_b_v);
|
||||
|
||||
#ifndef vp8_lf_simple_mb_h
|
||||
#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_c
|
||||
#define vp8_lf_simple_mb_h vp8_loop_filter_simple_horizontal_edge_c
|
||||
#endif
|
||||
extern prototype_loopfilter_block(vp8_lf_simple_mb_h);
|
||||
extern prototype_simple_loopfilter(vp8_lf_simple_mb_h);
|
||||
|
||||
#ifndef vp8_lf_simple_b_h
|
||||
#define vp8_lf_simple_b_h vp8_loop_filter_bhs_c
|
||||
#endif
|
||||
extern prototype_loopfilter_block(vp8_lf_simple_b_h);
|
||||
extern prototype_simple_loopfilter(vp8_lf_simple_b_h);
|
||||
|
||||
typedef prototype_loopfilter_block((*vp8_lf_block_fn_t));
|
||||
typedef prototype_simple_loopfilter((*vp8_slf_block_fn_t));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vp8_lf_block_fn_t normal_mb_v;
|
||||
vp8_lf_block_fn_t normal_b_v;
|
||||
vp8_lf_block_fn_t normal_mb_h;
|
||||
vp8_lf_block_fn_t normal_b_h;
|
||||
vp8_lf_block_fn_t simple_mb_v;
|
||||
vp8_lf_block_fn_t simple_b_v;
|
||||
vp8_lf_block_fn_t simple_mb_h;
|
||||
vp8_lf_block_fn_t simple_b_h;
|
||||
vp8_slf_block_fn_t simple_mb_v;
|
||||
vp8_slf_block_fn_t simple_b_v;
|
||||
vp8_slf_block_fn_t simple_mb_h;
|
||||
vp8_slf_block_fn_t simple_b_h;
|
||||
} vp8_loopfilter_rtcd_vtable_t;
|
||||
|
||||
#if CONFIG_RUNTIME_CPU_DETECT
|
||||
@ -115,9 +136,9 @@ typedef void loop_filter_uvfunction
|
||||
(
|
||||
unsigned char *u, /* source pointer */
|
||||
int p, /* pitch */
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
const unsigned char *blimit,
|
||||
const unsigned char *limit,
|
||||
const unsigned char *thresh,
|
||||
unsigned char *v
|
||||
);
|
||||
|
||||
|
@ -24,8 +24,9 @@ static __inline signed char vp8_signed_char_clamp(int t)
|
||||
|
||||
|
||||
/* should we apply any filter at all ( 11111111 yes, 00000000 no) */
|
||||
static __inline signed char vp8_filter_mask(signed char limit, signed char flimit,
|
||||
uc p3, uc p2, uc p1, uc p0, uc q0, uc q1, uc q2, uc q3)
|
||||
static __inline signed char vp8_filter_mask(uc limit, uc blimit,
|
||||
uc p3, uc p2, uc p1, uc p0,
|
||||
uc q0, uc q1, uc q2, uc q3)
|
||||
{
|
||||
signed char mask = 0;
|
||||
mask |= (abs(p3 - p2) > limit) * -1;
|
||||
@ -34,13 +35,13 @@ static __inline signed char vp8_filter_mask(signed char limit, signed char flimi
|
||||
mask |= (abs(q1 - q0) > limit) * -1;
|
||||
mask |= (abs(q2 - q1) > limit) * -1;
|
||||
mask |= (abs(q3 - q2) > limit) * -1;
|
||||
mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > flimit * 2 + limit) * -1;
|
||||
mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1;
|
||||
mask = ~mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/* is there high variance internal edge ( 11111111 yes, 00000000 no) */
|
||||
static __inline signed char vp8_hevmask(signed char thresh, uc p1, uc p0, uc q0, uc q1)
|
||||
static __inline signed char vp8_hevmask(uc thresh, uc p1, uc p0, uc q0, uc q1)
|
||||
{
|
||||
signed char hev = 0;
|
||||
hev |= (abs(p1 - p0) > thresh) * -1;
|
||||
@ -48,7 +49,8 @@ static __inline signed char vp8_hevmask(signed char thresh, uc p1, uc p0, uc q0,
|
||||
return hev;
|
||||
}
|
||||
|
||||
static __inline void vp8_filter(signed char mask, signed char hev, uc *op1, uc *op0, uc *oq0, uc *oq1)
|
||||
static __inline void vp8_filter(signed char mask, uc hev, uc *op1,
|
||||
uc *op0, uc *oq0, uc *oq1)
|
||||
|
||||
{
|
||||
signed char ps0, qs0;
|
||||
@ -98,9 +100,9 @@ void vp8_loop_filter_horizontal_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p, /* pitch */
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
const unsigned char *blimit,
|
||||
const unsigned char *limit,
|
||||
const unsigned char *thresh,
|
||||
int count
|
||||
)
|
||||
{
|
||||
@ -113,11 +115,11 @@ void vp8_loop_filter_horizontal_edge_c
|
||||
*/
|
||||
do
|
||||
{
|
||||
mask = vp8_filter_mask(limit[i], flimit[i],
|
||||
mask = vp8_filter_mask(limit[0], blimit[0],
|
||||
s[-4*p], s[-3*p], s[-2*p], s[-1*p],
|
||||
s[0*p], s[1*p], s[2*p], s[3*p]);
|
||||
|
||||
hev = vp8_hevmask(thresh[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
hev = vp8_hevmask(thresh[0], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
|
||||
vp8_filter(mask, hev, s - 2 * p, s - 1 * p, s, s + 1 * p);
|
||||
|
||||
@ -130,9 +132,9 @@ void vp8_loop_filter_vertical_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p,
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
const unsigned char *blimit,
|
||||
const unsigned char *limit,
|
||||
const unsigned char *thresh,
|
||||
int count
|
||||
)
|
||||
{
|
||||
@ -145,10 +147,10 @@ void vp8_loop_filter_vertical_edge_c
|
||||
*/
|
||||
do
|
||||
{
|
||||
mask = vp8_filter_mask(limit[i], flimit[i],
|
||||
mask = vp8_filter_mask(limit[0], blimit[0],
|
||||
s[-4], s[-3], s[-2], s[-1], s[0], s[1], s[2], s[3]);
|
||||
|
||||
hev = vp8_hevmask(thresh[i], s[-2], s[-1], s[0], s[1]);
|
||||
hev = vp8_hevmask(thresh[0], s[-2], s[-1], s[0], s[1]);
|
||||
|
||||
vp8_filter(mask, hev, s - 2, s - 1, s, s + 1);
|
||||
|
||||
@ -157,7 +159,7 @@ void vp8_loop_filter_vertical_edge_c
|
||||
while (++i < count * 8);
|
||||
}
|
||||
|
||||
static __inline void vp8_mbfilter(signed char mask, signed char hev,
|
||||
static __inline void vp8_mbfilter(signed char mask, uc hev,
|
||||
uc *op2, uc *op1, uc *op0, uc *oq0, uc *oq1, uc *oq2)
|
||||
{
|
||||
signed char s, u;
|
||||
@ -216,9 +218,9 @@ void vp8_mbloop_filter_horizontal_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p,
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
const unsigned char *blimit,
|
||||
const unsigned char *limit,
|
||||
const unsigned char *thresh,
|
||||
int count
|
||||
)
|
||||
{
|
||||
@ -232,11 +234,11 @@ void vp8_mbloop_filter_horizontal_edge_c
|
||||
do
|
||||
{
|
||||
|
||||
mask = vp8_filter_mask(limit[i], flimit[i],
|
||||
mask = vp8_filter_mask(limit[0], blimit[0],
|
||||
s[-4*p], s[-3*p], s[-2*p], s[-1*p],
|
||||
s[0*p], s[1*p], s[2*p], s[3*p]);
|
||||
|
||||
hev = vp8_hevmask(thresh[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
hev = vp8_hevmask(thresh[0], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
|
||||
vp8_mbfilter(mask, hev, s - 3 * p, s - 2 * p, s - 1 * p, s, s + 1 * p, s + 2 * p);
|
||||
|
||||
@ -251,9 +253,9 @@ void vp8_mbloop_filter_vertical_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p,
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
const unsigned char *blimit,
|
||||
const unsigned char *limit,
|
||||
const unsigned char *thresh,
|
||||
int count
|
||||
)
|
||||
{
|
||||
@ -264,10 +266,10 @@ void vp8_mbloop_filter_vertical_edge_c
|
||||
do
|
||||
{
|
||||
|
||||
mask = vp8_filter_mask(limit[i], flimit[i],
|
||||
mask = vp8_filter_mask(limit[0], blimit[0],
|
||||
s[-4], s[-3], s[-2], s[-1], s[0], s[1], s[2], s[3]);
|
||||
|
||||
hev = vp8_hevmask(thresh[i], s[-2], s[-1], s[0], s[1]);
|
||||
hev = vp8_hevmask(thresh[0], s[-2], s[-1], s[0], s[1]);
|
||||
|
||||
vp8_mbfilter(mask, hev, s - 3, s - 2, s - 1, s, s + 1, s + 2);
|
||||
|
||||
@ -278,13 +280,13 @@ void vp8_mbloop_filter_vertical_edge_c
|
||||
}
|
||||
|
||||
/* should we apply any filter at all ( 11111111 yes, 00000000 no) */
|
||||
static __inline signed char vp8_simple_filter_mask(signed char limit, signed char flimit, uc p1, uc p0, uc q0, uc q1)
|
||||
static __inline signed char vp8_simple_filter_mask(uc blimit, uc p1, uc p0, uc q0, uc q1)
|
||||
{
|
||||
/* Why does this cause problems for win32?
|
||||
* error C2143: syntax error : missing ';' before 'type'
|
||||
* (void) limit;
|
||||
*/
|
||||
signed char mask = (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 <= flimit * 2 + limit) * -1;
|
||||
signed char mask = (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 <= blimit) * -1;
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -317,47 +319,37 @@ void vp8_loop_filter_simple_horizontal_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p,
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
int count
|
||||
const unsigned char *blimit
|
||||
)
|
||||
{
|
||||
signed char mask = 0;
|
||||
int i = 0;
|
||||
(void) thresh;
|
||||
|
||||
do
|
||||
{
|
||||
/*mask = vp8_simple_filter_mask( limit[i], flimit[i],s[-1*p],s[0*p]);*/
|
||||
mask = vp8_simple_filter_mask(limit[i], flimit[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
mask = vp8_simple_filter_mask(blimit[0], s[-2*p], s[-1*p], s[0*p], s[1*p]);
|
||||
vp8_simple_filter(mask, s - 2 * p, s - 1 * p, s, s + 1 * p);
|
||||
++s;
|
||||
}
|
||||
while (++i < count * 8);
|
||||
while (++i < 16);
|
||||
}
|
||||
|
||||
void vp8_loop_filter_simple_vertical_edge_c
|
||||
(
|
||||
unsigned char *s,
|
||||
int p,
|
||||
const signed char *flimit,
|
||||
const signed char *limit,
|
||||
const signed char *thresh,
|
||||
int count
|
||||
const unsigned char *blimit
|
||||
)
|
||||
{
|
||||
signed char mask = 0;
|
||||
int i = 0;
|
||||
(void) thresh;
|
||||
|
||||
do
|
||||
{
|
||||
/*mask = vp8_simple_filter_mask( limit[i], flimit[i],s[-1],s[0]);*/
|
||||
mask = vp8_simple_filter_mask(limit[i], flimit[i], s[-2], s[-1], s[0], s[1]);
|
||||
mask = vp8_simple_filter_mask(blimit[0], s[-2], s[-1], s[0], s[1]);
|
||||
vp8_simple_filter(mask, s - 2, s - 1, s, s + 1);
|
||||
s += p;
|
||||
}
|
||||
while (++i < count * 8);
|
||||
while (++i < 16);
|
||||
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ typedef struct VP8_COMMON_RTCD
|
||||
} VP8_COMMON_RTCD;
|
||||
|
||||
typedef struct VP8Common
|
||||
|
||||
{
|
||||
struct vpx_internal_error_info error;
|
||||
|
||||
@ -107,7 +108,8 @@ typedef struct VP8Common
|
||||
YV12_BUFFER_CONFIG post_proc_buffer;
|
||||
YV12_BUFFER_CONFIG temp_scale_frame;
|
||||
|
||||
FRAME_TYPE last_frame_type; /* Save last frame's frame type for loopfilter init checking and motion search. */
|
||||
|
||||
FRAME_TYPE last_frame_type; /* Save last frame's frame type for motion search. */
|
||||
FRAME_TYPE frame_type;
|
||||
|
||||
int show_frame;
|
||||
@ -148,11 +150,9 @@ typedef struct VP8Common
|
||||
INTERPOLATIONFILTERTYPE mcomp_filter_type;
|
||||
LOOPFILTERTYPE last_filter_type;
|
||||
LOOPFILTERTYPE filter_type;
|
||||
loop_filter_info lf_info[MAX_LOOP_FILTER+1];
|
||||
prototype_loopfilter_block((*lf_mbv));
|
||||
prototype_loopfilter_block((*lf_mbh));
|
||||
prototype_loopfilter_block((*lf_bv));
|
||||
prototype_loopfilter_block((*lf_bh));
|
||||
|
||||
loop_filter_info_n lf_info;
|
||||
|
||||
int filter_level;
|
||||
int last_sharpness_level;
|
||||
int sharpness_level;
|
||||
@ -205,10 +205,9 @@ typedef struct VP8Common
|
||||
struct postproc_state postproc_state;
|
||||
} VP8_COMMON;
|
||||
|
||||
|
||||
int vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int filter_level);
|
||||
void vp8_init_loop_filter(VP8_COMMON *cm);
|
||||
void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type);
|
||||
extern void vp8_loop_filter_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val);
|
||||
void vp8_loop_filter_init(VP8_COMMON *cm);
|
||||
void vp8_loop_filter_frame_init(VP8_COMMON *cm, MACROBLOCKD *mbd,
|
||||
int default_filt_lvl, int sharpness_lvl);
|
||||
void vp8_loop_filter_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val);
|
||||
|
||||
#endif
|
||||
|
@ -95,7 +95,7 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
|
||||
{
|
||||
VP8_COMMON *cm = &pbi->common;
|
||||
|
||||
vp8_init_loop_filter(cm);
|
||||
vp8_loop_filter_init(cm);
|
||||
cm->last_frame_type = KEY_FRAME;
|
||||
cm->last_filter_type = cm->filter_type;
|
||||
cm->last_sharpness_level = cm->sharpness_level;
|
||||
|
@ -274,9 +274,7 @@ static THREAD_FUNCTION thread_decoding_proc(void *p_data)
|
||||
int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
|
||||
|
||||
int filter_level;
|
||||
loop_filter_info *lfi = pc->lf_info;
|
||||
int alt_flt_enabled = xd->segmentation_enabled;
|
||||
int Segment;
|
||||
loop_filter_info_n *lfi_n = &pc->lf_info;
|
||||
|
||||
pbi->mb_row_di[ithread].mb_row = mb_row;
|
||||
pbi->mb_row_di[ithread].mbd.current_bc = &pbi->mbc[mb_row%num_part];
|
||||
@ -362,7 +360,16 @@ static THREAD_FUNCTION thread_decoding_proc(void *p_data)
|
||||
|
||||
if (pbi->common.filter_level)
|
||||
{
|
||||
int skip_lf;
|
||||
int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
xd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
|
||||
const int seg = xd->mode_info_context->mbmi.segment_id;
|
||||
const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
|
||||
|
||||
filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
|
||||
|
||||
if( mb_row != pc->mb_rows-1 )
|
||||
{
|
||||
/* Save decoded MB last row data for next-row decoding */
|
||||
@ -388,35 +395,57 @@ static THREAD_FUNCTION thread_decoding_proc(void *p_data)
|
||||
}
|
||||
}
|
||||
|
||||
/* update loopfilter info */
|
||||
Segment = (alt_flt_enabled) ? xd->mode_info_context->mbmi.segment_id : 0;
|
||||
skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
xd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
filter_level = pbi->mt_baseline_filter_level[Segment];
|
||||
/* Distance of Mb to the various image edges.
|
||||
* These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
|
||||
* Apply any context driven MB level adjustment
|
||||
*/
|
||||
filter_level = vp8_adjust_mb_lf_value(xd, filter_level);
|
||||
|
||||
/* loopfilter on this macroblock. */
|
||||
if (filter_level)
|
||||
{
|
||||
if (mb_col > 0)
|
||||
pc->lf_mbv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if(pc->filter_type == NORMAL_LOOPFILTER)
|
||||
{
|
||||
loop_filter_info lfi;
|
||||
FRAME_TYPE frame_type = pc->frame_type;
|
||||
const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
|
||||
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];
|
||||
|
||||
if (!skip_lf)
|
||||
pc->lf_bv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
pc->lf_mbh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
pc->lf_bh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
recon_yoffset += 16;
|
||||
@ -681,53 +710,6 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void lpf_init( VP8D_COMP *pbi, int default_filt_lvl)
|
||||
{
|
||||
VP8_COMMON *cm = &pbi->common;
|
||||
MACROBLOCKD *mbd = &pbi->mb;
|
||||
/*YV12_BUFFER_CONFIG *post = &cm->new_frame;*/ /*frame_to_show;*/
|
||||
loop_filter_info *lfi = cm->lf_info;
|
||||
FRAME_TYPE frame_type = cm->frame_type;
|
||||
|
||||
/*int mb_row;
|
||||
int mb_col;
|
||||
int baseline_filter_level[MAX_MB_SEGMENTS];*/
|
||||
int alt_flt_enabled = mbd->segmentation_enabled;
|
||||
|
||||
int i;
|
||||
/*unsigned char *y_ptr, *u_ptr, *v_ptr;*/
|
||||
|
||||
/* Note the baseline filter values for each segment */
|
||||
if (alt_flt_enabled)
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
{
|
||||
/* Abs value */
|
||||
if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
|
||||
pbi->mt_baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
/* Delta Value */
|
||||
else
|
||||
{
|
||||
pbi->mt_baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
|
||||
pbi->mt_baseline_filter_level[i] = (pbi->mt_baseline_filter_level[i] >= 0) ? ((pbi->mt_baseline_filter_level[i] <= MAX_LOOP_FILTER) ? pbi->mt_baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; /* Clamp to valid range */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MB_SEGMENTS; i++)
|
||||
pbi->mt_baseline_filter_level[i] = default_filt_lvl;
|
||||
}
|
||||
|
||||
/* Initialize the loop filter for this frame. */
|
||||
if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
|
||||
vp8_init_loop_filter(cm);
|
||||
else if (frame_type != cm->last_frame_type)
|
||||
vp8_frame_init_loop_filter(lfi, frame_type);
|
||||
}
|
||||
|
||||
|
||||
void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
{
|
||||
int mb_row;
|
||||
@ -738,12 +720,10 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
volatile int *last_row_current_mb_col = NULL;
|
||||
int nsync = pbi->sync_range;
|
||||
|
||||
int filter_level;
|
||||
loop_filter_info *lfi = pc->lf_info;
|
||||
int alt_flt_enabled = xd->segmentation_enabled;
|
||||
int Segment;
|
||||
int filter_level = pc->filter_level;
|
||||
loop_filter_info_n *lfi_n = &pc->lf_info;
|
||||
|
||||
if(pbi->common.filter_level)
|
||||
if (filter_level)
|
||||
{
|
||||
/* Set above_row buffer to 127 for decoding first MB row */
|
||||
vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, pc->yv12_fb[pc->lst_fb_idx].y_width + 5);
|
||||
@ -764,7 +744,9 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
|
||||
vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
|
||||
}
|
||||
lpf_init(pbi, pc->filter_level);
|
||||
|
||||
/* Initialize the loop filter for this frame. */
|
||||
vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level, pc->sharpness_level);
|
||||
}
|
||||
|
||||
setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
|
||||
@ -774,7 +756,6 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
|
||||
for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
|
||||
{
|
||||
|
||||
xd->current_bc = &pbi->mbc[mb_row%num_part];
|
||||
|
||||
/* vp8_decode_mb_row(pbi, pc, mb_row, xd); */
|
||||
@ -875,7 +856,16 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
|
||||
if (pbi->common.filter_level)
|
||||
{
|
||||
int skip_lf;
|
||||
int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
xd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
|
||||
const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
|
||||
const int seg = xd->mode_info_context->mbmi.segment_id;
|
||||
const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
|
||||
|
||||
filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
|
||||
|
||||
/* Save decoded MB last row data for next-row decoding */
|
||||
if(mb_row != pc->mb_rows-1)
|
||||
{
|
||||
@ -901,36 +891,58 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
|
||||
}
|
||||
}
|
||||
|
||||
/* update loopfilter info */
|
||||
Segment = (alt_flt_enabled) ? xd->mode_info_context->mbmi.segment_id : 0;
|
||||
skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
|
||||
xd->mode_info_context->mbmi.mode != SPLITMV &&
|
||||
xd->mode_info_context->mbmi.mb_skip_coeff);
|
||||
filter_level = pbi->mt_baseline_filter_level[Segment];
|
||||
/* Distance of Mb to the various image edges.
|
||||
* These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
|
||||
* Apply any context driven MB level adjustment
|
||||
*/
|
||||
filter_level = vp8_adjust_mb_lf_value(xd, filter_level);
|
||||
|
||||
/* loopfilter on this macroblock. */
|
||||
if (filter_level)
|
||||
{
|
||||
if (mb_col > 0)
|
||||
pc->lf_mbv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if(pc->filter_type == NORMAL_LOOPFILTER)
|
||||
{
|
||||
loop_filter_info lfi;
|
||||
FRAME_TYPE frame_type = pc->frame_type;
|
||||
const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
|
||||
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];
|
||||
|
||||
if (!skip_lf)
|
||||
pc->lf_bv(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
pc->lf_mbh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
pc->lf_bh(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi[filter_level]);
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
|
||||
(xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mb_col > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
|
||||
|
||||
/* don't apply across umv border */
|
||||
if (mb_row > 0)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
|
||||
|
||||
if (!skip_lf)
|
||||
LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
|
||||
(xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
recon_yoffset += 16;
|
||||
recon_uvoffset += 8;
|
||||
|
||||
|
@ -2105,7 +2105,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
|
||||
//when needed. This will avoid unnecessary calls of vp8cx_init_quantizer() for every frame.
|
||||
vp8cx_init_quantizer(cpi);
|
||||
{
|
||||
vp8_init_loop_filter(cm);
|
||||
vp8_loop_filter_init(cm);
|
||||
cm->last_frame_type = KEY_FRAME;
|
||||
cm->last_filter_type = cm->filter_type;
|
||||
cm->last_sharpness_level = cm->sharpness_level;
|
||||
|
Loading…
x
Reference in New Issue
Block a user