From 2a375bb400febf8c1a2dfa87c29fd4185663454c Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sun, 3 Jul 2011 13:19:44 +0200 Subject: [PATCH] Add mode to yadif to enable/disable deinterlacing based on src frame "interlaced" flag Signed-off-by: Joakim Plate --- doc/filters.texi | 14 +++++++++++++- libavfilter/vf_yadif.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index b4ffcd9a04..c96de41bfa 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1737,7 +1737,7 @@ Flip the input video vertically. Deinterlace the input video ("yadif" means "yet another deinterlacing filter"). -It accepts the optional parameters: @var{mode}:@var{parity}. +It accepts the optional parameters: @var{mode}:@var{parity}:@var(auto). @var{mode} specifies the interlacing mode to adopt, accepts one of the following values: @@ -1771,6 +1771,18 @@ Default value is -1. If interlacing is unknown or decoder does not export this information, top field first will be assumed. +@var{auto] specifies if deinterlacer should trust the interlaced flag +and only deinterlace frames marked as interlaced + +@table @option +@item 0 +deinterlace all frames +@item 1 +only deinterlace frames marked as interlaced +@end table + +Default value is 0. + @c man end VIDEO FILTERS @chapter Video Sources diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 296328b71a..56e4489986 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -44,6 +44,12 @@ typedef struct { int frame_pending; + /** + * 0: deinterlace all frames + * 1: only deinterlace frames marked as interlaced + */ + int auto_enable; + AVFilterBufferRef *cur; AVFilterBufferRef *next; AVFilterBufferRef *prev; @@ -240,6 +246,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) if (!yadif->cur) return; + if (yadif->auto_enable && !yadif->cur->video->interlaced) { + yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); + avfilter_unref_buffer(yadif->prev); + yadif->prev = NULL; + avfilter_start_frame(ctx->outputs[0], yadif->out); + return; + } + if (!yadif->prev) yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); @@ -259,6 +273,12 @@ static void end_frame(AVFilterLink *link) if (!yadif->out) return; + if (yadif->auto_enable && !yadif->cur->video->interlaced) { + avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1); + avfilter_end_frame(ctx->outputs[0]); + return; + } + return_frame(ctx, 0); } @@ -299,6 +319,9 @@ static int poll_frame(AVFilterLink *link) } assert(yadif->next || !val); + if (yadif->auto_enable && yadif->next && !yadif->next->video->interlaced) + return val; + return val * ((yadif->mode&1)+1); } @@ -344,9 +367,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) yadif->mode = 0; yadif->parity = -1; + yadif->auto_enable = 0; yadif->csp = NULL; - if (args) sscanf(args, "%d:%d", &yadif->mode, &yadif->parity); + if (args) sscanf(args, "%d:%d:%d", &yadif->mode, &yadif->parity, &yadif->auto_enable); yadif->filter_line = filter_line_c; if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3) @@ -356,7 +380,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) yadif->filter_line = ff_yadif_filter_line_mmx; - av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d\n", yadif->mode, yadif->parity); + av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d auto_enable:%d\n", yadif->mode, yadif->parity, yadif->auto_enable); return 0; }