summaryrefslogtreecommitdiff
path: root/libavfilter/vf_yadif.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavfilter/vf_yadif.c')
-rw-r--r--libavfilter/vf_yadif.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 684f9099fa..fb4862d0be 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -59,6 +59,7 @@ typedef struct {
int w, int prefs, int mrefs, int parity, int mode);
const AVPixFmtDescriptor *csp;
+ int eof;
} YADIFContext;
#define CHECK(j)\
@@ -216,22 +217,11 @@ static void return_frame(AVFilterContext *ctx, int is_second)
filter(ctx, yadif->out, tff ^ !is_second, tff);
if (is_second) {
- if (yadif->next->pts != AV_NOPTS_VALUE &&
- yadif->cur->pts != AV_NOPTS_VALUE) {
- uint64_t next_pts = yadif->next->pts;
- uint64_t cur_pts = yadif->cur->pts;
- uint64_t prev_pts = yadif->prev->pts;
-
- uint64_t ft = FFMIN3( cur_pts-prev_pts,
- next_pts-cur_pts,
- (next_pts-prev_pts)/2);
-
- if(next_pts - cur_pts < 2*ft)
- yadif->out->pts =
- (next_pts&cur_pts) +
- ((next_pts^cur_pts)>>1);
- else
- yadif->out->pts = cur_pts + ft/2;
+ int64_t cur_pts = yadif->cur->pts;
+ int64_t next_pts = yadif->next->pts;
+
+ if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {
+ yadif->out->pts = cur_pts + next_pts;
} else {
yadif->out->pts = AV_NOPTS_VALUE;
}
@@ -264,6 +254,8 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
avfilter_unref_buffer(yadif->prev);
yadif->prev = NULL;
+ if (yadif->out->pts != AV_NOPTS_VALUE)
+ yadif->out->pts *= 2;
avfilter_start_frame(ctx->outputs[0], yadif->out);
return;
}
@@ -276,6 +268,8 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
yadif->out->video->interlaced = 0;
+ if (yadif->out->pts != AV_NOPTS_VALUE)
+ yadif->out->pts *= 2;
avfilter_start_frame(ctx->outputs[0], yadif->out);
}
@@ -309,8 +303,21 @@ static int request_frame(AVFilterLink *link)
do {
int ret;
- if ((ret = avfilter_request_frame(link->src->inputs[0])))
+ if (yadif->eof)
+ return AVERROR_EOF;
+
+ ret = avfilter_request_frame(link->src->inputs[0]);
+
+ if (ret == AVERROR_EOF && yadif->next) {
+ AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ);
+ next->pts = yadif->next->pts * 2 - yadif->cur->pts;
+
+ start_frame(link->src->inputs[0], next);
+ end_frame(link->src->inputs[0]);
+ yadif->eof = 1;
+ } else if (ret < 0) {
return ret;
+ }
} while (!yadif->cur);
return 0;
@@ -411,6 +418,16 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { }
+static int config_props(AVFilterLink *link)
+{
+ link->time_base.num = link->src->inputs[0]->time_base.num;
+ link->time_base.den = link->src->inputs[0]->time_base.den * 2;
+ link->w = link->src->inputs[0]->w;
+ link->h = link->src->inputs[0]->h;
+
+ return 0;
+}
+
AVFilter avfilter_vf_yadif = {
.name = "yadif",
.description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."),
@@ -432,6 +449,7 @@ AVFilter avfilter_vf_yadif = {
.outputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.poll_frame = poll_frame,
- .request_frame = request_frame, },
+ .request_frame = request_frame,
+ .config_props = config_props, },
{ .name = NULL}},
};