Makes it possible to use deinterlacers which output one frame for each field as 
fallback if field
matching fails (combmatch=full).

Currently, the documented example with fallback on a post-deinterlacer will 
only work in case the
deinterlacer outputs one frame per first field (as yadif=mode=0). The reason 
for that is that
fieldmatch will attempt to match the second field regardless of whether it 
recognizes the end
result is still interlaced. This produces garbled output with for example mixed 
telecined 24fps and
60i content combined with a field-based deinterlaced such as yadif=mode=1.
This patch orders fieldmatch to revert to using the second field of the current 
frame in case the
end result is still interlaced and a post-deinterlacer is assumed to be used.

Signed-off-by: lovesyk <love...@users.noreply.github.com>
---
 libavfilter/vf_fieldmatch.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index 40e559df9e..bf946beec9 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -680,7 +680,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFilterLink *outlink = ctx->outputs[0];
     FieldMatchContext *fm = ctx->priv;
     int combs[] = { -1, -1, -1, -1, -1 };
-    int order, field, i, match, sc = 0, ret = 0;
+    int order, field, i, match, interlaced_frame, sc = 0, ret = 0;
     const int *fxo;
     AVFrame *gen_frames[] = { NULL, NULL, NULL, NULL, NULL };
     AVFrame *dst = NULL;
@@ -793,6 +793,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         }
     }
 
+    /* keep fields as-is if not matched properly */
+    interlaced_frame = combs[match] >= fm->combpel;
+    if (interlaced_frame && fm->combmatch == COMBMATCH_FULL) {
+        match = mC;
+    }
+
     /* get output frame and drop the others */
     if (fm->ppsrc) {
         /* field matching was based on a filtered/post-processed input, we now
@@ -813,7 +819,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     /* mark the frame we are unable to match properly as interlaced so a proper
      * de-interlacer can take the relay */
-    dst->interlaced_frame = combs[match] >= fm->combpel;
+    dst->interlaced_frame = interlaced_frame;
     if (dst->interlaced_frame) {
         av_log(ctx, AV_LOG_WARNING, "Frame #%"PRId64" at %s is still 
interlaced\n",
                outlink->frame_count_in, av_ts2timestr(in->pts, 
&inlink->time_base));
-- 
2.34.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to