Commit 17af2748 authored by Zoe Liu's avatar Zoe Liu
Browse files

Add encoder/decoder support to frame_sign_bias

Frame sign bias value will not be signaled in frame header. Instead,
the sign bias of reference frames are derived from their corresponding
frame offsets at both encoder and decoder.

The tool of 'frame_sign_bias' is dependent of 'frame_marker'. Compared
against baseline, the enabling of both tools obtains a small coding gain
of -0.08 ~ -0.11% in BDRate over Google lowres/midres tests.

Change-Id: I8d85dc427ced0b2152712ccf61be4be6068075b9
parent 41d37c20
......@@ -1425,6 +1425,23 @@ void av1_setup_frame_buf_refs(AV1_COMMON *cm) {
cm->buffer_pool->frame_bufs[alt2_buf_idx].cur_frame_offset;
#endif
}
#if CONFIG_FRAME_SIGN_BIAS
void av1_setup_frame_sign_bias(AV1_COMMON *cm) {
MV_REFERENCE_FRAME ref_frame;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
const int buf_idx = cm->frame_refs[ref_frame - LAST_FRAME].idx;
if (buf_idx != INVALID_IDX) {
const int ref_frame_offset =
cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
cm->ref_frame_sign_bias[ref_frame] =
(ref_frame_offset <= (int)cm->frame_offset) ? 0 : 1;
} else {
cm->ref_frame_sign_bias[ref_frame] = 0;
}
}
}
#endif // CONFIG_FRAME_SIGN_BIAS
#endif // CONFIG_FRAME_MARKER
#if CONFIG_MFMV
......
......@@ -390,6 +390,9 @@ static INLINE uint8_t av1_drl_ctx(const CANDIDATE_MV *ref_mv_stack,
#if CONFIG_FRAME_MARKER
void av1_setup_frame_buf_refs(AV1_COMMON *cm);
#if CONFIG_FRAME_SIGN_BIAS
void av1_setup_frame_sign_bias(AV1_COMMON *cm);
#endif // CONFIG_FRAME_SIGN_BIAS
#if CONFIG_MFMV
void av1_setup_motion_field(AV1_COMMON *cm);
#endif // CONFIG_MFMV
......
......@@ -579,12 +579,12 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif // CONFIG_ONE_SIDED_COMPOUND
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
......@@ -689,12 +689,12 @@ int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif // CONFIG_ONE_SIDED_COMPOUND
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
......@@ -797,12 +797,11 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif // CONFIG_ONE_SIDED_COMPOUND
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
......
......@@ -4881,12 +4881,20 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
RefBuffer *const ref_frame = &cm->frame_refs[i];
ref_frame->idx = idx;
ref_frame->buf = &frame_bufs[idx].buf;
#if CONFIG_FRAME_SIGN_BIAS
#if CONFIG_OBU
// NOTE: For the scenario of (cm->frame_type != S_FRAME),
// ref_frame_sign_bias will be reset based on frame offsets.
cm->ref_frame_sign_bias[LAST_FRAME + i] = 0;
#endif // CONFIG_OBU
#else // !CONFIG_FRAME_SIGN_BIAS
#if CONFIG_OBU
cm->ref_frame_sign_bias[LAST_FRAME + i] =
(cm->frame_type == S_FRAME) ? 0 : aom_rb_read_bit(rb);
#else
#else // !CONFIG_OBU
cm->ref_frame_sign_bias[LAST_FRAME + i] = aom_rb_read_bit(rb);
#endif
#endif // CONFIG_OBU
#endif // CONFIG_FRAME_SIGN_BIAS
#if CONFIG_REFERENCE_BUFFER
if (cm->seq_params.frame_id_numbers_present_flag) {
int frame_id_length = cm->seq_params.frame_id_length_minus7 + 7;
......@@ -4957,7 +4965,29 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
} else {
cm->frame_offset = cm->current_video_frame;
}
#endif
av1_setup_frame_buf_refs(cm);
#if CONFIG_FRAME_SIGN_BIAS
#if CONFIG_OBU
if (cm->frame_type != S_FRAME)
#endif // CONFIG_OBU
av1_setup_frame_sign_bias(cm);
#define FRAME_SIGN_BIAS_DEBUG 0
#if FRAME_SIGN_BIAS_DEBUG
{
printf("\n\nDECODER: Frame=%d, show_frame=%d:", cm->current_video_frame,
cm->show_frame);
MV_REFERENCE_FRAME ref_frame;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
printf(" sign_bias[%d]=%d", ref_frame,
cm->ref_frame_sign_bias[ref_frame]);
}
printf("\n");
}
#endif // FRAME_SIGN_BIAS_DEBUG
#undef FRAME_SIGN_BIAS_DEBUG
#endif // CONFIG_FRAME_SIGN_BIAS
#endif // CONFIG_FRAME_MARKER
#if CONFIG_TEMPMV_SIGNALING
cm->cur_frame->intra_only = cm->frame_type == KEY_FRAME || cm->intra_only;
......@@ -5557,12 +5587,9 @@ size_t av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data,
(cm->last_frame_type != KEY_FRAME);
#endif // CONFIG_TEMPMV_SIGNALING
#if CONFIG_FRAME_MARKER
av1_setup_frame_buf_refs(cm);
#if CONFIG_MFMV
av1_setup_motion_field(cm);
#endif // CONFIG_MFMV
#endif // CONFIG_FRAME_MARKER
av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
......
......@@ -1540,15 +1540,15 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
#endif // CONFIG_EXT_COMP_REFS
// Normative in decoder (for low delay)
#if CONFIG_ONE_SIDED_COMPOUND
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS
const int idx = 1;
#else // !CONFIG_ONE_SIDED_COMPOUND
#else // !(CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS)
#if CONFIG_EXT_REFS
const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#else // !CONFIG_EXT_REFS
const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
#endif // CONFIG_EXT_REFS
#endif // CONFIG_ONE_SIDED_COMPOUND
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_FRAME_SIGN_BIAS)
const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
#if CONFIG_VAR_REFS
......@@ -2232,7 +2232,7 @@ static void dec_dump_logs(AV1_COMMON *cm, MODE_INFO *const mi, int mi_row,
int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
#define FRAME_TO_CHECK 1
if (cm->current_video_frame == FRAME_TO_CHECK /*&& cm->show_frame == 0*/) {
if (cm->current_video_frame == FRAME_TO_CHECK && cm->show_frame == 1) {
printf(
"=== DECODER ===: "
"Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
......
......@@ -2306,7 +2306,7 @@ static void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) {
m = xd->mi[0];
if (is_inter_block(&m->mbmi)) {
#define FRAME_TO_CHECK 1
if (cm->current_video_frame == FRAME_TO_CHECK /* && cm->show_frame == 1*/) {
if (cm->current_video_frame == FRAME_TO_CHECK && cm->show_frame == 1) {
const MB_MODE_INFO *const mbmi = &m->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type;
......@@ -4672,7 +4672,9 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi,
assert(get_ref_frame_map_idx(cpi, ref_frame) != INVALID_IDX);
aom_wb_write_literal(wb, get_ref_frame_map_idx(cpi, ref_frame),
REF_FRAMES_LOG2);
#if !CONFIG_FRAME_SIGN_BIAS
aom_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]);
#endif // !CONFIG_FRAME_SIGN_BIAS
#if CONFIG_REFERENCE_BUFFER
if (cm->seq_params.frame_id_numbers_present_flag) {
int i = get_ref_frame_map_idx(cpi, ref_frame);
......@@ -4691,6 +4693,22 @@ static void write_uncompressed_header_frame(AV1_COMP *cpi,
#endif // CONFIG_REFERENCE_BUFFER
}
#if CONFIG_FRAME_SIGN_BIAS
#define FRAME_SIGN_BIAS_DEBUG 0
#if FRAME_SIGN_BIAS_DEBUG
{
printf("\n\nENCODER: Frame=%d, show_frame=%d:", cm->current_video_frame,
cm->show_frame);
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
printf(" sign_bias[%d]=%d", ref_frame,
cm->ref_frame_sign_bias[ref_frame]);
}
printf("\n");
}
#endif // FRAME_SIGN_BIAS_DEBUG
#undef FRAME_SIGN_BIAS_DEBUG
#endif // CONFIG_FRAME_SIGN_BIAS
#if CONFIG_FRAME_SIZE
if (cm->error_resilient_mode == 0) {
write_frame_size_with_refs(cpi, wb);
......@@ -4959,7 +4977,9 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
assert(get_ref_frame_map_idx(cpi, ref_frame) != INVALID_IDX);
aom_wb_write_literal(wb, get_ref_frame_map_idx(cpi, ref_frame),
REF_FRAMES_LOG2);
#if !CONFIG_FRAME_SIGN_BIAS
aom_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]);
#endif // !CONFIG_FRAME_SIGN_BIAS
#if CONFIG_REFERENCE_BUFFER
if (cm->seq_params.frame_id_numbers_present_flag) {
int i = get_ref_frame_map_idx(cpi, ref_frame);
......
......@@ -5517,25 +5517,9 @@ static void encode_frame_internal(AV1_COMP *cpi) {
av1_zero(x->blk_skip_drl);
#endif
#if CONFIG_FRAME_MARKER
if (cm->show_frame == 0) {
int arf_offset = AOMMIN(
(MAX_GF_INTERVAL - 1),
cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
#if CONFIG_EXT_REFS
int brf_offset =
cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
#endif
cm->frame_offset = cm->current_video_frame + arf_offset;
} else {
cm->frame_offset = cm->current_video_frame;
}
av1_setup_frame_buf_refs(cm);
#if CONFIG_MFMV
av1_setup_motion_field(cm);
#endif // CONFIG_MFMV
#endif // CONFIG_FRAME_MARKER
{
struct aom_usec_timer emr_timer;
......@@ -5596,6 +5580,26 @@ void av1_encode_frame(AV1_COMP *cpi) {
cm->reduced_tx_set_used = 0;
#endif // CONFIG_EXT_TX
#if CONFIG_FRAME_MARKER
if (cm->show_frame == 0) {
int arf_offset = AOMMIN(
(MAX_GF_INTERVAL - 1),
cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
#if CONFIG_EXT_REFS
int brf_offset =
cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
#endif // CONFIG_EXT_REFS
cm->frame_offset = cm->current_video_frame + arf_offset;
} else {
cm->frame_offset = cm->current_video_frame;
}
av1_setup_frame_buf_refs(cm);
#if CONFIG_FRAME_SIGN_BIAS
av1_setup_frame_sign_bias(cm);
#endif // CONFIG_FRAME_SIGN_BIAS
#endif // CONFIG_FRAME_MARKER
// In the longer term the encoder should be generalized to match the
// decoder such that we allow compound where one of the 3 buffers has a
// different sign bias and that buffer is then the fixed ref. However, this
......
......@@ -5197,6 +5197,7 @@ static void set_ext_overrides(AV1_COMP *cpi) {
}
}
#if !CONFIG_FRAME_SIGN_BIAS
static void set_arf_sign_bias(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
int arf_sign_bias;
......@@ -5225,6 +5226,7 @@ static void set_arf_sign_bias(AV1_COMP *cpi) {
cm->ref_frame_sign_bias[ALTREF_FRAME];
#endif // CONFIG_EXT_REFS
}
#endif // !CONFIG_FRAME_SIGN_BIAS
static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
InterpFilter ifilter;
......@@ -5373,8 +5375,11 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
set_ext_overrides(cpi);
aom_clear_system_state();
#if !CONFIG_FRAME_SIGN_BIAS
// Set the arf sign bias for this frame.
set_arf_sign_bias(cpi);
#endif // !CONFIG_FRAME_SIGN_BIAS
#if CONFIG_TEMPMV_SIGNALING
// frame type has been decided outside of this function call
cm->cur_frame->intra_only = cm->frame_type == KEY_FRAME || cm->intra_only;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment