]> granicus.if.org Git - libvpx/commitdiff
vp9-svc: Fix for scene detection for SVC
authorMarco Paniconi <marpan@google.com>
Thu, 9 Aug 2018 16:34:05 +0000 (09:34 -0700)
committerMarco Paniconi <marpan@google.com>
Thu, 9 Aug 2018 20:49:42 +0000 (13:49 -0700)
For spatial layers: use the correct mi_cols/rows in the
scene detection. The scene detection for spatial layers
is only called once per superframe, but we were using wrong
mi_cols/rows (those for base spatial were being used).

Also increase frame_since_key threshold to account for spatial
layers.

Change-Id: I2731da49684a798c4718693a0468eda7db82d2bd

vp9/encoder/vp9_ratectrl.c

index 1ec6965174ef7a4af0c957b2736bd85b9a748827..e0c877833318c41c0027de364572b7ff5da9310c 100644 (file)
@@ -2636,6 +2636,8 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) {
   if (cpi->svc.spatial_layer_id == 0 && src_width == last_src_width &&
       src_height == last_src_height) {
     YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
+    int num_mi_cols = cm->mi_cols;
+    int num_mi_rows = cm->mi_rows;
     int start_frame = 0;
     int frames_to_buffer = 1;
     int frame = 0;
@@ -2650,6 +2652,12 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) {
       min_thresh = 65000;
       thresh = 2.1f;
     }
+    if (cpi->use_svc && cpi->svc.number_spatial_layers > 1) {
+      const int aligned_width = ALIGN_POWER_OF_TWO(src_width, MI_SIZE_LOG2);
+      const int aligned_height = ALIGN_POWER_OF_TWO(src_height, MI_SIZE_LOG2);
+      num_mi_cols = aligned_width >> MI_SIZE_LOG2;
+      num_mi_rows = aligned_height >> MI_SIZE_LOG2;
+    }
     if (cpi->oxcf.lag_in_frames > 0) {
       frames_to_buffer = (cm->current_video_frame == 1)
                              ? (int)vp9_lookahead_depth(cpi->lookahead) - 1
@@ -2696,8 +2704,8 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) {
         uint64_t avg_sad = 0;
         uint64_t tmp_sad = 0;
         int num_samples = 0;
-        int sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
-        int sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
+        int sb_cols = (num_mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
+        int sb_rows = (num_mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
         if (cpi->oxcf.lag_in_frames > 0) {
           src_y = frames[frame]->y_buffer;
           src_ystride = frames[frame]->y_stride;
@@ -2733,7 +2741,7 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) {
           if (avg_sad >
                   VPXMAX(min_thresh,
                          (unsigned int)(rc->avg_source_sad[0] * thresh)) &&
-              rc->frames_since_key > 1 &&
+              rc->frames_since_key > 1 + cpi->svc.number_spatial_layers &&
               num_zero_temp_sad < 3 * (num_samples >> 2))
             rc->high_source_sad = 1;
           else