Commit f91498c0 authored by Zoe Liu's avatar Zoe Liu

Add pred prob handling for new references in EXT_REFS

For the experiment of EXT_REFS, add the handling of the context
probabilities for both forward reference frames (namely
LAST/LAST2/LAST3/GOLDEN) and backward reference frames
(namely BWDREF/ALTREF).

Change-Id: Ibd991673acf6ff2fc9a56b8805eca9173cbf5fdc
parent a97f8e20
......@@ -266,11 +266,33 @@ static const aom_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
239, 183, 119, 96, 41
};
#if CONFIG_EXT_REFS
// TODO(zoeliu): To adjust the initial prob values.
static const aom_prob default_comp_fwdref_p[REF_CONTEXTS][FWD_REFS - 1] = {
{ 33, 16, 16 },
{ 77, 74, 74 },
{ 142, 142, 142 },
{ 172, 170, 170 },
{ 238, 247, 247 }
};
static const aom_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = {
{ 16 }, { 74 }, { 142 }, { 170 }, { 247 }
};
#else
static const aom_prob default_comp_ref_p[REF_CONTEXTS] = { 50, 126, 123, 221,
226 };
static const aom_prob default_single_ref_p[REF_CONTEXTS][2] = {
#endif // CONFIG_EXT_REFS
static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
#if CONFIG_EXT_REFS
{ 33, 16, 16, 16, 16 },
{ 77, 74, 74, 74, 74 },
{ 142, 142, 142, 142, 142 },
{ 172, 170, 170, 170, 170 },
{ 238, 247, 247, 247, 247 }
#else
{ 33, 16 }, { 77, 74 }, { 142, 142 }, { 172, 170 }, { 238, 247 }
#endif // CONFIG_EXT_REFS
};
static const struct tx_probs default_tx_probs = { { { 3, 136, 37 },
......@@ -349,7 +371,12 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->partition_prob, default_partition_probs);
av1_copy(fc->intra_inter_prob, default_intra_inter_p);
av1_copy(fc->comp_inter_prob, default_comp_inter_p);
#if CONFIG_EXT_REFS
av1_copy(fc->comp_fwdref_prob, default_comp_fwdref_p);
av1_copy(fc->comp_bwdref_prob, default_comp_bwdref_p);
#else
av1_copy(fc->comp_ref_prob, default_comp_ref_p);
#endif // CONFIG_EXT_REFS
av1_copy(fc->single_ref_prob, default_single_ref_p);
fc->tx_probs = default_tx_probs;
av1_copy(fc->skip_probs, default_skip_probs);
......@@ -400,11 +427,24 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
fc->comp_inter_prob[i] =
mode_mv_merge_probs(pre_fc->comp_inter_prob[i], counts->comp_inter[i]);
#if CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (FWD_REFS - 1); j++)
fc->comp_fwdref_prob[i][j] = mode_mv_merge_probs(
pre_fc->comp_fwdref_prob[i][j], counts->comp_fwdref[i][j]);
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (BWD_REFS - 1); j++)
fc->comp_bwdref_prob[i][j] = mode_mv_merge_probs(
pre_fc->comp_bwdref_prob[i][j], counts->comp_bwdref[i][j]);
#else
for (i = 0; i < REF_CONTEXTS; i++)
fc->comp_ref_prob[i] =
mode_mv_merge_probs(pre_fc->comp_ref_prob[i], counts->comp_ref[i]);
#endif // CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < 2; j++)
for (j = 0; j < (SINGLE_REFS - 1); j++)
fc->single_ref_prob[i][j] = mode_mv_merge_probs(
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
......@@ -531,7 +571,14 @@ static void set_default_lf_deltas(struct loopfilter *lf) {
lf->ref_deltas[INTRA_FRAME] = 1;
lf->ref_deltas[LAST_FRAME] = 0;
#if CONFIG_EXT_REFS
lf->ref_deltas[LAST2_FRAME] = 0;
lf->ref_deltas[LAST3_FRAME] = 0;
#endif // CONFIG_EXT_REFS
lf->ref_deltas[GOLDEN_FRAME] = -1;
#if CONFIG_EXT_REFS
lf->ref_deltas[BWDREF_FRAME] = -1;
#endif // CONFIG_EXT_REFS
lf->ref_deltas[ALTREF_FRAME] = -1;
lf->mode_deltas[0] = 0;
......
......@@ -71,8 +71,13 @@ typedef struct frame_contexts {
#endif // CONFIG_MOTION_VAR
aom_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
aom_prob comp_inter_prob[COMP_INTER_CONTEXTS];
aom_prob single_ref_prob[REF_CONTEXTS][2];
aom_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS - 1];
#if CONFIG_EXT_REFS
aom_prob comp_fwdref_prob[REF_CONTEXTS][FWD_REFS - 1];
aom_prob comp_bwdref_prob[REF_CONTEXTS][BWD_REFS - 1];
#else
aom_prob comp_ref_prob[REF_CONTEXTS];
#endif // CONFIG_EXT_REFS
struct tx_probs tx_probs;
aom_prob skip_probs[SKIP_CONTEXTS];
#if CONFIG_REF_MV
......@@ -112,8 +117,13 @@ typedef struct FRAME_COUNTS {
#endif // CONFIG_MOTION_VAR
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][2][2];
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS - 1][2];
#if CONFIG_EXT_REFS
unsigned int comp_fwdref[REF_CONTEXTS][FWD_REFS - 1][2];
unsigned int comp_bwdref[REF_CONTEXTS][BWD_REFS - 1][2];
#else
unsigned int comp_ref[REF_CONTEXTS][2];
#endif // CONFIG_EXT_REFS
struct tx_counts tx;
unsigned int skip[SKIP_CONTEXTS][2];
#if CONFIG_REF_MV
......
......@@ -105,8 +105,18 @@ typedef enum {
typedef enum {
AOM_LAST_FLAG = 1 << 0,
#if CONFIG_EXT_REFS
AOM_LAST2_FLAG = 1 << 1,
AOM_LAST3_FLAG = 1 << 2,
AOM_GOLD_FLAG = 1 << 3,
AOM_BWD_FLAG = 1 << 4,
AOM_ALT_FLAG = 1 << 5,
AOM_REFFRAME_ALL = (1 << 6) - 1
#else
AOM_GOLD_FLAG = 1 << 1,
AOM_ALT_FLAG = 1 << 2,
AOM_REFFRAME_ALL = (1 << 3) - 1
#endif // CONFIG_EXT_REFS
} AOM_REFFRAME;
typedef enum { PLANE_TYPE_Y = 0, PLANE_TYPE_UV = 1, PLANE_TYPES } PLANE_TYPE;
......@@ -182,6 +192,14 @@ typedef enum {
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
#if CONFIG_EXT_REFS
#define FWD_REFS 4
#define BWD_REFS 2
#define SINGLE_REFS (FWD_REFS + BWD_REFS)
#else
#define SINGLE_REFS 3
#endif // CONFIG_EXT_REFS
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -13,15 +13,15 @@
#define AV1_COMMON_ONYXC_INT_H_
#include "./aom_config.h"
#include "./av1_rtcd.h"
#include "aom/internal/aom_codec_internal.h"
#include "aom_util/aom_thread.h"
#include "./av1_rtcd.h"
#include "av1/common/alloccommon.h"
#include "av1/common/loopfilter.h"
#include "av1/common/entropymv.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/frame_buffers.h"
#include "av1/common/loopfilter.h"
#include "av1/common/tile_common.h"
#ifdef __cplusplus
......@@ -176,6 +176,10 @@ typedef struct AV1Common {
int show_frame;
int last_show_frame;
int show_existing_frame;
#if CONFIG_EXT_REFS
// Flag for a frame used as a reference - not written to the bitstream
int is_reference_frame;
#endif // CONFIG_EXT_REFS
// Flag signaling that the frame is encoded using only INTRA modes.
uint8_t intra_only;
......@@ -273,9 +277,14 @@ typedef struct AV1Common {
int frame_parallel_decode; // frame-based threading.
// Context probabilities for reference frame prediction
// Context probabilities for reference frame prediction
#if CONFIG_EXT_REFS
MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS];
MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS];
#else
MV_REFERENCE_FRAME comp_fixed_ref;
MV_REFERENCE_FRAME comp_var_ref[2];
#endif // CONFIG_EXT_REFS
REFERENCE_MODE reference_mode;
FRAME_CONTEXT *fc; /* this frame entropy */
......
This diff is collapsed.
......@@ -83,6 +83,45 @@ static INLINE aom_prob av1_get_reference_mode_prob(const AV1_COMMON *cm,
return cm->fc->comp_inter_prob[av1_get_reference_mode_context(cm, xd)];
}
#if CONFIG_EXT_REFS
int av1_get_pred_context_comp_fwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_fwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_fwdref_p(cm, xd);
return cm->fc->comp_fwdref_prob[pred_context][0];
}
int av1_get_pred_context_comp_fwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_fwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_fwdref_p1(cm, xd);
return cm->fc->comp_fwdref_prob[pred_context][1];
}
int av1_get_pred_context_comp_fwdref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_fwdref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_fwdref_p2(cm, xd);
return cm->fc->comp_fwdref_prob[pred_context][2];
}
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][0];
}
#else
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
......@@ -91,6 +130,7 @@ static INLINE aom_prob av1_get_pred_prob_comp_ref_p(const AV1_COMMON *cm,
const int pred_context = av1_get_pred_context_comp_ref_p(cm, xd);
return cm->fc->comp_ref_prob[pred_context];
}
#endif // CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
......@@ -106,6 +146,29 @@ static INLINE aom_prob av1_get_pred_prob_single_ref_p2(const AV1_COMMON *cm,
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p2(xd)][1];
}
#if CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p3(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p3(xd)][2];
}
int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p4(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p4(xd)][3];
}
int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p5(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p5(xd)][4];
}
#endif // CONFIG_EXT_REFS
// Returns a context number for the given MB prediction signal
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real blocks.
......
......@@ -395,12 +395,23 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
cm->counts.comp_inter[i][j] += counts->comp_inter[i][j];
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < 2; j++)
for (j = 0; j < (SINGLE_REFS - 1); j++)
for (k = 0; k < 2; k++)
cm->counts.single_ref[i][j][k] += counts->single_ref[i][j][k];
#if CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (FWD_REFS - 1); j++)
for (k = 0; k < 2; k++)
cm->counts.comp_fwdref[i][j][k] += counts->comp_fwdref[i][j][k];
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (BWD_REFS - 1); j++)
for (k = 0; k < 2; k++)
cm->counts.comp_bwdref[i][j][k] += counts->comp_bwdref[i][j][k];
#else
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < 2; j++) cm->counts.comp_ref[i][j] += counts->comp_ref[i][j];
#endif // CONFIG_EXT_REFS
for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
for (j = 0; j < TX_SIZES; j++)
......
......@@ -63,6 +63,14 @@ static int is_compound_reference_allowed(const AV1_COMMON *cm) {
}
static void setup_compound_reference_mode(AV1_COMMON *cm) {
#if CONFIG_EXT_REFS
cm->comp_fwd_ref[0] = LAST_FRAME;
cm->comp_fwd_ref[1] = LAST2_FRAME;
cm->comp_fwd_ref[2] = LAST3_FRAME;
cm->comp_fwd_ref[3] = GOLDEN_FRAME;
cm->comp_bwd_ref[0] = BWDREF_FRAME;
cm->comp_bwd_ref[1] = ALTREF_FRAME;
#else
if (cm->ref_frame_sign_bias[LAST_FRAME] ==
cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
cm->comp_fixed_ref = ALTREF_FRAME;
......@@ -78,6 +86,7 @@ static void setup_compound_reference_mode(AV1_COMMON *cm) {
cm->comp_var_ref[0] = GOLDEN_FRAME;
cm->comp_var_ref[1] = ALTREF_FRAME;
}
#endif // CONFIG_EXT_REFS
}
static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
......@@ -169,21 +178,29 @@ static REFERENCE_MODE read_frame_reference_mode(const AV1_COMMON *cm,
static void read_frame_reference_mode_probs(AV1_COMMON *cm, aom_reader *r) {
FRAME_CONTEXT *const fc = cm->fc;
int i;
int i, j;
if (cm->reference_mode == REFERENCE_MODE_SELECT)
for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
av1_diff_update_prob(r, &fc->comp_inter_prob[i]);
if (cm->reference_mode != COMPOUND_REFERENCE)
for (i = 0; i < REF_CONTEXTS; ++i) {
av1_diff_update_prob(r, &fc->single_ref_prob[i][0]);
av1_diff_update_prob(r, &fc->single_ref_prob[i][1]);
}
for (i = 0; i < REF_CONTEXTS; ++i)
for (j = 0; j < (SINGLE_REFS - 1); ++j)
av1_diff_update_prob(r, &fc->single_ref_prob[i][j]);
if (cm->reference_mode != SINGLE_REFERENCE)
#if CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; ++i) {
for (j = 0; j < (FWD_REFS - 1); ++j)
av1_diff_update_prob(r, &fc->comp_fwdref_prob[i][j]);
for (j = 0; j < (BWD_REFS - 1); ++j)
av1_diff_update_prob(r, &fc->comp_bwdref_prob[i][j]);
}
#else
for (i = 0; i < REF_CONTEXTS; ++i)
av1_diff_update_prob(r, &fc->comp_ref_prob[i]);
#endif // CONFIG_EXT_REFS
}
static void update_mv_probs(aom_prob *p, int n, aom_reader *r) {
......@@ -1979,8 +1996,15 @@ static void debug_check_frame_counts(const AV1_COMMON *const cm) {
sizeof(cm->counts.comp_inter)));
assert(!memcmp(cm->counts.single_ref, zero_counts.single_ref,
sizeof(cm->counts.single_ref)));
#if CONFIG_EXT_REFS
assert(!memcmp(cm->counts.comp_fwdref, zero_counts.comp_fwdref,
sizeof(cm->counts.comp_fwdref)));
assert(!memcmp(cm->counts.comp_bwdref, zero_counts.comp_bwdref,
sizeof(cm->counts.comp_bwdref)));
#else
assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref,
sizeof(cm->counts.comp_ref)));
#endif // CONFIG_EXT_REFS
assert(!memcmp(&cm->counts.tx, &zero_counts.tx, sizeof(cm->counts.tx)));
assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip)));
#if CONFIG_REF_MV
......
......@@ -506,13 +506,66 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r);
// FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
if (mode == COMPOUND_REFERENCE) {
#if CONFIG_EXT_REFS
const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
const int ctx_fwd = av1_get_pred_context_comp_fwdref_p(cm, xd);
const int bit_fwd = aom_read(r, fc->comp_fwdref_prob[ctx_fwd][0]);
const int ctx_bwd = av1_get_pred_context_comp_bwdref_p(cm, xd);
const int bit_bwd = aom_read(r, fc->comp_bwdref_prob[ctx_bwd][0]);
// Decode forward references.
if (counts) ++counts->comp_fwdref[ctx_fwd][0][bit_fwd];
if (!bit_fwd) {
const int ctx_fwd1 = av1_get_pred_context_comp_fwdref_p1(cm, xd);
const int bit_fwd1 = aom_read(r, fc->comp_fwdref_prob[ctx_fwd1][1]);
if (counts) ++counts->comp_fwdref[ctx_fwd1][1][bit_fwd1];
ref_frame[!idx] = cm->comp_fwd_ref[bit_fwd1 ? 0 : 1];
} else {
const int ctx_fwd2 = av1_get_pred_context_comp_fwdref_p2(cm, xd);
const int bit_fwd2 = aom_read(r, fc->comp_fwdref_prob[ctx_fwd2][2]);
if (counts) ++counts->comp_fwdref[ctx_fwd2][2][bit_fwd2];
ref_frame[!idx] = cm->comp_fwd_ref[bit_fwd2 ? 3 : 2];
}
// Decode backward references.
if (counts) ++counts->comp_bwdref[ctx_bwd][0][bit_bwd];
ref_frame[idx] = cm->comp_bwd_ref[bit_bwd];
#else
const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
const int bit = aom_read(r, fc->comp_ref_prob[ctx]);
if (counts) ++counts->comp_ref[ctx][bit];
ref_frame[idx] = cm->comp_fixed_ref;
ref_frame[!idx] = cm->comp_var_ref[bit];
#endif // CONFIG_EXT_REFS
} else if (mode == SINGLE_REFERENCE) {
#if CONFIG_EXT_REFS
const int ctx0 = av1_get_pred_context_single_ref_p1(xd);
const int bit0 = aom_read(r, fc->single_ref_prob[ctx0][0]);
if (counts) ++counts->single_ref[ctx0][0][bit0];
if (bit0) {
const int ctx1 = av1_get_pred_context_single_ref_p2(xd);
const int bit1 = aom_read(r, fc->single_ref_prob[ctx1][1]);
if (counts) ++counts->single_ref[ctx1][1][bit1];
ref_frame[0] = bit1 ? ALTREF_FRAME : BWDREF_FRAME;
} else {
const int ctx2 = av1_get_pred_context_single_ref_p3(xd);
const int bit2 = aom_read(r, fc->single_ref_prob[ctx2][2]);
if (counts) ++counts->single_ref[ctx2][2][bit2];
if (bit2) {
const int ctx4 = av1_get_pred_context_single_ref_p5(xd);
const int bit4 = aom_read(r, fc->single_ref_prob[ctx4][4]);
if (counts) ++counts->single_ref[ctx4][4][bit4];
ref_frame[0] = bit4 ? GOLDEN_FRAME : LAST3_FRAME;
} else {
const int ctx3 = av1_get_pred_context_single_ref_p4(xd);
const int bit3 = aom_read(r, fc->single_ref_prob[ctx3][3]);
if (counts) ++counts->single_ref[ctx3][3][bit3];
ref_frame[0] = bit3 ? LAST2_FRAME : LAST_FRAME;
}
}
#else
const int ctx0 = av1_get_pred_context_single_ref_p1(xd);
const int bit0 = aom_read(r, fc->single_ref_prob[ctx0][0]);
if (counts) ++counts->single_ref[ctx0][0][bit0];
......@@ -524,6 +577,7 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
} else {
ref_frame[0] = LAST_FRAME;
}
#endif // CONFIG_EXT_REFS
ref_frame[1] = NONE;
} else {
......
......@@ -409,15 +409,53 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd,
}
if (is_compound) {
#if CONFIG_EXT_REFS
const int bit_fwd = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
mbmi->ref_frame[0] == LAST3_FRAME);
const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME;
aom_write(w, bit_fwd, av1_get_pred_prob_comp_fwdref_p(cm, xd));
if (!bit_fwd) {
const int bit1_fwd = mbmi->ref_frame[0] == LAST_FRAME;
aom_write(w, bit1_fwd, av1_get_pred_prob_comp_fwdref_p1(cm, xd));
} else {
const int bit2_fwd = mbmi->ref_frame[0] == GOLDEN_FRAME;
aom_write(w, bit2_fwd, av1_get_pred_prob_comp_fwdref_p2(cm, xd));
}
aom_write(w, bit_bwd, av1_get_pred_prob_comp_bwdref_p(cm, xd));
#else
aom_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
av1_get_pred_prob_comp_ref_p(cm, xd));
#endif // CONFIG_EXT_REFS
} else {
#if CONFIG_EXT_REFS
const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME ||
mbmi->ref_frame[0] == BWDREF_FRAME);
aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd));
if (bit0) {
const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME;
aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd));
} else {
const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
mbmi->ref_frame[0] == GOLDEN_FRAME);
aom_write(w, bit2, av1_get_pred_prob_single_ref_p3(cm, xd));
if (!bit2) {
const int bit3 = mbmi->ref_frame[0] != LAST_FRAME;
aom_write(w, bit3, av1_get_pred_prob_single_ref_p4(cm, xd));
} else {
const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME;
aom_write(w, bit4, av1_get_pred_prob_single_ref_p5(cm, xd));
}
}
#else
const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd));
if (bit0) {
const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd));
}
#endif // CONFIG_EXT_REFS
}
}
}
......@@ -1539,10 +1577,7 @@ static size_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
FRAME_CONTEXT *const fc = cm->fc;
FRAME_COUNTS *counts = cpi->td.counts;
aom_writer header_bc;
int i;
#if CONFIG_MISC_FIXES
int j;
#endif
int i, j;
aom_start_encode(&header_bc, data);
......@@ -1620,19 +1655,27 @@ static size_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
#endif
}
if (cm->reference_mode != COMPOUND_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
av1_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
counts->single_ref[i][0]);
av1_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
counts->single_ref[i][1]);
}
}
if (cm->reference_mode != COMPOUND_REFERENCE)
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (SINGLE_REFS - 1); j++)
av1_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][j],
counts->single_ref[i][j]);
if (cm->reference_mode != SINGLE_REFERENCE)
#if CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++) {
for (j = 0; j < (FWD_REFS - 1); j++)
av1_cond_prob_diff_update(&header_bc, &fc->comp_fwdref_prob[i][j],
counts->comp_fwdref[i][j]);
for (j = 0; j < (BWD_REFS - 1); j++)
av1_cond_prob_diff_update(&header_bc, &fc->comp_bwdref_prob[i][j],
counts->comp_bwdref[i][j]);
}
#else
for (i = 0; i < REF_CONTEXTS; i++)
av1_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
counts->comp_ref[i]);
#endif // CONFIG_EXT_REFS
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
prob_diff_update(av1_intra_mode_tree, cm->fc->y_mode_prob[i],
......
......@@ -1221,19 +1221,59 @@ static void update_stats(AV1_COMMON *cm, ThreadData *td) {
// the reference frame counts used to work out probabilities.
if (inter_block) {
const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
#if CONFIG_EXT_REFS
const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
#endif // CONFIG_EXT_REFS
if (cm->reference_mode == REFERENCE_MODE_SELECT)
counts->comp_inter[av1_get_reference_mode_context(
cm, xd)][has_second_ref(mbmi)]++;
if (has_second_ref(mbmi)) {
#if CONFIG_EXT_REFS
const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
counts->comp_fwdref[av1_get_pred_context_comp_fwdref_p(cm,
xd)][0][bit]++;
if (!bit)
counts->comp_fwdref[av1_get_pred_context_comp_fwdref_p1(
cm, xd)][1][ref0 == LAST_FRAME]++;
else
counts->comp_fwdref[av1_get_pred_context_comp_fwdref_p2(
cm, xd)][2][ref0 == GOLDEN_FRAME]++;
counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(
cm, xd)][0][ref1 == ALTREF_FRAME]++;
#else
counts->comp_ref[av1_get_pred_context_comp_ref_p(
cm, xd)][ref0 == GOLDEN_FRAME]++;
#endif // CONFIG_EXT_REFS
} else {
#if CONFIG_EXT_REFS
const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
if (bit) {
counts->single_ref[av1_get_pred_context_single_ref_p2(