shithub: libvpx

Download patch

ref: 514b8adacd152168eac053d0a21278ee85f7e10f
parent: 747f76fc999a0fc6cd38b5a5e5aee512302dacc7
author: Dmitry Kovalev <dkovalev@google.com>
date: Fri Jun 7 09:41:44 EDT 2013

Preparation to new frame size encoding.

Just an intermediate change set to simplify merges. Reordering several
uncompressed header bits, code restructuring + minor cleanups.

Change-Id: I28272f520762f8c4e3ad230ae39fff5102ba5c0d

--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -727,51 +727,60 @@
   *height = h;
 }
 
-static void setup_frame_size(VP9D_COMP *pbi, int scaling_active,
-                             struct vp9_read_bit_buffer *rb) {
-  // If error concealment is enabled we should only parse the new size
-  // if we have enough data. Otherwise we will end up with the wrong size.
-  VP9_COMMON *const pc = &pbi->common;
-  int display_width = pc->display_width;
-  int display_height = pc->display_height;
-  int width = pc->width;
-  int height = pc->height;
+static void setup_display_size(VP9D_COMP *pbi,
+                               struct vp9_read_bit_buffer *rb) {
+  VP9_COMMON *const cm = &pbi->common;
+  if (vp9_rb_read_bit(rb)) {
+    int width, height;
+    read_frame_size(cm, rb, &width, &height);
+    cm->display_width = width;
+    cm->display_height = height;
+  } else {
+    cm->display_width = cm->width;
+    cm->display_height = cm->height;
+  }
+}
 
-  if (scaling_active)
-    read_frame_size(pc, rb, &display_width, &display_height);
+static void apply_frame_size(VP9D_COMP *pbi, int width, int height) {
+  VP9_COMMON *cm = &pbi->common;
 
-  read_frame_size(pc, rb, &width, &height);
-
-  if (pc->width != width || pc->height != height) {
+  if (cm->width != width || cm->height != height) {
     if (!pbi->initial_width || !pbi->initial_height) {
-      if (vp9_alloc_frame_buffers(pc, width, height))
-        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+      if (vp9_alloc_frame_buffers(cm, width, height))
+        vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                            "Failed to allocate frame buffers");
       pbi->initial_width = width;
       pbi->initial_height = height;
     } else {
       if (width > pbi->initial_width)
-        vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+        vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
                            "Frame width too large");
 
       if (height > pbi->initial_height)
-        vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+        vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
                            "Frame height too large");
     }
 
-    pc->width = width;
-    pc->height = height;
-    pc->display_width = scaling_active ? display_width : width;
-    pc->display_height = scaling_active ? display_height : height;
+    cm->width = width;
+    cm->height = height;
 
-    vp9_update_frame_size(pc);
+    vp9_update_frame_size(cm);
   }
 
-  vp9_realloc_frame_buffer(&pc->yv12_fb[pc->new_fb_idx], pc->width, pc->height,
-                           pc->subsampling_x, pc->subsampling_y,
+  vp9_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx], cm->width, cm->height,
+                           cm->subsampling_x, cm->subsampling_y,
                            VP9BORDERINPIXELS);
 }
 
+static void setup_frame_size(VP9D_COMP *pbi,
+                             struct vp9_read_bit_buffer *rb) {
+  VP9_COMMON *const cm = &pbi->common;
+  int width, height;
+  read_frame_size(cm, rb, &width, &height);
+  setup_display_size(pbi, rb);
+  apply_frame_size(pbi, width, height);
+}
+
 static void update_frame_context(FRAME_CONTEXT *fc) {
   vp9_copy(fc->pre_coef_probs, fc->coef_probs);
   vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob);
@@ -921,13 +930,14 @@
       vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, \
                          "Reserved bit must be unset")
 
