shithub: libvpx

Download patch

ref: 1a24011469d524f24213c955677d27561c56697c
parent: 601bab4fdeb4191474bbd3337c64a622b81e968a
author: Dmitry Kovalev <dkovalev@google.com>
date: Mon May 27 22:24:52 EDT 2013

Revert "Adding API to read/write uncompressed frame header bits." because of bitstream mismatches.

This reverts commit df037b615fcc0196386977faae060fdfd9a887a8

Change-Id: I1a529f2590df7bc912f5035d22311268933e3dd6

--- a/vp9/common/vp9_common.h
+++ b/vp9/common/vp9_common.h
@@ -60,8 +60,4 @@
   return (value + 15) & ~15;
 }
 
-// TODO(dkovalev): remove later
-#define HEADER_SIZE_IN_BYTES 4
-
-
 #endif  // VP9_COMMON_VP9_COMMON_H_
--- /dev/null
+++ b/vp9/common/vp9_header.h
@@ -1,0 +1,39 @@
+/*
+ *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VP9_COMMON_VP9_HEADER_H_
+#define VP9_COMMON_VP9_HEADER_H_
+
+/* 24 bits total */
+typedef struct {
+  unsigned int type: 1;
+  unsigned int version: 3;
+  unsigned int show_frame: 1;
+
+  /* Allow 2^20 bytes = 8 megabits for first partition */
+
+  unsigned int first_partition_length_in_bytes: 19;
+
+#ifdef PACKET_TESTING
+  unsigned int frame_number;
+  unsigned int update_gold: 1;
+  unsigned int uses_gold: 1;
+  unsigned int update_last: 1;
+  unsigned int uses_last: 1;
+#endif
+} VP9_HEADER;
+
+#ifdef PACKET_TESTING
+#define VP9_HEADER_SIZE 8
+#else
+#define VP9_HEADER_SIZE 3
+#endif
+
+#endif  // VP9_COMMON_VP9_HEADER_H_
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -24,6 +24,10 @@
 #include "vp9/common/vp9_postproc.h"
 #endif
 
+/*#ifdef PACKET_TESTING*/
+#include "vp9/common/vp9_header.h"
+/*#endif*/
+
 /* Create/destroy static data structures. */
 
 void vp9_initialize_common(void);
@@ -255,6 +259,9 @@
   int near_boffset[3];
   int version;
 
+#ifdef PACKET_TESTING
+  VP9_HEADER oh;
+#endif
   double bitrate;
   double framerate;
 
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -10,32 +10,30 @@
 
 #include <assert.h>
 
-#include "./vp9_rtcd.h"
-
-#include "vpx_scale/vpx_scale.h"
-#include "vpx_mem/vpx_mem.h"
-
+#include "vp9/decoder/vp9_onyxd_int.h"
 #include "vp9/common/vp9_common.h"
+#include "vp9/common/vp9_header.h"
 #include "vp9/common/vp9_reconintra.h"
 #include "vp9/common/vp9_reconinter.h"
 #include "vp9/common/vp9_entropy.h"
+#include "vp9/decoder/vp9_decodframe.h"
+#include "vp9/decoder/vp9_detokenize.h"
 #include "vp9/common/vp9_invtrans.h"
 #include "vp9/common/vp9_alloccommon.h"
 #include "vp9/common/vp9_entropymode.h"
 #include "vp9/common/vp9_quant_common.h"
+#include "vpx_scale/vpx_scale.h"
+
+#include "vp9/decoder/vp9_decodemv.h"
 #include "vp9/common/vp9_extend.h"
 #include "vp9/common/vp9_modecont.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vp9/decoder/vp9_dboolhuff.h"
+
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_tile_common.h"
+#include "./vp9_rtcd.h"
 
-#include "vp9/decoder/vp9_decodemv.h"
-#include "vp9/decoder/vp9_dboolhuff.h"
-#include "vp9/decoder/vp9_read_bit_buffer.h"
-#include "vp9/decoder/vp9_onyxd_int.h"
-#include "vp9/decoder/vp9_decodframe.h"
-#include "vp9/decoder/vp9_detokenize.h"
-
-
 // #define DEC_DEBUG
 #ifdef DEC_DEBUG
 int dec_debug = 0;
