]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_decimate.c
avfilter/vf_identity: fix typo
[ffmpeg] / libavfilter / vf_decimate.c
index 8407d9942cdc26dc3713c60a99f4ab3a7b09e0ce..72ed349427b9971845bc45537100517b6c56225e 100644 (file)
@@ -167,11 +167,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     dm->got_frame[INPUT_MAIN] = dm->got_frame[INPUT_CLEANSRC] = 0;
 
     if (dm->ppsrc)
-        in = dm->clean_src[dm->fid];
+        in = dm->queue[dm->fid].frame;
 
     if (in) {
         /* update frame metrics */
-        prv = dm->fid ? (dm->ppsrc ? dm->clean_src[dm->fid - 1] : dm->queue[dm->fid - 1].frame) : dm->last;
+        prv = dm->fid ? dm->queue[dm->fid - 1].frame : dm->last;
         if (!prv) {
             dm->queue[dm->fid].maxbdiff = INT64_MAX;
             dm->queue[dm->fid].totdiff  = INT64_MAX;
@@ -219,8 +219,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
             av_frame_free(&dm->queue[i].frame);
         } else {
             AVFrame *frame = dm->queue[i].frame;
-            if (!frame)
-                continue;
             dm->queue[i].frame = NULL;
             if (frame->pts != AV_NOPTS_VALUE && dm->start_pts == AV_NOPTS_VALUE)
                 dm->start_pts = frame->pts;
@@ -269,19 +267,25 @@ static int activate(AVFilterContext *ctx)
     }
     if (ret < 0) {
         return ret;
-    } else if (dm->eof & ((1 << INPUT_MAIN) | (dm->ppsrc << INPUT_CLEANSRC))) {
+    } else if (dm->eof == ((1 << INPUT_MAIN) | (dm->ppsrc << INPUT_CLEANSRC))) {
         ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts);
         return 0;
     } else if (!(dm->eof & (1 << INPUT_MAIN)) && ff_inlink_acknowledge_status(ctx->inputs[INPUT_MAIN], &status, &pts)) {
         if (status == AVERROR_EOF) { // flushing
             dm->eof |= 1 << INPUT_MAIN;
-            if (!dm->ppsrc)
-                return filter_frame(ctx->inputs[INPUT_MAIN], NULL);
+            if (dm->ppsrc)
+                filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL);
+            filter_frame(ctx->inputs[INPUT_MAIN], NULL);
+            ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts);
+            return 0;
         }
     } else if (dm->ppsrc && !(dm->eof & (1 << INPUT_CLEANSRC)) && ff_inlink_acknowledge_status(ctx->inputs[INPUT_CLEANSRC], &status, &pts)) {
         if (status == AVERROR_EOF) { // flushing
             dm->eof |= 1 << INPUT_CLEANSRC;
-            return filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL);
+            filter_frame(ctx->inputs[INPUT_MAIN], NULL);
+            filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL);
+            ff_outlink_set_status(ctx->outputs[0], AVERROR_EOF, dm->last_pts);
+            return 0;
         }
     }
 
@@ -297,46 +301,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;
 
@@ -387,8 +357,12 @@ static int query_formats(AVFilterContext *ctx)
 #define PF_ALPHA(suf)   AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf
 #define PF(suf)         PF_NOALPHA(suf), PF_ALPHA(suf)
         PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16),
+        AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV440P12,
         AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
-        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
+        AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
+        AV_PIX_FMT_YUVJ411P,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14,
+        AV_PIX_FMT_GRAY16,
         AV_PIX_FMT_NONE
     };
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
@@ -401,9 +375,33 @@ static int config_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
     DecimateContext *dm = ctx->priv;
-    const AVFilterLink *inlink =
-        ctx->inputs[dm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN];
+    const AVFilterLink *inlink = ctx->inputs[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; "
@@ -416,8 +414,13 @@ static int config_output(AVFilterLink *outlink)
     outlink->time_base  = inlink->time_base;
     outlink->frame_rate = fps;
     outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
-    outlink->w = inlink->w;
-    outlink->h = inlink->h;
+    if (dm->ppsrc) {
+        outlink->w = ctx->inputs[INPUT_CLEANSRC]->w;
+        outlink->h = ctx->inputs[INPUT_CLEANSRC]->h;
+    } else {
+        outlink->w = inlink->w;
+        outlink->h = inlink->h;
+    }
     dm->ts_unit = av_inv_q(av_mul_q(fps, outlink->time_base));
     return 0;
 }
@@ -431,7 +434,7 @@ static const AVFilterPad decimate_outputs[] = {
     { NULL }
 };
 
-AVFilter ff_vf_decimate = {
+const AVFilter ff_vf_decimate = {
     .name          = "decimate",
     .description   = NULL_IF_CONFIG_SMALL("Decimate frames (post field matching filter)."),
     .init          = decimate_init,