avfilter/vf_idet: Fixes issue with idet not flushing last frame.
Uses a similar approach as vf_yadif to flush the last frame in idet. Quick test with 50 frames from vsynth1: ./ffmpeg.old -i fate-suite/ffmpeg-synthetic/vsynth1/%02d.pgm -vf idet -f mp4 -y /dev/null 2>&1 | grep Multi (gives) [Parsed_idet_0 @ 0x261ebb0] Multi frame detection: TFF:0 BFF:0 Progressive:48 Undetermined:1 ./ffmpeg -i fate-suite/ffmpeg-synthetic/vsynth1/%02d.pgm -vf idet -f mp4 -y /dev/null 2>&1 | grep Multi (gives) [Parsed_idet_0 @ 0x35a0bb0] Multi frame detection: TFF:0 BFF:0 Progressive:49 Undetermined:1 Fate tests have been updated. (In testing, it seems this filter will also need a subsequent patch for single frame input) Signed-off-by: Neil Birkbeck <neil.birkbeck@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
committed by
Michael Niedermayer
parent
a39201818f
commit
ad5c43bb36
@ -191,6 +191,35 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
|
|||||||
return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
|
return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int request_frame(AVFilterLink *link)
|
||||||
|
{
|
||||||
|
AVFilterContext *ctx = link->src;
|
||||||
|
IDETContext *idet = ctx->priv;
|
||||||
|
|
||||||
|
do {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (idet->eof)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
|
||||||
|
ret = ff_request_frame(link->src->inputs[0]);
|
||||||
|
|
||||||
|
if (ret == AVERROR_EOF && idet->cur) {
|
||||||
|
AVFrame *next = av_frame_clone(idet->next);
|
||||||
|
|
||||||
|
if (!next)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
filter_frame(link->src->inputs[0], next);
|
||||||
|
idet->eof = 1;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (!idet->cur);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static av_cold void uninit(AVFilterContext *ctx)
|
static av_cold void uninit(AVFilterContext *ctx)
|
||||||
{
|
{
|
||||||
IDETContext *idet = ctx->priv;
|
IDETContext *idet = ctx->priv;
|
||||||
@ -253,6 +282,7 @@ static av_cold int init(AVFilterContext *ctx)
|
|||||||
{
|
{
|
||||||
IDETContext *idet = ctx->priv;
|
IDETContext *idet = ctx->priv;
|
||||||
|
|
||||||
|
idet->eof = 0;
|
||||||
idet->last_type = UNDETERMINED;
|
idet->last_type = UNDETERMINED;
|
||||||
memset(idet->history, UNDETERMINED, HIST_SIZE);
|
memset(idet->history, UNDETERMINED, HIST_SIZE);
|
||||||
|
|
||||||
@ -279,6 +309,7 @@ static const AVFilterPad idet_outputs[] = {
|
|||||||
.name = "default",
|
.name = "default",
|
||||||
.type = AVMEDIA_TYPE_VIDEO,
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
.config_props = config_output,
|
.config_props = config_output,
|
||||||
|
.request_frame = request_frame
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
@ -50,6 +50,7 @@ typedef struct {
|
|||||||
ff_idet_filter_func filter_line;
|
ff_idet_filter_func filter_line;
|
||||||
|
|
||||||
const AVPixFmtDescriptor *csp;
|
const AVPixFmtDescriptor *csp;
|
||||||
|
int eof;
|
||||||
} IDETContext;
|
} IDETContext;
|
||||||
|
|
||||||
void ff_idet_init_x86(IDETContext *idet, int for_16b);
|
void ff_idet_init_x86(IDETContext *idet, int for_16b);
|
||||||
|
@ -1 +1 @@
|
|||||||
idet 1790336872e844c867a53150b8ee8810
|
idet 005e6ddc8a5daf11cf866a1ec76c2572
|
||||||
|
Reference in New Issue
Block a user