@@ -949,7 +947,7 @@
 int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
   vp9_reader header_bc, residual_bc;
   VP9_COMMON *const pc = &pbi->common;
-  MACROBLOCKD *const xd = &pbi->mb;
+  MACROBLOCKD *const xd  = &pbi->mb;
   const uint8_t *data = pbi->source;
   const uint8_t *data_end = data + pbi->source_sz;
   size_t first_partition_size = 0;
@@ -959,40 +957,24 @@
   xd->corrupted = 0;  // start with no corruption of current frame
   new_fb->corrupted = 0;
 
-
-
   if (data_end - data < 3) {
     vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
   } else {
-    struct vp9_read_bit_buffer rb = {data, 0};
-
     int scaling_active;
     pc->last_frame_type = pc->frame_type;
+    pc->frame_type = (FRAME_TYPE)(data[0] & 1);
+    pc->version = (data[0] >> 1) & 7;
+    pc->show_frame = (data[0] >> 4) & 1;
+    scaling_active = (data[0] >> 5) & 1;
+    pc->subsampling_x = (data[0] >> 6) & 1;
+    pc->subsampling_y = (data[0] >> 7) & 1;
+    first_partition_size = read_le16(data + 1);
 
-    pc->frame_type = (FRAME_TYPE) vp9_rb_read_bit(&rb);
-    pc->version = vp9_rb_read_literal(&rb, 3);
-    pc->show_frame = vp9_rb_read_bit(&rb);
-    scaling_active = vp9_rb_read_bit(&rb);
-    pc->subsampling_x = vp9_rb_read_bit(&rb);
-    pc->subsampling_y = vp9_rb_read_bit(&rb);
-
-    pc->clr_type = (YUV_TYPE)vp9_rb_read_bit(&rb);
-    pc->error_resilient_mode = vp9_rb_read_bit(&rb);
-    if (!pc->error_resilient_mode) {
-      pc->refresh_frame_context = vp9_rb_read_bit(&rb);
-      pc->frame_parallel_decoding_mode = vp9_rb_read_bit(&rb);
-    } else {
-      pc->refresh_frame_context = 0;
-      pc->frame_parallel_decoding_mode = 1;
-    }
-
-    first_partition_size = vp9_rb_read_literal(&rb, 16);
-
     if (!read_is_valid(data, first_partition_size, data_end))
       vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                          "Truncated packet or corrupt partition 0 length");
 
-    data += HEADER_SIZE_IN_BYTES;  // header size
+    data += 3;
 
     vp9_setup_version(pc);
 
@@ -1026,6 +1008,9 @@
     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder 0");
 
+  pc->clr_type = (YUV_TYPE)vp9_read_bit(&header_bc);
+  pc->error_resilient_mode = vp9_read_bit(&header_bc);
+
   setup_loopfilter(pc, xd, &header_bc);
 
   setup_quantization(pbi, &header_bc);
@@ -1070,6 +1055,14 @@
 
     // To enable choice of different interpolation filters
     vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
+  }
+
+  if (!pc->error_resilient_mode) {
+    pc->refresh_frame_context = vp9_read_bit(&header_bc);
+    pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
+  } else {
+    pc->refresh_frame_context = 0;
+    pc->frame_parallel_decoding_mode = 1;
   }
 
   pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
--- a/vp9/decoder/vp9_read_bit_buffer.h
+++ /dev/null
@@ -1,35 +1,0 @@
-/*
- *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef VP9_READ_BIT_BUFFER_
-#define VP9_READ_BIT_BUFFER_
-
-struct vp9_read_bit_buffer {
-  const uint8_t *const bit_buffer;
-  size_t bit_offset;
-};
-
-static int vp9_rb_read_bit(struct vp9_read_bit_buffer *rb) {
-  const int off = rb->bit_offset;
-  const int p = off / CHAR_BIT;
-  const int q = /*CHAR_BIT - 1 -*/ off % CHAR_BIT;
-  const int bit = (rb->bit_buffer[p] & (1 << q)) >> q;
-  rb->bit_offset = off + 1;
-  return bit;
-}
-
-static int vp9_rb_read_literal(struct vp9_read_bit_buffer *rb, int bits) {
-  int value = 0, bit;
-  for (bit = bits - 1; bit >= 0; bit--)
-    value |= vp9_rb_read_bit(rb) << bit;
-  return value;
-}
-
-#endif  // VP9_READ_BIT_BUFFER_
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -12,15 +12,20 @@
 #include <stdio.h>
 #include <limits.h>
 
