Index: source/libvpx/vp9/common/vp9_loopfilter.c |
=================================================================== |
--- source/libvpx/vp9/common/vp9_loopfilter.c (revision 219822) |
+++ source/libvpx/vp9/common/vp9_loopfilter.c (working copy) |
@@ -16,13 +16,19 @@ |
#include "vp9/common/vp9_seg_common.h" |
+struct loop_filter_info { |
+ const uint8_t *mblim; |
+ const uint8_t *lim; |
+ const uint8_t *hev_thr; |
+}; |
+ |
static void lf_init_lut(loop_filter_info_n *lfi) { |
lfi->mode_lf_lut[DC_PRED] = 0; |
lfi->mode_lf_lut[D45_PRED] = 0; |
lfi->mode_lf_lut[D135_PRED] = 0; |
lfi->mode_lf_lut[D117_PRED] = 0; |
lfi->mode_lf_lut[D153_PRED] = 0; |
- lfi->mode_lf_lut[D27_PRED] = 0; |
+ lfi->mode_lf_lut[D207_PRED] = 0; |
lfi->mode_lf_lut[D63_PRED] = 0; |
lfi->mode_lf_lut[V_PRED] = 0; |
lfi->mode_lf_lut[H_PRED] = 0; |
@@ -55,8 +61,9 @@ |
} |
} |
-void vp9_loop_filter_init(VP9_COMMON *cm, struct loopfilter *lf) { |
+void vp9_loop_filter_init(VP9_COMMON *cm) { |
loop_filter_info_n *lfi = &cm->lf_info; |
+ struct loopfilter *lf = &cm->lf; |
int i; |
// init limits for given sharpness |
@@ -71,15 +78,15 @@ |
vpx_memset(lfi->hev_thr[i], i, SIMD_WIDTH); |
} |
-void vp9_loop_filter_frame_init(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
- int default_filt_lvl) { |
- int seg; |
+void vp9_loop_filter_frame_init(VP9_COMMON *const cm, int default_filt_lvl) { |
+ int seg_id; |
// n_shift is the a multiplier for lf_deltas |
// the multiplier is 1 for when filter_lvl is between 0 and 31; |
// 2 when filter_lvl is between 32 and 63 |
const int n_shift = default_filt_lvl >> 5; |
loop_filter_info_n *const lfi = &cm->lf_info; |
- struct loopfilter *lf = &xd->lf; |
+ struct loopfilter *const lf = &cm->lf; |
+ struct segmentation *const seg = &cm->seg; |
// update limits if sharpness has changed |
if (lf->last_sharpness_level != lf->sharpness_level) { |
@@ -87,13 +94,13 @@ |
lf->last_sharpness_level = lf->sharpness_level; |
} |
- for (seg = 0; seg < MAX_SEGMENTS; seg++) { |
+ for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { |
int lvl_seg = default_filt_lvl, ref, mode, intra_lvl; |
// Set the baseline filter values for each segment |
- if (vp9_segfeature_active(&xd->seg, seg, SEG_LVL_ALT_LF)) { |
- const int data = vp9_get_segdata(&xd->seg, seg, SEG_LVL_ALT_LF); |
- lvl_seg = xd->seg.abs_delta == SEGMENT_ABSDATA |
+ if (vp9_segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) { |
+ const int data = vp9_get_segdata(seg, seg_id, SEG_LVL_ALT_LF); |
+ lvl_seg = seg->abs_delta == SEGMENT_ABSDATA |
? data |
: clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER); |
} |
@@ -101,18 +108,18 @@ |
if (!lf->mode_ref_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); |
+ vpx_memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id])); |
continue; |
} |
intra_lvl = lvl_seg + (lf->ref_deltas[INTRA_FRAME] << n_shift); |
- lfi->lvl[seg][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER); |
+ lfi->lvl[seg_id][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER); |
for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) |
for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { |
const int inter_lvl = lvl_seg + (lf->ref_deltas[ref] << n_shift) |
+ (lf->mode_deltas[mode] << n_shift); |
- lfi->lvl[seg][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER); |
+ lfi->lvl[seg_id][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER); |
} |
} |
} |
@@ -255,8 +262,8 @@ |
// Determine the vertical edges that need filtering |
for (c = 0; c < MI_BLOCK_SIZE && mi_col + c < cm->mi_cols; c += col_step) { |
- const int skip_this = mi[c].mbmi.mb_skip_coeff |
- && mi[c].mbmi.ref_frame[0] != INTRA_FRAME; |
+ const int skip_this = mi[c].mbmi.skip_coeff |
+ && is_inter_block(&mi[c].mbmi); |
// left edge of current unit is block/partition edge -> no skip |
const int block_edge_left = b_width_log2(mi[c].mbmi.sb_type) ? |
!(c & ((1 << (b_width_log2(mi[c].mbmi.sb_type)-1)) - 1)) : 1; |
@@ -370,9 +377,29 @@ |
} |
void vp9_loop_filter_frame(VP9_COMMON *cm, MACROBLOCKD *xd, |
- int frame_filter_level, int y_only) { |
+ int frame_filter_level, |
+ int y_only, int partial) { |
+ int start_mi_row, end_mi_row, mi_rows_to_filter; |
if (!frame_filter_level) return; |
- vp9_loop_filter_frame_init(cm, xd, frame_filter_level); |
+ |
+ start_mi_row = 0; |
+ mi_rows_to_filter = cm->mi_rows; |
+ if (partial && cm->mi_rows > 8) { |
+ start_mi_row = cm->mi_rows >> 1; |
+ start_mi_row &= 0xfffffff8; |
+ mi_rows_to_filter = MAX(cm->mi_rows / 8, 8); |
+ } |
+ end_mi_row = start_mi_row + mi_rows_to_filter; |
+ vp9_loop_filter_frame_init(cm, frame_filter_level); |
vp9_loop_filter_rows(cm->frame_to_show, cm, xd, |
- 0, cm->mi_rows, y_only); |
+ start_mi_row, end_mi_row, |
+ y_only); |
} |
+ |
+int vp9_loop_filter_worker(void *arg1, void *arg2) { |
+ LFWorkerData *const lf_data = (LFWorkerData*)arg1; |
+ (void)arg2; |
+ vp9_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, &lf_data->xd, |
+ lf_data->start, lf_data->stop, lf_data->y_only); |
+ return 1; |
+} |