shithub: libvpx

Download patch

ref: 7c8ae69ad8049d0d20f9c84bd85e10c6cd37d59f
parent: 7c3e704e6d1de71115b688615b63fc737d0514db
parent: 74e8446e586380597441094bb9b4d82933fb305d
author: John Koleszar <jkoleszar@google.com>
date: Thu Dec 23 19:05:05 EST 2010

Merge remote branch 'origin/master' into experimental

Change-Id: I05d5b211674cb4560d3a54dcdfa853f8d84599e6

--- a/vp8/encoder/generic/csystemdependent.c
+++ b/vp8/encoder/generic/csystemdependent.c
@@ -94,6 +94,8 @@
 
     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:
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -73,6 +73,7 @@
 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);
 
@@ -4970,7 +4971,7 @@
                 {
                     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));
@@ -4985,7 +4986,7 @@
                 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
@@ -4997,7 +4998,7 @@
                     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
--- 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
@@ -228,6 +229,7 @@
     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
--- 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 @@
         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 @@
             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 @@
 #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 @@
 }
 #endif
 
-static void vp8cx_temp_blur1_c
+static void vp8_temporal_filter_iterate_c
 (
     VP8_COMP *cpi,
     int frame_count,
@@ -412,11 +417,12 @@
 #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 @@
                 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 @@
     mbd->pre.v_buffer = v_buffer;
 }
 
-void vp8cx_temp_filter_c
+void vp8_temporal_filter_prepare_c
 (
     VP8_COMP *cpi
 )
@@ -642,7 +651,7 @@
                 = &cpi->src_buffer[which_buffer].source_buffer;
     }
 
-    vp8cx_temp_blur1_c (
+    vp8_temporal_filter_iterate_c (
         cpi,
         frames_to_blur,
         frames_to_blur_backward,
--- 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
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -186,11 +186,11 @@
 }
 
 
-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
@@ -205,7 +205,7 @@
     }
     else
     {
-        if (stats->pass == 1)
+        if (stats->pass == last_pass)
             free(stats->buf.buf);
     }
 }
@@ -1692,7 +1692,7 @@
         }
 
         fclose(outfile);
-        stats_close(&stats);
+        stats_close(&stats, arg_passes-1);
         fprintf(stderr, "\n");
 
         if (one_pass_only)