-#include "vpx/vpx_encoder.h"
-#include "vpx_mem/vpx_mem.h"
-
+#include "vp9/common/vp9_header.h"
+#include "vp9/encoder/vp9_encodemv.h"
 #include "vp9/common/vp9_entropymode.h"
 #include "vp9/common/vp9_entropymv.h"
 #include "vp9/common/vp9_findnearmv.h"
 #include "vp9/common/vp9_tile_common.h"
+#include "vp9/encoder/vp9_mcomp.h"
 #include "vp9/common/vp9_systemdependent.h"
 #include "vp9/common/vp9_pragmas.h"
+#include "vpx/vpx_encoder.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vp9/encoder/vp9_bitstream.h"
+#include "vp9/encoder/vp9_segmentation.h"
+
 #include "vp9/common/vp9_seg_common.h"
 #include "vp9/common/vp9_pred_common.h"
 #include "vp9/common/vp9_entropy.h"
@@ -28,12 +33,6 @@
 #include "vp9/common/vp9_mvref_common.h"
 #include "vp9/common/vp9_treecoder.h"
 
-#include "vp9/encoder/vp9_encodemv.h"
-#include "vp9/encoder/vp9_mcomp.h"
-#include "vp9/encoder/vp9_bitstream.h"
-#include "vp9/encoder/vp9_segmentation.h"
-#include "vp9/encoder/vp9_write_bit_buffer.h"
-
 #if defined(SECTIONBITS_OUTPUT)
 unsigned __int64 Sectionbits[500];
 #endif
@@ -1279,6 +1278,10 @@
   }
 }
 
+#ifdef PACKET_TESTING
+FILE *vpxlogc = 0;
+#endif
+
 static void decide_kf_ymode_entropy(VP9_COMP *cpi) {
   int mode_cost[MB_MODE_COUNT];
   int bestcost = INT_MAX;
@@ -1489,34 +1492,44 @@
 
 void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
   int i;
+  VP9_HEADER oh;
   VP9_COMMON *const pc = &cpi->common;
-  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
   vp9_writer header_bc, residual_bc;
+  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
   int extra_bytes_packed = 0;
+
   uint8_t *cx_data = dest;
 
-  cx_data += HEADER_SIZE_IN_BYTES;
+  oh.show_frame = (int) pc->show_frame;
+  oh.type = (int)pc->frame_type;
+  oh.version = pc->version;
+  oh.first_partition_length_in_bytes = 0;
 
+  cx_data += 3;
+
 #if defined(SECTIONBITS_OUTPUT)
-  Sectionbits[active_section = 1] += HEADER_SIZE_IN_BYTES * 8 * 256;
+  Sectionbits[active_section = 1] += sizeof(VP9_HEADER) * 8 * 256;
 #endif
 
   compute_update_table();
 
-  if (pc->frame_type == KEY_FRAME) {
+  /* every keyframe send startcode, width, height, scale factor, clamp
+   * and color type.
+   */
+  if (oh.type == KEY_FRAME) {
     // Start / synch code
     cx_data[0] = 0x49;
     cx_data[1] = 0x83;
     cx_data[2] = 0x42;
-    extra_bytes_packed += 3;
-    cx_data += 3;
+    extra_bytes_packed = 3;
+    cx_data += extra_bytes_packed;
   }
 
   if (pc->width != pc->display_width || pc->height != pc->display_height) {
     write_le16(cx_data, pc->display_width);
     write_le16(cx_data + 2, pc->display_height);
-    extra_bytes_packed += 4;
     cx_data += 4;
+    extra_bytes_packed += 4;
   }
 
   write_le16(cx_data, pc->width);
@@ -1526,6 +1539,12 @@
 
   vp9_start_encode(&header_bc, cx_data);
 
+  // TODO(jkoleszar): remove these two unused bits?
+  vp9_write_bit(&header_bc, pc->clr_type);
+
+  // error resilient mode
+  vp9_write_bit(&header_bc, pc->error_resilient_mode);
+
   encode_loopfilter(pc, xd, &header_bc);
 
   encode_quantization(pc, &header_bc);
@@ -1574,8 +1593,9 @@
     vp9_write_literal(&header_bc, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2);
 
     // Indicate the sign bias for each reference frame buffer.
-    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+    for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
       vp9_write_bit(&header_bc, pc->ref_frame_sign_bias[LAST_FRAME + i]);
+    }
 
     // Signal whether to allow high MV precision
     vp9_write_bit(&header_bc, (xd->allow_high_precision_mv) ? 1 : 0);
@@ -1605,6 +1625,11 @@
       vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2);
   }
 
