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>
pull/101/head
Michael Niedermayer 10 years ago
parent 42411a85b7
commit a79ac73b63
  1. 7
      doc/filters.texi
  2. 41
      libavfilter/vf_idet.c
  3. 4
      libavfilter/vf_idet.h

@ -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

@ -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)

@ -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;

Loading…
Cancel
Save