]> granicus.if.org Git - libvpx/commitdiff
Allow OVERLAY frames to use the show_exsiting_frame flag
authorWei-ting Lin <weitinglin@google.com>
Tue, 12 Jul 2016 20:19:45 +0000 (13:19 -0700)
committerWei-ting Lin <weitinglin@google.com>
Tue, 19 Jul 2016 00:15:33 +0000 (17:15 -0700)
ARF with zero strength temporal filter can be reused by setting the
show_existing_frame = 1, and in this case, there is no need to
refresh the reference frame buffer. However, we used the flag
"refresh_golden_frame" as the identifier for the starting point of a gf
group.

A new flags "is_arf_filter_off" is used to record if the filter with
strengrh zero is used.

Change-Id: I25971a760f6e1638d5147fe30488c48125512b1a

vp10/encoder/bitstream.c
vp10/encoder/bitstream.h
vp10/encoder/encoder.c
vp10/encoder/encoder.h
vp10/encoder/firstpass.c
vp10/encoder/ratectrl.c
vp10/encoder/temporal_filter.c

index 3999c94609023a9deb369e403d4c01197a314214..4ef16a869421c1cfe709b7113dfa7b1ef65a2aca 100644 (file)
@@ -2671,7 +2671,6 @@ static void write_tile_info(const VP10_COMMON *const cm,
     vpx_wb_write_bit(wb, cm->log2_tile_rows != 1);
 #endif  // CONFIG_EXT_TILE
 }
-
 static int get_refresh_mask(VP10_COMP *cpi) {
   int refresh_mask = 0;
 
index cacdb43eb394095b3c2b5e556800c23450f3b85c..24934fe6bc76833c9beec01bf3cf8ebdda213faf 100644 (file)
@@ -23,8 +23,12 @@ void vp10_pack_bitstream(VP10_COMP *const cpi, uint8_t *dest, size_t *size);
 void vp10_encode_token_init(void);
 
 static INLINE int vp10_preserve_existing_gf(VP10_COMP *cpi) {
+#if CONFIG_EXT_REFS
+  return !cpi->multi_arf_allowed && cpi->rc.is_src_frame_alt_ref;
+#else
   return !cpi->multi_arf_allowed && cpi->refresh_golden_frame &&
          cpi->rc.is_src_frame_alt_ref;
+#endif
 }
 
 #ifdef __cplusplus
index 5adba4ca926cc75d6ed31ca39b84b7d7f633705f..0620b885c095a52ba4d66434ca8795fbd59b6e9e 100644 (file)
@@ -85,6 +85,7 @@ FILE *yuv_skinmap_file = NULL;
 #endif
 #ifdef OUTPUT_YUV_REC
 FILE *yuv_rec_file;
+#define FILE_NAME_LEN 80
 #endif
 
 #if 0
@@ -3061,9 +3062,36 @@ void vp10_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
 }
 #endif
 
+#if CONFIG_EXT_REFS
+static void check_show_existing_frame(VP10_COMP *cpi) {
+  const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+  VP10_COMMON *const cm = &cpi->common;
+  const FRAME_UPDATE_TYPE next_frame_update_type =
+      gf_group->update_type[gf_group->index];
+
+  if (cpi->rc.is_last_bipred_frame) {
+    // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
+    //               needed next to show the BWDREF_FRAME, which is pointed by
+    //               the last_fb_idxes[0] after reference frame buffer update
+    cpi->rc.is_last_bipred_frame = 0;
+    cm->show_existing_frame = 1;
+    cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
+  } else if (next_frame_update_type == OVERLAY_UPDATE &&
+      cpi->is_arf_filter_off) {
+    // Other parameters related to OVERLAY_UPDATE will be taken care of
+    // in vp10_rc_get_second_pass_params(cpi)
+    cm->show_existing_frame = 1;
+    cpi->rc.is_src_frame_alt_ref = 1;
+    cpi->existing_fb_idx_to_show = cpi->alt_fb_idx;
+    cpi->is_arf_filter_off = 0;
+  } else {
+    cm->show_existing_frame = 0;
+  }
+}
+#endif
+
 #ifdef OUTPUT_YUV_REC
