ref: 622958449b9388cca0f4a4e287b3e94422e4a573
parent: 973a9c075d2db817e489f5ba050fc49963bf2c71
author: Attila Nagy <attilanagy@google.com>
date: Fri Jun 10 10:10:21 EDT 2011
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
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -108,9 +108,9 @@
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)
--- a/vp8/common/loopfilter.c
+++ b/vp8/common/loopfilter.c
@@ -9,153 +9,150 @@
*/
-#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);
+ vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_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);
-}
-
/* 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);
+ vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_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);
-}
-
/* 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);
block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
@@ -169,119 +166,120 @@
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;
- }
-
+ 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);
}
+}
- /* Set up the function pointers depending on the type of loop filtering selected */
- if (lft == NORMAL_LOOPFILTER)
+void vp8_loop_filter_init(VP8_COMMON *cm)
+{
+ loop_filter_info_n *lfi = &cm->lf_info;
+ int 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++)
{
- 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);
+ vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH);
}
- 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);
- }
}
-/* 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_frame_init(VP8_COMMON *cm,
+ MACROBLOCKD *mbd,
+ int default_filt_lvl,
+ int sharpness_lvl)
{
- int HEVThresh;
- int i, j;
+ int seg, /* segment number */
+ ref, /* index in ref_lf_deltas */
+ mode; /* index in mode_lf_deltas */
- /* For each possible value for the loop filter fill out a "loop_filter_info" entry. */
- for (i = 0; i <= MAX_LOOP_FILTER; i++)
+ loop_filter_info_n *lfi = &cm->lf_info;
+
+ /* update limits if sharpness has changed */
+ if(cm->last_sharpness_level != sharpness_lvl)
{
- int filt_lvl = i;
+ vp8_loop_filter_update_sharpness(lfi, sharpness_lvl);
+ cm->last_sharpness_level = sharpness_lvl;
+ }
- if (frame_type == KEY_FRAME)
+ 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)
{
- if (filt_lvl >= 40)
- HEVThresh = 2;
- else if (filt_lvl >= 15)
- HEVThresh = 1;
- else
- HEVThresh = 0;
+ /* 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;
+ }
}
- 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++)
+ if (!mbd->mode_ref_lf_delta_enabled)
{
- /*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;
+ /* 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;
-int vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int filter_level)
-{
- MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
+ /* INTRA_FRAME */
+ ref = INTRA_FRAME;
- if (mbd->mode_ref_lf_delta_enabled)
- {
/* 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];
- }
- else
- {
- /* Zero motion mode */
- if (mbmi->mode == ZEROMV)
- filter_level += mbd->mode_lf_deltas[1];
+ int lvl_ref = lvl_seg;
- /* Split MB motion mode */
- else if (mbmi->mode == SPLITMV)
- filter_level += mbd->mode_lf_deltas[3];
+ /* Apply delta for reference frame */
+ lvl_ref += mbd->ref_lf_deltas[ref];
- /* All other inter motion modes (Nearest, Near, New) */
- else
- filter_level += mbd->mode_lf_deltas[2];
- }
+ /* 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 */
- /* Range check */
- if (filter_level > MAX_LOOP_FILTER)
- filter_level = MAX_LOOP_FILTER;
- else if (filter_level < 0)
- filter_level = 0;
+ lfi->lvl[seg][ref][mode] = lvl_mode;
+ }
+ }
}
- return filter_level;
}
-
void vp8_loop_filter_frame
(
VP8_COMMON *cm,
@@ -290,49 +288,23 @@
)
{
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 */
+ /* Point at base of Mb MODE_INFO list */
+ const MODE_INFO *mode_info_context = cm->mi;
- /* 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;
- }
-
/* 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,33 +316,62 @@
{
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;
@@ -377,7 +378,7 @@
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;
@@ -384,11 +385,10 @@
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 @@
{
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 @@
{
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,26 +510,33 @@
{
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 *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;
+ 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));
if (linestocopy < 1)
@@ -531,29 +548,24 @@
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 @@
{
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 */
}
}
--- a/vp8/common/loopfilter.h
+++ b/vp8/common/loopfilter.h
@@ -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 @@
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,28 +91,29 @@
#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;
@@ -99,10 +120,10 @@
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 @@
(
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
);
--- a/vp8/common/loopfilter_filters.c
+++ b/vp8/common/loopfilter_filters.c
@@ -24,8 +24,9 @@
/* 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 @@
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 @@
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 @@
(
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 @@
*/
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 @@
(
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 @@
*/
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 @@
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 @@
(
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 @@
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 @@
(
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 @@
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 @@
}
/* 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,24 +319,19 @@
(
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
@@ -341,23 +338,18 @@
(
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);
}
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -83,6 +83,7 @@
} VP8_COMMON_RTCD;
typedef struct VP8Common
+
{
struct vpx_internal_error_info error;
@@ -107,7 +108,8 @@
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 @@
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 @@
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
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -95,7 +95,7 @@
{
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;
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -274,9 +274,7 @@
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 @@
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 @@
}
}
- /* 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 @@
}
}
-
-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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- /* 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;
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2105,7 +2105,7 @@
//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;
--
⑨