+  if (!pc->error_resilient_mode) {
+    vp9_write_bit(&header_bc, pc->refresh_frame_context);
+    vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
+  }
+
   vp9_write_literal(&header_bc, pc->frame_context_idx,
                     NUM_FRAME_CONTEXTS_LG2);
 
@@ -1803,35 +1828,27 @@
 
   vp9_stop_encode(&header_bc);
 
+  oh.first_partition_length_in_bytes = header_bc.pos;
+
   /* update frame tag */
   {
-    const int first_partition_length_in_bytes = header_bc.pos;
     int scaling = (pc->width != pc->display_width ||
                    pc->height != pc->display_height);
+    int v = (oh.first_partition_length_in_bytes << 8) |
+            (pc->subsampling_y << 7) |
+            (pc->subsampling_x << 6) |
+            (scaling << 5) |
+            (oh.show_frame << 4) |
+            (oh.version << 1) |
+            oh.type;
 
-    struct vp9_write_bit_buffer wb = {dest, 0};
-
-    assert(first_partition_length_in_bytes <= 0xffff);
-
-    vp9_wb_write_bit(&wb, pc->frame_type);
-    vp9_wb_write_literal(&wb, pc->version, 3);
-    vp9_wb_write_bit(&wb, pc->show_frame);
-    vp9_wb_write_bit(&wb, scaling);
-    vp9_wb_write_bit(&wb, pc->subsampling_x);
-    vp9_wb_write_bit(&wb, pc->subsampling_y);
-
-    vp9_wb_write_bit(&wb, pc->clr_type);
-    vp9_wb_write_bit(&wb, pc->error_resilient_mode);
-    if (!pc->error_resilient_mode) {
-      vp9_wb_write_bit(&wb, pc->refresh_frame_context);
-      vp9_wb_write_bit(&wb, pc->frame_parallel_decoding_mode);
-    }
-
-
-    vp9_wb_write_literal(&wb, first_partition_length_in_bytes, 16);
+    assert(oh.first_partition_length_in_bytes <= 0xffff);
+    dest[0] = v;
+    dest[1] = v >> 8;
+    dest[2] = v >> 16;
   }
 
-  *size = HEADER_SIZE_IN_BYTES + extra_bytes_packed + header_bc.pos;
+  *size = VP9_HEADER_SIZE + extra_bytes_packed + header_bc.pos;
 
   if (pc->frame_type == KEY_FRAME) {
     decide_kf_ymode_entropy(cpi);
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -258,6 +258,9 @@
     init_done = 1;
   }
 }
