Commit 38897306 authored by Arild Fuldseth (arilfuld)'s avatar Arild Fuldseth (arilfuld) Committed by Arild Fuldseth
Browse files

Enable low-latency (uni-directional) compound mode (normative)

Change-Id: Ie9cb6bb66c35eecd173532b3111b98a2aaf0d913
parent e508db4e
...@@ -278,19 +278,29 @@ int av1_get_reference_mode_context(const AV1_COMMON *cm, ...@@ -278,19 +278,29 @@ int av1_get_reference_mode_context(const AV1_COMMON *cm,
// //
// NOTE(zoeliu): The probability of ref_frame[0] is either // NOTE(zoeliu): The probability of ref_frame[0] is either
// GOLDEN_FRAME or LAST3_FRAME. // GOLDEN_FRAME or LAST3_FRAME.
#if CONFIG_LOWDELAY_COMPOUND
int av1_get_pred_context_comp_ref_p(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm, int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
#endif
int pred_context; int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available; const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available; const int left_in_image = xd->left_available;
// Note: // Note:
// The mode info data structure has a one element border above and to the // The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks. // left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0. // The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_LOWDELAY_COMPOUND // No change to bitstream
// 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]]; const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
const int fwd_ref_sign_idx = !bwd_ref_sign_idx; const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
if (above_in_image && left_in_image) { // both edges available if (above_in_image && left_in_image) { // both edges available
...@@ -378,19 +388,29 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm, ...@@ -378,19 +388,29 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
// //
// NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME, // NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME,
// conditioning on it is either LAST_FRAME or LAST2_FRAME. // conditioning on it is either LAST_FRAME or LAST2_FRAME.
#if CONFIG_LOWDELAY_COMPOUND
int av1_get_pred_context_comp_ref_p1(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm, int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
#endif
int pred_context; int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available; const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available; const int left_in_image = xd->left_available;
// Note: // Note:
// The mode info data structure has a one element border above and to the // The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks. // left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0. // The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_LOWDELAY_COMPOUND // No change to bitstream
// 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]]; const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
const int fwd_ref_sign_idx = !bwd_ref_sign_idx; const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
if (above_in_image && left_in_image) { // both edges available if (above_in_image && left_in_image) { // both edges available
...@@ -479,19 +499,29 @@ int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm, ...@@ -479,19 +499,29 @@ int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
// //
// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME, // NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME,
// conditioning on it is either GOLDEN or LAST3. // conditioning on it is either GOLDEN or LAST3.
#if CONFIG_LOWDELAY_COMPOUND
int av1_get_pred_context_comp_ref_p2(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm, int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
#endif
int pred_context; int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available; const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available; const int left_in_image = xd->left_available;
// Note: // Note:
// The mode info data structure has a one element border above and to the // The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks. // left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0. // The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_LOWDELAY_COMPOUND // No change to bitstream
// 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]]; const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
const int fwd_ref_sign_idx = !bwd_ref_sign_idx; const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
if (above_in_image && left_in_image) { // both edges available if (above_in_image && left_in_image) { // both edges available
...@@ -574,19 +604,29 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm, ...@@ -574,19 +604,29 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
} }
// Returns a context number for the given MB prediction signal // Returns a context number for the given MB prediction signal
#if CONFIG_LOWDELAY_COMPOUND
int av1_get_pred_context_comp_bwdref_p(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm, int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
#endif
int pred_context; int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available; const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available; const int left_in_image = xd->left_available;
// Note: // Note:
// The mode info data structure has a one element border above and to the // The mode info data structure has a one element border above and to the
// left of the entries corresponding to real macroblocks. // left of the entries corresponding to real macroblocks.
// The prediction flags in these dummy entries are initialized to 0. // The prediction flags in these dummy entries are initialized to 0.
#if CONFIG_LOWDELAY_COMPOUND // No change to bitstream
// 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]]; const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
const int fwd_ref_sign_idx = !bwd_ref_sign_idx; const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
if (above_in_image && left_in_image) { // both edges available if (above_in_image && left_in_image) { // both edges available
......
...@@ -92,12 +92,16 @@ static size_t read_uncompressed_header(AV1Decoder *pbi, ...@@ -92,12 +92,16 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
struct aom_read_bit_buffer *rb); struct aom_read_bit_buffer *rb);
static int is_compound_reference_allowed(const AV1_COMMON *cm) { static int is_compound_reference_allowed(const AV1_COMMON *cm) {
#if CONFIG_LOWDELAY_COMPOUND // Normative in decoder
return !frame_is_intra_only(cm);
#else
int i; int i;
if (frame_is_intra_only(cm)) return 0; if (frame_is_intra_only(cm)) return 0;
for (i = 1; i < INTER_REFS_PER_FRAME; ++i) for (i = 1; i < INTER_REFS_PER_FRAME; ++i)
if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1; if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
return 0; return 0;
#endif
} }
static void setup_compound_reference_mode(AV1_COMMON *cm) { static void setup_compound_reference_mode(AV1_COMMON *cm) {
......
...@@ -1238,11 +1238,15 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd, ...@@ -1238,11 +1238,15 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r); const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r);
// FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
if (mode == COMPOUND_REFERENCE) { if (mode == COMPOUND_REFERENCE) {
#if CONFIG_LOWDELAY_COMPOUND // Normative in decoder (for low delay)
const int idx = 1;
#else
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]]; const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#else #else
const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
#endif
const int ctx = av1_get_pred_context_comp_ref_p(cm, xd); const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
const int bit = aom_read(r, fc->comp_ref_prob[ctx][0], ACCT_STR); const int bit = aom_read(r, fc->comp_ref_prob[ctx][0], ACCT_STR);
......
...@@ -5428,6 +5428,21 @@ void av1_encode_frame(AV1_COMP *cpi) { ...@@ -5428,6 +5428,21 @@ void av1_encode_frame(AV1_COMP *cpi) {
// side behavior is where the ALT ref buffer has opposite sign bias to // side behavior is where the ALT ref buffer has opposite sign bias to
// the other two. // the other two.
if (!frame_is_intra_only(cm)) { if (!frame_is_intra_only(cm)) {
#if CONFIG_LOWDELAY_COMPOUND // Normative in encoder
cpi->allow_comp_inter_inter = 1;
#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
cm->comp_fixed_ref = ALTREF_FRAME;
cm->comp_var_ref[0] = LAST_FRAME;
cm->comp_var_ref[1] = GOLDEN_FRAME;
#endif // CONFIG_EXT_REFS
#else
if ((cm->ref_frame_sign_bias[ALTREF_FRAME] == if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
cm->ref_frame_sign_bias[GOLDEN_FRAME]) || cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
(cm->ref_frame_sign_bias[ALTREF_FRAME] == (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
...@@ -5449,6 +5464,7 @@ void av1_encode_frame(AV1_COMP *cpi) { ...@@ -5449,6 +5464,7 @@ void av1_encode_frame(AV1_COMP *cpi) {
cm->comp_var_ref[1] = GOLDEN_FRAME; cm->comp_var_ref[1] = GOLDEN_FRAME;
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
} }
#endif
} else { } else {
cpi->allow_comp_inter_inter = 0; cpi->allow_comp_inter_inter = 0;
} }
......
...@@ -323,6 +323,7 @@ EXPERIMENT_LIST=" ...@@ -323,6 +323,7 @@ EXPERIMENT_LIST="
new_multisymbol new_multisymbol
compound_singleref compound_singleref
aom_qm aom_qm
lowdelay_compound
" "
CONFIG_LIST=" CONFIG_LIST="
dependency_tracking dependency_tracking
......
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