Commit 5805a14c authored by Zoe Liu's avatar Zoe Liu

Merge bi-predictive frames to EXT_REFS

This patch removed the experiment of BIDIR_PRED and merged the feature
into the experiment of EXT_REFS:

(1) Each frame now has up to 6 reference frames, namely
    LAST_FRAME, LAST2_FRAME, LAST3_FRAME, GOLDEN_FRAME, (forward) and
    BWDREF_FRAME, ALTREF_FRAME (backward);
    LAST4_FRAME has been removed;
(2) First pass still keeps the 8 updates:
    KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, and
    BRF_UPDATE, LAST_BIPRED_UPDATE, BI_PRED_UPDATE;
(3) show_existing_frame==1 is supported in the experiment of EXT_REFS;
(4) New encoding modes are added for both single-ref and compound cases,
    through the use of the 2 extra forward references (LAST2 & LAST3)
    and the 1 extra backward reference (BWDREF).

RD performance wise, using Overall PSNR: Avg/BDRate
        Bipred only      Prev EXT_REFS    Current EXT_REFS with bipred
lowres: -3.474/-3.324    -1.748/-1.586    -4.613/-4.387
derflr: -2.097/-1.353    -1.439/-1.215    -3.120/-2.252
midres: -2.129/-1.901    -1.345/-1.185    -2.898/-2.636

If in vp10/encoder/firstpass.h, change BFG_INTERVAL from 2 to 3, i.e. to
use 2 bi-predictive frames than 1, a further improvement may be
obtained:
                 Current EXT_REFS with bipred
        1 bi-predictive frame    2 bi-predictive frames
lowres: -4.613/-4.387            -4.675/-4.465
derflr: -3.120/-2.252            -3.333/-2.516
midres: -2.898/-2.636            -3.406/-3.095