-size_t read_uncompressed_header(VP9D_COMP *pbi,
-                                struct vp9_read_bit_buffer *rb) {
+static size_t read_uncompressed_header(VP9D_COMP *pbi,
+                                       struct vp9_read_bit_buffer *rb) {
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
+  int i;
 
-  int scaling_active, i;
   cm->last_frame_type = cm->frame_type;
+
   if (vp9_rb_read_literal(rb, 2) != 0x2)
       vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                          "Invalid frame marker");
@@ -943,9 +953,10 @@
     cm->filter_level = 0;
     return 0;
   }
+
   cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
   cm->show_frame = vp9_rb_read_bit(rb);
-  scaling_active = vp9_rb_read_bit(rb);
+  cm->error_resilient_mode = vp9_rb_read_bit(rb);
 
   if (cm->frame_type == KEY_FRAME) {
     if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
@@ -954,6 +965,7 @@
       vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                          "Invalid frame sync code");
     }
+
     vp9_rb_read_literal(rb, 3);  // colorspace
     if (cm->version == 1) {
       cm->subsampling_x = vp9_rb_read_bit(rb);
@@ -962,22 +974,7 @@
     } else {
       cm->subsampling_y = cm->subsampling_x = 1;
     }
-  }
 
-  setup_frame_size(pbi, scaling_active, rb);
-
-  cm->error_resilient_mode = vp9_rb_read_bit(rb);
-  if (!cm->error_resilient_mode) {
-    cm->reset_frame_context = vp9_rb_read_bit(rb);
-    cm->refresh_frame_context = vp9_rb_read_bit(rb);
-    cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
-  } else {
-    cm->reset_frame_context = 0;
-    cm->refresh_frame_context = 0;
-    cm->frame_parallel_decoding_mode = 1;
-  }
-
-  if (cm->frame_type == KEY_FRAME) {
     vp9_setup_past_independence(cm, xd);
 
     pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1;
@@ -984,6 +981,8 @@
 
     for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
       cm->active_ref_idx[i] = cm->new_fb_idx;
+
+    setup_frame_size(pbi, rb);
   } else {
     if (cm->error_resilient_mode)
       vp9_setup_past_independence(cm, xd);
@@ -993,16 +992,19 @@
     for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
       const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2);
       cm->active_ref_idx[i] = cm->ref_frame_map[ref];
-      vp9_setup_scale_factors(cm, i);
+      cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
     }
 
+    setup_frame_size(pbi, rb);
+
     // Read the sign bias for each reference frame buffer.
     cm->allow_comp_inter_inter = 0;
     for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
-      cm->ref_frame_sign_bias[i + 1] = vp9_rb_read_bit(rb);
+      vp9_setup_scale_factors(cm, i);
       cm->allow_comp_inter_inter |= i > 0 &&
           cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1];
     }
