From a04ed0e8f3c2005aacfad83939ac8af70a9221ef Mon Sep 17 00:00:00 2001 From: Johann Date: Wed, 20 Jul 2011 15:53:42 -0400 Subject: [PATCH] fix sharpness bug and clean up sharpness was not recalculated in vp8cx_pick_filter_level_fast remove last_filter_type. all values are calculated, don't need to update the lfi data when it changes. always use cm->sharpness_level. the extra indirection was annoying. don't track last frame_type or sharpness_level manually. frame type only matters for motion search and sharpness_level is taken care of in frame_init move function declarations to their proper header Change-Id: I7ef037bd4bf8cf5e37d2d36bd03b5e22a2ad91db --- vp8/common/blockd.h | 2 +- vp8/common/loopfilter.c | 43 ++++++++++++++------------------------- vp8/common/loopfilter.h | 23 +++++++++++++++++++++ vp8/common/onyxc_int.h | 6 ------ vp8/decoder/decodframe.c | 8 -------- vp8/decoder/onyxd_if.c | 17 +++------------- vp8/decoder/threading.c | 2 +- vp8/encoder/onyx_if.c | 16 ++++----------- vp8/encoder/picklpf.c | 52 ++++++++++++------------------------------------ 9 files changed, 60 insertions(+), 109 deletions(-) diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index 84c52773..16b7281e 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -192,7 +192,7 @@ typedef struct union b_mode_info bmi; } BLOCKD; -typedef struct +typedef struct MacroBlockD { DECLARE_ALIGNED(16, short, diff[400]); /* from idct diff */ DECLARE_ALIGNED(16, unsigned char, predictor[384]); diff --git a/vp8/common/loopfilter.c b/vp8/common/loopfilter.c index be3f5359..fe0644bd 100644 --- a/vp8/common/loopfilter.c +++ b/vp8/common/loopfilter.c @@ -195,8 +195,7 @@ 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) + int default_filt_lvl) { int seg, /* segment number */ ref, /* index in ref_lf_deltas */ @@ -205,10 +204,10 @@ void vp8_loop_filter_frame_init(VP8_COMMON *cm, loop_filter_info_n *lfi = &cm->lf_info; /* update limits if sharpness has changed */ - if(cm->last_sharpness_level != sharpness_lvl) + if(cm->last_sharpness_level != cm->sharpness_level) { - vp8_loop_filter_update_sharpness(lfi, sharpness_lvl); - cm->last_sharpness_level = sharpness_lvl; + vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level); + cm->last_sharpness_level = cm->sharpness_level; } for(seg = 0; seg < MAX_MB_SEGMENTS; seg++) @@ -283,8 +282,7 @@ void vp8_loop_filter_frame_init(VP8_COMMON *cm, void vp8_loop_filter_frame ( VP8_COMMON *cm, - MACROBLOCKD *mbd, - int default_filt_lvl + MACROBLOCKD *mbd ) { YV12_BUFFER_CONFIG *post = cm->frame_to_show; @@ -304,7 +302,7 @@ void vp8_loop_filter_frame const MODE_INFO *mode_info_context = cm->mi; /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl, cm->sharpness_level); + vp8_loop_filter_frame_init(cm, mbd, cm->filter_level); /* Set up the buffer pointers */ y_ptr = post->y_buffer; @@ -393,8 +391,7 @@ void vp8_loop_filter_frame_yonly ( VP8_COMMON *cm, MACROBLOCKD *mbd, - int default_filt_lvl, - int sharpness_lvl + int default_filt_lvl ) { YV12_BUFFER_CONFIG *post = cm->frame_to_show; @@ -412,15 +409,13 @@ void vp8_loop_filter_frame_yonly /* Point at base of Mb MODE_INFO list */ const MODE_INFO *mode_info_context = cm->mi; - sharpness_lvl = cm->sharpness_level; - #if 0 if(default_filt_lvl == 0) /* no filter applied */ return; #endif /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl, sharpness_lvl); + vp8_loop_filter_frame_init( cm, mbd, default_filt_lvl); /* Set up the buffer pointers */ y_ptr = post->y_buffer; @@ -503,9 +498,7 @@ void vp8_loop_filter_partial_frame ( VP8_COMMON *cm, MACROBLOCKD *mbd, - int default_filt_lvl, - int sharpness_lvl, - int Fraction + int default_filt_lvl ) { YV12_BUFFER_CONFIG *post = cm->frame_to_show; @@ -528,16 +521,10 @@ void vp8_loop_filter_partial_frame 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)); + /* 3 is a magic number. 4 is probably magic too */ + linestocopy = (post->y_height >> (4 + 3)); if (linestocopy < 1) linestocopy = 1; @@ -545,6 +532,9 @@ void vp8_loop_filter_partial_frame linestocopy <<= 4; /* Note the baseline filter values for each segment */ + /* See vp8_loop_filter_frame_init. Rather than call that for each change + * to default_filt_lvl, copy the relevant calculation here. + */ if (alt_flt_enabled) { for (i = 0; i < MAX_MB_SEGMENTS; i++) @@ -563,9 +553,6 @@ void vp8_loop_filter_partial_frame } } } - else - lvl_seg[0] = default_filt_lvl; - /* Set up the buffer pointers */ y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride; @@ -582,7 +569,7 @@ void vp8_loop_filter_partial_frame if (alt_flt_enabled) filter_level = lvl_seg[mode_info_context->mbmi.segment_id]; else - filter_level = lvl_seg[0]; + filter_level = default_filt_lvl; if (filter_level) { diff --git a/vp8/common/loopfilter.h b/vp8/common/loopfilter.h index 2d6dad30..9887cf55 100644 --- a/vp8/common/loopfilter.h +++ b/vp8/common/loopfilter.h @@ -142,4 +142,27 @@ typedef void loop_filter_uvfunction unsigned char *v ); +/* assorted loopfilter functions which get used elsewhere */ +struct VP8Common; +struct MacroBlockD; + +void vp8_loop_filter_init(struct VP8Common *cm); + +void vp8_loop_filter_frame_init(struct VP8Common *cm, + struct MacroBlockD *mbd, + int default_filt_lvl); + +void vp8_loop_filter_frame(struct VP8Common *cm, struct MacroBlockD *mbd); + +void vp8_loop_filter_partial_frame(struct VP8Common *cm, + struct MacroBlockD *mbd, + int default_filt_lvl); + +void vp8_loop_filter_frame_yonly(struct VP8Common *cm, + struct MacroBlockD *mbd, + int default_filt_lvl); + +void vp8_loop_filter_update_sharpness(loop_filter_info_n *lfi, + int sharpness_lvl); + #endif diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 4356b513..7fe8f7de 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -148,7 +148,6 @@ typedef struct VP8Common INTERPOLATIONFILTERTYPE mcomp_filter_type; - LOOPFILTERTYPE last_filter_type; LOOPFILTERTYPE filter_type; loop_filter_info_n lf_info; @@ -205,9 +204,4 @@ typedef struct VP8Common struct postproc_state postproc_state; } VP8_COMMON; -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 diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index a300bb5f..9b35ffd6 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -1030,14 +1030,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION) { vp8mt_decode_mb_rows(pbi, xd); - if(pbi->common.filter_level) - { - /*vp8_mt_loop_filter_frame(pbi);*/ /*cm, &pbi->mb, cm->filter_level);*/ - - pc->last_frame_type = pc->frame_type; - pc->last_filter_type = pc->filter_type; - pc->last_sharpness_level = pc->sharpness_level; - } vp8_yv12_extend_frame_borders_ptr(&pc->yv12_fb[pc->new_fb_idx]); /*cm->frame_to_show);*/ } else diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index aeb1607b..829a675a 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -92,14 +92,7 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) */ vp8cx_init_de_quantizer(pbi); - { - VP8_COMMON *cm = &pbi->common; - - 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; - } + vp8_loop_filter_init(&pbi->common); pbi->common.error.setjmp = 0; @@ -454,14 +447,10 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign return -1; } - if(pbi->common.filter_level) + if(cm->filter_level) { /* Apply the loop filter if appropriate. */ - vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level); - - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_frame(cm, &pbi->mb); } vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show); } diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c index 0c21689c..1e033027 100644 --- a/vp8/decoder/threading.c +++ b/vp8/decoder/threading.c @@ -746,7 +746,7 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd) } /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level, pc->sharpness_level); + vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level); } setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count); diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index ba8793dc..5fda5c79 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -50,9 +50,6 @@ extern void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi); extern void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val); extern void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi); -extern void vp8_init_loop_filter(VP8_COMMON *cm); -extern void vp8_loop_filter_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val); -extern void vp8_loop_filter_frame_yonly(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val, int sharpness_lvl); extern void vp8_dmachine_specific_config(VP8_COMP *cpi); extern void vp8_cmachine_specific_config(VP8_COMP *cpi); extern void vp8_deblock_frame(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *post, int filt_lvl, int low_var_thresh, int flag); @@ -2083,12 +2080,9 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) //vp8cx_init_quantizer() is first called here. Add check in vp8cx_frame_init_quantizer() so that vp8cx_init_quantizer is only called later //when needed. This will avoid unnecessary calls of vp8cx_init_quantizer() for every frame. vp8cx_init_quantizer(cpi); - { - 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; - } + + vp8_loop_filter_init(cm); + cpi->common.error.setjmp = 0; return (VP8_PTR) cpi; @@ -3179,9 +3173,7 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) if (cm->filter_level > 0) { vp8cx_set_alt_lf_level(cpi, cm->filter_level); - vp8_loop_filter_frame(cm, &cpi->mb.e_mbd, cm->filter_level); - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_frame(cm, &cpi->mb.e_mbd); } vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show); diff --git a/vp8/encoder/picklpf.c b/vp8/encoder/picklpf.c index 3d47412f..49de62d7 100644 --- a/vp8/encoder/picklpf.c +++ b/vp8/encoder/picklpf.c @@ -16,12 +16,11 @@ #include "vpx_scale/yv12extend.h" #include "vpx_scale/vpxscale.h" #include "vp8/common/alloccommon.h" +#include "vp8/common/loopfilter.h" #if ARCH_ARM #include "vpx_ports/arm.h" #endif -extern void vp8_loop_filter_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val); -extern void vp8_loop_filter_frame_yonly(VP8_COMMON *cm, MACROBLOCKD *mbd, int filt_val, int sharpness_lvl); extern int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd); #if HAVE_ARMV7 extern void vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc); @@ -104,15 +103,6 @@ static int vp8_calc_partial_ssl_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONF return Total; } -extern void vp8_loop_filter_partial_frame -( - VP8_COMMON *cm, - MACROBLOCKD *mbd, - int default_filt_lvl, - int sharpness_lvl, - int Fraction -); - // Enforce a minimum filter level based upon baseline Q static int get_min_filter_level(VP8_COMP *cpi, int base_qindex) { @@ -161,7 +151,6 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) int best_filt_val = cm->filter_level; // Make a copy of the unfiltered / processed recon buffer - //vp8_yv12_copy_frame_ptr( cm->frame_to_show, &cpi->last_frame_uf ); vp8_yv12_copy_partial_frame_ptr(cm->frame_to_show, &cpi->last_frame_uf, 3); if (cm->frame_type == KEY_FRAME) @@ -169,6 +158,12 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) else cm->sharpness_level = cpi->oxcf.Sharpness; + if (cm->sharpness_level != cm->last_sharpness_level) + { + vp8_loop_filter_update_sharpness(&cm->lf_info, cm->sharpness_level); + cm->last_sharpness_level = cm->last_sharpness_level; + } + // Start the search at the previous frame filter level unless it is now out of range. if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level; @@ -178,13 +173,8 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) filt_val = cm->filter_level; best_filt_val = filt_val; - // Set up alternate filter values - // Get the err using the previous frame's filter value. - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0 , 3); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); best_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance)); @@ -197,15 +187,11 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) while (filt_val >= min_filter_level) { // Apply the loop filter - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0, 3); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); // Get the err for filtered frame filt_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance)); - // Re-instate the unfiltered frame vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show, 3); @@ -234,10 +220,7 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) while (filt_val < max_filter_level) { // Apply the loop filter - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0, 3); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); // Get the err for filtered frame filt_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance)); @@ -336,10 +319,7 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) // Get baseline error score vp8cx_set_alt_lf_level(cpi, filt_mid); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid, 0); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid); best_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); filt_best = filt_mid; @@ -377,10 +357,7 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) { // Get Low filter error score vp8cx_set_alt_lf_level(cpi, filt_low); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low, 0); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low); filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); @@ -417,10 +394,7 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) if ((filt_direction >= 0) && (filt_high != filt_mid)) { vp8cx_set_alt_lf_level(cpi, filt_high); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high, 0); - cm->last_frame_type = cm->frame_type; - cm->last_filter_type = cm->filter_type; - cm->last_sharpness_level = cm->sharpness_level; + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high); filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); -- 2.11.4.GIT