diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c index 824af5e46..be00d0218 100644 --- a/vp8/encoder/generic/csystemdependent.c +++ b/vp8/encoder/generic/csystemdependent.c @@ -94,6 +94,8 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi) cpi->rtcd.search.full_search = vp8_full_search_sad; cpi->rtcd.search.diamond_search = vp8_diamond_search_sad; + + cpi->rtcd.temporal.apply = vp8_temporal_filter_apply_c; #endif // Pure C: diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 741b312d4..c2e197f8c 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -73,6 +73,7 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi); int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd); int vp8_calc_low_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd); +extern void vp8_temporal_filter_prepare_c(VP8_COMP *cpi); static void set_default_lf_deltas(VP8_COMP *cpi); @@ -4969,7 +4970,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon { int thiserr; cpi->oxcf.arnr_strength = i; - vp8cx_temp_filter_c(cpi); + vp8_temporal_filter_prepare_c(cpi); thiserr = vp8_calc_low_ss_err(&cpi->alt_ref_buffer.source_buffer, &cpi->src_buffer[start_frame].source_buffer, IF_RTCD(&cpi->rtcd.variance)); @@ -4984,7 +4985,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon if (besti != -1) { cpi->oxcf.arnr_strength = besti; - vp8cx_temp_filter_c(cpi); + vp8_temporal_filter_prepare_c(cpi); s = &cpi->alt_ref_buffer; // FWG not sure if I need to copy this data for the Alt Ref frame @@ -4996,7 +4997,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon s = &cpi->src_buffer[cpi->last_alt_ref_sei]; #else - vp8cx_temp_filter_c(cpi); + vp8_temporal_filter_prepare_c(cpi); s = &cpi->alt_ref_buffer; // FWG not sure if I need to copy this data for the Alt Ref frame diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 33de6e2d7..598f07e2e 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -27,6 +27,7 @@ #include "vpx_ports/mem.h" #include "vpx/internal/vpx_codec_internal.h" #include "mcomp.h" +#include "temporal_filter.h" //#define SPEEDSTATS 1 #define MIN_GF_INTERVAL 4 @@ -232,6 +233,7 @@ typedef struct VP8_ENCODER_RTCD vp8_encodemb_rtcd_vtable_t encodemb; vp8_quantize_rtcd_vtable_t quantize; vp8_search_rtcd_vtable_t search; + vp8_temporal_rtcd_vtable_t temporal; } VP8_ENCODER_RTCD; enum diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c index e4d47462f..2fffaa95f 100644 --- a/vp8/encoder/temporal_filter.c +++ b/vp8/encoder/temporal_filter.c @@ -36,30 +36,37 @@ #define ALT_REF_MC_ENABLED 1 // dis/enable MC in AltRef filtering #define ALT_REF_SUBPEL_ENABLED 1 // dis/enable subpel in MC AltRef filtering +#define USE_FILTER_LUT 0 // use lookup table to improve filter -#define USE_FILTER_LUT 1 #if VP8_TEMPORAL_ALT_REF #if USE_FILTER_LUT +// for (strength = 0; strength <= 6; strength++) { +// for (delta = 0; delta <= 18; delta++) { +// float coeff = (3.0 * delta * delta) / pow(2, strength); +// printf("%3d", (int)roundf(coeff > 16 ? 0 : 16-coeff)); +// } +// printf("\n"); +// } static int modifier_lut[7][19] = { // Strength=0 - {16, 13, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {16, 13, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Strength=1 - {16, 15, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {16, 15, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Strength=2 - {16, 15, 13, 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {16, 15, 13, 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Strength=3 - {16, 16, 15, 13, 10, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {16, 16, 15, 13, 10, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Strength=4 - {16, 16, 15, 14, 13, 11, 9, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {16, 16, 15, 14, 13, 11, 9, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Strength=5 - {16, 16, 16, 15, 15, 14, 13, 11, 10, 8, 7, 5, 3, 0, 0, 0, 0, 0, 0}, + {16, 16, 16, 15, 15, 14, 13, 11, 10, 8, 7, 5, 3, 0, 0, 0, 0, 0, 0}, // Strength=6 - {16, 16, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10, 9, 8, 7, 5, 4, 2, 1} + {16, 16, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10, 9, 8, 7, 5, 4, 2, 1} }; #endif -static void build_predictors_mb +static void vp8_temporal_filter_predictors_mb_c ( MACROBLOCKD *x, unsigned char *y_mb_ptr, @@ -111,7 +118,7 @@ static void build_predictors_mb RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, stride, &pred[320], 8); } } -static void apply_temporal_filter +void vp8_temporal_filter_apply_c ( unsigned char *frame1, unsigned int stride, @@ -140,16 +147,14 @@ static void apply_temporal_filter int pixel_value = *frame2++; #if USE_FILTER_LUT - // LUT implementation -- - // improves precision of filter modifier = abs(src_byte-pixel_value); modifier = modifier>18 ? 0 : lut[modifier]; #else - modifier = src_byte; - modifier -= pixel_value; + modifier = src_byte - pixel_value; modifier *= modifier; - modifier >>= strength; modifier *= 3; + modifier += 1 << (strength - 1); + modifier >>= strength; if (modifier > 16) modifier = 16; @@ -171,7 +176,7 @@ static void apply_temporal_filter #if ALT_REF_MC_ENABLED static int dummy_cost[2*mv_max+1]; -static int find_matching_mb +static int vp8_temporal_filter_find_matching_mb_c ( VP8_COMP *cpi, YV12_BUFFER_CONFIG *arf_frame, @@ -308,7 +313,7 @@ static int find_matching_mb } #endif -static void vp8cx_temp_blur1_c +static void vp8_temporal_filter_iterate_c ( VP8_COMP *cpi, int frame_count, @@ -412,11 +417,12 @@ static void vp8cx_temp_blur1_c #define THRESH_HIGH 20000 // Correlation has been lost try MC - err = find_matching_mb ( cpi, - cpi->frames[alt_ref_index], - cpi->frames[frame], - mb_y_offset, - THRESH_LOW ); + err = vp8_temporal_filter_find_matching_mb_c + (cpi, + cpi->frames[alt_ref_index], + cpi->frames[frame], + mb_y_offset, + THRESH_LOW); if (filter_weight[frame] < 2) { @@ -429,43 +435,46 @@ static void vp8cx_temp_blur1_c if (filter_weight[frame] != 0) { // Construct the predictors - build_predictors_mb ( - mbd, - cpi->frames[frame]->y_buffer + mb_y_offset, - cpi->frames[frame]->u_buffer + mb_uv_offset, - cpi->frames[frame]->v_buffer + mb_uv_offset, - cpi->frames[frame]->y_stride, - mbd->block[0].bmi.mv.as_mv.row, - mbd->block[0].bmi.mv.as_mv.col, - predictor ); + vp8_temporal_filter_predictors_mb_c + (mbd, + cpi->frames[frame]->y_buffer + mb_y_offset, + cpi->frames[frame]->u_buffer + mb_uv_offset, + cpi->frames[frame]->v_buffer + mb_uv_offset, + cpi->frames[frame]->y_stride, + mbd->block[0].bmi.mv.as_mv.row, + mbd->block[0].bmi.mv.as_mv.col, + predictor); // Apply the filter (YUV) - apply_temporal_filter ( f->y_buffer + mb_y_offset, - f->y_stride, - predictor, - 16, - strength, - filter_weight[frame], - accumulator, - count ); + TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply) + (f->y_buffer + mb_y_offset, + f->y_stride, + predictor, + 16, + strength, + filter_weight[frame], + accumulator, + count); - apply_temporal_filter ( f->u_buffer + mb_uv_offset, - f->uv_stride, - predictor + 256, - 8, - strength, - filter_weight[frame], - accumulator + 256, - count + 256 ); + TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply) + (f->u_buffer + mb_uv_offset, + f->uv_stride, + predictor + 256, + 8, + strength, + filter_weight[frame], + accumulator + 256, + count + 256); - apply_temporal_filter ( f->v_buffer + mb_uv_offset, - f->uv_stride, - predictor + 320, - 8, - strength, - filter_weight[frame], - accumulator + 320, - count + 320 ); + TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply) + (f->v_buffer + mb_uv_offset, + f->uv_stride, + predictor + 320, + 8, + strength, + filter_weight[frame], + accumulator + 320, + count + 320); } } @@ -534,7 +543,7 @@ static void vp8cx_temp_blur1_c mbd->pre.v_buffer = v_buffer; } -void vp8cx_temp_filter_c +void vp8_temporal_filter_prepare_c ( VP8_COMP *cpi ) @@ -642,7 +651,7 @@ void vp8cx_temp_filter_c = &cpi->src_buffer[which_buffer].source_buffer; } - vp8cx_temp_blur1_c ( + vp8_temporal_filter_iterate_c ( cpi, frames_to_blur, frames_to_blur_backward, diff --git a/vp8/encoder/temporal_filter.h b/vp8/encoder/temporal_filter.h index f70e8c01e..7b8c21c04 100644 --- a/vp8/encoder/temporal_filter.h +++ b/vp8/encoder/temporal_filter.h @@ -12,8 +12,33 @@ #ifndef __INC_VP8_TEMPORAL_FILTER_H #define __INC_VP8_TEMPORAL_FILTER_H -#include "onyx_int.h" +#define prototype_apply(sym)\ + void (sym) \ + ( \ + unsigned char *frame1, \ + unsigned int stride, \ + unsigned char *frame2, \ + unsigned int block_size, \ + int strength, \ + int filter_weight, \ + unsigned int *accumulator, \ + unsigned int *count \ + ) -void vp8cx_temp_filter_c(VP8_COMP *cpi); +#ifndef vp8_temporal_filter_apply +#define vp8_temporal_filter_apply vp8_temporal_filter_apply_c +#endif +extern prototype_apply(vp8_temporal_filter_apply); + +typedef struct +{ + prototype_apply(*apply); +} vp8_temporal_rtcd_vtable_t; + +#if CONFIG_RUNTIME_CPU_DETECT +#define TEMPORAL_INVOKE(ctx,fn) (ctx)->fn +#else +#define TEMPORAL_INVOKE(ctx,fn) vp8_temporal_filter_##fn +#endif #endif // __INC_VP8_TEMPORAL_FILTER_H diff --git a/vpxenc.c b/vpxenc.c index dc235e340..9d1d2f0bb 100755 --- a/vpxenc.c +++ b/vpxenc.c @@ -190,11 +190,11 @@ int stats_open_mem(stats_io_t *stats, int pass) } -void stats_close(stats_io_t *stats) +void stats_close(stats_io_t *stats, int last_pass) { if (stats->file) { - if (stats->pass == 1) + if (stats->pass == last_pass) { #if 0 #elif USE_POSIX_MMAP @@ -209,7 +209,7 @@ void stats_close(stats_io_t *stats) } else { - if (stats->pass == 1) + if (stats->pass == last_pass) free(stats->buf.buf); } } @@ -1700,7 +1700,7 @@ int main(int argc, const char **argv_) } fclose(outfile); - stats_close(&stats); + stats_close(&stats, arg_passes-1); fprintf(stderr, "\n"); if (one_pass_only)