]> granicus.if.org Git - libvpx/commitdiff
Add bits for colorspace, profile
authorJohn Koleszar <jkoleszar@google.com>
Fri, 7 Jun 2013 06:53:56 +0000 (23:53 -0700)
committerJohn Koleszar <jkoleszar@google.com>
Fri, 7 Jun 2013 07:00:16 +0000 (00:00 -0700)
Adds 3 bits for colorspace (sent on keyframes), 2 bits for version.

Change-Id: Iaa0cf1dcdd085cebb46e2bc4a7c78cd33cf24325

vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/vp9_dx_iface.c

index 0961ab7679e4e5960b9634f9513ffd2ec562369d..632560798ec0e0636f43f65b94148e8feee61d87 100644 (file)
@@ -907,6 +907,11 @@ static void error_handler(void *data, int bit_offset) {
   vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
 }
 
+#define RESERVED \
+  if (vp9_rb_read_bit(rb)) \
+      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) {
   VP9_COMMON *const cm = &pbi->common;
@@ -914,12 +919,17 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
 
   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");
+
+  cm->version = vp9_rb_read_bit(rb);
+  RESERVED;
+
   cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
-  cm->version = vp9_rb_read_literal(rb, 3);
   cm->show_frame = vp9_rb_read_bit(rb);
   scaling_active = vp9_rb_read_bit(rb);
-  cm->subsampling_x = vp9_rb_read_bit(rb);
-  cm->subsampling_y = vp9_rb_read_bit(rb);
+  RESERVED;
 
   if (cm->frame_type == KEY_FRAME) {
     if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
@@ -928,6 +938,14 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
       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);
+      cm->subsampling_y = vp9_rb_read_bit(rb);
+      vp9_rb_read_bit(rb);  // has extra plane
+    } else {
+      cm->subsampling_y = cm->subsampling_x = 1;
+    }
   }
 
   setup_frame_size(pbi, scaling_active, rb);
index 844a1c1bd06ee72f697db829057b5403a226b3e9..c0da212f4053ae9bd96ad9da3c920e6889ae383a 100644 (file)
@@ -1317,17 +1317,37 @@ void write_uncompressed_header(VP9_COMP *cpi,
   const int scaling_active = cm->width != cm->display_width ||
                              cm->height != cm->display_height;
 
+  // frame marker bits
+  vp9_wb_write_bit(wb, 1);
+  vp9_wb_write_bit(wb, 0);
+
+  // bitstream version.
+  // 00 - profile 0. 4:2:0 only
+  // 10 - profile 1. adds 4:4:4, 4:2:2, alpha
+  vp9_wb_write_bit(wb, cm->version);
+  vp9_wb_write_bit(wb, 0);
+
   vp9_wb_write_bit(wb, cm->frame_type);
-  vp9_wb_write_literal(wb, cm->version, 3);
   vp9_wb_write_bit(wb, cm->show_frame);
   vp9_wb_write_bit(wb, scaling_active);
-  vp9_wb_write_bit(wb, cm->subsampling_x);
-  vp9_wb_write_bit(wb, cm->subsampling_y);
+  vp9_wb_write_bit(wb, 0);
 
   if (cm->frame_type == KEY_FRAME) {
     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);
+    // colorspaces
+    // 000 - Unknown
+    // 001 - BT.601
+    // 010 - BT.709
+    // 011 - xvYCC
+    // 1xx - Reserved
+    vp9_wb_write_literal(wb, 0, 3);
+    if (cm->version == 1) {
+      vp9_wb_write_bit(wb, cm->subsampling_x);
+      vp9_wb_write_bit(wb, cm->subsampling_y);
+      vp9_wb_write_bit(wb, 0);  // has extra plane
+    }
   }
 
   if (scaling_active) {
index b5aa10d522c4731c83a1e9f9baaf50cc1fbc6160..32cd62037f811bcfb2c535b13d63c4a31ffaf3e2 100644 (file)
@@ -217,7 +217,7 @@ static vpx_codec_err_t vp8_peek_si(const uint8_t         *data,
   else {
     si->is_kf = 0;
 
-    if (data_sz >= 8 && !(data[0] & 0x80)) { /* I-Frame */
+    if (data_sz >= 8 && (data[0] & 0xD8) == 0x80) { /* I-Frame */
       const uint8_t *c = data + 1;
       si->is_kf = 1;