This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 40a836bbb86532990e3ec7cec143a48b0dc0b3f7 Author: Niklas Haas <[email protected]> AuthorDate: Fri Sep 18 14:00:30 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Fri Oct 2 12:35:06 2026 +0000 avfilter/vf_limiter: resolve per-plane limits once per frame Instead of in the slice thread. These values do not differ by slice. We do it per-frame, rather than in config_input(), to respect dynamically changing filter settings. Signed-off-by: Niklas Haas <[email protected]> --- libavfilter/vf_limiter.c | 54 ++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c index 197688225e..19dbcfd30e 100644 --- a/libavfilter/vf_limiter.c +++ b/libavfilter/vf_limiter.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" @@ -35,10 +36,11 @@ typedef struct ThreadData { typedef struct LimiterContext { const AVClass *class; - int min; - int max; + int min, max; /* user-facing option */ int planes; int nb_planes; + int plane_min[4]; /* resolved per-plane limits */ + int plane_max[4]; int linesize[4]; int width[4]; int height[4]; @@ -135,9 +137,6 @@ static int config_input(AVFilterLink *inlink) s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); s->width[0] = s->width[3] = inlink->w; - s->max = FFMIN(s->max, (1 << depth) - 1); - s->min = FFMIN(s->min, (1 << depth) - 1); - if (depth == 8) { s->dsp.limiter = limiter8; } else { @@ -162,22 +161,13 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(in->format); const int depth = desc->comp[0].depth; const int full_range = (1 << depth) - 1; - const int is_mpeg = in->color_range == AVCOL_RANGE_MPEG && - !(desc->flags & AV_PIX_FMT_FLAG_RGB); for (p = 0; p < s->nb_planes; p++) { const int h = s->height[p]; const int slice_start = ff_slice_pos(h, jobnr, nb_jobs); const int slice_end = ff_slice_pos(h, jobnr + 1, nb_jobs); - const int mpeg_min = 16 << (depth - 8); - const int mpeg_max = (p ? 240 : 235) << (depth - 8); - - int min = s->min, max = s->max; - if (min < 0) - min = (is_mpeg && p != 3) ? mpeg_min : 0; - if (max < 0) - max = (is_mpeg && p != 3) ? mpeg_max : full_range; - + const int min = s->plane_min[p]; + const int max = s->plane_max[p]; if (!((1 << p) & s->planes) || (min == 0 && max == full_range)) { if (out != in) av_image_copy_plane(out->data[p] + slice_start * out->linesize[p], @@ -188,10 +178,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) continue; } - /* check only after resolving no-op planes */ - if (min > max) - return AVERROR(EINVAL); - + av_assert1(max >= min); s->dsp.limiter(in->data[p] + slice_start * in->linesize[p], out->data[p] + slice_start * out->linesize[p], in->linesize[p], out->linesize[p], @@ -210,6 +197,33 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) ThreadData td; AVFrame *out; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(in->format); + const int is_mpeg = in->color_range == AVCOL_RANGE_MPEG && + !(desc->flags & AV_PIX_FMT_FLAG_RGB); + + const int depth = desc->comp[0].depth; + const int full_range = (1 << depth) - 1; + const int max = FFMIN(s->max, full_range); + const int min = FFMIN(s->min, full_range); + + for (int p = 0; p < s->nb_planes; p++) { + const int mpeg_min = 16 << (depth - 8); + const int mpeg_max = (p ? 240 : 235) << (depth - 8); + s->plane_min[p] = min; + s->plane_max[p] = max; + if (min < 0) + s->plane_min[p] = (is_mpeg && p != 3) ? mpeg_min : 0; + if (max < 0) + s->plane_max[p] = (is_mpeg && p != 3) ? mpeg_max : full_range; + + if (((1 << p) & s->planes) && s->plane_max[p] < s->plane_min[p]) { + av_log(ctx, AV_LOG_ERROR, "Invalid min/max values for plane %d: " + "min=%d > max=%d\n", p, s->plane_min[p], s->plane_max[p]); + av_frame_free(&in); + return AVERROR(EINVAL); + } + } + const int nb_jobs = FFMIN3(ff_filter_get_nb_threads(ctx), MAX_THREADS, s->height[2]); -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