Change-Id: Ib06fe9ea0a5cfd7418a1d79b978ee9d80bf191cb
parent 019dbb4c
...@@ -102,29 +102,18 @@ typedef struct { ...@@ -102,29 +102,18 @@ typedef struct {
#define LAST2_FRAME 2 #define LAST2_FRAME 2
#define LAST3_FRAME 3 #define LAST3_FRAME 3
#define LAST4_FRAME 4 #define GOLDEN_FRAME 4
#define GOLDEN_FRAME 5 #define BWDREF_FRAME 5
#define ALTREF_FRAME 6 #define ALTREF_FRAME 6
#define MAX_REF_FRAMES 7 #define MAX_REF_FRAMES 7
#define LAST_REF_FRAMES (LAST4_FRAME - LAST_FRAME + 1) #define LAST_REF_FRAMES (LAST3_FRAME - LAST_FRAME + 1)
#else // CONFIG_EXT_REFS #else
#if CONFIG_BIDIR_PRED
#define GOLDEN_FRAME 2
#define BWDREF_FRAME 3
#define ALTREF_FRAME 4
#define MAX_REF_FRAMES 5
#else // CONFIG_BIDIR_PRED
#define GOLDEN_FRAME 2 #define GOLDEN_FRAME 2
#define ALTREF_FRAME 3 #define ALTREF_FRAME 3
#define MAX_REF_FRAMES 4 #define MAX_REF_FRAMES 4
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
typedef int8_t MV_REFERENCE_FRAME; typedef int8_t MV_REFERENCE_FRAME;
......
...@@ -428,32 +428,21 @@ static const vpx_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = { ...@@ -428,32 +428,21 @@ static const vpx_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
static const vpx_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = {
// TODO(zoeliu): To adjust the initial prob values.
{ 33, 16, 16, 16 },
{ 77, 74, 74, 74 },
{ 142, 142, 142, 142 },
{ 172, 170, 170, 170 },
{ 238, 247, 247, 247 }
};
#else // CONFIG_EXT_REFS
#if CONFIG_BIDIR_PRED
// TODO(zoeliu): To adjust the initial prob values.
static const vpx_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1] = { static const vpx_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1] = {
// { 50 }, { 126 }, { 123 }, { 221 }, { 226 } // TODO(zoeliu): To adjust the initial prob values.
{ 33 }, { 77 }, { 142 }, { 172 }, { 238 } { 33, 16, 16 },
{ 77, 74, 74 },
{ 142, 142, 142 },
{ 172, 170, 170 },
{ 238, 247, 247 }
}; };
static const vpx_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = { static const vpx_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = {
{ 16 }, { 74 }, { 142 }, { 170 }, { 247 } { 16 }, { 74 }, { 142 }, { 170 }, { 247 }
}; };
#else // CONFIG_BIDIR_PRED #else
static const vpx_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = { static const vpx_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = {
{ 50 }, { 126 }, { 123 }, { 221 }, { 226 } { 50 }, { 126 }, { 123 }, { 221 }, { 226 }
}; };
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
static const vpx_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = { static const vpx_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
...@@ -463,20 +452,12 @@ static const vpx_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = { ...@@ -463,20 +452,12 @@ static const vpx_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
{ 142, 142, 142, 142, 142 }, { 142, 142, 142, 142, 142 },
{ 172, 170, 170, 170, 170 }, { 172, 170, 170, 170, 170 },
{ 238, 247, 247, 247, 247 } { 238, 247, 247, 247, 247 }
#else // CONFIG_EXT_REFS #else
#if CONFIG_BIDIR_PRED
{ 33, 16, 16 },
{ 77, 74, 74 },
{ 142, 142, 142 },
{ 172, 170, 170 },
{ 238, 247, 247 }
#else // CONFIG_BIDIR_PRED
{ 33, 16 }, { 33, 16 },
{ 77, 74 }, { 77, 74 },
{ 142, 142 }, { 142, 142 },
{ 172, 170 }, { 172, 170 },
{ 238, 247 } { 238, 247 }
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
}; };
...@@ -1311,9 +1292,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -1311,9 +1292,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
vp10_copy(fc->intra_inter_prob, default_intra_inter_p); vp10_copy(fc->intra_inter_prob, default_intra_inter_p);
vp10_copy(fc->comp_inter_prob, default_comp_inter_p); vp10_copy(fc->comp_inter_prob, default_comp_inter_p);
vp10_copy(fc->comp_ref_prob, default_comp_ref_p); vp10_copy(fc->comp_ref_prob, default_comp_ref_p);
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
vp10_copy(fc->comp_bwdref_prob, default_comp_bwdref_p); vp10_copy(fc->comp_bwdref_prob, default_comp_bwdref_p);
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
vp10_copy(fc->single_ref_prob, default_single_ref_p); vp10_copy(fc->single_ref_prob, default_single_ref_p);
vp10_copy(fc->tx_size_probs, default_tx_size_prob); vp10_copy(fc->tx_size_probs, default_tx_size_prob);
#if CONFIG_VAR_TX #if CONFIG_VAR_TX
...@@ -1382,7 +1363,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { ...@@ -1382,7 +1363,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
fc->comp_inter_prob[i] = vp10_mode_mv_merge_probs( fc->comp_inter_prob[i] = vp10_mode_mv_merge_probs(
pre_fc->comp_inter_prob[i], counts->comp_inter[i]); pre_fc->comp_inter_prob[i], counts->comp_inter[i]);
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++) for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (FWD_REFS - 1); j++) for (j = 0; j < (FWD_REFS - 1); j++)
fc->comp_ref_prob[i][j] = mode_mv_merge_probs( fc->comp_ref_prob[i][j] = mode_mv_merge_probs(
...@@ -1396,7 +1377,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { ...@@ -1396,7 +1377,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
for (j = 0; j < (COMP_REFS - 1); j++) for (j = 0; j < (COMP_REFS - 1); j++)
fc->comp_ref_prob[i][j] = mode_mv_merge_probs( fc->comp_ref_prob[i][j] = mode_mv_merge_probs(
pre_fc->comp_ref_prob[i][j], counts->comp_ref[i][j]); pre_fc->comp_ref_prob[i][j], counts->comp_ref[i][j]);
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
for (i = 0; i < REF_CONTEXTS; i++) for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (SINGLE_REFS - 1); j++) for (j = 0; j < (SINGLE_REFS - 1); j++)
...@@ -1599,7 +1580,7 @@ static void set_default_lf_deltas(struct loopfilter *lf) { ...@@ -1599,7 +1580,7 @@ static void set_default_lf_deltas(struct loopfilter *lf) {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
lf->ref_deltas[LAST2_FRAME] = lf->ref_deltas[LAST_FRAME]; lf->ref_deltas[LAST2_FRAME] = lf->ref_deltas[LAST_FRAME];
lf->ref_deltas[LAST3_FRAME] = lf->ref_deltas[LAST_FRAME]; lf->ref_deltas[LAST3_FRAME] = lf->ref_deltas[LAST_FRAME];
lf->ref_deltas[LAST4_FRAME] = lf->ref_deltas[LAST_FRAME]; lf->ref_deltas[BWDREF_FRAME] = lf->ref_deltas[LAST_FRAME];
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
lf->ref_deltas[GOLDEN_FRAME] = -1; lf->ref_deltas[GOLDEN_FRAME] = -1;
lf->ref_deltas[ALTREF_FRAME] = -1; lf->ref_deltas[ALTREF_FRAME] = -1;
......
...@@ -85,12 +85,12 @@ typedef struct frame_contexts { ...@@ -85,12 +85,12 @@ typedef struct frame_contexts {
vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS]; vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS]; vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1]; vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
vpx_prob comp_ref_prob[REF_CONTEXTS][FWD_REFS-1]; vpx_prob comp_ref_prob[REF_CONTEXTS][FWD_REFS-1];
vpx_prob comp_bwdref_prob[REF_CONTEXTS][BWD_REFS-1]; vpx_prob comp_bwdref_prob[REF_CONTEXTS][BWD_REFS-1];
#else #else
vpx_prob comp_ref_prob[REF_CONTEXTS][COMP_REFS-1]; vpx_prob comp_ref_prob[REF_CONTEXTS][COMP_REFS-1];
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
vpx_prob tx_size_probs[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES - 1]; vpx_prob tx_size_probs[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES - 1];
#if CONFIG_VAR_TX #if CONFIG_VAR_TX
vpx_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS]; vpx_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
...@@ -160,12 +160,12 @@ typedef struct FRAME_COUNTS { ...@@ -160,12 +160,12 @@ typedef struct FRAME_COUNTS {
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2]; unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2]; unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2]; unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
unsigned int comp_ref[REF_CONTEXTS][FWD_REFS-1][2]; unsigned int comp_ref[REF_CONTEXTS][FWD_REFS-1][2];
unsigned int comp_bwdref[REF_CONTEXTS][BWD_REFS-1][2]; unsigned int comp_bwdref[REF_CONTEXTS][BWD_REFS-1][2];
#else #else
unsigned int comp_ref[REF_CONTEXTS][COMP_REFS-1][2]; unsigned int comp_ref[REF_CONTEXTS][COMP_REFS-1][2];
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
unsigned int tx_size_totals[TX_SIZES]; unsigned int tx_size_totals[TX_SIZES];
unsigned int tx_size[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES]; unsigned int tx_size[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES];
#if CONFIG_VAR_TX #if CONFIG_VAR_TX
......
...@@ -204,21 +204,14 @@ typedef enum { ...@@ -204,21 +204,14 @@ typedef enum {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
VP9_LAST2_FLAG = 1 << 1, VP9_LAST2_FLAG = 1 << 1,
VP9_LAST3_FLAG = 1 << 2, VP9_LAST3_FLAG = 1 << 2,
VP9_LAST4_FLAG = 1 << 3, VP9_GOLD_FLAG = 1 << 3,
VP9_GOLD_FLAG = 1 << 4, VP9_BWD_FLAG = 1 << 4,
VP9_ALT_FLAG = 1 << 5, VP9_ALT_FLAG = 1 << 5,
VP9_REFFRAME_ALL = (1 << 6) - 1 VP9_REFFRAME_ALL = (1 << 6) - 1
#else // CONFIG_EXT_REFS #else
#if CONFIG_BIDIR_PRED
VP9_GOLD_FLAG = 1 << 1,
VP9_BWD_FLAG = 1 << 2,
VP9_ALT_FLAG = 1 << 3,
VP9_REFFRAME_ALL = (1 << 4) - 1
#else // CONFIG_BIDIR_PRED
VP9_GOLD_FLAG = 1 << 1, VP9_GOLD_FLAG = 1 << 1,
VP9_ALT_FLAG = 1 << 2, VP9_ALT_FLAG = 1 << 2,
VP9_REFFRAME_ALL = (1 << 3) - 1 VP9_REFFRAME_ALL = (1 << 3) - 1
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
} VP9_REFFRAME; } VP9_REFFRAME;
...@@ -389,24 +382,14 @@ typedef TX_SIZE TXFM_CONTEXT; ...@@ -389,24 +382,14 @@ typedef TX_SIZE TXFM_CONTEXT;
#endif #endif
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
#define FWD_REFS 4
#define SINGLE_REFS 6
#define COMP_REFS 5
#else // CONFIG_EXT_REFS
#if CONFIG_BIDIR_PRED
#define FWD_REFS 2
#define BWD_REFS 2 #define BWD_REFS 2
#define SINGLE_REFS (FWD_REFS + BWD_REFS) #define SINGLE_REFS (FWD_REFS + BWD_REFS)
#define COMP_REFS (FWD_REFS * BWD_REFS) // NOTE(zoeliu): Following parameter is currently not being used
// #define COMP_REFS (FWD_REFS * BWD_REFS)
#else // CONFIG_BIDIR_PRED #else
#define SINGLE_REFS 3 #define SINGLE_REFS 3
#define COMP_REFS 2 #define COMP_REFS 2
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
#if CONFIG_SUPERTX #if CONFIG_SUPERTX
......
...@@ -44,8 +44,8 @@ struct loopfilter { ...@@ -44,8 +44,8 @@ struct loopfilter {
uint8_t mode_ref_delta_enabled; uint8_t mode_ref_delta_enabled;
uint8_t mode_ref_delta_update; uint8_t mode_ref_delta_update;
// 0 = Intra, Last, Last2+Last3+LAST4(CONFIG_EXT_REFS), // 0 = Intra, Last, Last2+Last3(CONFIG_EXT_REFS),
// GF, BRF(CONFIG_BIDIR_PRED), ARF // GF, BRF(CONFIG_EXT_REFS), ARF
signed char ref_deltas[MAX_REF_FRAMES]; signed char ref_deltas[MAX_REF_FRAMES];
signed char last_ref_deltas[MAX_REF_FRAMES]; signed char last_ref_deltas[MAX_REF_FRAMES];
......
...@@ -178,6 +178,7 @@ typedef struct VP10Common { ...@@ -178,6 +178,7 @@ typedef struct VP10Common {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
// frame type of the frame before last frame // frame type of the frame before last frame
FRAME_TYPE last2_frame_type; FRAME_TYPE last2_frame_type;
// TODO(zoeliu): To check whether last3_frame_type is still needed.
// frame type of the frame two frames before last frame // frame type of the frame two frames before last frame
FRAME_TYPE last3_frame_type; FRAME_TYPE last3_frame_type;
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
...@@ -186,10 +187,10 @@ typedef struct VP10Common { ...@@ -186,10 +187,10 @@ typedef struct VP10Common {
int show_frame; int show_frame;
int last_show_frame; int last_show_frame;
int show_existing_frame; int show_existing_frame;
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
// Flag for a frame used as a reference - not written to the bitstream // Flag for a frame used as a reference - not written to the bitstream
int is_reference_frame; int is_reference_frame;
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
// Flag signaling that the frame is encoded using only INTRA modes. // Flag signaling that the frame is encoded using only INTRA modes.
uint8_t intra_only; uint8_t intra_only;
...@@ -278,13 +279,13 @@ typedef struct VP10Common { ...@@ -278,13 +279,13 @@ typedef struct VP10Common {
int frame_parallel_decode; // frame-based threading. int frame_parallel_decode; // frame-based threading.
// Context probabilities for reference frame prediction // Context probabilities for reference frame prediction
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS]; MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS];
MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS]; MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS];
#else #else
MV_REFERENCE_FRAME comp_fixed_ref; MV_REFERENCE_FRAME comp_fixed_ref;
MV_REFERENCE_FRAME comp_var_ref[COMP_REFS]; MV_REFERENCE_FRAME comp_var_ref[COMP_REFS];
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
REFERENCE_MODE reference_mode; REFERENCE_MODE reference_mode;
FRAME_CONTEXT *fc; /* this frame entropy */ FRAME_CONTEXT *fc; /* this frame entropy */
......
This diff is collapsed.
...@@ -119,18 +119,6 @@ static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p2(const VP10_COMMON *cm, ...@@ -119,18 +119,6 @@ static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p2(const VP10_COMMON *cm,
return cm->fc->comp_ref_prob[pred_context][2]; return cm->fc->comp_ref_prob[pred_context][2];
} }
int vp10_get_pred_context_comp_ref_p3(const VP10_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p3(const VP10_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = vp10_get_pred_context_comp_ref_p3(cm, xd);
return cm->fc->comp_ref_prob[pred_context][3];
}
#else // CONFIG_EXT_REFS
#if CONFIG_BIDIR_PRED
int vp10_get_pred_context_comp_bwdref_p(const VP10_COMMON *cm, int vp10_get_pred_context_comp_bwdref_p(const VP10_COMMON *cm,
const MACROBLOCKD *xd); const MACROBLOCKD *xd);
...@@ -139,7 +127,6 @@ static INLINE vpx_prob vp10_get_pred_prob_comp_bwdref_p(const VP10_COMMON *cm, ...@@ -139,7 +127,6 @@ static INLINE vpx_prob vp10_get_pred_prob_comp_bwdref_p(const VP10_COMMON *cm,
const int pred_context = vp10_get_pred_context_comp_bwdref_p(cm, xd); const int pred_context = vp10_get_pred_context_comp_bwdref_p(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][0]; return cm->fc->comp_bwdref_prob[pred_context][0];
} }
#endif // CONFIG_BIDIR_PRED
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
...@@ -157,16 +144,14 @@ static INLINE vpx_prob vp10_get_pred_prob_single_ref_p2(const VP10_COMMON *cm, ...@@ -157,16 +144,14 @@ static INLINE vpx_prob vp10_get_pred_prob_single_ref_p2(const VP10_COMMON *cm,
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p2(xd)][1]; return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p2(xd)][1];
} }
#if CONFIG_EXT_REFS || CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
int vp10_get_pred_context_single_ref_p3(const MACROBLOCKD *xd); int vp10_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p3(const VP10_COMMON *cm, static INLINE vpx_prob vp10_get_pred_prob_single_ref_p3(const VP10_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p3(xd)][2]; return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p3(xd)][2];
} }
#endif // CONFIG_EXT_REFS || CONFIR_BIDIR_PRED
#if CONFIG_EXT_REFS
int vp10_get_pred_context_single_ref_p4(const MACROBLOCKD *xd); int vp10_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p4(const VP10_COMMON *cm, static INLINE vpx_prob vp10_get_pred_prob_single_ref_p4(const VP10_COMMON *cm,
......
...@@ -57,43 +57,31 @@ static int is_compound_reference_allowed(const VP10_COMMON *cm) { ...@@ -57,43 +57,31 @@ static int is_compound_reference_allowed(const VP10_COMMON *cm) {
} }
static void setup_compound_reference_mode(VP10_COMMON *cm) { static void setup_compound_reference_mode(VP10_COMMON *cm) {
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
cm->comp_fwd_ref[0] = LAST_FRAME; cm->comp_fwd_ref[0] = LAST_FRAME;
cm->comp_fwd_ref[1] = GOLDEN_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[0] = BWDREF_FRAME;
cm->comp_bwd_ref[1] = ALTREF_FRAME; cm->comp_bwd_ref[1] = ALTREF_FRAME;
#else
#else // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED
if (cm->ref_frame_sign_bias[LAST_FRAME] == if (cm->ref_frame_sign_bias[LAST_FRAME] ==
cm->ref_frame_sign_bias[GOLDEN_FRAME]) { cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
cm->comp_fixed_ref = ALTREF_FRAME; cm->comp_fixed_ref = ALTREF_FRAME;
cm->comp_var_ref[0] = LAST_FRAME; cm->comp_var_ref[0] = LAST_FRAME;
#if CONFIG_EXT_REFS
cm->comp_var_ref[1] = LAST2_FRAME;
cm->comp_var_ref[2] = LAST3_FRAME;
cm->comp_var_ref[3] = LAST4_FRAME;
cm->comp_var_ref[4] = GOLDEN_FRAME;
#else // CONFIG_EXT_REFS
cm->comp_var_ref[1] = GOLDEN_FRAME; cm->comp_var_ref[1] = GOLDEN_FRAME;
#endif // CONFIG_EXT_REFS
} else if (cm->ref_frame_sign_bias[LAST_FRAME] == } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
cm->ref_frame_sign_bias[ALTREF_FRAME]) { cm->ref_frame_sign_bias[ALTREF_FRAME]) {
#if CONFIG_EXT_REFS
assert(0);
#endif // CONFIG_EXT_REFS
cm->comp_fixed_ref = GOLDEN_FRAME; cm->comp_fixed_ref = GOLDEN_FRAME;
cm->comp_var_ref[0] = LAST_FRAME; cm->comp_var_ref[0] = LAST_FRAME;
cm->comp_var_ref[1] = ALTREF_FRAME; cm->comp_var_ref[1] = ALTREF_FRAME;
} else { } else {
#if CONFIG_EXT_REFS
assert(0);
#endif // CONFIG_EXT_REFS
cm->comp_fixed_ref = LAST_FRAME; cm->comp_fixed_ref = LAST_FRAME;
cm->comp_var_ref[0] = GOLDEN_FRAME; cm->comp_var_ref[0] = GOLDEN_FRAME;
cm->comp_var_ref[1] = ALTREF_FRAME; cm->comp_var_ref[1] = ALTREF_FRAME;
} }
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
} }
static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) { static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
...@@ -180,7 +168,7 @@ static void read_frame_reference_mode_probs(VP10_COMMON *cm, vp10_reader *r) { ...@@ -180,7 +168,7 @@ static void read_frame_reference_mode_probs(VP10_COMMON *cm, vp10_reader *r) {
if (cm->reference_mode != SINGLE_REFERENCE) { if (cm->reference_mode != SINGLE_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; ++i) { for (i = 0; i < REF_CONTEXTS; ++i) {
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
for (j = 0; j < (FWD_REFS - 1); ++j) for (j = 0; j < (FWD_REFS - 1); ++j)
vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]); vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
for (j = 0; j < (BWD_REFS - 1); ++j) for (j = 0; j < (BWD_REFS - 1); ++j)
...@@ -188,7 +176,7 @@ static void read_frame_reference_mode_probs(VP10_COMMON *cm, vp10_reader *r) { ...@@ -188,7 +176,7 @@ static void read_frame_reference_mode_probs(VP10_COMMON *cm, vp10_reader *r) {
#else #else
for (j = 0; j < (COMP_REFS - 1); ++j) for (j = 0; j < (COMP_REFS - 1); ++j)
vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]); vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
} }
} }
} }
...@@ -3128,10 +3116,10 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, ...@@ -3128,10 +3116,10 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
cm->last_frame_type = cm->frame_type; cm->last_frame_type = cm->frame_type;
cm->last_intra_only = cm->intra_only; cm->last_intra_only = cm->intra_only;
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
// NOTE: By default all coded frames to be used as a reference // NOTE: By default all coded frames to be used as a reference
cm->is_reference_frame = 1; cm->is_reference_frame = 1;
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
if (vpx_rb_read_literal(rb, 2) != VP9_FRAME_MARKER) if (vpx_rb_read_literal(rb, 2) != VP9_FRAME_MARKER)
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
...@@ -3167,7 +3155,7 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, ...@@ -3167,7 +3155,7 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
cm->lf.filter_level = 0; cm->lf.filter_level = 0;
cm->show_frame = 1; cm->show_frame = 1;
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
// NOTE(zoeliu): The existing frame to show is adopted as a reference frame. // NOTE(zoeliu): The existing frame to show is adopted as a reference frame.
pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES); pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES);
...@@ -3225,7 +3213,7 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, ...@@ -3225,7 +3213,7 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
for (i = 0; i < REF_FRAMES; ++i) for (i = 0; i < REF_FRAMES; ++i)
cm->next_ref_frame_map[i] = cm->ref_frame_map[i]; cm->next_ref_frame_map[i] = cm->ref_frame_map[i];
} }
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
return 0; return 0;
} }
...@@ -3291,13 +3279,13 @@ static size_t read_uncompressed_header(VP10Decoder *pbi, ...@@ -3291,13 +3279,13 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
} else if (pbi->need_resync != 1) { /* Skip if need resync */ } else if (pbi->need_resync != 1) { /* Skip if need resync */
pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES); pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES);
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
if (!pbi->refresh_frame_flags) { if (!pbi->refresh_frame_flags) {
// NOTE: "pbi->refresh_frame_flags == 0" indicates that the coded frame // NOTE: "pbi->refresh_frame_flags == 0" indicates that the coded frame
// will not be used as a reference // will not be used as a reference
cm->is_reference_frame = 0; cm->is_reference_frame = 0;
} }
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
for (i = 0; i < REFS_PER_FRAME; ++i) { for (i = 0; i < REFS_PER_FRAME; ++i) {
const int ref = vpx_rb_read_literal(rb, REF_FRAMES_LOG2); const int ref = vpx_rb_read_literal(rb, REF_FRAMES_LOG2);
...@@ -3692,12 +3680,12 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) { ...@@ -3692,12 +3680,12 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) {
sizeof(cm->counts.single_ref))); sizeof(cm->counts.single_ref)));
assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref, assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref,
sizeof(cm->counts.comp_ref))); sizeof(cm->counts.comp_ref)));
assert(!memcmp(&cm->counts.tx_size, &zero_counts.tx_size, #if CONFIG_EXT_REFS
sizeof(cm->counts.tx_size)));
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED
assert(!memcmp(cm->counts.comp_bwdref, zero_counts.comp_bwdref, assert(!memcmp(cm->counts.comp_bwdref, zero_counts.comp_bwdref,
sizeof(cm->counts.comp_bwdref))); sizeof(cm->counts.comp_bwdref)));
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
assert(!memcmp(&cm->counts.tx_size, &zero_counts.tx_size,
sizeof(cm->counts.tx_size)));
assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip))); assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip)));
#if CONFIG_REF_MV #if CONFIG_REF_MV
assert(!memcmp(&cm->counts.mv[0], &zero_counts.mv[0], assert(!memcmp(&cm->counts.mv[0], &zero_counts.mv[0],
...@@ -3772,11 +3760,11 @@ void vp10_decode_frame(VP10Decoder *pbi, ...@@ -3772,11 +3760,11 @@ void vp10_decode_frame(VP10Decoder *pbi,
if (!first_partition_size) { if (!first_partition_size) {
// showing a frame directly // showing a frame directly
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
if (cm->show_existing_frame) if (cm->show_existing_frame)
*p_data_end = data + vpx_rb_bytes_read(&rb); *p_data_end = data + vpx_rb_bytes_read(&rb);
else else
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
*p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2); *p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2);
return; return;
...@@ -3793,7 +3781,7 @@ void vp10_decode_frame(VP10Decoder *pbi, ...@@ -3793,7 +3781,7 @@ void vp10_decode_frame(VP10Decoder *pbi,
!cm->last_intra_only && !cm->last_intra_only &&
cm->last_show_frame && cm->last_show_frame &&
(cm->last_frame_type != KEY_FRAME); (cm->last_frame_type != KEY_FRAME);
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #if CONFIG_EXT_REFS
// NOTE(zoeliu): As cm->prev_frame can take neither a frame of // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
// show_exisiting_frame=1, nor can it take a frame not used as // show_exisiting_frame=1, nor can it take a frame not used as
// a reference, it is probable that by the time it is being // a reference, it is probable that by the time it is being
...@@ -3809,7 +3797,7 @@ void vp10_decode_frame(VP10Decoder *pbi, ...@@ -3809,7 +3797,7 @@ void vp10_decode_frame(VP10Decoder *pbi,
RefBuffer *last_fb_ref_buf = &cm->frame_refs[LAST_FRAME - LAST_FRAME]; RefBuffer *last_fb_ref_buf = &cm->frame_refs[LAST_FRAME - LAST_FRAME];
cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_ref_buf->idx]; cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_ref_buf->idx];
} }
#endif // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
vp10_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y); vp10_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
......
...@@ -766,68 +766,58 @@ static void read_ref_frames(VP10_COMMON *const cm, MACROBLOCKD *const xd, ...@@ -766,68 +766,58 @@ static void read_ref_frames(VP10_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_EXT_REFS && CONFIG_BIDIR_PRED #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 && CONFIG_BIDIR_PRED #endif // CONFIG_EXT_REFS
const int ctx = vp10_get_pred_context_comp_ref_p(cm, xd); const int ctx = vp10_get_pred_context_comp_ref_p(cm, xd);
const int bit = vp10_read(r, fc->comp_ref_prob[ctx][0]); const int bit = vp10_read(r, fc->comp_ref_prob[ctx][0]);
if (counts) if (counts)
++counts->comp_ref[ctx][0][bit]; ++counts->comp_ref[ctx][0][bit];
#if !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED
ref_frame[!idx] = cm->comp_fwd_ref[bit];
{
const int ctx1 = vp10_get_pred_context_comp_bwdref_p(cm, xd);
const int bit1 = vp10_read(r, fc->comp_bwdref_prob[ctx1][0]);
if (counts)
++counts->comp_bwdref[ctx1][0][bit1];
ref_frame[idx] = cm->comp_bwd_ref[bit1];
}
#else // !CONFIG_EXT_REFS && CONFIG_BIDIR_PRED
ref_frame[idx] = cm->comp_fixed_ref;
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
// Decode forward references.
if (!bit) { if (!bit) {
const int ctx1 = vp10_get_pred_context_comp_ref_p1(cm, xd); const int ctx1 = vp10_get_pred_context_comp_ref_p1(cm, xd);
const int