From e5b956f620ffc3b84c71b88e41e67c15095f7c1c Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Thu, 6 Jun 2013 23:53:56 -0700 Subject: [PATCH] Add bits for colorspace, profile Adds 3 bits for colorspace (sent on keyframes), 2 bits for version. Change-Id: Iaa0cf1dcdd085cebb46e2bc4a7c78cd33cf24325 --- vp9/decoder/vp9_decodframe.c | 24 +++++++++++++++++++++--- vp9/encoder/vp9_bitstream.c | 26 +++++++++++++++++++++++--- vp9/vp9_dx_iface.c | 2 +- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 0961ab767..632560798 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -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); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 844a1c1bd..c0da212f4 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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) { diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index b5aa10d52..32cd62037 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -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;