PR #25680 opened by zsoltiv URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25680 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25680.patch
# Summary of changes Looking at the generated assembly of `set_frame_data` in `perf report` highlighted the divisions by `1 << mi_ctx->log2_chroma_w` and `1 << mi_ctx->log2_chroma_h` as hotspots. I rewrote them using the trick for dividing signed integers by powers of two from Hacker's Delight, and it yielded an extra 0.5 fps on my initial test clip (GCC 16.2.1 on a Ryzen 7 4750U) which was a second long (`perf.data` files eat up lots of space). I marked the PR as WIP, because I haven't found a suitable division macro implementing this trick when I skimmed avutil's sources. Maybe this functionality could be added as a more generic macro as well? >From 8f19999de6fbc9a5fe80d310a5cd0af3f754d38c Mon Sep 17 00:00:00 2001 From: Zsolt Vadasz <[email protected]> Date: Mon, 2 Nov 2026 12:59:34 +0100 Subject: [PATCH] avfilter/vf_minterpolate: Use bit twiddling for division by power of two --- libavfilter/vf_minterpolate.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c index 75bffd4bf58..96159b46268 100644 --- a/libavfilter/vf_minterpolate.c +++ b/libavfilter/vf_minterpolate.c @@ -192,9 +192,9 @@ typedef struct MIContext { double prev_mafd; double scd_threshold; - int log2_chroma_w; - int log2_chroma_h; int nb_planes; + uint8_t log2_chroma_w; + uint8_t log2_chroma_h; } MIContext; #define OFFSET(x) offsetof(MIContext, x) @@ -910,6 +910,11 @@ static void bidirectional_obmc(MIContext *mi_ctx, int alpha) } } +static inline int chroma_div(int16_t a, uint8_t log2_chroma) +{ + return (a + ((a >> 15) & ((1 << log2_chroma) - 1))) >> log2_chroma; +} + static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out) { int x, y, plane; @@ -948,8 +953,8 @@ static void set_frame_data(MIContext *mi_ctx, int alpha, AVFrame *avf_out) if (chroma) { for (i = 0; i < pixel_refs->nb; i++) { Frame *frame = &mi_ctx->frames[pixel_refs->refs[i]]; - x_mv = (x >> mi_ctx->log2_chroma_w) + pixel_mvs->mvs[i][0] / (1 << mi_ctx->log2_chroma_w); - y_mv = (y >> mi_ctx->log2_chroma_h) + pixel_mvs->mvs[i][1] / (1 << mi_ctx->log2_chroma_h); + x_mv = (x >> mi_ctx->log2_chroma_w) + chroma_div(pixel_mvs->mvs[i][0], mi_ctx->log2_chroma_w); + y_mv = (y >> mi_ctx->log2_chroma_h) + chroma_div(pixel_mvs->mvs[i][1], mi_ctx->log2_chroma_h); val += pixel_weights->weights[i] * frame->avf->data[plane][x_mv + y_mv * frame->avf->linesize[plane]]; } } else { -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
