mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
avfilter/vf_tinterlace: Fix vf_tinterlace mode 6 (interlacex2)
The purpose of this filter mode is to allow interlaced content to display properly in interlaced video modes, as described in http://forum.xbmc.org/showthread.php?tid=81834 and https://github.com/mpv-player/mpv/issues/624#issuecomment-37685195 . The filter doubles the video frame rate, but does not work properly because: (1) it does not set the properties of the output stream to indicate the doubled frame rate, and (2) it does not set an appropriate PTS on the extra frames. The attached patch fixes these problems by settling these values the same way they are set in vf_yadif mode 1 (field) which also doubles the frame rate. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
9b1d264e87
commit
0d5ae023b2
@ -145,6 +145,12 @@ static int config_out_props(AVFilterLink *outlink)
|
|||||||
tinterlace->mode);
|
tinterlace->mode);
|
||||||
tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
|
tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
|
||||||
}
|
}
|
||||||
|
if (tinterlace->mode == MODE_INTERLACEX2) {
|
||||||
|
outlink->time_base.num = inlink->time_base.num;
|
||||||
|
outlink->time_base.den = inlink->time_base.den * 2;
|
||||||
|
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
|
||||||
|
}
|
||||||
|
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
|
av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
|
||||||
tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",
|
tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",
|
||||||
inlink->h, outlink->h);
|
inlink->h, outlink->h);
|
||||||
@ -321,6 +327,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
|
|||||||
if (!out)
|
if (!out)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
out->interlaced_frame = 1;
|
out->interlaced_frame = 1;
|
||||||
|
if (cur->pts != AV_NOPTS_VALUE)
|
||||||
|
out->pts = cur->pts*2;
|
||||||
|
|
||||||
if ((ret = ff_filter_frame(outlink, out)) < 0)
|
if ((ret = ff_filter_frame(outlink, out)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -333,6 +341,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
|
|||||||
av_frame_copy_props(out, next);
|
av_frame_copy_props(out, next);
|
||||||
out->interlaced_frame = 1;
|
out->interlaced_frame = 1;
|
||||||
|
|
||||||
|
if (next->pts != AV_NOPTS_VALUE && cur->pts != AV_NOPTS_VALUE)
|
||||||
|
out->pts = cur->pts + next->pts;
|
||||||
|
else
|
||||||
|
out->pts = AV_NOPTS_VALUE;
|
||||||
/* write current frame second field lines into the second field of the new frame */
|
/* write current frame second field lines into the second field of the new frame */
|
||||||
copy_picture_field(out->data, out->linesize,
|
copy_picture_field(out->data, out->linesize,
|
||||||
(const uint8_t **)cur->data, cur->linesize,
|
(const uint8_t **)cur->data, cur->linesize,
|
||||||
|
Loading…
Reference in New Issue
Block a user