-void vp10_write_yuv_rec_frame(VP10_COMMON *cm) {
-  YV12_BUFFER_CONFIG *s = cm->frame_to_show;
+void vp10_write_one_yuv_frame(VP10_COMMON *cm, YV12_BUFFER_CONFIG *s) {
   uint8_t *src = s->y_buffer;
   int h = cm->height;
 
@@ -3120,7 +3148,7 @@ void vp10_write_yuv_rec_frame(VP10_COMMON *cm) {
 
   fflush(yuv_rec_file);
 }
-#endif
+#endif  // OUTPUT_YUV_REC
 
 #if CONFIG_VP9_HIGHBITDEPTH
 static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
@@ -4849,6 +4877,15 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi,
     // Update the frame type
     cm->last_frame_type = cm->frame_type;
 
+#if CONFIG_EXT_REFS
+    // Since we allocate a spot for the OVERLAY frame in the gf group, we need
+    // to do post-encoding update accordingly.
+    if (cpi->rc.is_src_frame_alt_ref) {
+      vp10_set_target_rate(cpi);
+      vp10_rc_postencode_update(cpi, *size);
+    }
+#endif
+
     cm->last_width = cm->width;
     cm->last_height = cm->height;
 
@@ -4976,14 +5013,6 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi,
     dump_filtered_recon_frames(cpi);
 #endif  // DUMP_RECON_FRAMES
 
-#if CONFIG_EXT_REFS
-  if (cpi->rc.is_last_bipred_frame) {
-    // NOTE: If the current frame is a LAST_BIPRED_FRAME, next it is needed
-    //       to show the BWDREF_FRAME.
-    cpi->existing_fb_idx_to_show = cpi->bwd_fb_idx;
-  }
-#endif  // CONFIG_EXT_REFS
-
   if (cm->seg.update_map)
     update_reference_segmentation_map(cpi);
 
@@ -5097,13 +5126,20 @@ static void Pass0Encode(VP10_COMP *cpi, size_t *size, uint8_t *dest,
 static void Pass2Encode(VP10_COMP *cpi, size_t *size,
                         uint8_t *dest, unsigned int *frame_flags) {
   cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
+
   encode_frame_to_data_rate(cpi, size, dest, frame_flags);
 
 #if CONFIG_EXT_REFS
-  // Donot do the post-encoding update for show_existing_frame==1.
-  if (!cpi->common.show_existing_frame)
-#endif  // CONFIG_EXT_REFS
+  // Do not do post-encoding update for those frames that do not have a spot in
+  // a gf group, but note that an OVERLAY frame always has a spot in a gf group,
+  // even when show_existing_frame is used.
+  if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
     vp10_twopass_postencode_update(cpi);
+  }
+  check_show_existing_frame(cpi);
+#else
+  vp10_twopass_postencode_update(cpi);
+#endif  // CONFIG_EXT_REFS
 }
 
 static void init_ref_frame_bufs(VP10_COMMON *cm) {
@@ -5500,6 +5536,11 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
     *time_stamp = source->ts_start;
     *time_end = source->ts_end;
 
+    // We need to adjust frame rate for an overlay frame
+    if (cpi->rc.is_src_frame_alt_ref) {
+      adjust_frame_rate(cpi, source);
+    }
+
     // Find a free buffer for the new frame, releasing the reference previously
     // held.
     if (cm->new_fb_idx != INVALID_IDX) {
@@ -5516,6 +5557,11 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
     // Start with a 0 size frame.
     *size = 0;
 
+    // We need to update the gf_group for show_existing overlay frame
+    if (cpi->rc.is_src_frame_alt_ref) {
+      vp10_rc_get_second_pass_params(cpi);
+    }
+
     Pass2Encode(cpi, size, dest, frame_flags);
 
     if (cpi->b_calculate_psnr)
@@ -5717,17 +5763,6 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
 
   vpx_clear_system_state();
 
-#if CONFIG_EXT_REFS
-  if (cpi->rc.is_last_bipred_frame) {
-    // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
-    //               needed next to show the BWDREF_FRAME.
-    cpi->rc.is_last_bipred_frame = 0;
-    cm->show_existing_frame = 1;
-  } else {
-    cm->show_existing_frame = 0;
-  }
-#endif  // CONFIG_EXT_REFS
-
   return 0;
 }
 
index d7c62b2588c59d5899c6ca44b809f8cebbe76384..c8555f26796e4e8e239a9548c834531bf3063a31 100644 (file)
@@ -614,6 +614,7 @@ typedef struct VP10_COMP {
 #if CONFIG_EXT_REFS
   int refresh_frame_mask;
   int existing_fb_idx_to_show;
+  int is_arf_filter_off;
 #endif  // CONFIG_EXT_REFS
 } VP10_COMP;
 
index add251036da8f6debb64665e969b03f2597965c6..6bb716554f0f2c540baabdd941a7c444d90e75d4 100644 (file)
@@ -2519,6 +2519,9 @@ static void find_next_key_frame(VP10_COMP *cpi, FIRSTPASS_STATS *this_frame) {
 static void configure_buffer_updates(VP10_COMP *cpi) {
   TWO_PASS *const twopass = &cpi->twopass;
 
+  // Wei-Ting: Should we define another function to take care of
+  // cpi->rc.is_$Source_Type to make this function as it is in the comment?
+
   cpi->rc.is_src_frame_alt_ref = 0;
 #if CONFIG_EXT_REFS
   cpi->rc.is_bwd_ref_frame = 0;
@@ -2739,6 +2742,7 @@ void vp10_rc_get_second_pass_params(VP10_COMP *cpi) {
   }
 
   target_rate = gf_group->bit_allocation[gf_group->index];
+
   if (cpi->common.frame_type == KEY_FRAME)
     target_rate = vp10_rc_clamp_iframe_target_size(cpi, target_rate);
   else
index 5dd42d4178c880bbcfbca1186bbdf8fa836eda04..2f2f2b72d6461e11c8f1a7ad9e48cfa45bc77881 100644 (file)
@@ -203,7 +203,11 @@ int vp10_rc_clamp_pframe_target_size(const VP10_COMP *const cpi, int target) {
                                       rc->avg_frame_bandwidth >> 5);
   if (target < min_frame_target)
     target = min_frame_target;
+#if CONFIG_EXT_REFS
+  if (cpi->rc.is_src_frame_alt_ref) {
+#else
   if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
+#endif
     // If there is an active ARF at this location use the minimum
     // bits on this frame even if it is a constructed arf.
     // The active maximum quantizer insures that an appropriate
@@ -1232,8 +1236,16 @@ static void update_alt_ref_frame_stats(VP10_COMP *cpi) {
 static void update_golden_frame_stats(VP10_COMP *cpi) {
   RATE_CONTROL *const rc = &cpi->rc;
 
+#if CONFIG_EXT_REFS
   // Update the Golden frame usage counts.
+  // Wei-Ting: If we use show_existing_frame for an OVERLAY frame, only the
+  //           virtual indices for the reference frame will be updated and
+  //           cpi->refresh_golden_frame will still be zero.
+  if (cpi->refresh_golden_frame || rc->is_src_frame_alt_ref) {
+#else
+    // Update the Golden frame usage counts.
   if (cpi->refresh_golden_frame) {
+#endif
     // this frame refreshes means next frames don't unless specified by user
     rc->frames_since_golden = 0;
 
index d125daec13d635e1ca55865ab12ae2bb51702a4c..707de96fa0c88eb6818598eaf3720771fdf0a287 100644 (file)
@@ -733,6 +733,12 @@ void vp10_temporal_filter(VP10_COMP *cpi, int distance) {
 
   // Apply context specific adjustments to the arnr filter parameters.
   adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, &strength);
+#if CONFIG_EXT_REFS
+  if (strength == 0 && frames_to_blur == 1)
+    cpi->is_arf_filter_off = 1;
+  else
+    cpi->is_arf_filter_off = 0;
+#endif
   frames_to_blur_backward = (frames_to_blur / 2);
   frames_to_blur_forward = ((frames_to_blur - 1) / 2);
   start_frame = distance + frames_to_blur_forward;