shithub: libvpx

Download patch

ref: 9debbc2ec7e6ff004dba4d66d2780e216ca50b1a
parent: 373e08f921e5bfd5a96963fabbbbe16ec793d44e
author: Marco <marpan@google.com>
date: Tue Jan 16 06:37:40 EST 2018

vp8: Fix to multi-res-encoder for skipping streams.

For the vp8 simulcast/multi-res-encoder:

Add flags to keep track of the disabling/skipping of
streams for the multi-res-encoder. And if the lower spatial
stream is skipped for a given stream, disable the motion
vector reuse for that stream.

Also remove the condition of forcing same frame type
across all streams.

This fix allows for the skipping/disabling of the base
or middle layer streams.

Change-Id: Idfa94b32b6d2256932f6602cde19579b8e50a8bd

--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -180,6 +180,9 @@
   unsigned int low_res_ref_frames[MAX_REF_FRAMES];
   // The video frame counter value for the key frame, for lowest resolution.
   unsigned int key_frame_counter_value;
+  // Flags to signal skipped encoding of previous and base layer stream.
+  unsigned int skip_encoding_prev_stream;
+  unsigned int skip_encoding_base_stream;
   LOWER_RES_MB_INFO *mb_info;
 } LOWER_RES_FRAME_INFO;
 #endif
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3364,11 +3364,6 @@
         (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info;
 
     if (cpi->oxcf.mr_encoder_id) {
-      // TODO(marpan): This constraint shouldn't be needed, as we would like
-      // to allow for key frame setting (forced or periodic) defined per
-      // spatial layer. For now, keep this in.
-      cm->frame_type = low_res_frame_info->frame_type;
-
       // Check if lower resolution is available for motion vector reuse.
       if (cm->frame_type != KEY_FRAME) {
         cpi->mr_low_res_mv_avail = 1;
@@ -3393,7 +3388,16 @@
                      == low_res_frame_info->low_res_ref_frames[ALTREF_FRAME]);
         */
       }
+      // Disable motion vector reuse (i.e., disable any usage of the low_res)
+      // if the previous lower stream is skipped/disabled.
+      if (low_res_frame_info->skip_encoding_prev_stream) {
+        cpi->mr_low_res_mv_avail = 0;
+      }
     }
+    // This stream is not skipped (i.e., it's being encoded), so set this skip
+    // flag to 0. This is needed for the next stream (i.e., which is the next
+    // frame to be encoded).
+    low_res_frame_info->skip_encoding_prev_stream = 0;
 
     // On a key frame: For the lowest resolution, keep track of the key frame
     // counter value. For the higher resolutions, reset the current video
@@ -4999,10 +5003,13 @@
         // be received for that high layer, which will yield an incorrect
         // frame rate (from time-stamp adjustment in above calculation).
         if (cpi->oxcf.mr_encoder_id) {
-          cpi->ref_framerate = low_res_frame_info->low_res_framerate;
+          if (!low_res_frame_info->skip_encoding_base_stream)
+            cpi->ref_framerate = low_res_frame_info->low_res_framerate;
         } else {
           // Keep track of frame rate for lowest resolution.
           low_res_frame_info->low_res_framerate = cpi->ref_framerate;
+          // The base stream is being encoded so set skip flag to 0.
+          low_res_frame_info->skip_encoding_base_stream = 0;
         }
       }
 #endif
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -802,7 +802,16 @@
                                    unsigned long deadline) {
   vpx_codec_err_t res = VPX_CODEC_OK;
 
-  if (!ctx->cfg.rc_target_bitrate) return res;
+  if (!ctx->cfg.rc_target_bitrate) {
+#if CONFIG_MULTI_RES_ENCODING
+    LOWER_RES_FRAME_INFO *low_res_frame_info =
+        (LOWER_RES_FRAME_INFO *)ctx->cpi->oxcf.mr_low_res_mode_info;
+    low_res_frame_info->skip_encoding_prev_stream = 1;
+    if (ctx->cpi->oxcf.mr_encoder_id == 0)
+      low_res_frame_info->skip_encoding_base_stream = 1;
+#endif
+    return res;
+  }
 
   if (img) res = validate_img(ctx, img);