ref: 514b8adacd152168eac053d0a21278ee85f7e10f
parent: 747f76fc999a0fc6cd38b5a5e5aee512302dacc7
author: Dmitry Kovalev <[email protected]>
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 {