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
This commit is contained in:
@@ -727,51 +727,60 @@ static void read_frame_size(VP9_COMMON *cm,
|
||||
*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 @@ static void error_handler(void *data, int bit_offset) {
|
||||
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 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
|
||||
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 @@ 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);
|
||||
@@ -962,28 +974,15 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
|
||||
} 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;
|
||||
|
||||
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 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
|
||||
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] ==
|
||||
@@ -1026,6 +1028,16 @@ size_t read_uncompressed_header(VP9D_COMP *pbi,
|
||||
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);
|
||||
cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
|
||||
cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1293,17 +1293,60 @@ static void write_tile_info(VP9_COMMON *cm, struct vp9_write_bit_buffer *wb) {
|
||||
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 @@ void write_uncompressed_header(VP9_COMP *cpi,
|
||||
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,68 +1375,29 @@ void write_uncompressed_header(VP9_COMP *cpi,
|
||||
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);
|
||||
|
||||
// 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]);
|
||||
// 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);
|
||||
@@ -1403,6 +1407,12 @@ void write_uncompressed_header(VP9_COMP *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_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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
|
||||
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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
|
||||
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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user