Commit fcf5fa27 authored by Zoe Liu's avatar Zoe Liu

Further work on ext-comp-refs for ref frame coding

(1) Work with var-refs to remove redundant bits in ref frame
    coding;
(2) Add a new uni-directional compound reference pair:
    (LAST_FRAME, LAST3_FRAME);
(3) Redesign the contexts for encoding uni-directional reference frame
    pairs;
(4) Use aom_entropy_optimizer to collect stats for all the default
    probability setups related to the coding of reference frames.

Compared against the baseline (default enabled tools excluding ext-tx
and global-motion for encoder speed concern) with one-sided-compound,
the coding gain of ext-comp-refs + var-refs - one-sided-compound is:

lowres: avg_psnr -0.385%; ovr_psnr -0.378% ssim -0.344%
midres: avg_psnr -0.466%; ovr_psnr -0.447% ssim -0.513%

AWCY - High Latency:
   PSNR | PSNR Cb | PSNR Cr | PSNR HVS |    SSIM | MS SSIM | CIEDE 2000
-0.2758 | -0.1526 | -0.0965 |  -0.2581 | -0.2492 | -0.2534 |    -0.2118

AWCY - Low Latency:
   PSNR | PSNR Cb | PSNR Cr | PSNR HVS |    SSIM | MS SSIM | CIEDE 2000
-1.0467 | -1.4500 | -0.9732 |  -0.9928 | -1.0407 | -1.0180 |    -1.0049

Compared against the baseline (default enabled tools excluding ext-tx
and global-motion for encoder speed concern) without
one-sided-compound, the coding gain of
ext-comp-refs + var-refs - one-sided-compound is:

lowres: avg_psnr -0.875%; ovr_psnr -0.877% ssim -0.895%
midres: avg_psnr -0.824%; ovr_psnr -0.802% ssim -0.843%

