]> granicus.if.org Git - libvpx/blobdiff - vp9/encoder/vp9_encoder.c
Merge "Revert "Restore vp8_sixtap_predict4x4_neon""
[libvpx] / vp9 / encoder / vp9_encoder.c
index 421fcd11560793caaf431cfad8a67c471f822ecd..55103627e8fab5fd55eae491762c33fda2982c04 100644 (file)
@@ -36,6 +36,7 @@
 #include "vp9/common/vp9_reconintra.h"
 #include "vp9/common/vp9_tile_common.h"
 
+#include "vp9/encoder/vp9_alt_ref_aq.h"
 #include "vp9/encoder/vp9_aq_360.h"
 #include "vp9/encoder/vp9_aq_complexity.h"
 #include "vp9/encoder/vp9_aq_cyclicrefresh.h"
@@ -1618,6 +1619,8 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf,
   cpi->use_skin_detection = 0;
   cpi->common.buffer_pool = pool;
 
+  cpi->force_update_segmentation = 0;
+
   init_config(cpi, oxcf);
   vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
 
@@ -1627,6 +1630,8 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf,
 
   realloc_segmentation_maps(cpi);
 
+  CHECK_MEM_ERROR(cm, cpi->alt_ref_aq, vp9_alt_ref_aq_create());
+
   CHECK_MEM_ERROR(
       cm, cpi->consec_zero_mv,
       vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
@@ -1979,8 +1984,9 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
           SNPRINT2(results, "\t%7.3f", consistency);
           SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
         }
-        fprintf(f, "%s\t    Time  Rc-Err Abs Err\n", headings);
-        fprintf(f, "%s\t%8.0f %7.2f %7.2f\n", results, total_encode_time,
+
+        fprintf(f, "%s\t    Time\tRcErr\tAbsErr\n", headings);
+        fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
                 rate_err, fabs(rate_err));
       }
 
@@ -2024,6 +2030,8 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
 
   if (cpi->num_workers > 1) vp9_loop_filter_dealloc(&cpi->lf_row_sync);
 
+  vp9_alt_ref_aq_destroy(cpi->alt_ref_aq);
+
   dealloc_compressor_data(cpi);
 
   for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
@@ -2394,6 +2402,18 @@ static int big_rate_miss(VP9_COMP *cpi, int high_limit, int low_limit) {
          (rc->projected_frame_size < (low_limit / 2));
 }
 
+// test in two pass for the first
+static int two_pass_first_group_inter(VP9_COMP *cpi) {
+  TWO_PASS *const twopass = &cpi->twopass;
+  GF_GROUP *const gf_group = &twopass->gf_group;
+  if ((cpi->oxcf.pass == 2) &&
+      (gf_group->index == gf_group->first_inter_index)) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
 // Function to test for conditions that indicate we should loop
 // back and recode a frame.
 static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q,
@@ -2406,7 +2426,9 @@ static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q,
   if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
       big_rate_miss(cpi, high_limit, low_limit) ||
       (cpi->sf.recode_loop == ALLOW_RECODE) ||
-      (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
+      (two_pass_first_group_inter(cpi) &&
+       (cpi->sf.recode_loop == ALLOW_RECODE_FIRST)) ||
+      (frame_is_kfgfarf && (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF))) {
     if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
         scale_down(cpi, q)) {
       // Code this group at a lower resolution.
@@ -3125,6 +3147,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
   setup_frame(cpi);
 
   suppress_active_map(cpi);
+
   // Variance adaptive and in frame q adjustment experiments are mutually
   // exclusive.
   if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
@@ -3135,7 +3158,12 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
     vp9_setup_in_frame_q_adj(cpi);
   } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
     vp9_cyclic_refresh_setup(cpi);
+  } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
+    // it may be pretty bad for rate-control,
+    // and I should handle it somehow
+    vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
   }
+
   apply_active_map(cpi);
 
   vp9_encode_frame(cpi);
@@ -3273,6 +3301,8 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
       vp9_360aq_frame_setup(cpi);
     } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
       vp9_setup_in_frame_q_adj(cpi);
+    } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
+      vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
     }
 
     vp9_encode_frame(cpi);
@@ -3735,6 +3765,30 @@ static void spatial_denoise_frame(VP9_COMP *cpi) {
 }
 #endif  // ENABLE_KF_DENOISE
 
+static void vp9_try_disable_lookahead_aq(VP9_COMP *cpi, size_t *size,
+                                         uint8_t *dest) {
+  if (cpi->common.seg.enabled)
+    if (ALT_REF_AQ_PROTECT_GAIN) {
+      size_t nsize = *size;
+      int overhead;
+
+      // TODO(yuryg): optimize this, as
+      // we don't really need to repack
+
+      save_coding_context(cpi);
+      vp9_disable_segmentation(&cpi->common.seg);
+      vp9_pack_bitstream(cpi, dest, &nsize);
+      restore_coding_context(cpi);
+
+      overhead = (int)*size - (int)nsize;
+
+      if (vp9_alt_ref_aq_disable_if(cpi->alt_ref_aq, overhead, (int)*size))
+        vp9_encode_frame(cpi);
+      else
+        vp9_enable_segmentation(&cpi->common.seg);
+    }
+}
+
 static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
                                       uint8_t *dest,
                                       unsigned int *frame_flags) {
@@ -3860,6 +3914,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
     encode_with_recode_loop(cpi, size, dest);
   }
 
+  // Disable segmentation if it decrease rate/distortion ratio
+  if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
+    vp9_try_disable_lookahead_aq(cpi, size, dest);
+
 #if CONFIG_VP9_TEMPORAL_DENOISING
 #ifdef OUTPUT_YUV_DENOISED
   if (oxcf->noise_sensitivity > 0) {
@@ -3983,6 +4041,11 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
                                cpi->svc.number_temporal_layers +
                            cpi->svc.temporal_layer_id]
         .last_frame_type = cm->frame_type;
+
+  cpi->force_update_segmentation = 0;
+
+  if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
+    vp9_alt_ref_aq_unset_all(cpi->alt_ref_aq, cpi);
 }
 
 static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
@@ -4411,9 +4474,21 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
 #endif
 
       if ((oxcf->arnr_max_frames > 0) && (oxcf->arnr_strength > 0)) {
+        int bitrate = cpi->rc.avg_frame_bandwidth / 40;
+        int not_low_bitrate = bitrate > ALT_REF_AQ_LOW_BITRATE_BOUNDARY;
+
+        int not_last_frame = (cpi->lookahead->sz - arf_src_index > 1);
+        not_last_frame |= ALT_REF_AQ_APPLY_TO_LAST_FRAME;
+
         // Produce the filtered ARF frame.
         vp9_temporal_filter(cpi, arf_src_index);
         vpx_extend_frame_borders(&cpi->alt_ref_buffer);
+
+        // for small bitrates segmentation overhead usually
+        // eats all bitrate gain from enabling delta quantizers
+        if (cpi->oxcf.alt_ref_aq != 0 && not_low_bitrate && not_last_frame)
+          vp9_alt_ref_aq_setup_mode(cpi->alt_ref_aq, cpi);
+
         force_src_buffer = &cpi->alt_ref_buffer;
       }
 
@@ -4775,6 +4850,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
         cpi->svc.spatial_layer_to_encode = 0;
     }
   }
+
   vpx_clear_system_state();
   return 0;
 }