diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-01-01 02:35:39 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-01-06 01:21:19 +0100 |
commit | a79ac73b631a2d8347f45fbdcb666f37e40ab9fe (patch) | |
tree | e754cd1338d238afc94d1702cd89f335da2ce6a8 | |
parent | 42411a85b78c73897fedf321697fedd61f9c41a6 (diff) | |
download | ffmpeg-a79ac73b631a2d8347f45fbdcb666f37e40ab9fe.tar.gz |
avfilter/vf_idet: Add analyze_interlaced_flag mode
This should allow us to insert idet before scale and let scale have interl=-1 as default in that case
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | doc/filters.texi | 7 | ||||
-rw-r--r-- | libavfilter/vf_idet.c | 41 | ||||
-rw-r--r-- | libavfilter/vf_idet.h | 4 |
3 files changed, 50 insertions, 2 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index 1e2567e9a5..f14f6a9cdf 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -5760,6 +5760,13 @@ Number of frames after which a given frame's contribution to the statistics is halved (i.e., it contributes only 0.5 to it's classification). The default of 0 means that all frames seen are given full weight of 1.0 forever. +@item analyze_interlaced_flag +When this is not 0 then idet will use the specified number of frames to determine +if the interlaced flag is accurate, it will not count undetermined frames. +If the flag is found to be accurate it will be used without any further +computations, if it is found to be inaccuarte it will be cleared without any +further computations. This allows inserting the idet filter as a low computational +method to clean up the interlaced flag @end table @section il diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c index 56e6e76956..4532e48430 100644 --- a/libavfilter/vf_idet.c +++ b/libavfilter/vf_idet.c @@ -34,6 +34,7 @@ static const AVOption idet_options[] = { { "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5}, -1, FLT_MAX, FLAGS }, { "rep_thres", "set repeat threshold", OFFSET(repeat_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 3.0}, -1, FLT_MAX, FLAGS }, { "half_life", "half life of cumulative statistics", OFFSET(half_life), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -1, INT_MAX, FLAGS }, + { "analyze_interlaced_flag", "set number of frames to use to determine if the interlace flag is accurate", OFFSET(analyze_interlaced_flag), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, FLAGS }, { NULL } }; @@ -235,6 +236,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) AVFilterContext *ctx = link->dst; IDETContext *idet = ctx->priv; + // initial frame(s) and not interlaced, just pass through for + // the analyze_interlaced_flag mode + if (idet->analyze_interlaced_flag && + !picref->interlaced_frame && + !idet->next) { + return ff_filter_frame(ctx->outputs[0], picref); + } + if (idet->analyze_interlaced_flag_done) { + if (picref->interlaced_frame && idet->interlaced_flag_accuracy < 0) + picref->interlaced_frame = 0; + return ff_filter_frame(ctx->outputs[0], picref); + } + if (idet->prev) av_frame_free(&idet->prev); idet->prev = idet->cur; @@ -256,7 +270,30 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) ff_idet_init_x86(idet, 1); } - filter(ctx); + if (idet->analyze_interlaced_flag) { + if (idet->cur->interlaced_frame) { + idet->cur->interlaced_frame = 0; + filter(ctx); + if (idet->last_type == PROGRESSIVE) { + idet->interlaced_flag_accuracy --; + idet->analyze_interlaced_flag --; + } else if (idet->last_type != UNDETERMINED) { + idet->interlaced_flag_accuracy ++; + idet->analyze_interlaced_flag --; + } + if (idet->analyze_interlaced_flag == 1) { + ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); + + if (idet->next->interlaced_frame && idet->interlaced_flag_accuracy < 0) + idet->next->interlaced_frame = 0; + idet->analyze_interlaced_flag_done = 1; + av_log(ctx, AV_LOG_INFO, "Final flag accuracy %d\n", idet->interlaced_flag_accuracy); + return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->next)); + } + } + } else { + filter(ctx); + } return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); } @@ -274,7 +311,7 @@ static int request_frame(AVFilterLink *link) ret = ff_request_frame(link->src->inputs[0]); - if (ret == AVERROR_EOF && idet->cur) { + if (ret == AVERROR_EOF && idet->cur && !idet->analyze_interlaced_flag_done) { AVFrame *next = av_frame_clone(idet->next); if (!next) diff --git a/libavfilter/vf_idet.h b/libavfilter/vf_idet.h index af759b476e..47e3d9ce81 100644 --- a/libavfilter/vf_idet.h +++ b/libavfilter/vf_idet.h @@ -63,6 +63,10 @@ typedef struct { AVFrame *prev; ff_idet_filter_func filter_line; + int interlaced_flag_accuracy; + int analyze_interlaced_flag; + int analyze_interlaced_flag_done; + const AVPixFmtDescriptor *csp; int eof; } IDETContext; |