2 * Copyright (c) 2013 Nicolas George
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
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
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/avassert.h"
23 #include "bufferqueue.h"
24 #include "framesync.h"
27 #define OFFSET(member) offsetof(FFFrameSync, member)
29 static const char *framesync_name(void *ptr
)
34 static const AVClass framesync_class
= {
35 .version
= LIBAVUTIL_VERSION_INT
,
36 .class_name
= "framesync",
37 .item_name
= framesync_name
,
38 .category
= AV_CLASS_CATEGORY_FILTER
,
40 .parent_log_context_offset
= OFFSET(parent
),
49 void ff_framesync_init(FFFrameSync
*fs
, void *parent
, unsigned nb_in
)
51 fs
->class = &framesync_class
;
56 static void framesync_sync_level_update(FFFrameSync
*fs
)
58 unsigned i
, level
= 0;
60 for (i
= 0; i
< fs
->nb_in
; i
++)
61 if (fs
->in
[i
].state
!= STATE_EOF
)
62 level
= FFMAX(level
, fs
->in
[i
].sync
);
63 av_assert0(level
<= fs
->sync_level
);
64 if (level
< fs
->sync_level
)
65 av_log(fs
, AV_LOG_VERBOSE
, "Sync level %u\n", level
);
67 fs
->sync_level
= level
;
72 int ff_framesync_configure(FFFrameSync
*fs
)
77 if (!fs
->time_base
.num
) {
78 for (i
= 0; i
< fs
->nb_in
; i
++) {
80 if (fs
->time_base
.num
) {
81 gcd
= av_gcd(fs
->time_base
.den
, fs
->in
[i
].time_base
.den
);
82 lcm
= (fs
->time_base
.den
/ gcd
) * fs
->in
[i
].time_base
.den
;
83 if (lcm
< AV_TIME_BASE
/ 2) {
84 fs
->time_base
.den
= lcm
;
85 fs
->time_base
.num
= av_gcd(fs
->time_base
.num
,
86 fs
->in
[i
].time_base
.num
);
88 fs
->time_base
.num
= 1;
89 fs
->time_base
.den
= AV_TIME_BASE
;
93 fs
->time_base
= fs
->in
[i
].time_base
;
97 if (!fs
->time_base
.num
) {
98 av_log(fs
, AV_LOG_ERROR
, "Impossible to set time base\n");
99 return AVERROR(EINVAL
);
101 av_log(fs
, AV_LOG_VERBOSE
, "Selected %d/%d time base\n",
102 fs
->time_base
.num
, fs
->time_base
.den
);
105 for (i
= 0; i
< fs
->nb_in
; i
++)
106 fs
->in
[i
].pts
= fs
->in
[i
].pts_next
= AV_NOPTS_VALUE
;
107 fs
->sync_level
= UINT_MAX
;
108 framesync_sync_level_update(fs
);
113 static void framesync_advance(FFFrameSync
*fs
)
121 while (!fs
->frame_ready
) {
123 for (i
= 0; i
< fs
->nb_in
; i
++) {
124 if (!fs
->in
[i
].have_next
) {
125 if (latest
< 0 || fs
->in
[i
].pts
< fs
->in
[latest
].pts
)
130 fs
->in_request
= latest
;
134 pts
= fs
->in
[0].pts_next
;
135 for (i
= 1; i
< fs
->nb_in
; i
++)
136 if (fs
->in
[i
].pts_next
< pts
)
137 pts
= fs
->in
[i
].pts_next
;
138 if (pts
== INT64_MAX
) {
142 for (i
= 0; i
< fs
->nb_in
; i
++) {
143 if (fs
->in
[i
].pts_next
== pts
||
144 (fs
->in
[i
].before
== EXT_INFINITY
&&
145 fs
->in
[i
].state
== STATE_BOF
)) {
146 av_frame_free(&fs
->in
[i
].frame
);
147 fs
->in
[i
].frame
= fs
->in
[i
].frame_next
;
148 fs
->in
[i
].pts
= fs
->in
[i
].pts_next
;
149 fs
->in
[i
].frame_next
= NULL
;
150 fs
->in
[i
].pts_next
= AV_NOPTS_VALUE
;
151 fs
->in
[i
].have_next
= 0;
152 fs
->in
[i
].state
= fs
->in
[i
].frame
? STATE_RUN
: STATE_EOF
;
153 if (fs
->in
[i
].sync
== fs
->sync_level
&& fs
->in
[i
].frame
)
155 if (fs
->in
[i
].state
== STATE_EOF
&&
156 fs
->in
[i
].after
== EXT_STOP
)
163 for (i
= 0; i
< fs
->nb_in
; i
++)
164 if ((fs
->in
[i
].state
== STATE_BOF
&&
165 fs
->in
[i
].before
== EXT_STOP
))
171 static int64_t framesync_pts_extrapolate(FFFrameSync
*fs
, unsigned in
,
174 /* Possible enhancement: use the link's frame rate */
178 static void framesync_inject_frame(FFFrameSync
*fs
, unsigned in
, AVFrame
*frame
)
182 av_assert0(!fs
->in
[in
].have_next
);
184 pts
= av_rescale_q(frame
->pts
, fs
->in
[in
].time_base
, fs
->time_base
);
187 pts
= fs
->in
[in
].state
!= STATE_RUN
|| fs
->in
[in
].after
== EXT_INFINITY
188 ? INT64_MAX
: framesync_pts_extrapolate(fs
, in
, fs
->in
[in
].pts
);
190 framesync_sync_level_update(fs
);
192 fs
->in
[in
].frame_next
= frame
;
193 fs
->in
[in
].pts_next
= pts
;
194 fs
->in
[in
].have_next
= 1;
197 int ff_framesync_add_frame(FFFrameSync
*fs
, unsigned in
, AVFrame
*frame
)
199 av_assert1(in
< fs
->nb_in
);
200 if (!fs
->in
[in
].have_next
)
201 framesync_inject_frame(fs
, in
, frame
);
203 ff_bufqueue_add(fs
, &fs
->in
[in
].queue
, frame
);
207 void ff_framesync_next(FFFrameSync
*fs
)
211 av_assert0(!fs
->frame_ready
);
212 for (i
= 0; i
< fs
->nb_in
; i
++)
213 if (!fs
->in
[i
].have_next
&& fs
->in
[i
].queue
.available
)
214 framesync_inject_frame(fs
, i
, ff_bufqueue_get(&fs
->in
[i
].queue
));
216 framesync_advance(fs
);
219 void ff_framesync_drop(FFFrameSync
*fs
)
224 int ff_framesync_get_frame(FFFrameSync
*fs
, unsigned in
, AVFrame
**rframe
,
228 unsigned need_copy
= 0, i
;
232 if (!fs
->in
[in
].frame
) {
236 frame
= fs
->in
[in
].frame
;
238 /* Find out if we need to copy the frame: is there another sync
239 stream, and do we know if its current frame will outlast this one? */
240 pts_next
= fs
->in
[in
].have_next
? fs
->in
[in
].pts_next
: INT64_MAX
;
241 for (i
= 0; i
< fs
->nb_in
&& !need_copy
; i
++)
242 if (i
!= in
&& fs
->in
[i
].sync
&&
243 (!fs
->in
[i
].have_next
|| fs
->in
[i
].pts_next
< pts_next
))
246 if (!(frame
= av_frame_clone(frame
)))
247 return AVERROR(ENOMEM
);
248 if ((ret
= av_frame_make_writable(frame
)) < 0) {
249 av_frame_free(&frame
);
253 fs
->in
[in
].frame
= NULL
;
261 void ff_framesync_uninit(FFFrameSync
*fs
)
265 for (i
= 0; i
< fs
->nb_in
; i
++) {
266 av_frame_free(&fs
->in
[i
].frame
);
267 av_frame_free(&fs
->in
[i
].frame_next
);
268 ff_bufqueue_discard_all(&fs
->in
[i
].queue
);
272 int ff_framesync_process_frame(FFFrameSync
*fs
, unsigned all
)
276 av_assert0(fs
->on_event
);
278 ff_framesync_next(fs
);
279 if (fs
->eof
|| !fs
->frame_ready
)
281 if ((ret
= fs
->on_event(fs
)) < 0)
283 ff_framesync_drop(fs
);
288 if (!count
&& fs
->eof
)
293 int ff_framesync_filter_frame(FFFrameSync
*fs
, AVFilterLink
*inlink
,
298 if ((ret
= ff_framesync_process_frame(fs
, 1)) < 0)
300 if ((ret
= ff_framesync_add_frame(fs
, FF_INLINK_IDX(inlink
), in
)) < 0)
302 if ((ret
= ff_framesync_process_frame(fs
, 0)) < 0)
307 int ff_framesync_request_frame(FFFrameSync
*fs
, AVFilterLink
*outlink
)
309 AVFilterContext
*ctx
= outlink
->src
;
312 if ((ret
= ff_framesync_process_frame(fs
, 0)) < 0)
318 outlink
->flags
|= FF_LINK_FLAG_REQUEST_LOOP
;
319 input
= fs
->in_request
;
320 ret
= ff_request_frame(ctx
->inputs
[input
]);
321 if (ret
== AVERROR_EOF
) {
322 if ((ret
= ff_framesync_add_frame(fs
, input
, NULL
)) < 0)
324 if ((ret
= ff_framesync_process_frame(fs
, 0)) < 0)