]> granicus.if.org Git - libvpx/commitdiff
vp9-svc: Fix in pickmode for key frames.
authorMarco Paniconi <marpan@google.com>
Wed, 28 Mar 2018 23:10:17 +0000 (16:10 -0700)
committerMarco Paniconi <marpan@google.com>
Wed, 28 Mar 2018 23:57:08 +0000 (16:57 -0700)
For the fixed/default SVC patterns, GOLDEN is the
spatial reference, except on key frames, where LAST
is labeled as the spatial reference.

The current code was assuming GOLDEN is always the
spatial reference for the purpose of selecting the
subpel motion (due to the downsampling filter).

Fix is make sure flag_svc_subpel is set and used
with spatial_ref, which is labeled as the proper
spatial reference before entering mode check.

Some quality improvement on key frames.
Change-Id: Id236bcd47055b035731cc910ed84449d7e29f50c

vp9/encoder/vp9_pickmode.c

index 212c260fa24a4ad2c1fd349b4dcef40b8dd07c39..a9c7c7d3d19728b8e294c44f4875743569ad6472 100644 (file)
@@ -1495,6 +1495,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
 #endif
   INTERP_FILTER filter_gf_svc = EIGHTTAP;
   MV_REFERENCE_FRAME best_second_ref_frame = NONE;
+  MV_REFERENCE_FRAME spatial_ref = GOLDEN_FRAME;
   const struct segmentation *const seg = &cm->seg;
   int comp_modes = 0;
   int num_inter_modes = (cpi->use_svc) ? RT_INTER_MODES_SVC : RT_INTER_MODES;
@@ -1615,11 +1616,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
       cpi->svc.spatial_layer_id > 0) {
     if (cpi->ref_frame_flags & flag_list[LAST_FRAME]) {
       struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
-      if (vp9_is_scaled(sf)) svc_force_zero_mode[LAST_FRAME - 1] = 1;
+      if (vp9_is_scaled(sf)) {
+        svc_force_zero_mode[LAST_FRAME - 1] = 1;
+        spatial_ref = LAST_FRAME;
+      }
     }
     if (cpi->ref_frame_flags & flag_list[GOLDEN_FRAME]) {
       struct scale_factors *const sf = &cm->frame_refs[GOLDEN_FRAME - 1].sf;
-      if (vp9_is_scaled(sf)) svc_force_zero_mode[GOLDEN_FRAME - 1] = 1;
+      if (vp9_is_scaled(sf)) {
+        svc_force_zero_mode[GOLDEN_FRAME - 1] = 1;
+        spatial_ref = GOLDEN_FRAME;
+      }
     }
   }
 
@@ -1673,10 +1680,10 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
 
   // Set the flag_svc_subpel to 1 for SVC if the lower spatial layer used
   // an averaging filter for downsampling (phase = 8). If so, we will test
-  // a nonzero motion mode on the spatial (goldeen) reference.
+  // a nonzero motion mode on the spatial reference.
   // The nonzero motion is half pixel shifted to left and top (-4, -4).
   if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 &&
-      svc_force_zero_mode[GOLDEN_FRAME - 1] &&
+      svc_force_zero_mode[spatial_ref - 1] &&
       cpi->svc.downsample_filter_phase[cpi->svc.spatial_layer_id - 1] == 8) {
     svc_mv_col = -4;
     svc_mv_row = -4;
@@ -1726,7 +1733,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
         get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame)
       continue;
 
-    if (flag_svc_subpel && ref_frame == GOLDEN_FRAME) {
+    if (flag_svc_subpel && ref_frame == spatial_ref) {
       force_gf_mv = 1;
       // Only test mode if NEARESTMV/NEARMV is (svc_mv_col, svc_mv_row),
       // otherwise set NEWMV to (svc_mv_col, svc_mv_row).