]> git.sesse.net Git - ffmpeg/commitdiff
avfilter/vf_decimate: fix overreads when using ppsrc
authorPaul B Mahol <onemda@gmail.com>
Tue, 22 Dec 2020 12:19:12 +0000 (13:19 +0100)
committerPaul B Mahol <onemda@gmail.com>
Tue, 22 Dec 2020 12:31:55 +0000 (13:31 +0100)
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

index 8407d9942cdc26dc3713c60a99f4ab3a7b09e0ce..25bd5bda57ee960a50b21504cef49646b765f2c8 100644 (file)
@@ -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; "