Rework key frame intra mode context model
Reduce the context model size for key frame modes from 30240 bits
to 4500 bits, i.e., less than 1/6 of the original context model.
The coding performance loss on key frame is 0.14% for lowres and
noise level difference for video sequence. The loss on key frame
for midres is 0.05% and noise level for whole video. The change
on hdres kf coding is 0.015%.
Change-Id: I9e36825e5c5ee6ba35038c3ca349ad1ad3429910
diff --git a/av1/common/common_data.h b/av1/common/common_data.h
index d063122..4211be5 100644
--- a/av1/common/common_data.h
+++ b/av1/common/common_data.h
@@ -2109,6 +2109,16 @@
};
/* clang-format on */
+#if CONFIG_KF_CTX
+static const int intra_mode_context[INTRA_MODES] = {
+ 0, 1, 2, 3, 4, 4, 4, 4, 3, 0,
+#if CONFIG_SMOOTH_HV
+ 1, 2,
+#endif
+ 0,
+};
+#endif
+
#if CONFIG_SUPERTX
static const TX_SIZE uvsupertx_size_lookup[TX_SIZES][2][2] = {
// ss_x == 0 ss_x == 0 ss_x == 1 ss_x == 1
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index e337021..6ccd098 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -3769,6 +3769,184 @@
};
#endif
+#if CONFIG_KF_CTX
+// TODO(jingning): This initial models are copied directly from the entries
+// from the original table. The copied indexes are (0, 0), (0, 1), .. (4, 4).
+// It is possible to re-train this model and bring back the 0.14% loss in CIF
+// set key frame coding. This reduction in context model does not change the
+// key frame coding stats for mid and high resolution sets.
+const aom_cdf_prob
+ default_kf_y_mode_cdf[KF_MODE_CONTEXTS][KF_MODE_CONTEXTS][CDF_SIZE(
+ INTRA_MODES)] = {
+ {
+ {
+ AOM_ICDF(14208), AOM_ICDF(17049), AOM_ICDF(20482),
+ AOM_ICDF(21400), AOM_ICDF(22520), AOM_ICDF(23261),
+ AOM_ICDF(23963), AOM_ICDF(25010), AOM_ICDF(25828),
+ AOM_ICDF(28398), AOM_ICDF(29394), AOM_ICDF(30738),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(10496), AOM_ICDF(18295), AOM_ICDF(19872),
+ AOM_ICDF(20945), AOM_ICDF(21933), AOM_ICDF(22818),
+ AOM_ICDF(23334), AOM_ICDF(24033), AOM_ICDF(24996),
+ AOM_ICDF(27652), AOM_ICDF(29060), AOM_ICDF(30071),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(5120), AOM_ICDF(6461), AOM_ICDF(19840), AOM_ICDF(20310),
+ AOM_ICDF(21151), AOM_ICDF(21506), AOM_ICDF(22535),
+ AOM_ICDF(23900), AOM_ICDF(24281), AOM_ICDF(26958),
+ AOM_ICDF(27680), AOM_ICDF(29636), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(12544), AOM_ICDF(15177), AOM_ICDF(17666),
+ AOM_ICDF(19855), AOM_ICDF(21147), AOM_ICDF(22017),
+ AOM_ICDF(22797), AOM_ICDF(24514), AOM_ICDF(25779),
+ AOM_ICDF(28716), AOM_ICDF(29772), AOM_ICDF(31267),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(7552), AOM_ICDF(9909), AOM_ICDF(11908), AOM_ICDF(13141),
+ AOM_ICDF(18765), AOM_ICDF(22029), AOM_ICDF(23872),
+ AOM_ICDF(24920), AOM_ICDF(25674), AOM_ICDF(29031),
+ AOM_ICDF(30244), AOM_ICDF(31684), AOM_ICDF(32768), 0,
+ },
+ },
+ {
+ {
+ AOM_ICDF(3968), AOM_ICDF(17613), AOM_ICDF(19125), AOM_ICDF(19550),
+ AOM_ICDF(20305), AOM_ICDF(21908), AOM_ICDF(22274),
+ AOM_ICDF(22719), AOM_ICDF(23959), AOM_ICDF(26970),
+ AOM_ICDF(29013), AOM_ICDF(29843), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(3072), AOM_ICDF(21231), AOM_ICDF(21863), AOM_ICDF(22306),
+ AOM_ICDF(22674), AOM_ICDF(23414), AOM_ICDF(23517),
+ AOM_ICDF(23798), AOM_ICDF(24770), AOM_ICDF(27032),
+ AOM_ICDF(29016), AOM_ICDF(29636), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(2560), AOM_ICDF(9825), AOM_ICDF(15681), AOM_ICDF(16370),
+ AOM_ICDF(17054), AOM_ICDF(17687), AOM_ICDF(18236),
+ AOM_ICDF(19273), AOM_ICDF(20311), AOM_ICDF(24863),
+ AOM_ICDF(26825), AOM_ICDF(28756), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(6912), AOM_ICDF(15140), AOM_ICDF(16485), AOM_ICDF(18364),
+ AOM_ICDF(19181), AOM_ICDF(20394), AOM_ICDF(20663),
+ AOM_ICDF(22098), AOM_ICDF(23936), AOM_ICDF(27555),
+ AOM_ICDF(29704), AOM_ICDF(30849), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(2944), AOM_ICDF(13101), AOM_ICDF(14006), AOM_ICDF(14974),
+ AOM_ICDF(17818), AOM_ICDF(21093), AOM_ICDF(21930),
+ AOM_ICDF(22566), AOM_ICDF(24137), AOM_ICDF(27732),
+ AOM_ICDF(29814), AOM_ICDF(30904), AOM_ICDF(32768), 0,
+ },
+ },
+ {
+ {
+ AOM_ICDF(11392), AOM_ICDF(12961), AOM_ICDF(20901),
+ AOM_ICDF(21544), AOM_ICDF(22490), AOM_ICDF(22928),
+ AOM_ICDF(23888), AOM_ICDF(25214), AOM_ICDF(25777),
+ AOM_ICDF(28256), AOM_ICDF(29102), AOM_ICDF(30513),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(8064), AOM_ICDF(13595), AOM_ICDF(18888), AOM_ICDF(19616),
+ AOM_ICDF(20765), AOM_ICDF(21454), AOM_ICDF(21990),
+ AOM_ICDF(23103), AOM_ICDF(23980), AOM_ICDF(26772),
+ AOM_ICDF(28070), AOM_ICDF(29197), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(4352), AOM_ICDF(5059), AOM_ICDF(21705), AOM_ICDF(22099),
+ AOM_ICDF(22703), AOM_ICDF(22846), AOM_ICDF(23679),
+ AOM_ICDF(25469), AOM_ICDF(25728), AOM_ICDF(27919),
+ AOM_ICDF(28484), AOM_ICDF(30215), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(10752), AOM_ICDF(12277), AOM_ICDF(16471),
+ AOM_ICDF(18276), AOM_ICDF(19443), AOM_ICDF(19917),
+ AOM_ICDF(21158), AOM_ICDF(23881), AOM_ICDF(24892),
+ AOM_ICDF(27709), AOM_ICDF(28771), AOM_ICDF(30274),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(8320), AOM_ICDF(10000), AOM_ICDF(14147), AOM_ICDF(15330),
+ AOM_ICDF(19197), AOM_ICDF(20923), AOM_ICDF(22954),
+ AOM_ICDF(24541), AOM_ICDF(25285), AOM_ICDF(28407),
+ AOM_ICDF(29431), AOM_ICDF(30953), AOM_ICDF(32768), 0,
+ },
+ },
+ {
+ {
+ AOM_ICDF(10240), AOM_ICDF(12819), AOM_ICDF(15545),
+ AOM_ICDF(18248), AOM_ICDF(19779), AOM_ICDF(20932),
+ AOM_ICDF(21899), AOM_ICDF(23377), AOM_ICDF(25448),
+ AOM_ICDF(28730), AOM_ICDF(29936), AOM_ICDF(31536),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(7552), AOM_ICDF(15309), AOM_ICDF(16645), AOM_ICDF(19760),
+ AOM_ICDF(20653), AOM_ICDF(21650), AOM_ICDF(22221),
+ AOM_ICDF(23273), AOM_ICDF(25509), AOM_ICDF(28683),
+ AOM_ICDF(30153), AOM_ICDF(31192), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(5248), AOM_ICDF(6840), AOM_ICDF(16129), AOM_ICDF(17940),
+ AOM_ICDF(19069), AOM_ICDF(19660), AOM_ICDF(20588),
+ AOM_ICDF(22760), AOM_ICDF(23927), AOM_ICDF(27538),
+ AOM_ICDF(28397), AOM_ICDF(30725), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(11008), AOM_ICDF(11903), AOM_ICDF(13794),
+ AOM_ICDF(21320), AOM_ICDF(21931), AOM_ICDF(22310),
+ AOM_ICDF(22546), AOM_ICDF(25375), AOM_ICDF(27347),
+ AOM_ICDF(29800), AOM_ICDF(30761), AOM_ICDF(31833),
+ AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(6272), AOM_ICDF(8678), AOM_ICDF(10313), AOM_ICDF(13073),
+ AOM_ICDF(16823), AOM_ICDF(19980), AOM_ICDF(21520),
+ AOM_ICDF(23242), AOM_ICDF(25344), AOM_ICDF(28797),
+ AOM_ICDF(30405), AOM_ICDF(31940), AOM_ICDF(32768), 0,
+ },
+ },
+ {
+ {
+ AOM_ICDF(7296), AOM_ICDF(9304), AOM_ICDF(11772), AOM_ICDF(12529),
+ AOM_ICDF(18014), AOM_ICDF(20418), AOM_ICDF(23076),
+ AOM_ICDF(24662), AOM_ICDF(25549), AOM_ICDF(29074),
+ AOM_ICDF(30392), AOM_ICDF(31773), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(7168), AOM_ICDF(11687), AOM_ICDF(13541), AOM_ICDF(14431),
+ AOM_ICDF(18214), AOM_ICDF(20761), AOM_ICDF(22269),
+ AOM_ICDF(23320), AOM_ICDF(24633), AOM_ICDF(28339),
+ AOM_ICDF(30193), AOM_ICDF(31268), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(3584), AOM_ICDF(4428), AOM_ICDF(13496), AOM_ICDF(14189),
+ AOM_ICDF(17372), AOM_ICDF(18617), AOM_ICDF(20609),
+ AOM_ICDF(22615), AOM_ICDF(23270), AOM_ICDF(27280),
+ AOM_ICDF(28305), AOM_ICDF(30602), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(7424), AOM_ICDF(8834), AOM_ICDF(10499), AOM_ICDF(14357),
+ AOM_ICDF(17671), AOM_ICDF(19150), AOM_ICDF(20460),
+ AOM_ICDF(23235), AOM_ICDF(24391), AOM_ICDF(28351),
+ AOM_ICDF(29843), AOM_ICDF(31481), AOM_ICDF(32768), 0,
+ },
+ {
+ AOM_ICDF(4480), AOM_ICDF(5888), AOM_ICDF(7093), AOM_ICDF(7902),
+ AOM_ICDF(18290), AOM_ICDF(22123), AOM_ICDF(24511),
+ AOM_ICDF(25532), AOM_ICDF(26360), AOM_ICDF(29653),
+ AOM_ICDF(30954), AOM_ICDF(32215), AOM_ICDF(32768), 0,
+ },
+ },
+ };
+#else
const aom_cdf_prob default_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(
INTRA_MODES)] = {
#if CONFIG_SMOOTH_HV
@@ -5442,6 +5620,7 @@
},
#endif // CONFIG_SMOOTH_HV
};
+#endif // CONFIG_KF_CTX
static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->partition_prob, default_partition_probs);
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 55b67f2..92cd94a 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -68,6 +68,10 @@
#define PALETTE_MAX_BLOCK_SIZE (64 * 64)
+#if CONFIG_KF_CTX
+#define KF_MODE_CONTEXTS 5
+#endif
+
struct AV1Common;
typedef struct {
@@ -354,11 +358,16 @@
#endif
aom_cdf_prob switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS]
[CDF_SIZE(SWITCHABLE_FILTERS)];
- /* kf_y_cdf is discarded after use, so does not require persistent storage.
- However, we keep it with the other CDFs in this struct since it needs to
- be copied to each tile to support parallelism just like the others.
- */
+/* kf_y_cdf is discarded after use, so does not require persistent storage.
+ However, we keep it with the other CDFs in this struct since it needs to
+ be copied to each tile to support parallelism just like the others.
+*/
+#if CONFIG_KF_CTX
+ aom_cdf_prob kf_y_cdf[KF_MODE_CONTEXTS][KF_MODE_CONTEXTS]
+ [CDF_SIZE(INTRA_MODES)];
+#else
aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(INTRA_MODES)];
+#endif
aom_cdf_prob tx_size_cdf[MAX_TX_DEPTH][TX_SIZE_CONTEXTS]
[CDF_SIZE(MAX_TX_DEPTH + 1)];
aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)];
@@ -549,8 +558,14 @@
#endif // CONFIG_FILTER_INTRA
} FRAME_COUNTS;
+#if CONFIG_KF_CTX
+extern const aom_cdf_prob default_kf_y_mode_cdf[KF_MODE_CONTEXTS]
+ [KF_MODE_CONTEXTS]
+ [CDF_SIZE(INTRA_MODES)];
+#else
extern const aom_cdf_prob default_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES]
[CDF_SIZE(INTRA_MODES)];
+#endif
extern const aom_prob av1_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES]
[PALETTE_Y_MODE_CONTEXTS];
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 758276d..c777bd3 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -853,7 +853,14 @@
int block) {
const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, block);
const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, block);
+
+#if CONFIG_KF_CTX
+ int above_ctx = intra_mode_context[above];
+ int left_ctx = intra_mode_context[left];
+ return tile_ctx->kf_y_cdf[above_ctx][left_ctx];
+#else
return tile_ctx->kf_y_cdf[above][left];
+#endif
}
static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row,
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 8387b1c..cd8e323 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -137,9 +137,15 @@
#endif // CONFIG_UNPOISON_PARTITION_CTX
}
+#if CONFIG_KF_CTX
+ for (i = 0; i < KF_MODE_CONTEXTS; ++i)
+ for (j = 0; j < KF_MODE_CONTEXTS; ++j)
+ av1_cost_tokens_from_cdf(x->y_mode_costs[i][j], fc->kf_y_cdf[i][j], NULL);
+#else
for (i = 0; i < INTRA_MODES; ++i)
for (j = 0; j < INTRA_MODES; ++j)
av1_cost_tokens_from_cdf(x->y_mode_costs[i][j], fc->kf_y_cdf[i][j], NULL);
+#endif
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
av1_cost_tokens_from_cdf(x->mbmode_cost[i], fc->y_mode_cdf[i], NULL);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 71b00be..09d2acf 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -3625,7 +3625,13 @@
const PREDICTION_MODE L =
av1_left_block_mode(mic, left_mi, pred_block_idx);
+#if CONFIG_KF_CTX
+ const int above_ctx = intra_mode_context[A];
+ const int left_ctx = intra_mode_context[L];
+ bmode_costs = mb->y_mode_costs[above_ctx][left_ctx];
+#else
bmode_costs = mb->y_mode_costs[A][L];
+#endif
}
this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
cpi, mb, idy, idx, &best_mode, bmode_costs,
@@ -4126,7 +4132,14 @@
od_encode_checkpoint(&x->daala_enc, &pre_buf);
od_encode_checkpoint(&x->daala_enc, &post_buf);
#endif // CONFIG_PVQ
+
+#if CONFIG_KF_CTX
+ const int above_ctx = intra_mode_context[A];
+ const int left_ctx = intra_mode_context[L];
+ bmode_costs = x->y_mode_costs[above_ctx][left_ctx];
+#else
bmode_costs = x->y_mode_costs[A][L];
+#endif
#if CONFIG_EXT_INTRA
mbmi->angle_delta[0] = 0;