Change-Id: I8de774c9a74c20632ea93ccb0c17779fa94431cb
parent 9c52192b
...@@ -518,6 +518,7 @@ static INLINE int has_uni_comp_refs(const MB_MODE_INFO *mbmi) { ...@@ -518,6 +518,7 @@ static INLINE int has_uni_comp_refs(const MB_MODE_INFO *mbmi) {
static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) { static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) {
static const MV_REFERENCE_FRAME lut[] = { static const MV_REFERENCE_FRAME lut[] = {
LAST_FRAME, // LAST_LAST2_FRAMES, LAST_FRAME, // LAST_LAST2_FRAMES,
LAST_FRAME, // LAST_LAST3_FRAMES,
LAST_FRAME, // LAST_GOLDEN_FRAMES, LAST_FRAME, // LAST_GOLDEN_FRAMES,
BWDREF_FRAME, // BWDREF_ALTREF_FRAMES, BWDREF_FRAME, // BWDREF_ALTREF_FRAMES,
}; };
...@@ -528,6 +529,7 @@ static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) { ...@@ -528,6 +529,7 @@ static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) {
static INLINE MV_REFERENCE_FRAME comp_ref1(int ref_idx) { static INLINE MV_REFERENCE_FRAME comp_ref1(int ref_idx) {
static const MV_REFERENCE_FRAME lut[] = { static const MV_REFERENCE_FRAME lut[] = {
LAST2_FRAME, // LAST_LAST2_FRAMES, LAST2_FRAME, // LAST_LAST2_FRAMES,
LAST3_FRAME, // LAST_LAST3_FRAMES,
GOLDEN_FRAME, // LAST_GOLDEN_FRAMES, GOLDEN_FRAME, // LAST_GOLDEN_FRAMES,
ALTREF_FRAME, // BWDREF_ALTREF_FRAMES, ALTREF_FRAME, // BWDREF_ALTREF_FRAMES,
}; };
...@@ -621,8 +623,6 @@ typedef struct RefBuffer { ...@@ -621,8 +623,6 @@ typedef struct RefBuffer {
YV12_BUFFER_CONFIG *buf; YV12_BUFFER_CONFIG *buf;
struct scale_factors sf; struct scale_factors sf;
#if CONFIG_VAR_REFS #if CONFIG_VAR_REFS
// TODO(zoeliu): To evaluate whether "is_valid" is needed or the use of it can
// be simply replaced by checking the "idx".
int is_valid; int is_valid;
#endif // CONFIG_VAR_REFS #endif // CONFIG_VAR_REFS
} RefBuffer; } RefBuffer;
......
...@@ -1040,44 +1040,94 @@ static const aom_cdf_prob ...@@ -1040,44 +1040,94 @@ static const aom_cdf_prob
#endif #endif
static const aom_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = { static const aom_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
216, 170, 131, 92, 42, #if !CONFIG_EXT_COMP_REFS
216, 170, 131, 92, 42
#else // CONFIG_EXT_COMP_REFS
206, 182, 117, 104, 32
#endif // !CONFIG_EXT_COMP_REFS
}; };
#if CONFIG_NEW_MULTISYMBOL #if CONFIG_NEW_MULTISYMBOL
static const aom_cdf_prob default_comp_inter_cdf[COMP_INTER_CONTEXTS][CDF_SIZE( static const aom_cdf_prob
2)] = { { AOM_ICDF(216 * 128), AOM_ICDF(32768), 0 }, default_comp_inter_cdf[COMP_INTER_CONTEXTS][CDF_SIZE(2)] = {
{ AOM_ICDF(170 * 128), AOM_ICDF(32768), 0 }, #if !CONFIG_EXT_COMP_REFS
{ AOM_ICDF(131 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(216 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(92 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(170 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(42 * 128), AOM_ICDF(32768), 0 } }; { AOM_ICDF(131 * 128), AOM_ICDF(32768), 0 },
#endif { AOM_ICDF(92 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(42 * 128), AOM_ICDF(32768), 0 }
#else // CONFIG_EXT_COMP_REFS
{ AOM_ICDF(206 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(182 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(117 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(104 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(32 * 128), AOM_ICDF(32768), 0 }
#endif // !CONFIG_EXT_COMP_REFS
};
#endif // CONFIG_NEW_MULTISYMBOL
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
static const aom_prob default_comp_ref_type_p[COMP_REF_TYPE_CONTEXTS] = { static const aom_prob default_comp_ref_type_p[COMP_REF_TYPE_CONTEXTS] = {
30, 75, 120, 170, 230 8, 20, 78, 91, 194
}; };
static const aom_prob static const aom_prob
default_uni_comp_ref_p[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1] = { default_uni_comp_ref_p[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1] = {
{ 30, 20 }, { 75, 70 }, { 130, 130 }, { 165, 165 }, { 215, 220 } { 88, 30, 28 }, { 218, 97, 105 }, { 254, 180, 196 }
}; };
#if CONFIG_NEW_MULTISYMBOL
static const aom_cdf_prob
default_comp_ref_type_cdf[COMP_REF_TYPE_CONTEXTS][CDF_SIZE(2)] = {
{ AOM_ICDF(8 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(20 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(78 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(91 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(194 * 128), AOM_ICDF(32768), 0 }
};
static const aom_cdf_prob
default_uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]
[CDF_SIZE(2)] = {
{ { AOM_ICDF(88 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(30 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(28 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(218 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(97 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(105 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(254 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(180 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(196 * 128), AOM_ICDF(32768), 0 } }
};
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
static const aom_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1] = { static const aom_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1] = {
// TODO(zoeliu): To adjust the initial prob values. #if !CONFIG_EXT_COMP_REFS
{ 33, 16, 16 }, { 33, 16, 16 },
{ 77, 74, 74 }, { 77, 74, 74 },
{ 142, 142, 142 }, { 142, 142, 142 },
{ 172, 170, 170 }, { 172, 170, 170 },
{ 238, 247, 247 } { 238, 247, 247 }
#else // CONFIG_EXT_COMP_REFS
{ 21, 7, 5 },
{ 68, 20, 16 },
{ 128, 56, 36 },
{ 197, 111, 139 },
{ 238, 131, 136 }
#endif // !CONFIG_EXT_COMP_REFS
}; };
static const aom_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = { static const aom_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = {
#if !CONFIG_EXT_COMP_REFS
{ 16 }, { 74 }, { 142 }, { 170 }, { 247 } { 16 }, { 74 }, { 142 }, { 170 }, { 247 }
#else // CONFIG_EXT_COMP_REFS
{ 7 }, { 56 }, { 29 }, { 230 }, { 220 }
#endif // CONFIG_EXT_COMP_REFS
}; };
#if CONFIG_NEW_MULTISYMBOL #if CONFIG_NEW_MULTISYMBOL
static const aom_cdf_prob static const aom_cdf_prob
default_comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)] = { default_comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)] = {
// TODO(zoeliu): To adjust the initial prob values. #if !CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(33 * 128), AOM_ICDF(32768), 0 }, { { AOM_ICDF(33 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 } }, { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 } },
...@@ -1093,17 +1143,42 @@ static const aom_cdf_prob ...@@ -1093,17 +1143,42 @@ static const aom_cdf_prob
{ { AOM_ICDF(238 * 128), AOM_ICDF(32768), 0 }, { { AOM_ICDF(238 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } } { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } }
#else // CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(21 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(7 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(5 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(68 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(20 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(128 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(56 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(36 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(197 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(111 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(139 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(238 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(131 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(136 * 128), AOM_ICDF(32768), 0 } }
#endif // !CONFIG_EXT_COMP_REFS
}; };
static const aom_cdf_prob static const aom_cdf_prob
default_comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)] = { default_comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)] = {
#if !CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 } }, { { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(74 * 128), AOM_ICDF(32768), 0 } }, { { AOM_ICDF(74 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(142 * 128), AOM_ICDF(32768), 0 } }, { { AOM_ICDF(142 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(170 * 128), AOM_ICDF(32768), 0 } }, { { AOM_ICDF(170 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } } { { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } }
#else // CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(7 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(56 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(29 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(230 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(220 * 128), AOM_ICDF(32768), 0 } }
#endif // !CONFIG_EXT_COMP_REFS
}; };
#endif // CONFIG_NEW_MULTISYMBOL #endif // CONFIG_NEW_MULTISYMBOL
#else #else // !CONFIG_EXT_REFS
static const aom_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = { static const aom_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = {
{ 43 }, { 100 }, { 137 }, { 212 }, { 229 }, { 43 }, { 100 }, { 137 }, { 212 }, { 229 },
}; };
...@@ -1121,19 +1196,29 @@ static const aom_cdf_prob ...@@ -1121,19 +1196,29 @@ static const aom_cdf_prob
static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = { static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
#if !CONFIG_EXT_COMP_REFS
{ 33, 16, 16, 16, 16 }, { 33, 16, 16, 16, 16 },
{ 77, 74, 74, 74, 74 }, { 77, 74, 74, 74, 74 },
{ 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 #else // CONFIG_EXT_COMP_REFS
{ 36, 2, 28, 58, 9 },
{ 64, 22, 60, 122, 40 },
{ 153, 69, 126, 179, 71 },
{ 128, 174, 189, 216, 101 },
{ 233, 252, 228, 246, 200 }
#endif // !CONFIG_EXT_COMP_REFS
#else // !CONFIG_EXT_REFS
{ 31, 25 }, { 72, 80 }, { 147, 148 }, { 197, 191 }, { 235, 247 }, { 31, 25 }, { 72, 80 }, { 147, 148 }, { 197, 191 }, { 235, 247 },
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
}; };
#if CONFIG_NEW_MULTISYMBOL #if CONFIG_NEW_MULTISYMBOL
static const aom_cdf_prob static const aom_cdf_prob
default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1][CDF_SIZE(2)] = { default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1][CDF_SIZE(2)] = {
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
#if !CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(33 * 128), AOM_ICDF(32768), 0 }, { { AOM_ICDF(33 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(16 * 128), AOM_ICDF(32768), 0 },
...@@ -1159,7 +1244,34 @@ static const aom_cdf_prob ...@@ -1159,7 +1244,34 @@ static const aom_cdf_prob
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 }, { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } } { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } }
#else #else // CONFIG_EXT_COMP_REFS
{ { AOM_ICDF(36 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(2 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(28 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(58 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(9 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(64 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(22 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(60 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(122 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(40 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(153 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(69 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(126 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(179 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(71 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(128 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(174 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(189 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(216 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(101 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(233 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(252 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(228 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(246 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(200 * 128), AOM_ICDF(32768), 0 } }
#endif // !CONFIG_EXT_COMP_REFS
#else // CONFIG_EXT_REFS
{ { AOM_ICDF(31 * 128), AOM_ICDF(32768), 0 }, { { AOM_ICDF(31 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(25 * 128), AOM_ICDF(32768), 0 } }, { AOM_ICDF(25 * 128), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(72 * 128), AOM_ICDF(32768), 0 }, { { AOM_ICDF(72 * 128), AOM_ICDF(32768), 0 },
...@@ -1172,7 +1284,7 @@ static const aom_cdf_prob ...@@ -1172,7 +1284,7 @@ static const aom_cdf_prob
{ AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } } { AOM_ICDF(247 * 128), AOM_ICDF(32768), 0 } }
#endif // CONFIG_EXT_REFS #endif // CONFIG_EXT_REFS
}; };
#endif #endif // CONFIG_NEW_MULTISYMBOL
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF #if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// TODO(zoeliu): Default values to be further adjusted based on the collected // TODO(zoeliu): Default values to be further adjusted based on the collected
...@@ -4560,6 +4672,10 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -4560,6 +4672,10 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
av1_copy(fc->comp_ref_type_prob, default_comp_ref_type_p); av1_copy(fc->comp_ref_type_prob, default_comp_ref_type_p);
av1_copy(fc->uni_comp_ref_prob, default_uni_comp_ref_p); av1_copy(fc->uni_comp_ref_prob, default_uni_comp_ref_p);
#if CONFIG_NEW_MULTISYMBOL
av1_copy(fc->comp_ref_type_cdf, default_comp_ref_type_cdf);
av1_copy(fc->uni_comp_ref_cdf, default_uni_comp_ref_cdf);
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
av1_copy(fc->comp_ref_prob, default_comp_ref_p); av1_copy(fc->comp_ref_prob, default_comp_ref_p);
#if CONFIG_NEW_MULTISYMBOL #if CONFIG_NEW_MULTISYMBOL
......
...@@ -248,6 +248,11 @@ typedef struct frame_contexts { ...@@ -248,6 +248,11 @@ typedef struct frame_contexts {
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
aom_prob comp_ref_type_prob[COMP_REF_TYPE_CONTEXTS]; aom_prob comp_ref_type_prob[COMP_REF_TYPE_CONTEXTS];
aom_prob uni_comp_ref_prob[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]; aom_prob uni_comp_ref_prob[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob comp_ref_type_cdf[COMP_REF_TYPE_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]
[CDF_SIZE(2)];
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
aom_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS - 1]; aom_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS - 1];
#if CONFIG_EXT_REFS #if CONFIG_EXT_REFS
......
...@@ -532,7 +532,7 @@ typedef enum { ...@@ -532,7 +532,7 @@ typedef enum {
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
#define COMP_REF_TYPE_CONTEXTS 5 #define COMP_REF_TYPE_CONTEXTS 5
#define UNI_COMP_REF_CONTEXTS 5 #define UNI_COMP_REF_CONTEXTS 3
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF #if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
...@@ -577,6 +577,7 @@ typedef uint8_t TXFM_CONTEXT; ...@@ -577,6 +577,7 @@ typedef uint8_t TXFM_CONTEXT;
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
typedef enum { typedef enum {
LAST_LAST2_FRAMES, // { LAST_FRAME, LAST2_FRAME } LAST_LAST2_FRAMES, // { LAST_FRAME, LAST2_FRAME }
LAST_LAST3_FRAMES, // { LAST_FRAME, LAST3_FRAME }
LAST_GOLDEN_FRAMES, // { LAST_FRAME, GOLDEN_FRAME } LAST_GOLDEN_FRAMES, // { LAST_FRAME, GOLDEN_FRAME }
BWDREF_ALTREF_FRAMES, // { BWDREF_FRAME, ALTREF_FRAME } BWDREF_ALTREF_FRAMES, // { BWDREF_FRAME, ALTREF_FRAME }
UNIDIR_COMP_REFS UNIDIR_COMP_REFS
......
...@@ -289,8 +289,8 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = { ...@@ -289,8 +289,8 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = {
// TODO(zoeliu): Temporarily disable uni-directional comp refs // TODO(zoeliu): Temporarily disable uni-directional comp refs
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
, { LAST_FRAME, LAST2_FRAME }, { LAST_FRAME, GOLDEN_FRAME }, , { LAST_FRAME, LAST2_FRAME }, { LAST_FRAME, LAST3_FRAME },
{ BWDREF_FRAME, ALTREF_FRAME } { LAST_FRAME, GOLDEN_FRAME }, { BWDREF_FRAME, ALTREF_FRAME }
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
#else // !CONFIG_EXT_REFS #else // !CONFIG_EXT_REFS
{ LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME } { LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME }
......
...@@ -522,6 +522,8 @@ static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) { ...@@ -522,6 +522,8 @@ static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) {
#define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm)) #define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm))
#define L_AND_L2(cm) (LAST_IS_VALID(cm) && LAST2_IS_VALID(cm)) #define L_AND_L2(cm) (LAST_IS_VALID(cm) && LAST2_IS_VALID(cm))
#define L_AND_L3(cm) (LAST_IS_VALID(cm) && LAST3_IS_VALID(cm))
#define L_AND_G(cm) (LAST_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
#define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm)) #define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm))
#define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm)) #define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
......
This diff is collapsed.
...@@ -109,32 +109,62 @@ static INLINE aom_cdf_prob *av1_get_reference_mode_cdf(const AV1_COMMON *cm, ...@@ -109,32 +109,62 @@ static INLINE aom_cdf_prob *av1_get_reference_mode_cdf(const AV1_COMMON *cm,
#endif #endif
#if CONFIG_EXT_COMP_REFS #if CONFIG_EXT_COMP_REFS
int av1_get_comp_reference_type_context(const AV1_COMMON *cm, int av1_get_comp_reference_type_context(const MACROBLOCKD *xd);
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_comp_reference_type_prob(const AV1_COMMON *cm, static INLINE aom_prob av1_get_comp_reference_type_prob(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc return cm->fc->comp_ref_type_prob[av1_get_comp_reference_type_context(xd)];
->comp_ref_type_prob[av1_get_comp_reference_type_context(cm, xd)];
} }
int av1_get_pred_context_uni_comp_ref_p(const AV1_COMMON *cm, int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd);
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_uni_comp_ref_p(const AV1_COMMON *cm, static INLINE aom_prob av1_get_pred_prob_uni_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p(cm, xd); const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
return cm->fc->uni_comp_ref_prob[pred_context][0]; return cm->fc->uni_comp_ref_prob[pred_context][0];
} }
int av1_get_pred_context_uni_comp_ref_p1(const AV1_COMMON *cm, int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd);
const MACROBLOCKD *xd);
static INLINE aom_prob static INLINE aom_prob
av1_get_pred_prob_uni_comp_ref_p1(const AV1_COMMON *cm, const MACROBLOCKD *xd) { av1_get_pred_prob_uni_comp_ref_p1(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p1(cm, xd); const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
return cm->fc->uni_comp_ref_prob[pred_context][1]; return cm->fc->uni_comp_ref_prob[pred_context][1];
} }
int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd);
static INLINE aom_prob
av1_get_pred_prob_uni_comp_ref_p2(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
return cm->fc->uni_comp_ref_prob[pred_context][2];
}
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_comp_reference_type_cdf(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_comp_reference_type_context(xd);
return xd->tile_ctx->comp_ref_type_cdf[pred_context];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
}
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm, int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
......
...@@ -1354,10 +1354,21 @@ static REFERENCE_MODE read_block_reference_mode(AV1_COMMON *cm, ...@@ -1354,10 +1354,21 @@ static REFERENCE_MODE read_block_reference_mode(AV1_COMMON *cm,
static REFERENCE_MODE read_comp_reference_type(AV1_COMMON *cm, static REFERENCE_MODE read_comp_reference_type(AV1_COMMON *cm,
const MACROBLOCKD *xd, const MACROBLOCKD *xd,
aom_reader *r) { aom_reader *r) {
const int ctx = av1_get_comp_reference_type_context(cm, xd); const int ctx = av1_get_comp_reference_type_context(xd);
#if USE_UNI_COMP_REFS #if USE_UNI_COMP_REFS
const COMP_REFERENCE_TYPE comp_ref_type = (COMP_REFERENCE_TYPE)aom_read( COMP_REFERENCE_TYPE comp_ref_type;
r, cm->fc->comp_ref_type_prob[ctx], ACCT_STR); #if CONFIG_VAR_REFS
if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm))
if (L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm) || BWD_AND_ALT(cm))
#endif // CONFIG_VAR_REFS
comp_ref_type = (COMP_REFERENCE_TYPE)aom_read(
r, cm->fc->comp_ref_type_prob[ctx], ACCT_STR);
#if CONFIG_VAR_REFS
else
comp_ref_type = BIDIR_COMP_REFERENCE;
else
comp_ref_type = UNIDIR_COMP_REFERENCE;
#endif // CONFIG_VAR_REFS
#else // !USE_UNI_COMP_REFS #else // !USE_UNI_COMP_REFS
// TODO(zoeliu): Temporarily turn off uni-directional comp refs // TODO(zoeliu): Temporarily turn off uni-directional comp refs
const COMP_REFERENCE_TYPE comp_ref_type = BIDIR_COMP_REFERENCE; const COMP_REFERENCE_TYPE comp_ref_type = BIDIR_COMP_REFERENCE;
...@@ -1395,22 +1406,54 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd, ...@@ -1395,22 +1406,54 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
#endif // !USE_UNI_COMP_REFS #endif // !USE_UNI_COMP_REFS
if (comp_ref_type == UNIDIR_COMP_REFERENCE) { if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
const int ctx = av1_get_pred_context_uni_comp_ref_p(cm, xd); const int ctx = av1_get_pred_context_uni_comp_ref_p(xd);
const int bit = aom_read(r, fc->uni_comp_ref_prob[ctx][0], ACCT_STR); int bit;
#if CONFIG_VAR_REFS
if ((L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm)) && BWD_AND_ALT(cm))
#endif // CONFIG_VAR_REFS
bit = aom_read(r, fc->uni_comp_ref_prob[ctx][0], ACCT_STR);
#if CONFIG_VAR_REFS
else
bit = BWD_AND_ALT(cm);
#endif // CONFIG_VAR_REFS
if (counts) ++counts->uni_comp_ref[ctx][0][bit]; if (counts) ++counts->uni_comp_ref[ctx][0][bit];
if (bit) { if (bit) {
ref_frame[0] = BWDREF_FRAME; ref_frame[0] = BWDREF_FRAME;
ref_frame[1] = ALTREF_FRAME; ref_frame[1] = ALTREF_FRAME;
} else { } else {
const int ctx1 = av1_get_pred_context_uni_comp_ref_p1(cm, xd); const int ctx1 = av1_get_pred_context_uni_comp_ref_p1(xd);
const int bit1 = int bit1;
aom_read(r, fc->uni_comp_ref_prob[ctx1][1], ACCT_STR); #if CONFIG_VAR_REFS
if (L_AND_L2(cm) && (L_AND_L3(cm) || L_AND_G(cm)))
#endif // CONFIG_VAR_REFS
bit1 = aom_read(r, fc->uni_comp_ref_prob[ctx1][1], ACCT_STR);
#if CONFIG_VAR_REFS
else
bit1 = L_AND_L3(cm) || L_AND_G(cm);
#endif // CONFIG_VAR_REFS
if (counts) ++counts->uni_comp_ref[ctx1][1][bit1]; if (counts) ++counts->uni_comp_ref[ctx1][1][bit1];
if (bit1) { if (bit1) {
ref_frame[0] = LAST_FRAME; const int ctx2 = av1_get_pred_context_uni_comp_ref_p2(xd);
ref_frame[1] = GOLDEN_FRAME; int bit2;
#if CONFIG_VAR_REFS
if (L_AND_L3(cm) && L_AND_G(cm))
#endif // CONFIG_VAR_REFS
bit2 = aom_read(r, fc->uni_comp_ref_prob[ctx2][2], ACCT_STR);
#if CONFIG_VAR_REFS
else
bit2 = L_AND_G(cm);
#endif // CONFIG_VAR_REFS
if (counts) ++counts->uni_comp_ref[ctx2][2][bit2];
if (bit2) {
ref_frame[0] = LAST_FRAME;
ref_frame[1] = GOLDEN_FRAME;
} else {
ref_frame[0] = LAST_FRAME;
ref_frame[1] = LAST3_FRAME;
}
} else { } else {
ref_frame[0] = LAST_FRAME; ref_frame[0] = LAST_FRAME;
ref_frame[1] = LAST2_FRAME; ref_frame[1] = LAST2_FRAME;
...@@ -1419,6 +1462,8 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd, ...@@ -1419,6 +1462,8 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
return; return;
} }
assert(comp_ref_type == BIDIR_COMP_REFERENCE);
#endif // CONFIG_EXT_COMP_REFS #endif // CONFIG_EXT_COMP_REFS
// Normative in decoder (for low delay) // Normative in decoder (for low delay)
...@@ -2077,9 +2122,7 @@ static void dec_dump_logs(AV1_COMMON *cm, MODE_INFO *const mi, ...@@ -2077,9 +2122,7 @@ static void dec_dump_logs(AV1_COMMON *cm, MODE_INFO *const mi,
int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame); int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
#define FRAME_TO_CHECK 1 #define FRAME_TO_CHECK 1
if (cm->current_video_frame == FRAME_TO_CHECK if (cm->current_video_frame == FRAME_TO_CHECK /*&& cm->show_frame == 0*/) {
// && cm->show_frame == 0
) {
printf( printf(
"=== DECODER ===: " "=== DECODER ===: "
"Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, " "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
......
...@@ -1098,9 +1098,18 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd, ...@@ -1098,9 +1098,18 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi) const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi)
? UNIDIR_COMP_REFERENCE ? UNIDIR_COMP_REFERENCE
: BIDIR_COMP_REFERENCE; : BIDIR_COMP_REFERENCE;
#if USE_UNI_COMP_REFS #if USE_UNI_COMP_REFS
aom_write(w, comp_ref_type, av1_get_comp_reference_type_prob(cm, xd)); #if CONFIG_VAR_REFS
if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm))
if (L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm) || BWD_AND_ALT(cm))
#endif // CONFIG_VAR_REFS
aom_write(w, comp_ref_type, av1_get_comp_reference_type_prob(cm, xd));
#if CONFIG_VAR_REFS
else
assert(comp_ref_type == BIDIR_COMP_REFERENCE);
else
assert(comp_ref_type == UNIDIR_COMP_REFERENCE);
#endif // CONFIG_VAR_REFS
#else // !USE_UNI_COMP_REFS #else // !USE_UNI_COMP_REFS
// NOTE: uni-directional comp refs disabled // NOTE: uni-directional comp refs disabled
assert(comp_ref_type == BIDIR_COMP_REFERENCE); assert(comp_ref_type == BIDIR_COMP_REFERENCE);
...@@ -1108,14 +1117,41 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd, ...@@ -1108,14 +1117,41 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd,
if (comp_ref_type == UNIDIR_COMP_REFERENCE) { if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
const int bit = mbmi->ref_frame[0] == BWDREF_FRAME; const int bit = mbmi->ref_frame[0] == BWDREF_FRAME;
aom_write(w, bit, av1_get_pred_prob_uni_comp_ref_p(cm, xd)); #if CONFIG_VAR_REFS
if ((L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm)) && BWD_AND_ALT(cm))
#endif // CONFIG_VAR_REFS
aom_write(w, bit, av1_get_pred_prob_uni_comp_ref_p(cm, xd));
if (!bit) { if (!bit) {
const int bit1 = mbmi->ref_frame[1] == GOLDEN_FRAME; assert(mbmi->ref_frame[0] == LAST_FRAME);
aom_write(w, bit1, av1_get_pred_prob_uni_comp_ref_p1(cm, xd)); #if CONFIG_VAR_REFS
if (L_AND_L2(cm) && (L_AND_L3(cm) || L_AND_G(cm))) {
#endif // CONFIG_VAR_REFS
const int bit1 = mbmi->ref_frame[1] == LAST3_FRAME ||
mbmi->ref_frame[1] == GOLDEN_FRAME;
aom_write(w, bit1, av1_get_pred_prob_uni_comp_ref_p1(cm, xd));
if (bit1) {
#if CONFIG_VAR_REFS
if (L_AND_L3(cm) && L_AND_G(cm)) {
#endif // CONFIG_VAR_REFS
const int bit2 = mbmi->ref_frame[1] == GOLDEN_FRAME;
aom_write(w, bit2, av1_get_pred_prob_uni_comp_ref_p2(cm, xd));
#if CONFIG_VAR_REFS
}
#endif // CONFIG_VAR_REFS
}
#if CONFIG_VAR_REFS
}
#endif // CONFIG_VAR_REFS
} else {