History

lavfi/framesync2: implement "activate" design.

With this helper API, filters that used the first framesync helper API can easily be changed to use the new and more extensible design for filters with a single activate() callback.

Nicolas George committed 9 years ago

Commit 4e0e9ce1 parent ed1c8842 files · +82 −161Browse files

Showing the changes to libavfilter/framesync2.c (1 of 2 files). Show all

Unified · Split

libavfilter/framesync2.c+68−98
@@ -18,12 +18,9 @@ · 17 unmodified lines
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */19 */
20 20
21#define FF_INTERNAL_FIELDS 1
22#include "framequeue.h"
23
24#include "libavutil/avassert.h"21#include "libavutil/avassert.h"
25#include "avfilter.h"22#include "avfilter.h"
26#include "bufferqueue.h"23#include "filters.h"
27#include "framesync2.h"24#include "framesync2.h"
28#include "internal.h"25#include "internal.h"
29 26
@@ -49,8 +46,13 @@ enum { · 19 unmodified lines
49 STATE_EOF,46 STATE_EOF,
50};47};
51 48
52int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in)49int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
53{50{
51 /* For filters with several outputs, we will not be able to assume which
52 output is relevant for ff_outlink_frame_wanted() and
53 ff_outlink_set_status(). To be designed when needed. */
54 av_assert0(parent->nb_outputs == 1);
55
54 fs->class = &framesync_class;56 fs->class = &framesync_class;
55 fs->parent = parent;57 fs->parent = parent;
56 fs->nb_in = nb_in;58 fs->nb_in = nb_in;
@@ -61,6 +63,13 @@ int ff_framesync2_init(FFFrameSync *fs, void *parent, unsigned nb_in) · 4 unmodified lines
61 return 0;63 return 0;
62}64}
63 65
66static void framesync_eof(FFFrameSync *fs)
67{
68 fs->eof = 1;
69 fs->frame_ready = 0;
70 ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE);
71}
72
64static void framesync_sync_level_update(FFFrameSync *fs)73static void framesync_sync_level_update(FFFrameSync *fs)
65{74{
66 unsigned i, level = 0;75 unsigned i, level = 0;
@@ -74,7 +83,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) · 7 unmodified lines
74 if (level)83 if (level)
75 fs->sync_level = level;84 fs->sync_level = level;
76 else85 else
77 fs->eof = 1;86 framesync_eof(fs);
78}87}
79 88
80int ff_framesync2_configure(FFFrameSync *fs)89int ff_framesync2_configure(FFFrameSync *fs)
@@ -144,7 +153,7 @@ static void framesync_advance(FFFrameSync *fs) · 63 unmodified lines
144 if (fs->in[i].pts_next < pts)153 if (fs->in[i].pts_next < pts)
145 pts = fs->in[i].pts_next;154 pts = fs->in[i].pts_next;
146 if (pts == INT64_MAX) {155 if (pts == INT64_MAX) {
147 fs->eof = 1;156 framesync_eof(fs);
148 break;157 break;
149 }158 }
150 for (i = 0; i < fs->nb_in; i++) {159 for (i = 0; i < fs->nb_in; i++) {
@@ -162,11 +171,9 @@ static void framesync_advance(FFFrameSync *fs) · 11 unmodified lines
162 fs->frame_ready = 1;171 fs->frame_ready = 1;
163 if (fs->in[i].state == STATE_EOF &&172 if (fs->in[i].state == STATE_EOF &&
164 fs->in[i].after == EXT_STOP)173 fs->in[i].after == EXT_STOP)
165 fs->eof = 1;174 framesync_eof(fs);
166 }175 }
167 }176 }
168 if (fs->eof)
169 fs->frame_ready = 0;
170 if (fs->frame_ready)177 if (fs->frame_ready)
171 for (i = 0; i < fs->nb_in; i++)178 for (i = 0; i < fs->nb_in; i++)
172 if ((fs->in[i].state == STATE_BOF &&179 if ((fs->in[i].state == STATE_BOF &&
@@ -188,45 +195,24 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) · 15 unmodified lines
188 int64_t pts;195 int64_t pts;
189 196
190 av_assert0(!fs->in[in].have_next);197 av_assert0(!fs->in[in].have_next);
191 if (frame) {198 av_assert0(frame);
192 pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base);199 pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base);
193 frame->pts = pts;200 frame->pts = pts;
194 } else {
195 pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY
196 ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts);
197 fs->in[in].sync = 0;
198 framesync_sync_level_update(fs);
199 }
200 fs->in[in].frame_next = frame;201 fs->in[in].frame_next = frame;
201 fs->in[in].pts_next = pts;202 fs->in[in].pts_next = pts;
202 fs->in[in].have_next = 1;203 fs->in[in].have_next = 1;
203}204}
204 205
205int ff_framesync2_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame)206static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
206{
207 av_assert1(in < fs->nb_in);
208 if (!fs->in[in].have_next)
209 framesync_inject_frame(fs, in, frame);
210 else
211 ff_bufqueue_add(fs, &fs->in[in].queue, frame);
212 return 0;
213}
214
215void ff_framesync2_next(FFFrameSync *fs)
216{
217 unsigned i;
218
219 av_assert0(!fs->frame_ready);
220 for (i = 0; i < fs->nb_in; i++)
221 if (!fs->in[i].have_next && fs->in[i].queue.available)
222 framesync_inject_frame(fs, i, ff_bufqueue_get(&fs->in[i].queue));
223 fs->frame_ready = 0;
224 framesync_advance(fs);
225}
226
227void ff_framesync2_drop(FFFrameSync *fs)
228{207{
229 fs->frame_ready = 0;208 av_assert0(!fs->in[in].have_next);
209 pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY
210 ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts);
211 fs->in[in].sync = 0;
212 framesync_sync_level_update(fs);
213 fs->in[in].frame_next = NULL;
214 fs->in[in].pts_next = pts;
215 fs->in[in].have_next = 1;
230}216}
231 217
232int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,218int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
@@ -273,71 +259,55 @@ void ff_framesync2_uninit(FFFrameSync *fs) · 40 unmodified lines
273 for (i = 0; i < fs->nb_in; i++) {259 for (i = 0; i < fs->nb_in; i++) {
274 av_frame_free(&fs->in[i].frame);260 av_frame_free(&fs->in[i].frame);
275 av_frame_free(&fs->in[i].frame_next);261 av_frame_free(&fs->in[i].frame_next);
276 ff_bufqueue_discard_all(&fs->in[i].queue);
277 }262 }
278 263
279 av_freep(&fs->in);264 av_freep(&fs->in);
280}265}
281 266
282int ff_framesync2_process_frame(FFFrameSync *fs, unsigned all)267int ff_framesync2_activate(FFFrameSync *fs)
283{268{
284 int ret, count = 0;269 AVFilterContext *ctx = fs->parent;
270 AVFrame *frame = NULL;
271 int64_t pts;
272 unsigned i, nb_active, nb_miss;
273 int ret, status;
285 274
286 av_assert0(fs->on_event);275 nb_active = nb_miss = 0;
287 while (1) {276 for (i = 0; i < fs->nb_in; i++) {
288 ff_framesync2_next(fs);277 if (fs->in[i].have_next || fs->in[i].state == STATE_EOF)
289 if (fs->eof || !fs->frame_ready)278 continue;
290 break;279 nb_active++;
291 if ((ret = fs->on_event(fs)) < 0)280 ret = ff_inlink_consume_frame(ctx->inputs[i], &frame);
281 if (ret < 0)
292 return ret;282 return ret;
293 ff_framesync2_drop(fs);283 if (ret) {
294 count++;284 av_assert0(frame);
295 if (!all)285 framesync_inject_frame(fs, i, frame);
296 break;286 } else {
287 ret = ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts);
288 if (ret > 0) {
289 framesync_inject_status(fs, i, status, pts);
290 } else if (!ret) {
291 nb_miss++;
292 }
293 }
294 }
295 if (nb_miss) {
296 if (nb_miss == nb_active && !ff_outlink_frame_wanted(ctx->outputs[0]))
297 return FFERROR_NOT_READY;
298 for (i = 0; i < fs->nb_in; i++)
299 if (!fs->in[i].have_next && fs->in[i].state != STATE_EOF)
300 ff_inlink_request_frame(ctx->inputs[i]);
301 return 0;
297 }302 }
298 if (!count && fs->eof)
299 return AVERROR_EOF;
300 return count;
301}
302
303int ff_framesync2_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
304 AVFrame *in)
305{
306 int ret;
307 303
308 if ((ret = ff_framesync2_process_frame(fs, 1)) < 0)304 framesync_advance(fs);
309 return ret;305 if (fs->eof || !fs->frame_ready)
310 if ((ret = ff_framesync2_add_frame(fs, FF_INLINK_IDX(inlink), in)) < 0)306 return 0;
311 return ret;307 ret = fs->on_event(fs);
312 if ((ret = ff_framesync2_process_frame(fs, 0)) < 0)308 if (ret < 0)
313 return ret;309 return ret;
314 return 0;310 fs->frame_ready = 0;
315}
316
317int ff_framesync2_request_frame(FFFrameSync *fs, AVFilterLink *outlink)
318{
319 AVFilterContext *ctx = outlink->src;
320 int input, ret, i;
321 311
322 if ((ret = ff_framesync2_process_frame(fs, 0)) < 0)312 return 0;
323 return ret;
324 if (ret > 0)
325 return 0;
326 if (fs->eof)
327 return AVERROR_EOF;
328 input = fs->in_request;
329 /* Detect status change early */
330 for (i = 0; i < fs->nb_in; i++)
331 if (!ff_framequeue_queued_frames(&ctx->inputs[i]->fifo) &&
332 ctx->inputs[i]->status_in && !ctx->inputs[i]->status_out)
333 input = i;
334 ret = ff_request_frame(ctx->inputs[input]);
335 if (ret == AVERROR_EOF) {
336 if ((ret = ff_framesync2_add_frame(fs, input, NULL)) < 0)
337 return ret;
338 if ((ret = ff_framesync2_process_frame(fs, 0)) < 0)
339 return ret;
340 ret = 0;
341 }
342 return ret;
343}313}

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