diff options
author | Erwin Jansen <jansene@google.com> | 2021-06-30 07:29:26 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-06-30 07:29:26 +0000 |
commit | 059cdc5996938f5f6b5343b6c969c12098275587 (patch) | |
tree | 6eacaffe4bebf8e00c290c1e1839e084b0c52e88 /third_party/libaom/source/libaom/av1/encoder/temporal_filter.c | |
parent | 97e54a7e73c7b24e464ef06ef3c3b3716f21bb15 (diff) | |
parent | 16be34ae72cdb525c88c2b31b21b976f35fe36d8 (diff) | |
download | webrtc-059cdc5996938f5f6b5343b6c969c12098275587.tar.gz |
Merge "Merge upstream-master and enable ARM64" into emu-master-devemu-31-stable-releaseemu-31-release
Diffstat (limited to 'third_party/libaom/source/libaom/av1/encoder/temporal_filter.c')
-rw-r--r-- | third_party/libaom/source/libaom/av1/encoder/temporal_filter.c | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/third_party/libaom/source/libaom/av1/encoder/temporal_filter.c b/third_party/libaom/source/libaom/av1/encoder/temporal_filter.c index 676e110e60..6833ac8a40 100644 --- a/third_party/libaom/source/libaom/av1/encoder/temporal_filter.c +++ b/third_party/libaom/source/libaom/av1/encoder/temporal_filter.c @@ -155,7 +155,7 @@ static void tf_motion_search(AV1_COMP *cpi, MACROBLOCK *mb, best_mv.as_mv.row = GET_MV_SUBPEL(mv_row); best_mv.as_mv.col = GET_MV_SUBPEL(mv_col); const int mv_offset = mv_row * y_stride + mv_col; - error = cpi->fn_ptr[block_size].vf( + error = cpi->ppi->fn_ptr[block_size].vf( ref_frame->y_buffer + y_offset + mv_offset, y_stride, frame_to_filter->y_buffer + y_offset, y_stride, &sse); block_mse = DIVIDE_AND_ROUND(error, mb_pels); @@ -561,9 +561,16 @@ void av1_apply_temporal_filter_c( (double)TF_WINDOW_BLOCK_BALANCE_WEIGHT * inv_factor; // Decay factors for non-local mean approach. double decay_factor[MAX_MB_PLANE] = { 0 }; - // Smaller q -> smaller filtering weight. + // Adjust filtering based on q. + // Larger q -> stronger filtering -> larger weight. + // Smaller q -> weaker filtering -> smaller weight. double q_decay = pow((double)q_factor / TF_Q_DECAY_THRESHOLD, 2); q_decay = CLIP(q_decay, 1e-5, 1); + if (q_factor >= TF_QINDEX_CUTOFF) { + // Max q_factor is 255, therefore the upper bound of q_decay is 8. + // We do not need a clip here. + q_decay = 0.5 * pow((double)q_factor / 64, 2); + } // Smaller strength -> smaller filtering weight. double s_decay = pow((double)filter_strength / TF_STRENGTH_THRESHOLD, 2); s_decay = CLIP(s_decay, 1e-5, 1); @@ -745,10 +752,19 @@ static void tf_normalize_filtered_frame( } int av1_get_q(const AV1_COMP *cpi) { - const GF_GROUP *gf_group = &cpi->gf_group; - const FRAME_TYPE frame_type = gf_group->frame_type[gf_group->index]; - const int q = (int)av1_convert_qindex_to_q( - cpi->rc.avg_frame_qindex[frame_type], cpi->common.seq_params.bit_depth); + const GF_GROUP *gf_group = &cpi->ppi->gf_group; + const FRAME_TYPE frame_type = gf_group->frame_type[cpi->gf_frame_index]; + int avg_frame_qindex; +#if CONFIG_FRAME_PARALLEL_ENCODE + avg_frame_qindex = + (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) + ? cpi->ppi->temp_avg_frame_qindex[frame_type] + : cpi->rc.avg_frame_qindex[frame_type]; +#else + avg_frame_qindex = cpi->rc.avg_frame_qindex[frame_type]; +#endif // CONFIG_FRAME_PARALLEL_ENCODE + const int q = (int)av1_convert_qindex_to_q(avg_frame_qindex, + cpi->common.seq_params->bit_depth); return q; } @@ -855,23 +871,24 @@ void av1_tf_do_filtering_row(AV1_COMP *cpi, ThreadData *td, int mb_row) { } } tf_normalize_filtered_frame(mbd, block_size, mb_row, mb_col, num_planes, - accum, count, &cpi->alt_ref_buffer); + accum, count, &cpi->ppi->alt_ref_buffer); if (check_show_existing) { const int y_height = mb_height >> mbd->plane[0].subsampling_y; const int y_width = mb_width >> mbd->plane[0].subsampling_x; const int source_y_stride = frame_to_filter->y_stride; - const int filter_y_stride = cpi->alt_ref_buffer.y_stride; + const int filter_y_stride = cpi->ppi->alt_ref_buffer.y_stride; const int source_offset = mb_row * y_height * source_y_stride + mb_col * y_width; const int filter_offset = mb_row * y_height * filter_y_stride + mb_col * y_width; unsigned int sse = 0; - cpi->fn_ptr[block_size].vf( + cpi->ppi->fn_ptr[block_size].vf( frame_to_filter->y_buffer + source_offset, source_y_stride, - cpi->alt_ref_buffer.y_buffer + filter_offset, filter_y_stride, &sse); + cpi->ppi->alt_ref_buffer.y_buffer + filter_offset, filter_y_stride, + &sse); diff->sum += sse; - diff->sse += sse * sse; + diff->sse += sse * (int64_t)sse; } } } @@ -939,8 +956,9 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi, const int lookahead_depth = av1_lookahead_depth(cpi->ppi->lookahead, cpi->compressor_stage); - int arf_src_offset = cpi->gf_group.arf_src_offset[cpi->gf_group.index]; - const FRAME_TYPE frame_type = cpi->gf_group.frame_type[cpi->gf_group.index]; + int arf_src_offset = cpi->ppi->gf_group.arf_src_offset[cpi->gf_frame_index]; + const FRAME_TYPE frame_type = + cpi->ppi->gf_group.frame_type[cpi->gf_frame_index]; // Temporal filtering should not go beyond key frames const int key_to_curframe = @@ -949,10 +967,10 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi, AOMMAX(cpi->rc.frames_to_key - arf_src_offset - 1, 0); // Number of buffered frames before the to-filter frame. - const int max_before = AOMMIN(filter_frame_lookahead_idx, key_to_curframe); + int max_before = AOMMIN(filter_frame_lookahead_idx, key_to_curframe); // Number of buffered frames after the to-filter frame. - const int max_after = + int max_after = AOMMIN(lookahead_depth - filter_frame_lookahead_idx - 1, curframe_to_key); // Estimate noises for each plane. @@ -964,26 +982,34 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi, double *noise_levels = tf_ctx->noise_levels; for (int plane = 0; plane < num_planes; ++plane) { noise_levels[plane] = av1_estimate_noise_from_single_plane( - to_filter_frame, plane, cpi->common.seq_params.bit_depth); + to_filter_frame, plane, cpi->common.seq_params->bit_depth); } // Get quantization factor. const int q = av1_get_q(cpi); - // Get correlation estimates from first-pass - RATE_CONTROL *rc = &cpi->rc; - const double *coeff = rc->cor_coeff; - const int offset = rc->regions_offset; - int cur_frame_idx = - filter_frame_lookahead_idx + rc->frames_since_key - offset; - + // Get correlation estimates from first-pass; + const FIRSTPASS_STATS *stats = + cpi->ppi->twopass.stats_in - (cpi->rc.frames_since_key == 0); double accu_coeff0 = 1.0, accu_coeff1 = 1.0; for (int i = 1; i <= max_after; i++) { - accu_coeff1 *= coeff[cur_frame_idx + i]; + if (stats + filter_frame_lookahead_idx + i >= + cpi->ppi->twopass.stats_buf_ctx->stats_in_end) { + max_after = i - 1; + break; + } + accu_coeff1 *= + AOMMAX(stats[filter_frame_lookahead_idx + i].cor_coeff, 0.001); } if (max_after >= 1) { accu_coeff1 = pow(accu_coeff1, 1.0 / (double)max_after); } for (int i = 1; i <= max_before; i++) { - accu_coeff0 *= coeff[cur_frame_idx - i + 1]; + if (stats + filter_frame_lookahead_idx - i + 1 <= + cpi->ppi->twopass.stats_buf_ctx->stats_in_start) { + max_before = i - 1; + break; + } + accu_coeff0 *= + AOMMAX(stats[filter_frame_lookahead_idx - i + 1].cor_coeff, 0.001); } if (max_before >= 1) { accu_coeff0 = pow(accu_coeff0, 1.0 / (double)max_before); @@ -1008,7 +1034,7 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi, num_before = AOMMIN(num_frames - 1, max_before); num_after = 0; } else { - num_frames = AOMMIN(num_frames, cpi->rc.gfu_boost / 150); + num_frames = AOMMIN(num_frames, cpi->ppi->p_rc.gfu_boost / 150); num_frames += !(num_frames & 1); // Make the number odd. // Only use 2 neighbours for the second ARF. if (is_second_arf) num_frames = AOMMIN(num_frames, 3); @@ -1051,10 +1077,10 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi, assert(frames[tf_ctx->filter_frame_idx] == to_filter_frame); av1_setup_src_planes(&cpi->td.mb, &to_filter_buf->img, 0, 0, num_planes, - cpi->common.seq_params.sb_size); + cpi->common.seq_params->sb_size); av1_setup_block_planes(&cpi->td.mb.e_mbd, - cpi->common.seq_params.subsampling_x, - cpi->common.seq_params.subsampling_y, num_planes); + cpi->common.seq_params->subsampling_x, + cpi->common.seq_params->subsampling_y, num_planes); } /*!\cond */ @@ -1174,8 +1200,8 @@ int av1_temporal_filter(AV1_COMP *cpi, const int filter_frame_lookahead_idx, int *show_existing_arf) { MultiThreadInfo *const mt_info = &cpi->mt_info; // Basic informaton of the current frame. - const GF_GROUP *const gf_group = &cpi->gf_group; - const uint8_t group_idx = gf_group->index; + const GF_GROUP *const gf_group = &cpi->ppi->gf_group; + const uint8_t group_idx = cpi->gf_frame_index; TemporalFilterCtx *tf_ctx = &cpi->tf_ctx; TemporalFilterData *tf_data = &cpi->td.tf_data; // Filter one more ARF if the lookahead index is leq 7 (w.r.t. 9-th frame). @@ -1236,9 +1262,9 @@ int av1_temporal_filter(AV1_COMP *cpi, const int filter_frame_lookahead_idx, int top_index = 0; int bottom_index = 0; const int q = av1_rc_pick_q_and_bounds( - cpi, &cpi->rc, cpi->oxcf.frm_dim_cfg.width, - cpi->oxcf.frm_dim_cfg.height, group_idx, &bottom_index, &top_index); - const int ac_q = av1_ac_quant_QTX(q, 0, cpi->common.seq_params.bit_depth); + cpi, cpi->oxcf.frm_dim_cfg.width, cpi->oxcf.frm_dim_cfg.height, + group_idx, &bottom_index, &top_index); + const int ac_q = av1_ac_quant_QTX(q, 0, cpi->common.seq_params->bit_depth); const float threshold = 0.7f * ac_q * ac_q; if (!is_second_arf) { |