aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2015-01-01 02:35:39 +0100
committerMichael Niedermayer <michaelni@gmx.at>2015-01-06 01:21:19 +0100
commita79ac73b631a2d8347f45fbdcb666f37e40ab9fe (patch)
treee754cd1338d238afc94d1702cd89f335da2ce6a8
parent42411a85b78c73897fedf321697fedd61f9c41a6 (diff)
downloadffmpeg-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.texi7
-rw-r--r--libavfilter/vf_idet.c41
-rw-r--r--libavfilter/vf_idet.h4
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;