Refactor encoder side for settomg lossless/tcq/ph
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 4f41ec9..d1473cc 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -1378,12 +1378,6 @@
int qmatrix_level_u; /*!< Level index for U plane */
int qmatrix_level_v; /*!< Level index for V plane */
/**@}*/
-#if CONFIG_TCQ
- /*!
- * Frame tcq_mode: 0 = disabled, 1 = enabled (8-state)
- */
- int tcq_mode;
-#endif // CONFIG_TCQ
};
typedef struct CommonContexts CommonContexts;
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c
index 4abbeaf..98d5325 100644
--- a/av1/encoder/av1_quantize.c
+++ b/av1/encoder/av1_quantize.c
@@ -437,7 +437,8 @@
void av1_init_quantizer(SequenceHeader *seq_params,
EncQuantDequantParams *const enc_quant_dequant_params,
- const CommonQuantParams *quant_params) {
+ const AV1_COMMON *const cm) {
+ const CommonQuantParams *quant_params = &cm->quant_params;
QUANTS *const quants = &enc_quant_dequant_params->quants;
Dequants *const dequants = &enc_quant_dequant_params->dequants;
av1_build_quantizer(seq_params->bit_depth, quant_params->y_dc_delta_q,
@@ -453,7 +454,7 @@
quants, dequants
#if CONFIG_TCQ
,
- quant_params->tcq_mode
+ cm->features.tcq_mode
#endif // CONFIG_TCQ
);
}
@@ -596,9 +597,6 @@
// quantizer has to be reinitialized with av1_init_quantizer() if any
// delta_q changes.
CommonQuantParams *quant_params = &cm->quant_params;
-#if CONFIG_TCQ
- quant_params->tcq_mode = cm->features.tcq_mode;
-#endif // CONFIG_TCQ
quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
cm->cur_frame->base_qindex = quant_params->base_qindex;
set_frame_dc_delta_q(cm, &quant_params->y_dc_delta_q, enable_chroma_deltaq,
diff --git a/av1/encoder/av1_quantize.h b/av1/encoder/av1_quantize.h
index 675260e..ca16938 100644
--- a/av1/encoder/av1_quantize.h
+++ b/av1/encoder/av1_quantize.h
@@ -122,7 +122,7 @@
void av1_init_quantizer(SequenceHeader *seq_params,
EncQuantDequantParams *const enc_quant_dequant_params,
- const CommonQuantParams *quant_params);
+ const AV1_COMMON *const cm);
void av1_set_quantizer(struct AV1Common *const cm, int min_qmlevel,
int max_qmlevel, int q, int enable_chroma_deltaq);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index cdb3ad3..611a984 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1548,7 +1548,75 @@
#endif // CONFIG_TIP_LD
}
-static void av1_enc_setup_ph_frame(AV1_COMP *cpi) {
+/*!\brief Set the lossless flags for a frame before encoding it
+ *
+ * \ingroup high_level_algo
+ */
+void av1_set_lossless(AV1_COMP *cpi) {
+ // NOTE lossless flags needs to be set before tcq_mode and parity_hiding are
+ // set for a frame
+ MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
+ AV1_COMMON *const cm = &cpi->common;
+ const CommonQuantParams *quant_params = &cm->quant_params;
+ for (int i = 0; i < MAX_SEGMENTS; ++i) {
+ const int qindex =
+ cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex,
+ cm->seq_params.bit_depth)
+ : quant_params->base_qindex;
+ xd->lossless[i] =
+ qindex == 0 && cm->features.tcq_mode == 0 &&
+ (quant_params->y_dc_delta_q + cm->seq_params.base_y_dc_delta_q <= 0) &&
+ (quant_params->u_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <= 0) &&
+ (quant_params->v_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <= 0) &&
+#if CONFIG_EXT_QUANT_UPD
+ (quant_params->u_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0) &&
+ (quant_params->v_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0);
+#else
+ (quant_params->u_ac_delta_q <= 0) && (quant_params->v_ac_delta_q <= 0);
+#endif // CONFIG_EXT_QUANT_UPD
+
+ if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
+ xd->qindex[i] = qindex;
+ if (xd->lossless[i]) {
+ cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
+ } else {
+ cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
+ }
+ }
+ cm->features.coded_lossless = is_coded_lossless(cm, xd);
+ cm->features.all_lossless = cm->features.coded_lossless
+#if CONFIG_ENABLE_SR
+ && !av1_superres_scaled(cm)
+#endif // CONFIG_ENABLE_SR
+ ;
+}
+
+#if CONFIG_TCQ
+/*!\brief Set the tcq_mode for a frame before encoding it
+ *
+ * \ingroup high_level_algo
+ */
+void av1_set_frame_tcq_mode(AV1_COMP *cpi) {
+ // NOTE tcq_mode needs to be set after lossless flags are set and before
+ // parity_hiding is set for a frame
+ AV1_COMMON *const cm = &cpi->common;
+ if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
+ // Disable TCQ for lossless since TCQ may not be reversible
+ cm->features.tcq_mode = 0;
+ } else {
+ if (cm->seq_params.enable_tcq >= TCQ_8ST_FR) {
+ cm->features.tcq_mode =
+ frame_is_intra_only(cm) || cm->current_frame.pyramid_level <= 1;
+ } else {
+ cm->features.tcq_mode = cm->seq_params.enable_tcq;
+ }
+ }
+}
+#endif // CONFIG_TCQ
+
+void av1_enc_setup_ph_frame(AV1_COMP *cpi) {
+ // Note parity_hiding is to be set for a frame after lossless and tcq_mode
+ // are set
AV1_COMMON *const cm = &cpi->common;
if (cm->features.coded_lossless || !cm->seq_params.enable_parity_hiding
#if CONFIG_TCQ
@@ -1695,37 +1763,6 @@
}
const CommonQuantParams *quant_params = &cm->quant_params;
- for (i = 0; i < MAX_SEGMENTS; ++i) {
- const int qindex =
- cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex,
- cm->seq_params.bit_depth)
- : quant_params->base_qindex;
- xd->lossless[i] =
- qindex == 0 && cm->features.tcq_mode == 0 &&
- (quant_params->y_dc_delta_q + cm->seq_params.base_y_dc_delta_q <= 0) &&
- (quant_params->u_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <= 0) &&
- (quant_params->v_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <= 0) &&
-#if CONFIG_EXT_QUANT_UPD
- (quant_params->u_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0) &&
- (quant_params->v_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0);
-#else
- (quant_params->u_ac_delta_q <= 0) && (quant_params->v_ac_delta_q <= 0);
-#endif // CONFIG_EXT_QUANT_UPD
-
- if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
- xd->qindex[i] = qindex;
- if (xd->lossless[i]) {
- cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
- } else {
- cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
- }
- }
- features->coded_lossless = is_coded_lossless(cm, xd);
- features->all_lossless = features->coded_lossless
-#if CONFIG_ENABLE_SR
- && !av1_superres_scaled(cm)
-#endif // CONFIG_ENABLE_SR
- ;
// Fix delta q resolution for the moment
cm->delta_q_info.delta_q_res = 0;
@@ -1847,8 +1884,6 @@
av1_enc_setup_tip_frame(cpi);
- av1_enc_setup_ph_frame(cpi);
-
cm->current_frame.skip_mode_info.skip_mode_flag =
check_skip_mode_enabled(cpi) && cpi->oxcf.tool_cfg.enable_skip_mode;
@@ -1969,6 +2004,8 @@
map += mi_cols;
}
}
+ // av1_set_lossless(cpi, xd);
+ // av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params, cm);
av1_setup_frame_buf_refs(cm);
enforce_max_ref_frames(cpi, &cm->ref_frame_flags);
diff --git a/av1/encoder/encodeframe.h b/av1/encoder/encodeframe.h
index 598190d..42e4efb 100644
--- a/av1/encoder/encodeframe.h
+++ b/av1/encoder/encodeframe.h
@@ -52,6 +52,12 @@
int use_optflow_refinement, uint16_t **mc_buf,
uint16_t **pre, SubpelParams *subpel_params,
int *src_stride);
+void av1_set_lossless(struct AV1_COMP *cpi);
+void av1_enc_setup_ph_frame(struct AV1_COMP *cpi);
+#if CONFIG_TCQ
+void av1_set_frame_tcq_mode(struct AV1_COMP *cpi);
+#endif // CONFIG_TCQ
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index fec494f..7157cf2 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1398,8 +1398,7 @@
* called later when needed. This will avoid unnecessary calls of
* av1_init_quantizer() for every frame.
*/
- av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params,
- &cm->quant_params);
+ av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params, cm);
av1_qm_init(&cm->quant_params, av1_num_planes(cm));
#if CONFIG_DF_PAR_BITS
@@ -3145,8 +3144,7 @@
#endif // CONFIG_PRIMARY_REF_FRAME_OPT
av1_set_speed_features_qindex_dependent(cpi, cpi->oxcf.speed);
- av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params,
- &cm->quant_params);
+
av1_setup_frame(cpi);
if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ) {
@@ -3185,6 +3183,13 @@
// av1_set_high_precision_mv(cpi, MV_PRECISION_ONE_PEL);
}
+#if CONFIG_TCQ
+ av1_set_frame_tcq_mode(cpi);
+#endif // CONFIG_TCQ
+ av1_set_lossless(cpi);
+ av1_enc_setup_ph_frame(cpi);
+ av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params, cm);
+
// transform / motion compensation build reconstruction frame
av1_encode_frame(cpi);
@@ -3337,6 +3342,7 @@
q = av1_get_vmaf_base_qindex(cpi, q);
}
#endif
+
av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
q_cfg->enable_chroma_deltaq);
@@ -3345,8 +3351,6 @@
#endif // CONFIG_PRIMARY_REF_FRAME_OPT
av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
- av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params,
- &cm->quant_params);
// printf("Frame %d/%d: q = %d, frame_type = %d superres_denom = %d\n",
// cm->current_frame.frame_number, cm->show_frame, q,
@@ -3410,6 +3414,13 @@
// av1_set_high_precision_mv(cpi, MV_PRECISION_ONE_PEL);
}
+#if CONFIG_TCQ
+ av1_set_frame_tcq_mode(cpi);
+#endif // CONFIG_TCQ
+ av1_set_lossless(cpi);
+ av1_enc_setup_ph_frame(cpi);
+ av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params, cm);
+
// transform / motion compensation build reconstruction frame
av1_encode_frame(cpi);
@@ -3940,6 +3951,8 @@
#endif
int err;
+ AV1_COMMON *const cm = &cpi->common;
+
if (cpi->sf.hl_sf.recode_loop == DISALLOW_RECODE)
err = encode_without_recode(cpi);
else
@@ -3959,7 +3972,6 @@
return err;
}
- AV1_COMMON *const cm = &cpi->common;
SequenceHeader *const seq_params = &cm->seq_params;
#if CONFIG_BRU
if (cm->bru.enabled && cm->current_frame.frame_type != KEY_FRAME) {
@@ -4739,20 +4751,6 @@
av1_invalidate_corner_list(cpi->source->corners);
}
-#if CONFIG_TCQ
- if (is_lossless_requested(&oxcf->rc_cfg)) {
- // Disable TCQ for lossless since TCQ may not be reversible
- features->tcq_mode = 0;
- } else {
- if (cm->seq_params.enable_tcq >= TCQ_8ST_FR) {
- features->tcq_mode =
- frame_is_intra_only(cm) || current_frame->pyramid_level <= 1;
- } else {
- features->tcq_mode = cm->seq_params.enable_tcq;
- }
- }
-#endif // CONFIG_TCQ
-
int largest_tile_id = 0;
#if CONFIG_ENABLE_SR
if (av1_superres_in_recode_allowed(cpi)) {
diff --git a/av1/encoder/encoder_utils.c b/av1/encoder/encoder_utils.c
index 02584db..f86c1a2 100644
--- a/av1/encoder/encoder_utils.c
+++ b/av1/encoder/encoder_utils.c
@@ -1179,10 +1179,13 @@
q_cfg->enable_chroma_deltaq);
av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
- av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params,
- &cm->quant_params);
-
av1_setup_frame(cpi);
+#if CONFIG_TCQ
+ cm->features.tcq_mode = 0;
+#endif // CONFIG_TCQ
+ av1_set_lossless(cpi);
+ av1_enc_setup_ph_frame(cpi);
+ av1_init_quantizer(&cm->seq_params, &cpi->enc_quant_dequant_params, cm);
// transform / motion compensation build reconstruction frame
av1_encode_frame(cpi);
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index ff59d5c..1766709 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -894,7 +894,7 @@
int av1_compute_rd_mult_based_on_qindex(const AV1_COMP *cpi, int qindex) {
#if CONFIG_TCQ
- const int tcq_mode = cpi->common.quant_params.tcq_mode;
+ const int tcq_mode = cpi->common.features.tcq_mode;
const int q =
av1_dc_quant_QTX_tcq(qindex, 0, cpi->common.seq_params.base_y_dc_delta_q,
cpi->common.seq_params.bit_depth, tcq_mode);