From 686c07fb1e0455c4205eaad18e8a01bf64058dec Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 22 Dec 2020 13:19:12 +0100 Subject: avfilter/vf_decimate: fix overreads when using ppsrc Derive input parameters from correct inlink when using ppsrc. Previously both input frames would use dimensions of first inlink, causing crash if first inlink w/h was smaller than second one. --- libavfilter/vf_decimate.c | 59 ++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c index 8407d9942c..25bd5bda57 100644 --- a/libavfilter/vf_decimate.c +++ b/libavfilter/vf_decimate.c @@ -297,46 +297,12 @@ static int activate(AVFilterContext *ctx) return 0; } -static int config_input(AVFilterLink *inlink) -{ - int max_value; - AVFilterContext *ctx = inlink->dst; - DecimateContext *dm = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - const int w = inlink->w; - const int h = inlink->h; - - dm->hsub = pix_desc->log2_chroma_w; - dm->vsub = pix_desc->log2_chroma_h; - dm->depth = pix_desc->comp[0].depth; - max_value = (1 << dm->depth) - 1; - dm->scthresh = (int64_t)(((int64_t)max_value * w * h * dm->scthresh_flt) / 100); - dm->dupthresh = (int64_t)(((int64_t)max_value * dm->blockx * dm->blocky * dm->dupthresh_flt) / 100); - dm->nxblocks = (w + dm->blockx/2 - 1) / (dm->blockx/2); - dm->nyblocks = (h + dm->blocky/2 - 1) / (dm->blocky/2); - dm->bdiffsize = dm->nxblocks * dm->nyblocks; - dm->bdiffs = av_malloc_array(dm->bdiffsize, sizeof(*dm->bdiffs)); - dm->queue = av_calloc(dm->cycle, sizeof(*dm->queue)); - - if (!dm->bdiffs || !dm->queue) - return AVERROR(ENOMEM); - - if (dm->ppsrc) { - dm->clean_src = av_calloc(dm->cycle, sizeof(*dm->clean_src)); - if (!dm->clean_src) - return AVERROR(ENOMEM); - } - - return 0; -} - static av_cold int decimate_init(AVFilterContext *ctx) { DecimateContext *dm = ctx->priv; AVFilterPad pad = { .name = "main", .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, }; int ret; @@ -404,6 +370,31 @@ static int config_output(AVFilterLink *outlink) const AVFilterLink *inlink = ctx->inputs[dm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN]; AVRational fps = inlink->frame_rate; + int max_value; + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); + const int w = inlink->w; + const int h = inlink->h; + + dm->hsub = pix_desc->log2_chroma_w; + dm->vsub = pix_desc->log2_chroma_h; + dm->depth = pix_desc->comp[0].depth; + max_value = (1 << dm->depth) - 1; + dm->scthresh = (int64_t)(((int64_t)max_value * w * h * dm->scthresh_flt) / 100); + dm->dupthresh = (int64_t)(((int64_t)max_value * dm->blockx * dm->blocky * dm->dupthresh_flt) / 100); + dm->nxblocks = (w + dm->blockx/2 - 1) / (dm->blockx/2); + dm->nyblocks = (h + dm->blocky/2 - 1) / (dm->blocky/2); + dm->bdiffsize = dm->nxblocks * dm->nyblocks; + dm->bdiffs = av_malloc_array(dm->bdiffsize, sizeof(*dm->bdiffs)); + dm->queue = av_calloc(dm->cycle, sizeof(*dm->queue)); + + if (!dm->bdiffs || !dm->queue) + return AVERROR(ENOMEM); + + if (dm->ppsrc) { + dm->clean_src = av_calloc(dm->cycle, sizeof(*dm->clean_src)); + if (!dm->clean_src) + return AVERROR(ENOMEM); + } if (!fps.num || !fps.den) { av_log(ctx, AV_LOG_ERROR, "The input needs a constant frame rate; " -- cgit v1.2.3