#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_tile_common.h"
+#include "vp9/encoder/vp9_alt_ref_aq.h"
#include "vp9/encoder/vp9_aq_360.h"
#include "vp9/encoder/vp9_aq_complexity.h"
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
cpi->use_skin_detection = 0;
cpi->common.buffer_pool = pool;
+ cpi->force_update_segmentation = 0;
+
init_config(cpi, oxcf);
vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
realloc_segmentation_maps(cpi);
+ CHECK_MEM_ERROR(cm, cpi->alt_ref_aq, vp9_alt_ref_aq_create());
+
CHECK_MEM_ERROR(
cm, cpi->consec_zero_mv,
vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
SNPRINT2(results, "\t%7.3f", consistency);
SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
}
- fprintf(f, "%s\t Time Rc-Err Abs Err\n", headings);
- fprintf(f, "%s\t%8.0f %7.2f %7.2f\n", results, total_encode_time,
+
+ fprintf(f, "%s\t Time\tRcErr\tAbsErr\n", headings);
+ fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
rate_err, fabs(rate_err));
}
if (cpi->num_workers > 1) vp9_loop_filter_dealloc(&cpi->lf_row_sync);
+ vp9_alt_ref_aq_destroy(cpi->alt_ref_aq);
+
dealloc_compressor_data(cpi);
for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
(rc->projected_frame_size < (low_limit / 2));
}
+// test in two pass for the first
+static int two_pass_first_group_inter(VP9_COMP *cpi) {
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+ if ((cpi->oxcf.pass == 2) &&
+ (gf_group->index == gf_group->first_inter_index)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
// Function to test for conditions that indicate we should loop
// back and recode a frame.
static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q,
if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
big_rate_miss(cpi, high_limit, low_limit) ||
(cpi->sf.recode_loop == ALLOW_RECODE) ||
- (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
+ (two_pass_first_group_inter(cpi) &&
+ (cpi->sf.recode_loop == ALLOW_RECODE_FIRST)) ||
+ (frame_is_kfgfarf && (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF))) {
if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
scale_down(cpi, q)) {
// Code this group at a lower resolution.
setup_frame(cpi);
suppress_active_map(cpi);
+
// Variance adaptive and in frame q adjustment experiments are mutually
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_setup_in_frame_q_adj(cpi);
} else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
vp9_cyclic_refresh_setup(cpi);
+ } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
+ // it may be pretty bad for rate-control,
+ // and I should handle it somehow
+ vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
}
+
apply_active_map(cpi);
vp9_encode_frame(cpi);
vp9_360aq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
vp9_setup_in_frame_q_adj(cpi);
+ } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
+ vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
}
vp9_encode_frame(cpi);
}
#endif // ENABLE_KF_DENOISE
+static void vp9_try_disable_lookahead_aq(VP9_COMP *cpi, size_t *size,
+ uint8_t *dest) {
+ if (cpi->common.seg.enabled)
+ if (ALT_REF_AQ_PROTECT_GAIN) {
+ size_t nsize = *size;
+ int overhead;
+
+ // TODO(yuryg): optimize this, as
+ // we don't really need to repack
+
+ save_coding_context(cpi);
+ vp9_disable_segmentation(&cpi->common.seg);
+ vp9_pack_bitstream(cpi, dest, &nsize);
+ restore_coding_context(cpi);
+
+ overhead = (int)*size - (int)nsize;
+
+ if (vp9_alt_ref_aq_disable_if(cpi->alt_ref_aq, overhead, (int)*size))
+ vp9_encode_frame(cpi);
+ else
+ vp9_enable_segmentation(&cpi->common.seg);
+ }
+}
+
static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size,
uint8_t *dest,
unsigned int *frame_flags) {
encode_with_recode_loop(cpi, size, dest);
}
+ // Disable segmentation if it decrease rate/distortion ratio
+ if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
+ vp9_try_disable_lookahead_aq(cpi, size, dest);
+
#if CONFIG_VP9_TEMPORAL_DENOISING
#ifdef OUTPUT_YUV_DENOISED
if (oxcf->noise_sensitivity > 0) {
cpi->svc.number_temporal_layers +
cpi->svc.temporal_layer_id]
.last_frame_type = cm->frame_type;
+
+ cpi->force_update_segmentation = 0;
+
+ if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
+ vp9_alt_ref_aq_unset_all(cpi->alt_ref_aq, cpi);
}
static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
#endif
if ((oxcf->arnr_max_frames > 0) && (oxcf->arnr_strength > 0)) {
+ int bitrate = cpi->rc.avg_frame_bandwidth / 40;
+ int not_low_bitrate = bitrate > ALT_REF_AQ_LOW_BITRATE_BOUNDARY;
+
+ int not_last_frame = (cpi->lookahead->sz - arf_src_index > 1);
+ not_last_frame |= ALT_REF_AQ_APPLY_TO_LAST_FRAME;
+
// Produce the filtered ARF frame.
vp9_temporal_filter(cpi, arf_src_index);
vpx_extend_frame_borders(&cpi->alt_ref_buffer);
+
+ // for small bitrates segmentation overhead usually
+ // eats all bitrate gain from enabling delta quantizers
+ if (cpi->oxcf.alt_ref_aq != 0 && not_low_bitrate && not_last_frame)
+ vp9_alt_ref_aq_setup_mode(cpi->alt_ref_aq, cpi);
+
force_src_buffer = &cpi->alt_ref_buffer;
}
cpi->svc.spatial_layer_to_encode = 0;
}
}
+
vpx_clear_system_state();
return 0;
}