1 /*
2 * Copyright (c) 2014 Nicholas Robbins
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * remove judder in video stream
24 *
25 * Algorithm:
26 * - If the old packets had PTS of old_pts[i]. Replace these with new
27 * value based on the running average of the last n=cycle frames. So
28 *
29 * new_pts[i] = Sum(k=i-n+1, i, old_pts[k])/n
30 * + (old_pts[i]-old_pts[i-n])*(n-1)/2n
31 *
32 * For any repeating pattern of length n of judder this will produce
33 * an even progression of PTS's.
34 *
35 * - In order to avoid calculating this sum ever frame, a running tally
36 * is maintained in ctx->new_pts. Each frame the new term at the start
37 * of the sum is added, the one and the end is removed, and the offset
38 * terms (second line in formula above) are recalculated.
39 *
40 * - To aid in this a ringbuffer of the last n-2 PTS's is maintained in
41 * ctx->ringbuff. With the indices of the first two and last two entries
42 * stored in i1, i2, i3, & i4.
43 *
44 * - To ensure that the new PTS's are integers, time_base is divided
45 * by 2n. This removes the division in the new_pts calculation.
46 *
47 * - frame_rate is also multiplied by 2n to allow the frames to fall
48 * where they may in what may now be a VFR output. This produces more
49 * even output then setting frame_rate=1/0 in practice.
50 */
51
56
63
64 /* options */
67
68 #define OFFSET(x) offsetof(DejudderContext, x)
69 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
70
72 {"cycle", "set the length of the cycle to use for dejuddering",
75 };
76
78
80 {
86
89
91
92 return 0;
93 }
94
96 {
98
99 s->ringbuff =
av_calloc(
s->cycle + 2,
sizeof(*
s->ringbuff));
102
108 s->start_count =
s->cycle + 2;
109
110 return 0;
111 }
112
114 {
116
118 }
119
121 {
122 int k;
129
132
133 if (
s->start_count) {
135 s->new_pts = next_pts * 2 *
s->cycle;
136 } else {
137 if (next_pts < judbuff[
s->i2]) {
138 offset = next_pts + judbuff[
s->i3] - judbuff[
s->i4] - judbuff[
s->i1];
139 for (k = 0; k <
s->cycle + 2; k++)
141 }
142 s->new_pts += (
s->cycle - 1) * (judbuff[
s->i3] - judbuff[
s->i1])
143 + (
s->cycle + 1) * (next_pts - judbuff[
s->i4]);
144 }
145
146 judbuff[
s->i2] = next_pts;
150 s->i4 = (
s->i4 + 1) % (
s->cycle + 2);
151
153
154 for (k = 0; k <
s->cycle + 2; k++)
157
159 }
160
162 {
166 },
167 };
168
170 {
174 },
175 };
176
181 .priv_class = &dejudder_class,
186 };