// AV1 loop filter applies to the whole frame according to mi_rows and mi_cols, // which are calculated based on aligned width and aligned height, // In addition, if super res is enabled, it copies the whole frame // according to the aligned width and height (av1_superres_upscale()). // So we need to copy the whole filtered region, instead of the cropped region. // For example, input image size is: 160x90. // Then src->y_crop_width = 160, src->y_crop_height = 90. // The aligned frame size is: src->y_width = 160, src->y_height = 96. // AV1 aligns frame size to a multiple of 8, if there is // chroma subsampling, it is able to ensure the chroma is also // an integer number of mi units. mi unit is 4x4, 8 = 4 * 2, and 2 luma mi // units correspond to 1 chroma mi unit if there is subsampling. // See: aom_realloc_frame_buffer() in yv12config.c. staticvoid yv12_copy_plane(const YV12_BUFFER_CONFIG *src_bc,
YV12_BUFFER_CONFIG *dst_bc, int plane) { switch (plane) { case0: aom_yv12_copy_y(src_bc, dst_bc, 0); break; case1: aom_yv12_copy_u(src_bc, dst_bc, 0); break; case2: aom_yv12_copy_v(src_bc, dst_bc, 0); break; default: assert(plane >= 0 && plane <= 2); break;
}
}
// yx, bias less for large block size if (cm->features.tx_mode != ONLY_4X4) bias >>= 1;
if (filt_direction <= 0 && filt_low != filt_mid) { // Get Low filter error score if (ss_err[filt_low] < 0) {
ss_err[filt_low] =
try_filter_frame(sd, cpi, filt_low, partial_frame, plane, dir);
} // If value is close to the best so far then bias towards a lower loop // filter value. if (ss_err[filt_low] < (best_err + bias)) { // Was it actually better than the previous best? if (ss_err[filt_low] < best_err) {
best_err = ss_err[filt_low];
}
filt_best = filt_low;
}
}
// Now look at filt_high if (filt_direction >= 0 && filt_high != filt_mid) { if (ss_err[filt_high] < 0) {
ss_err[filt_high] =
try_filter_frame(sd, cpi, filt_high, partial_frame, plane, dir);
} // If value is significantly better than previous best, bias added against // raising filter value if (ss_err[filt_high] < (best_err - bias)) {
best_err = ss_err[filt_high];
filt_best = filt_high;
}
}
// Half the step distance if the best filter value was the same as last time if (filt_best == filt_mid) {
filter_step /= 2;
filt_direction = 0;
} else {
filt_direction = (filt_best < filt_mid) ? -1 : 1;
filt_mid = filt_best;
}
}
// Enable loop filter sharpness only for all-intra encoding mode, // or tune IQ or SSIMULACRA2. This is because: // - All-intra: frames do not have to serve as references to others // - Tune IQ/SSIMULACRA2: enabling loop filter sharpness has been found to // be beneficial for sharpness perception if (cpi->oxcf.mode == ALLINTRA || cpi->oxcf.tune_cfg.tuning == AOM_TUNE_IQ ||
cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) {
lf->sharpness_level = cpi->oxcf.algo_cfg.sharpness;
} else {
lf->sharpness_level = 0;
}
if (cpi->oxcf.algo_cfg.enable_adaptive_sharpness) { // Loop filter sharpness levels are highly nonlinear. Visually, lf sharpness // 1 is closer to 7 than it is to 0, so in practice adaptive sharpness is // written to pick levels 0, 1 and 7 to keep it simple. int max_lf_sharpness;
if (cpi->sf.lpf_sf.adaptive_luma_loop_filter_skip >= 1) {
int32_t min_ref_filter_level[2] = { MAX_LOOP_FILTER, MAX_LOOP_FILTER }; // Find the minimum luma filter levels across all reference frames. for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) { const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref); if (buf == NULL) continue;
if (buf->filter_level[0] != -1)
min_ref_filter_level[0] =
AOMMIN(min_ref_filter_level[0], buf->filter_level[0]); if (buf->filter_level[1] != -1)
min_ref_filter_level[1] =
AOMMIN(min_ref_filter_level[1], buf->filter_level[1]);
}
// Reset luma filter levels to zero based on minimum filter levels of // reference frames and current frame's pyramid level. unsignedint pyramid_level = cm->current_frame.pyramid_level; if (pyramid_level > 1) { int filter_threshold; if (pyramid_level >= 4)
filter_threshold = 16; else
filter_threshold = 8;
// Calculate the percentage improvement in SSE for each plane. This // measures the relative reduction in error when applying the filter // compared to no filtering. for (int plane = 0; plane < num_planes; plane++) { constdouble pct_improvement_sse =
((zero_filter_sse[plane] - best_filter_sse[plane]) * 100.0) /
zero_filter_sse[plane];
reset_filter_level_y &= pct_improvement_sse < pct_improvement_thresh;
}
// Store the current frame's filter levels to be referenced // while determining the minimum filter level from reference frames.
cm->cur_frame->filter_level[0] = lf->filter_level[0];
cm->cur_frame->filter_level[1] = lf->filter_level[1];
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.