mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-11 09:59:50 +00:00
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:
parent
42411a85b7
commit
a79ac73b63
@ -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
|
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
|
classification). The default of 0 means that all frames seen are given
|
||||||
full weight of 1.0 forever.
|
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
|
@end table
|
||||||
|
|
||||||
@section il
|
@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 },
|
{ "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 },
|
{ "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 },
|
{ "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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,6 +236,19 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
|
|||||||
AVFilterContext *ctx = link->dst;
|
AVFilterContext *ctx = link->dst;
|
||||||
IDETContext *idet = ctx->priv;
|
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)
|
if (idet->prev)
|
||||||
av_frame_free(&idet->prev);
|
av_frame_free(&idet->prev);
|
||||||
idet->prev = idet->cur;
|
idet->prev = idet->cur;
|
||||||
@ -256,7 +270,30 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
|
|||||||
ff_idet_init_x86(idet, 1);
|
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));
|
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]);
|
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);
|
AVFrame *next = av_frame_clone(idet->next);
|
||||||
|
|
||||||
if (!next)
|
if (!next)
|
||||||
|
@ -63,6 +63,10 @@ typedef struct {
|
|||||||
AVFrame *prev;
|
AVFrame *prev;
|
||||||
ff_idet_filter_func filter_line;
|
ff_idet_filter_func filter_line;
|
||||||
|
|
||||||
|
int interlaced_flag_accuracy;
|
||||||
|
int analyze_interlaced_flag;
|
||||||
|
int analyze_interlaced_flag_done;
|
||||||
|
|
||||||
const AVPixFmtDescriptor *csp;
|
const AVPixFmtDescriptor *csp;
|
||||||
int eof;
|
int eof;
|
||||||
} IDETContext;
|
} IDETContext;
|
||||||
|
Loading…
Reference in New Issue
Block a user