History

avfilter/yadif_common: fix timestamps with very small timebases

Yadif filter assumed that the output timebase is always half of the input timebase. This is not true if halving the input time base is not representable as an AVRational causing the output timestamps to be invalidly scaled in such a case. So let's use av_reduce instead of av_mul_q when calculating the output time base and if the conversion is inexact then let's fall back to the original timebase which probably makes more parctical sense than using x/INT_MAX. Fixes invalidly scaled pts_time values in this command line: ffmpeg -f lavfi -i testsrc -vf settb=tb=1/2000000000,yadif,showinfo -f null none

Marton Balint committed 2 years ago

Commit 52cc89d1 parent 268062f2 files · +21 −5Browse files

Showing the changes to libavfilter (2 of 2 files). Show all

Unified · Split

2 files
  1. libavfilter/yadif.h +2 −0
  2. libavfilter/yadif_common.c +19 −5
libavfilter/yadif.h+2−0
@@ -86,6 +86,8 @@ typedef struct YADIFContext { · 85 unmodified lines
86 * the first field.86 * the first field.
87 */87 */
88 int current_field; ///< YADIFCurrentField88 int current_field; ///< YADIFCurrentField
89
90 int pts_multiplier;
89} YADIFContext;91} YADIFContext;
90 92
91void ff_yadif_init_x86(YADIFContext *yadif);93void ff_yadif_init_x86(YADIFContext *yadif);
libavfilter/yadif_common.c+19−5
@@ -62,6 +62,10 @@ FF_ENABLE_DEPRECATION_WARNINGS · 61 unmodified lines
62 62
63 if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {63 if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {
64 yadif->out->pts = cur_pts + next_pts;64 yadif->out->pts = cur_pts + next_pts;
65 if (yadif->pts_multiplier == 1) {
66 yadif->out->pts >>= 1;
67 yadif->out->duration >>= 1;
68 }
65 } else {69 } else {
66 yadif->out->pts = AV_NOPTS_VALUE;70 yadif->out->pts = AV_NOPTS_VALUE;
67 }71 }
@@ -150,8 +154,8 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) · 82 unmodified lines
150 ff_ccfifo_inject(&yadif->cc_fifo, yadif->out);154 ff_ccfifo_inject(&yadif->cc_fifo, yadif->out);
151 av_frame_free(&yadif->prev);155 av_frame_free(&yadif->prev);
152 if (yadif->out->pts != AV_NOPTS_VALUE)156 if (yadif->out->pts != AV_NOPTS_VALUE)
153 yadif->out->pts *= 2;157 yadif->out->pts *= yadif->pts_multiplier;
154 yadif->out->duration *= 2;158 yadif->out->duration *= yadif->pts_multiplier;
155 return ff_filter_frame(ctx->outputs[0], yadif->out);159 return ff_filter_frame(ctx->outputs[0], yadif->out);
156 }160 }
157 161
@@ -168,9 +172,11 @@ FF_ENABLE_DEPRECATION_WARNINGS · 10 unmodified lines
168 yadif->out->flags &= ~AV_FRAME_FLAG_INTERLACED;172 yadif->out->flags &= ~AV_FRAME_FLAG_INTERLACED;
169 173
170 if (yadif->out->pts != AV_NOPTS_VALUE)174 if (yadif->out->pts != AV_NOPTS_VALUE)
171 yadif->out->pts *= 2;175 yadif->out->pts *= yadif->pts_multiplier;
172 if (!(yadif->mode & 1))176 if (!(yadif->mode & 1))
173 yadif->out->duration *= 2;177 yadif->out->duration *= yadif->pts_multiplier;
178 else if (yadif->pts_multiplier == 1)
179 yadif->out->duration >>= 1;
174 180
175 return return_frame(ctx, 0);181 return return_frame(ctx, 0);
176}182}
@@ -213,9 +219,17 @@ int ff_yadif_config_output_common(AVFilterLink *outlink) · 36 unmodified lines
213{219{
214 AVFilterContext *ctx = outlink->src;220 AVFilterContext *ctx = outlink->src;
215 YADIFContext *yadif = ctx->priv;221 YADIFContext *yadif = ctx->priv;
222 AVRational tb = ctx->inputs[0]->time_base;
216 int ret;223 int ret;
217 224
218 outlink->time_base = av_mul_q(ctx->inputs[0]->time_base, (AVRational){1, 2});225 if (av_reduce(&outlink->time_base.num, &outlink->time_base.den, tb.num, tb.den * 2LL, INT_MAX)) {
226 yadif->pts_multiplier = 2;
227 } else {
228 av_log(ctx, AV_LOG_WARNING, "Cannot use exact output timebase\n");
229 outlink->time_base = tb;
230 yadif->pts_multiplier = 1;
231 }
232
219 outlink->w = ctx->inputs[0]->w;233 outlink->w = ctx->inputs[0]->w;
220 outlink->h = ctx->inputs[0]->h;234 outlink->h = ctx->inputs[0]->h;
221 235

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t