+#ifdef PACKET_TESTING
+extern FILE *vpxlogc;
+#endif
 
 static void setup_features(VP9_COMP *cpi) {
   MACROBLOCKD *xd = &cpi->mb.e_mbd;
--- a/vp9/encoder/vp9_write_bit_buffer.h
+++ /dev/null
@@ -1,38 +1,0 @@
-/*
- *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef VP9_BIT_WRITE_BUFFER_H_
-#define VP9_BIT_WRITE_BUFFER_H_
-
-#include "vpx/vpx_integer.h"
-
-struct vp9_write_bit_buffer {
-  uint8_t *const bit_buffer;
-  size_t bit_offset;
-};
-
-static void vp9_wb_write_bit(struct vp9_write_bit_buffer *wb, int bit) {
-  const int off = wb->bit_offset;
-  const int p = off / CHAR_BIT;
-  const int q = /*CHAR_BIT - 1 -*/ off % CHAR_BIT;
-  wb->bit_buffer[p] &= ~(1 << q);
-  wb->bit_buffer[p] |= bit << q;
-  wb->bit_offset = off + 1;
-}
-
-static void vp9_wb_write_literal(struct vp9_write_bit_buffer *wb,
-                              int data, int bits) {
-  int bit;
-  for (bit = bits - 1; bit >= 0; bit--)
-    vp9_wb_write_bit(wb, (data >> bit) & 1);
-}
-
-
-#endif  // VP9_BIT_WRITE_BUFFER_H_
--- a/vp9/vp9_common.mk
+++ b/vp9/vp9_common.mk
@@ -38,6 +38,7 @@
 VP9_COMMON_SRCS-yes += common/vp9_enums.h
 VP9_COMMON_SRCS-yes += common/vp9_extend.h
 VP9_COMMON_SRCS-yes += common/vp9_findnearmv.h
+VP9_COMMON_SRCS-yes += common/vp9_header.h
 VP9_COMMON_SRCS-yes += common/vp9_idct.h
 VP9_COMMON_SRCS-yes += common/vp9_invtrans.h
 VP9_COMMON_SRCS-yes += common/vp9_loopfilter.h
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -224,7 +224,7 @@
     si->is_kf = 0;
 
     if (data_sz >= 10 && !(data[0] & 0x01)) { /* I-Frame */
-      const uint8_t *c = data + HEADER_SIZE_IN_BYTES;
+      const uint8_t *c = data + 3;
       si->is_kf = 1;
 
       /* vet via sync code */
--- a/vp9/vp9cx.mk
+++ b/vp9/vp9cx.mk
@@ -19,8 +19,6 @@
 
 VP9_CX_SRCS-yes += encoder/vp9_bitstream.c
 VP9_CX_SRCS-yes += encoder/vp9_boolhuff.c
-VP9_CX_SRCS-yes += encoder/vp9_boolhuff.h
-VP9_CX_SRCS-yes += encoder/vp9_write_bit_buffer.h
 VP9_CX_SRCS-yes += encoder/vp9_dct.c
 VP9_CX_SRCS-yes += encoder/vp9_encodeframe.c
 VP9_CX_SRCS-yes += encoder/vp9_encodeframe.h
@@ -29,6 +27,7 @@
 VP9_CX_SRCS-yes += encoder/vp9_encodemv.c
 VP9_CX_SRCS-yes += encoder/vp9_firstpass.c
 VP9_CX_SRCS-yes += encoder/vp9_block.h
+VP9_CX_SRCS-yes += encoder/vp9_boolhuff.h
 VP9_CX_SRCS-yes += encoder/vp9_bitstream.h
 VP9_CX_SRCS-yes += encoder/vp9_encodeintra.h
 VP9_CX_SRCS-yes += encoder/vp9_encodemb.h
--- a/vp9/vp9dx.mk
+++ b/vp9/vp9dx.mk
@@ -19,12 +19,11 @@
 
 VP9_DX_SRCS-yes += decoder/vp9_asm_dec_offsets.c
 VP9_DX_SRCS-yes += decoder/vp9_dboolhuff.c
-VP9_DX_SRCS-yes += decoder/vp9_dboolhuff.h
-VP9_DX_SRCS-yes += decoder/vp9_read_bit_buffer.h
 VP9_DX_SRCS-yes += decoder/vp9_decodemv.c
 VP9_DX_SRCS-yes += decoder/vp9_decodframe.c
 VP9_DX_SRCS-yes += decoder/vp9_decodframe.h
 VP9_DX_SRCS-yes += decoder/vp9_detokenize.c
+VP9_DX_SRCS-yes += decoder/vp9_dboolhuff.h
 VP9_DX_SRCS-yes += decoder/vp9_decodemv.h
 VP9_DX_SRCS-yes += decoder/vp9_detokenize.h
 VP9_DX_SRCS-yes += decoder/vp9_onyxd.h