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>
This commit is contained in:
Michael Niedermayer
2015-01-01 02:35:39 +01:00
parent 42411a85b7
commit a79ac73b63
3 changed files with 50 additions and 2 deletions

View File

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

View File

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