Frame header changes to support intra_only frames
authorAdrian Grange <agrange@google.com>
Fri, 7 Jun 2013 22:55:15 +0000 (15:55 -0700)
committerAdrian Grange <agrange@google.com>
Fri, 7 Jun 2013 23:19:34 +0000 (16:19 -0700)
Made changes to the frame header to write the sync
code in the frame header for a non-displayable,
intra-only frame.

Extended reset_frame_context to 2-bits.

(Submitting on behalf of Dmitri)

Change-Id: Ie836ae0df9ed572fb4f08aabe9351a555c4f3b96

vp9/common/vp9_onyxc_int.h
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c

index d430727..791dbb9 100644 (file)
@@ -174,6 +174,8 @@ typedef struct VP9Common {
   int intra_only;
 
   // Flag signaling that the frame context should be reset to default values.
+  // 0 or 1 implies don't reset, 2 reset just the context specified in the
+  // frame header, 3 reset all contexts.
   int reset_frame_context;
 
   int frame_flags;
index b408f40..4d07997 100644 (file)
@@ -1021,52 +1021,67 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
 
     setup_frame_size(pbi, rb);
   } else {
+    cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
+
     if (cm->error_resilient_mode)
       vp9_setup_past_independence(cm, xd);
 
-    pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
+    if (cm->intra_only) {
+       if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
+           vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 ||
+           vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) {
+         vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+                            "Invalid frame sync code");
+       }
 
-    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];
-      cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
-    }
+       pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
 
-    setup_frame_size(pbi, rb);
+       setup_frame_size(pbi, rb);
+    } else {
+       pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
 
-    // Read the sign bias for each reference frame buffer.
-    cm->allow_comp_inter_inter = 0;
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
-      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];
-    }
+      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];
+        cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
+      }
 
-    if (cm->allow_comp_inter_inter) {
-      // which one is always-on in comp inter-inter?
-      if (cm->ref_frame_sign_bias[LAST_FRAME] ==
-          cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
-        cm->comp_fixed_ref = ALTREF_FRAME;
-        cm->comp_var_ref[0] = LAST_FRAME;
-        cm->comp_var_ref[1] = GOLDEN_FRAME;
-      } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
-                 cm->ref_frame_sign_bias[ALTREF_FRAME]) {
-        cm->comp_fixed_ref = GOLDEN_FRAME;
-        cm->comp_var_ref[0] = LAST_FRAME;
-        cm->comp_var_ref[1] = ALTREF_FRAME;
-      } else {
-        cm->comp_fixed_ref = LAST_FRAME;
-        cm->comp_var_ref[0] = GOLDEN_FRAME;
-        cm->comp_var_ref[1] = ALTREF_FRAME;
+      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) {
+        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] ==
+            cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
+          cm->comp_fixed_ref = ALTREF_FRAME;
+          cm->comp_var_ref[0] = LAST_FRAME;
+          cm->comp_var_ref[1] = GOLDEN_FRAME;
+        } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
+                   cm->ref_frame_sign_bias[ALTREF_FRAME]) {
+          cm->comp_fixed_ref = GOLDEN_FRAME;
+          cm->comp_var_ref[0] = LAST_FRAME;
+          cm->comp_var_ref[1] = ALTREF_FRAME;
+        } else {
+          cm->comp_fixed_ref = LAST_FRAME;
+          cm->comp_var_ref[0] = GOLDEN_FRAME;
+          cm->comp_var_ref[1] = ALTREF_FRAME;
+        }
       }
-    }
 
-    xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
-    cm->mcomp_filter_type = read_interp_filter_type(rb);
+      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->reset_frame_context = vp9_rb_read_literal(rb, 2);
     cm->refresh_frame_context = vp9_rb_read_bit(rb);
     cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
   } else {
@@ -1075,7 +1090,6 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
     cm->frame_parallel_decoding_mode = 1;
   }
 
-  cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
   cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
   cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
 
index 32c2d7a..575fda9 100644 (file)
@@ -1480,41 +1480,51 @@ static void write_uncompressed_header(VP9_COMP *cpi,
     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
-
     int i;
     int refs[ALLOWED_REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
                                         cpi->alt_fb_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]);
-    }
+    if (!cm->show_frame)
+      vp9_wb_write_bit(wb, cm->intra_only);
 
-    // frame size
-    vp9_wb_write_literal(wb, cm->width, 16);
-    vp9_wb_write_literal(wb, cm->height, 16);
-    write_display_size(cpi, wb);
+    if (cm->intra_only) {
+      vp9_wb_write_literal(wb, SYNC_CODE_0, 8);
+      vp9_wb_write_literal(wb, SYNC_CODE_1, 8);
+      vp9_wb_write_literal(wb, SYNC_CODE_2, 8);
 
-    // Signal whether to allow high MV precision
-    vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
+      vp9_wb_write_literal(wb, get_refresh_mask(cpi), NUM_REF_FRAMES);
 
-    // Signal the type of subpel filter to use
-    fix_mcomp_filter_type(cpi);
-    write_interp_filter_type(cm->mcomp_filter_type, wb);
+      // frame size
+      vp9_wb_write_literal(wb, cm->width, 16);
+      vp9_wb_write_literal(wb, cm->height, 16);
+      write_display_size(cpi, wb);
+    } else {
+      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]);
+      }
+
+      // frame size
+      vp9_wb_write_literal(wb, cm->width, 16);
+      vp9_wb_write_literal(wb, cm->height, 16);
+      write_display_size(cpi, wb);
+
+      // Signal whether to allow high MV precision
+      vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
+
+      // Signal the type of subpel filter to use
+      fix_mcomp_filter_type(cpi);
+      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_literal(wb, cm->reset_frame_context, 2);
     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);
-
   vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
   vp9_wb_write_bit(wb, cm->clr_type);