+
     if (cm->allow_comp_inter_inter) {
       // which one is always-on in comp inter-inter?
       if (cm->ref_frame_sign_bias[LAST_FRAME] ==
@@ -1024,6 +1026,16 @@
 
     xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
     cm->mcomp_filter_type = read_interp_filter_type(rb);
+  }
+
+  if (!cm->error_resilient_mode) {
+    cm->reset_frame_context = vp9_rb_read_bit(rb);
+    cm->refresh_frame_context = vp9_rb_read_bit(rb);
+    cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
+  } else {
+    cm->reset_frame_context = 0;
+    cm->refresh_frame_context = 0;
+    cm->frame_parallel_decoding_mode = 1;
   }
 
   cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
--- a/vp9/decoder/vp9_read_bit_buffer.h
+++ b/vp9/decoder/vp9_read_bit_buffer.h
@@ -11,6 +11,10 @@
 #ifndef VP9_READ_BIT_BUFFER_
 #define VP9_READ_BIT_BUFFER_
 
+#include <limits.h>
+
+#include "vpx/vpx_integer.h"
+
 typedef void (*vp9_rb_error_handler)(void *data, int bit_offset);
 
 struct vp9_read_bit_buffer {
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1293,17 +1293,60 @@
     vp9_wb_write_bit(wb, cm->log2_tile_rows != 1);
 }
 
-void write_uncompressed_header(VP9_COMP *cpi,
-                               struct vp9_write_bit_buffer *wb) {
+static int get_refresh_mask(VP9_COMP *cpi) {
+    // Should the GF or ARF be updated using the transmitted frame or buffer
+#if CONFIG_MULTIPLE_ARF
+    if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+        !cpi->refresh_alt_ref_frame) {
+#else
+    if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+#endif
+      // 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_onyx_if.c:update_reference_frames() so that it can
+      // be done outside of the recode loop.
+      return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
+             (cpi->refresh_golden_frame << cpi->alt_fb_idx);
+    } else {
+      int arf_idx = cpi->alt_fb_idx;
+#if CONFIG_MULTIPLE_ARF
+      // Determine which ARF buffer to use to encode this ARF frame.
+      if (cpi->multi_arf_enabled) {
+        int sn = cpi->sequence_number;
+        arf_idx = (cpi->frame_coding_order[sn] < 0) ?
+            cpi->arf_buffer_idx[sn + 1] :
+            cpi->arf_buffer_idx[sn];
+      }
+#endif
+      return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
+             (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
+             (cpi->refresh_alt_ref_frame << arf_idx);
+    }
+}
+
+static void write_display_size(VP9_COMP *cpi, struct vp9_write_bit_buffer *wb) {
   VP9_COMMON *const cm = &cpi->common;
-  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
 
   const int scaling_active = cm->width != cm->display_width ||
                              cm->height != cm->display_height;
+  vp9_wb_write_bit(wb, scaling_active);
+  if (scaling_active) {
+    vp9_wb_write_literal(wb, cm->display_width, 16);
+    vp9_wb_write_literal(wb, cm->display_height, 16);
+  }
+}
 
+static void write_uncompressed_header(VP9_COMP *cpi,
+                                      struct vp9_write_bit_buffer *wb) {
+  VP9_COMMON *const cm = &cpi->common;
+  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+
   // frame marker bits
-  vp9_wb_write_bit(wb, 1);
-  vp9_wb_write_bit(wb, 0);
+  vp9_wb_write_literal(wb, 0x2, 2);
 
   // bitstream version.
   // 00 - profile 0. 4:2:0 only
@@ -1314,7 +1357,7 @@
   vp9_wb_write_bit(wb, 0);
   vp9_wb_write_bit(wb, cm->frame_type);
   vp9_wb_write_bit(wb, cm->show_frame);
-  vp9_wb_write_bit(wb, scaling_active);
+  vp9_wb_write_bit(wb, cm->error_resilient_mode);
 
   if (cm->frame_type == KEY_FRAME) {
     vp9_wb_write_literal(wb, SYNC_CODE_0, 8);
@@ -1332,69 +1375,30 @@
       vp9_wb_write_bit(wb, cm->subsampling_y);
       vp9_wb_write_bit(wb, 0);  // has extra plane
     }
-  }
 
-  if (scaling_active) {
-    vp9_wb_write_literal(wb, cm->display_width, 16);
-    vp9_wb_write_literal(wb, cm->display_height, 16);
-  }
+    // frame size
+    vp9_wb_write_literal(wb, cm->width, 16);
+    vp9_wb_write_literal(wb, cm->height, 16);
+    write_display_size(cpi, wb);
+  } else {
+    // When there is a key frame all reference buffers are updated using the
+    // new key frame
 
-  vp9_wb_write_literal(wb, cm->width, 16);
-  vp9_wb_write_literal(wb, cm->height, 16);
+    int i;
+    int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
+                                        cpi->alt_fb_idx};
 
-  vp9_wb_write_bit(wb, cm->error_resilient_mode);
-  if (!cm->error_resilient_mode) {
-    vp9_wb_write_bit(wb, cm->reset_frame_context);
-    vp9_wb_write_bit(wb, cm->refresh_frame_context);
-    vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
-  }
-
-  // When there is a key frame all reference buffers are updated using the new key frame
-  if (cm->frame_type != KEY_FRAME) {
-    int refresh_mask, i;
-
-    // Should the GF or ARF be updated using the transmitted frame or buffer
-#if CONFIG_MULTIPLE_ARF
-    if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
-        !cpi->refresh_alt_ref_frame) {
-#else
-    if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
-#endif
-      // 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_onyx_if.c:update_reference_frames() so that it can
-      // be done outside of the recode loop.
-      refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
-                     (cpi->refresh_golden_frame << cpi->alt_fb_idx);
-    } else {
-      int arf_idx = cpi->alt_fb_idx;
-#if CONFIG_MULTIPLE_ARF
-      // Determine which ARF buffer to use to encode this ARF frame.
-      if (cpi->multi_arf_enabled) {
-        int sn = cpi->sequence_number;
-        arf_idx = (cpi->frame_coding_order[sn] < 0) ?
-            cpi->arf_buffer_idx[sn + 1] :
-            cpi->arf_buffer_idx[sn];
-      }
-#endif
-      refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
-                     (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
-                     (cpi->refresh_alt_ref_frame << arf_idx);
+    vp9_wb_write_literal(wb, get_refresh_mask(cpi), NUM_REF_FRAMES);
+    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+      vp9_wb_write_literal(wb, refs[i], NUM_REF_FRAMES_LG2);
+      vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
     }
 
-    vp9_wb_write_literal(wb, refresh_mask, NUM_REF_FRAMES);
-    vp9_wb_write_literal(wb, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2);
-    vp9_wb_write_literal(wb, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2);
-    vp9_wb_write_literal(wb, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2);
+    // frame size
+    vp9_wb_write_literal(wb, cm->width, 16);
+    vp9_wb_write_literal(wb, cm->height, 16);
+    write_display_size(cpi, wb);
 
-    // Indicate the sign bias for each reference frame buffer.
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
-      vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
-
     // Signal whether to allow high MV precision
     vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
 
@@ -1403,6 +1407,12 @@
     write_interp_filter_type(cm->mcomp_filter_type, wb);
   }
 
+  if (!cm->error_resilient_mode) {
+    vp9_wb_write_bit(wb, cm->reset_frame_context);
+    vp9_wb_write_bit(wb, cm->refresh_frame_context);
+    vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
+  }
+
   if (!cm->show_frame)
     vp9_wb_write_bit(wb, cm->intra_only);
 
@@ -1449,8 +1459,7 @@
   vp9_copy(pc->fc.pre_coef_probs, pc->fc.coef_probs);
   vp9_copy(pc->fc.pre_y_mode_prob, pc->fc.y_mode_prob);
   vp9_copy(pc->fc.pre_uv_mode_prob, pc->fc.uv_mode_prob);
-  vp9_copy(cpi->common.fc.pre_partition_prob,
-           cpi->common.fc.partition_prob[INTER_FRAME]);
+  vp9_copy(pc->fc.pre_partition_prob, pc->fc.partition_prob[INTER_FRAME]);
   pc->fc.pre_nmvc = pc->fc.nmvc;
   vp9_copy(pc->fc.pre_switchable_interp_prob, pc->fc.switchable_interp_prob);
   vp9_copy(pc->fc.pre_inter_mode_probs, pc->fc.inter_mode_probs);
@@ -1458,8 +1467,7 @@
   vp9_copy(pc->fc.pre_comp_inter_prob, pc->fc.comp_inter_prob);
   vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob);
   vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob);
-  cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
-  vp9_copy(cpi->common.fc.pre_tx_probs, cpi->common.fc.tx_probs);
+  vp9_copy(pc->fc.pre_tx_probs, pc->fc.tx_probs);
 
   if (xd->lossless) {
     pc->txfm_mode = ONLY_4X4;
--- a/vp9/encoder/vp9_write_bit_buffer.h
+++ b/vp9/encoder/vp9_write_bit_buffer.h
@@ -11,6 +11,8 @@
 #ifndef VP9_BIT_WRITE_BUFFER_H_
 #define VP9_BIT_WRITE_BUFFER_H_
 
+#include <limits.h>
+
 #include "vpx/vpx_integer.h"
 
 struct vp9_write_bit_buffer {