Turn off TPL when GOP size is too big
When size >= MAX_LENGTH_TPL_FRAME_STATS, we will turn off TPL.
Add ready to TplParams, which indicates whether the TPL stats
is ready.
Add av1_tpl_stats_ready() to check the status of TPL stats.
BUG=aomedia:3054
Change-Id: I1cc6b9412ace586c5f769a82b20718790ba9c43d
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index d4d927e..c428308 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -980,6 +980,10 @@
int allow_tpl = oxcf->gf_cfg.lag_in_frames > 1 &&
!is_stat_generation_stage(cpi) &&
oxcf->algo_cfg.enable_tpl_model;
+
+ if (gf_group->size > MAX_LENGTH_TPL_FRAME_STATS) {
+ allow_tpl = 0;
+ }
if (frame_params->frame_type == KEY_FRAME) {
// Don't do tpl for fwd key frames or fwd key frame overlays
allow_tpl = allow_tpl && !cpi->sf.tpl_sf.disable_filtered_key_tpl &&
@@ -1006,7 +1010,6 @@
av1_read_rd_command(filepath, &cpi->rd_command);
}
#endif // CONFIG_RD_COMMAND
-
if (allow_tpl == 0) {
// Avoid the use of unintended TPL stats from previous GOP's results.
if (cpi->gf_frame_index == 0 && !is_stat_generation_stage(cpi))
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index c76c9d7..a957771 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -331,9 +331,7 @@
av1_zero(x->tpl_keep_ref_frame);
- if (frame_idx >= MAX_TPL_FRAME_IDX) return;
- TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
- if (!tpl_frame->is_valid) return;
+ if (!av1_tpl_stats_ready(tpl_data, frame_idx)) return;
if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) return;
if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return;
@@ -344,6 +342,7 @@
return;
}
+ TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
const int tpl_stride = tpl_frame->stride;
int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index 6ce65a1..d2bf96a 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -60,6 +60,8 @@
av1_set_error_per_bit(errorperbit, *rdmult);
}
+// TODO(angiebird): Move these function to tpl_model.c
+#if !CONFIG_REALTIME_ONLY
// Return the end column for the current superblock, in unit of TPL blocks.
static int get_superblock_tpl_column_end(const AV1_COMMON *const cm, int mi_col,
int num_mi_w) {
@@ -89,9 +91,7 @@
cpi->gf_frame_index < cpi->ppi->gf_group.size));
const int tpl_idx = cpi->gf_frame_index;
const int deltaq_rdmult = set_deltaq_rdmult(cpi, x);
- if (tpl_idx >= MAX_TPL_FRAME_IDX) return deltaq_rdmult;
- const TplDepFrame *tpl_frame = &cpi->ppi->tpl_data.tpl_frame[tpl_idx];
- if (!tpl_frame->is_valid) return deltaq_rdmult;
+ if (!av1_tpl_stats_ready(&cpi->ppi->tpl_data, tpl_idx)) return deltaq_rdmult;
if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index))
return deltaq_rdmult;
if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return deltaq_rdmult;
@@ -139,6 +139,7 @@
#endif // !CONFIG_RD_COMMAND
return rdmult;
}
+#endif // !CONFIG_REALTIME_ONLY
static AOM_INLINE void update_filter_type_count(FRAME_COUNTS *counts,
const MACROBLOCKD *xd,
@@ -692,14 +693,16 @@
const int mi_wide = mi_size_wide[bsize];
const int mi_high = mi_size_high[bsize];
- if (tpl_idx >= MAX_TPL_FRAME_IDX) return orig_rdmult;
-
TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
int tpl_stride = tpl_frame->stride;
- if (!tpl_frame->is_valid) return orig_rdmult;
- if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) return orig_rdmult;
+ if (!av1_tpl_stats_ready(&cpi->ppi->tpl_data, cpi->gf_frame_index)) {
+ return orig_rdmult;
+ }
+ if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) {
+ return orig_rdmult;
+ }
int mi_count = 0;
const int mi_col_sr =
@@ -819,15 +822,13 @@
AV1_COMMON *const cm = &cpi->common;
const int gf_group_index = cpi->gf_frame_index;
TplParams *const tpl_data = &cpi->ppi->tpl_data;
+ if (!av1_tpl_stats_ready(tpl_data, gf_group_index)) return;
const int mi_wide = mi_size_wide[bsize];
const int mi_high = mi_size_high[bsize];
- if (gf_group_index >= MAX_TPL_FRAME_IDX) return;
-
TplDepFrame *tpl_frame = &tpl_data->tpl_frame[gf_group_index];
TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
int tpl_stride = tpl_frame->stride;
- if (!tpl_frame->is_valid) return;
int mi_count = 0;
int count = 0;
diff --git a/av1/encoder/encodeframe_utils.h b/av1/encoder/encodeframe_utils.h
index ed1187c..b033405 100644
--- a/av1/encoder/encodeframe_utils.h
+++ b/av1/encoder/encodeframe_utils.h
@@ -281,16 +281,16 @@
int av1_get_q_for_deltaq_objective(AV1_COMP *const cpi, BLOCK_SIZE bsize,
int mi_row, int mi_col);
+
+int av1_get_hier_tpl_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
+ const BLOCK_SIZE bsize, const int mi_row,
+ const int mi_col, int orig_rdmult);
#endif // !CONFIG_REALTIME_ONLY
void av1_set_ssim_rdmult(const AV1_COMP *const cpi, int *errorperbit,
const BLOCK_SIZE bsize, const int mi_row,
const int mi_col, int *const rdmult);
-int av1_get_hier_tpl_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
- const BLOCK_SIZE bsize, const int mi_row,
- const int mi_col, int orig_rdmult);
-
void av1_update_state(const AV1_COMP *const cpi, ThreadData *td,
const PICK_MODE_CONTEXT *const ctx, int mi_row,
int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run);
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index b7407f7..b38d932 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -554,12 +554,14 @@
}
}
+#if !CONFIG_REALTIME_ONLY
const AV1_COMMON *const cm = &cpi->common;
if (cm->delta_q_info.delta_q_present_flag &&
!cpi->sf.rt_sf.use_nonrd_pick_mode) {
x->rdmult =
av1_get_hier_tpl_rdmult(cpi, x, bsize, mi_row, mi_col, x->rdmult);
}
+#endif // !CONFIG_REALTIME_ONLY
if (cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIM) {
av1_set_ssim_rdmult(cpi, &x->errorperbit, bsize, mi_row, mi_col,
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 4849fd5..ef82af3 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -2187,14 +2187,8 @@
cpi->gf_frame_index < cpi->ppi->gf_group.size));
const int tpl_idx = cpi->gf_frame_index;
TplParams *const tpl_data = &cpi->ppi->tpl_data;
- if (tpl_idx >= MAX_TPL_FRAME_IDX) {
- return;
- }
+ if (!av1_tpl_stats_ready(tpl_data, tpl_idx)) return;
const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
- if (!tpl_frame->is_valid) {
- return;
- }
-
const TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
const int mi_wide = mi_size_wide[bsize];
const int mi_high = mi_size_high[bsize];
@@ -2577,11 +2571,14 @@
const int is_comp_pred = has_second_ref(mbmi);
const PREDICTION_MODE this_mode = mbmi->mode;
- const int tpl_idx = cpi->gf_frame_index;
- TplParams *const tpl_data = &cpi->ppi->tpl_data;
+#if CONFIG_REALTIME_ONLY
+ const int prune_modes_based_on_tpl = 0;
+#else // CONFIG_REALTIME_ONLY
+ const TplParams *const tpl_data = &cpi->ppi->tpl_data;
const int prune_modes_based_on_tpl =
cpi->sf.inter_sf.prune_inter_modes_based_on_tpl &&
- tpl_idx < MAX_TPL_FRAME_IDX && tpl_data->tpl_frame[tpl_idx].is_valid;
+ av1_tpl_stats_ready(tpl_data, cpi->gf_frame_index);
+#endif // CONFIG_REALTIME_ONLY
int i;
// Reference frames for this mode
const int refs[2] = { mbmi->ref_frame[0],
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 99d47b2..ac5812e 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -1493,6 +1493,7 @@
void av1_init_tpl_stats(TplParams *const tpl_data) {
int frame_idx;
+ tpl_data->ready = 0;
set_tpl_stats_block_size(&tpl_data->tpl_stats_block_mis_log2,
&tpl_data->tpl_bsize_1d);
for (frame_idx = 0; frame_idx < MAX_LAG_BUFFERS; ++frame_idx) {
@@ -1509,6 +1510,18 @@
#endif
}
+int av1_tpl_stats_ready(const TplParams *tpl_data, int gf_frame_index) {
+ if (tpl_data->ready == 0) {
+ return 0;
+ }
+ if (gf_frame_index >= MAX_LENGTH_TPL_FRAME_STATS) {
+ assert(gf_frame_index >= MAX_LENGTH_TPL_FRAME_STATS &&
+ "Invalid gf_frame_index\n");
+ return 0;
+ }
+ return tpl_data->tpl_frame[gf_frame_index].is_valid;
+}
+
static AOM_INLINE int eval_gop_length(double *beta, int gop_eval) {
switch (gop_eval) {
case 1:
@@ -1671,6 +1684,9 @@
end_timing(cpi, av1_tpl_setup_stats_time);
#endif
+ if (!approx_gop_eval) {
+ tpl_data->ready = 1;
+ }
if (cpi->common.tiles.large_scale) return 0;
if (gf_group->max_layer_depth_allowed == 0) return 1;
if (!gop_eval) return 0;
diff --git a/av1/encoder/tpl_model.h b/av1/encoder/tpl_model.h
index 408a4b2..c2fdb40 100644
--- a/av1/encoder/tpl_model.h
+++ b/av1/encoder/tpl_model.h
@@ -137,6 +137,11 @@
*/
typedef struct TplParams {
/*!
+ * Whether the tpl stats is ready.
+ */
+ int ready;
+
+ /*!
* Block granularity of tpl score storage.
*/
uint8_t tpl_stats_block_mis_log2;
@@ -276,6 +281,8 @@
void av1_init_tpl_stats(TplParams *const tpl_data);
+int av1_tpl_stats_ready(const TplParams *tpl_data, int gf_frame_index);
+
void av1_tpl_rdmult_setup(struct AV1_COMP *cpi);
void av1_tpl_rdmult_setup_sb(struct AV1_COMP *cpi, MACROBLOCK *const x,