shithub: libvpx

Download patch

ref: 7ec06cddc6026feaf09a699a8da45267ef7668dd
parent: ff40d9ec29a189262873e633a35689f38a9b7f1e
parent: 0984121f499748f0b4baf850a3025e5ea57def8c
author: Adrian Grange <[email protected]>
date: Wed Aug 6 10:50:51 EDT 2014

Merge "Create function vp9_preserve_existing_gf"

--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -888,21 +888,17 @@
 }
 
 static int get_refresh_mask(VP9_COMP *cpi) {
-  if (!cpi->multi_arf_allowed && cpi->refresh_golden_frame &&
-      cpi->rc.is_src_frame_alt_ref &&
-      (!cpi->use_svc ||      // Add spatial svc base layer case here
-       (cpi->svc.number_temporal_layers == 1 &&
-        cpi->svc.spatial_layer_id == 0 &&
-        cpi->svc.layer_context[0].gold_ref_idx >=0 &&
-        cpi->oxcf.ss_play_alternate[0]))) {
-    // Preserve the previously existing golden frame and update the frame in
-    // the alt ref slot instead. This is highly specific to the use of
-    // alt-ref as a forward reference, and this needs to be generalized as
-    // other uses are implemented (like RTC/temporal scaling)
-    //
-    // gld_fb_idx and alt_fb_idx need to be swapped for future frames, but
-    // that happens in vp9_encoder.c:update_reference_frames() so that it can
-    // be done outside of the recode loop.
+  if (vp9_preserve_existing_gf(cpi)) {
+    // We have decided to preserve the previously existing golden frame as our
+    // new ARF frame. However, in the short term we leave it in the GF slot and,
+    // if we're updating the GF with the current decoded frame, we save it
+    // instead to the ARF slot.
+    // Later, in the function vp9_encoder.c:vp9_update_reference_frames() we
+    // will swap gld_fb_idx and alt_fb_idx to achieve our objective. We do it
+    // there so that it can be done outside of the recode loop.
+    // Note: This is highly specific to the use of ARF as a forward reference,
+    // and this needs to be generalized as other uses are implemented
+    // (like RTC/temporal scalability).
     return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
            (cpi->refresh_golden_frame << cpi->alt_fb_idx);
   } else {
--- a/vp9/encoder/vp9_bitstream.h
+++ b/vp9/encoder/vp9_bitstream.h
@@ -16,11 +16,21 @@
 extern "C" {
 #endif
 
-struct VP9_COMP;
+#include "vp9/encoder/vp9_encoder.h"
 
 void vp9_entropy_mode_init();
 
-void vp9_pack_bitstream(struct VP9_COMP *cpi, uint8_t *dest, size_t *size);
+void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size);
+
+static INLINE int vp9_preserve_existing_gf(VP9_COMP *cpi) {
+  return !cpi->multi_arf_allowed && cpi->refresh_golden_frame &&
+         cpi->rc.is_src_frame_alt_ref &&
+         (!cpi->use_svc ||      // Add spatial svc base layer case here
+          (cpi->svc.number_temporal_layers == 1 &&
+           cpi->svc.spatial_layer_id == 0 &&
+           cpi->svc.layer_context[0].gold_ref_idx >=0 &&
+           cpi->oxcf.ss_play_alternate[0]));
+}
 
 #ifdef __cplusplus
 }  // extern "C"
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -1564,22 +1564,15 @@
                &cm->ref_frame_map[cpi->gld_fb_idx], cm->new_fb_idx);
     ref_cnt_fb(cm->frame_bufs,
                &cm->ref_frame_map[cpi->alt_fb_idx], cm->new_fb_idx);
-  } else if (!cpi->multi_arf_allowed && cpi->refresh_golden_frame &&
-             cpi->rc.is_src_frame_alt_ref &&
-             (!cpi->use_svc ||      // Add spatial svc base layer case here
-              (cpi->svc.number_temporal_layers == 1 &&
-               cpi->svc.spatial_layer_id == 0 &&
-               cpi->svc.layer_context[0].gold_ref_idx >=0 &&
-               cpi->oxcf.ss_play_alternate[0]))) {
-    /* Preserve the previously existing golden frame and update the frame in
-     * the alt ref slot instead. This is highly specific to the current use of
-     * alt-ref as a forward reference, and this needs to be generalized as
-     * other uses are implemented (like RTC/temporal scaling)
-     *
-     * The update to the buffer in the alt ref slot was signaled in
-     * vp9_pack_bitstream(), now swap the buffer pointers so that it's treated
-     * as the golden frame next time.
-     */
+  } else if (vp9_preserve_existing_gf(cpi)) {
+    // We have decided to preserve the previously existing golden frame as our
+    // new ARF frame. However, in the short term in function
+    // vp9_bitstream.c::get_refresh_mask() we left it in the GF slot and, if
+    // we're updating the GF with the current decoded frame, we save it to the
+    // ARF slot instead.
+    // We now have to update the ARF with the current frame and swap gld_fb_idx
+    // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
+    // slot and, if we're updating the GF, the current frame becomes the new GF.
     int tmp;
 
     ref_cnt_fb(cm->frame_bufs,