shithub: libvpx

Download patch

ref: 6dbf83d082311e2f708ec16e1a3b6e697c053807
parent: a867bb538bf9ae1e1bff393c1ce7bb74a93aee05
parent: d0312379991b81f2aec5a1fa4a50406ca764cdee
author: Paul Wilkins <paulwilkins@google.com>
date: Fri Nov 21 10:25:43 EST 2014

Merge "Add variance restriction to AQ2."

--- a/vp9/encoder/vp9_aq_complexity.c
+++ b/vp9/encoder/vp9_aq_complexity.c
@@ -11,8 +11,9 @@
 #include <limits.h>
 #include <math.h>
 
+#include "vp9/encoder/vp9_aq_variance.h"
+#include "vp9/encoder/vp9_encodeframe.h"
 #include "vp9/common/vp9_seg_common.h"
-
 #include "vp9/encoder/vp9_segmentation.h"
 
 #define AQ_C_SEGMENTS  3
@@ -22,6 +23,7 @@
   {{1.0, 1.0, 1.0}, {1.0, 2.0, 1.0}, {1.0, 1.5, 2.5}};
 static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] =
   {{1.0, 1.0, 1.0}, {1.0, 0.25, 0.0}, {1.0, 0.5, 0.25}};
+static const double aq_c_var_thresholds[AQ_C_SEGMENTS] = {100.0, 12.0, 10.0};
 
 static int get_aq_c_strength(int q_index, vpx_bit_depth_t bit_depth) {
   // Approximate base quatizer (truncated to int)
@@ -94,7 +96,7 @@
 // An "aq_strength" value determines how many segments are supported,
 // the set of transition points to use and the extent of the quantizer
 // adjustment for each segment (configured in vp9_setup_in_frame_q_adj()).
-void vp9_select_in_frame_q_segment(VP9_COMP *cpi,
+void vp9_select_in_frame_q_segment(VP9_COMP *cpi, BLOCK_SIZE bs,
                                    int mi_row, int mi_col,
                                    int output_enabled, int projected_rate) {
   VP9_COMMON *const cm = &cpi->common;
@@ -118,7 +120,11 @@
                             (bw * bh);
     const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth);
     const int active_segments = aq_c_active_segments[aq_strength];
+    double logvar;
 
+    vp9_setup_src_planes(&cpi->mb, cpi->Source, mi_row, mi_col);
+    logvar = vp9_log_block_var(cpi, &cpi->mb, bs);
+
     // The number of segments considered and the transition points used to
     // select them is determined by the "aq_strength" value.
     // Currently this loop only supports segments that reduce Q (i.e. where
@@ -127,8 +133,9 @@
     // with no Q adjustment.
     segment = active_segments - 1;
     while (segment > 0) {
-      if (projected_rate <
-          (target_rate * aq_c_transitions[aq_strength][segment])) {
+      if ((projected_rate <
+          target_rate * aq_c_transitions[aq_strength][segment]) &&
+          (logvar < aq_c_var_thresholds[segment])) {
         break;
       }
       --segment;
--- a/vp9/encoder/vp9_aq_complexity.h
+++ b/vp9/encoder/vp9_aq_complexity.h
@@ -19,9 +19,9 @@
 struct VP9_COMP;
 
 // Select a segment for the current SB64.
-void vp9_select_in_frame_q_segment(struct VP9_COMP *cpi, int mi_row, int mi_col,
+void vp9_select_in_frame_q_segment(struct VP9_COMP *cpi, BLOCK_SIZE bs,
+                                   int mi_row, int mi_col,
                                    int output_enabled, int projected_rate);
-
 
 // This function sets up a set of segments with delta Q values around
 // the baseline frame quantizer.
--- a/vp9/encoder/vp9_aq_variance.c
+++ b/vp9/encoder/vp9_aq_variance.c
@@ -126,12 +126,14 @@
   }
 }
 
-int vp9_block_energy(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
-  double energy;
+double vp9_log_block_var(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
   unsigned int var = block_variance(cpi, x, bs);
-
   vp9_clear_system_state();
+  return log(var + 1.0);
+}
 
-  energy = 0.9 * (log(var + 1.0) - 10.0);
+int vp9_block_energy(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
+  double energy;
+  energy = 0.9 * (vp9_log_block_var(cpi, x, bs) - 10.0);
   return clamp((int)round(energy), ENERGY_MIN, ENERGY_MAX);
 }
--- a/vp9/encoder/vp9_aq_variance.h
+++ b/vp9/encoder/vp9_aq_variance.h
@@ -22,6 +22,7 @@
 void vp9_vaq_frame_setup(VP9_COMP *cpi);
 
 int vp9_block_energy(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs);
+double vp9_log_block_var(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs);
 
 #ifdef __cplusplus
 }  // extern "C"
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1699,7 +1699,7 @@
     // and and if necessary apply a Q delta using segmentation to get
     // closer to the target.
     if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
-      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
+      vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col,
                                     output_enabled, chosen_rdc.rate);
     }
     encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
@@ -2438,7 +2438,7 @@
     // and and if necessary apply a Q delta using segmentation to get
     // closer to the target.
     if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map)
-      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
+      vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col, output_enabled,
                                     best_rdc.rate);
     encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled,
               bsize, pc_tree);
@@ -2943,7 +2943,7 @@
     // and and if necessary apply a Q delta using segmentation to get
     // closer to the target.
     if ((oxcf->aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
-      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
+      vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col, output_enabled,
                                     best_rdc.rate);
     }
     encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled,