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

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
8686 * the first field.
8787 */
8888 int current_field; ///< YADIFCurrentField
89+
90+ int pts_multiplier;
8991 } YADIFContext;
9092
9193 void ff_yadif_init_x86(YADIFContext *yadif);
libavfilter/yadif_common.c+19−5
@@ -62,6 +62,10 @@ FF_ENABLE_DEPRECATION_WARNINGS · 61 unmodified lines
6262
6363 if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) {
6464 yadif->out->pts = cur_pts + next_pts;
65+ if (yadif->pts_multiplier == 1) {
66+ yadif->out->pts >>= 1;
67+ yadif->out->duration >>= 1;
68+ }
6569 } else {
6670 yadif->out->pts = AV_NOPTS_VALUE;
6771 }
@@ -150,8 +154,8 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) · 82 unmodified lines
150154 ff_ccfifo_inject(&yadif->cc_fifo, yadif->out);
151155 av_frame_free(&yadif->prev);
152156 if (yadif->out->pts != AV_NOPTS_VALUE)
153− yadif->out->pts *= 2;
154− yadif->out->duration *= 2;
157+ yadif->out->pts *= yadif->pts_multiplier;
158+ yadif->out->duration *= yadif->pts_multiplier;
155159 return ff_filter_frame(ctx->outputs[0], yadif->out);
156160 }
157161
@@ -168,9 +172,11 @@ FF_ENABLE_DEPRECATION_WARNINGS · 10 unmodified lines
168172 yadif->out->flags &= ~AV_FRAME_FLAG_INTERLACED;
169173
170174 if (yadif->out->pts != AV_NOPTS_VALUE)
171− yadif->out->pts *= 2;
175+ yadif->out->pts *= yadif->pts_multiplier;
172176 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;
174180
175181 return return_frame(ctx, 0);
176182 }
@@ -213,9 +219,17 @@ int ff_yadif_config_output_common(AVFilterLink *outlink) · 36 unmodified lines
213219 {
214220 AVFilterContext *ctx = outlink->src;
215221 YADIFContext *yadif = ctx->priv;
222+ AVRational tb = ctx->inputs[0]->time_base;
216223 int ret;
217224
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+
219233 outlink->w = ctx->inputs[0]->w;
220234 outlink->h = ctx->inputs[0]->h;
221235

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