This breaks libavfilter ABI.
Anton Khirnov authored on 2012/05/16 16:19:46... | ... |
@@ -363,6 +363,14 @@ struct AVFilterPad { |
363 | 363 |
* and another value on error. |
364 | 364 |
*/ |
365 | 365 |
int (*config_props)(AVFilterLink *link); |
366 |
+ |
|
367 |
+ /** |
|
368 |
+ * The filter expects a fifo to be inserted on its input link, |
|
369 |
+ * typically because it has a delay. |
|
370 |
+ * |
|
371 |
+ * input pads only. |
|
372 |
+ */ |
|
373 |
+ int needs_fifo; |
|
366 | 374 |
}; |
367 | 375 |
#endif |
368 | 376 |
|
... | ... |
@@ -591,12 +591,52 @@ static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) |
591 | 591 |
return 0; |
592 | 592 |
} |
593 | 593 |
|
594 |
+static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx) |
|
595 |
+{ |
|
596 |
+ AVFilterContext *f; |
|
597 |
+ int i, j, ret; |
|
598 |
+ int fifo_count = 0; |
|
599 |
+ |
|
600 |
+ for (i = 0; i < graph->filter_count; i++) { |
|
601 |
+ f = graph->filters[i]; |
|
602 |
+ |
|
603 |
+ for (j = 0; j < f->nb_inputs; j++) { |
|
604 |
+ AVFilterLink *link = f->inputs[j]; |
|
605 |
+ AVFilterContext *fifo_ctx; |
|
606 |
+ AVFilter *fifo; |
|
607 |
+ char name[32]; |
|
608 |
+ |
|
609 |
+ if (!link->dstpad->needs_fifo) |
|
610 |
+ continue; |
|
611 |
+ |
|
612 |
+ fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ? |
|
613 |
+ avfilter_get_by_name("fifo") : |
|
614 |
+ avfilter_get_by_name("afifo"); |
|
615 |
+ |
|
616 |
+ snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++); |
|
617 |
+ |
|
618 |
+ ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL, |
|
619 |
+ NULL, graph); |
|
620 |
+ if (ret < 0) |
|
621 |
+ return ret; |
|
622 |
+ |
|
623 |
+ ret = avfilter_insert_filter(link, fifo_ctx, 0, 0); |
|
624 |
+ if (ret < 0) |
|
625 |
+ return ret; |
|
626 |
+ } |
|
627 |
+ } |
|
628 |
+ |
|
629 |
+ return 0; |
|
630 |
+} |
|
631 |
+ |
|
594 | 632 |
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx) |
595 | 633 |
{ |
596 | 634 |
int ret; |
597 | 635 |
|
598 | 636 |
if ((ret = graph_check_validity(graphctx, log_ctx))) |
599 | 637 |
return ret; |
638 |
+ if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0) |
|
639 |
+ return ret; |
|
600 | 640 |
if ((ret = graph_config_formats(graphctx, log_ctx))) |
601 | 641 |
return ret; |
602 | 642 |
if ((ret = graph_config_links(graphctx, log_ctx))) |
... | ... |
@@ -25,7 +25,7 @@ |
25 | 25 |
|
26 | 26 |
#include "libavutil/audio_fifo.h" |
27 | 27 |
#include "libavutil/audioconvert.h" |
28 |
-#include "libavutil/fifo.h" |
|
28 |
+#include "libavutil/avassert.h" |
|
29 | 29 |
#include "libavutil/mathematics.h" |
30 | 30 |
|
31 | 31 |
#include "audio.h" |
... | ... |
@@ -34,86 +34,45 @@ |
34 | 34 |
#include "internal.h" |
35 | 35 |
|
36 | 36 |
typedef struct { |
37 |
- AVFifoBuffer *fifo; ///< FIFO buffer of frame references |
|
38 |
- |
|
37 |
+ AVFilterBufferRef *cur_buf; ///< last buffer delivered on the sink |
|
39 | 38 |
AVAudioFifo *audio_fifo; ///< FIFO for audio samples |
40 | 39 |
int64_t next_pts; ///< interpolating audio pts |
41 | 40 |
} BufferSinkContext; |
42 | 41 |
|
43 |
-#define FIFO_INIT_SIZE 8 |
|
44 |
- |
|
45 | 42 |
static av_cold void uninit(AVFilterContext *ctx) |
46 | 43 |
{ |
47 | 44 |
BufferSinkContext *sink = ctx->priv; |
48 | 45 |
|
49 |
- while (sink->fifo && av_fifo_size(sink->fifo)) { |
|
50 |
- AVFilterBufferRef *buf; |
|
51 |
- av_fifo_generic_read(sink->fifo, &buf, sizeof(buf), NULL); |
|
52 |
- avfilter_unref_buffer(buf); |
|
53 |
- } |
|
54 |
- av_fifo_free(sink->fifo); |
|
55 |
- |
|
56 | 46 |
if (sink->audio_fifo) |
57 | 47 |
av_audio_fifo_free(sink->audio_fifo); |
58 | 48 |
} |
59 | 49 |
|
60 |
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
|
61 |
-{ |
|
62 |
- BufferSinkContext *sink = ctx->priv; |
|
63 |
- |
|
64 |
- if (!(sink->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef*)))) { |
|
65 |
- av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n"); |
|
66 |
- return AVERROR(ENOMEM); |
|
67 |
- } |
|
68 |
- |
|
69 |
- return 0; |
|
70 |
-} |
|
71 |
- |
|
72 |
-static void write_buf(AVFilterContext *ctx, AVFilterBufferRef *buf) |
|
50 |
+static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf) |
|
73 | 51 |
{ |
74 |
- BufferSinkContext *sink = ctx->priv; |
|
75 |
- |
|
76 |
- if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) && |
|
77 |
- (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) { |
|
78 |
- av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n"); |
|
79 |
- return; |
|
80 |
- } |
|
52 |
+ BufferSinkContext *s = link->dst->priv; |
|
81 | 53 |
|
82 |
- av_fifo_generic_write(sink->fifo, &buf, sizeof(buf), NULL); |
|
83 |
-} |
|
84 |
- |
|
85 |
-static void end_frame(AVFilterLink *link) |
|
86 |
-{ |
|
87 |
- write_buf(link->dst, link->cur_buf); |
|
54 |
+ av_assert0(!s->cur_buf); |
|
55 |
+ s->cur_buf = buf; |
|
88 | 56 |
link->cur_buf = NULL; |
89 |
-} |
|
90 |
- |
|
91 |
-static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf) |
|
92 |
-{ |
|
93 |
- write_buf(link->dst, buf); |
|
94 |
-} |
|
57 |
+}; |
|
95 | 58 |
|
96 | 59 |
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) |
97 | 60 |
{ |
98 |
- BufferSinkContext *sink = ctx->priv; |
|
61 |
+ BufferSinkContext *s = ctx->priv; |
|
99 | 62 |
AVFilterLink *link = ctx->inputs[0]; |
100 | 63 |
int ret; |
101 | 64 |
|
102 |
- if (!buf) { |
|
103 |
- if (av_fifo_size(sink->fifo)) |
|
104 |
- return av_fifo_size(sink->fifo)/sizeof(*buf); |
|
105 |
- else |
|
106 |
- return ff_poll_frame(ctx->inputs[0]); |
|
107 |
- } |
|
65 |
+ if (!buf) |
|
66 |
+ return ff_poll_frame(ctx->inputs[0]); |
|
108 | 67 |
|
109 |
- if (!av_fifo_size(sink->fifo) && |
|
110 |
- (ret = ff_request_frame(link)) < 0) |
|
68 |
+ if ((ret = ff_request_frame(link)) < 0) |
|
111 | 69 |
return ret; |
112 | 70 |
|
113 |
- if (!av_fifo_size(sink->fifo)) |
|
71 |
+ if (!s->cur_buf) |
|
114 | 72 |
return AVERROR(EINVAL); |
115 | 73 |
|
116 |
- av_fifo_generic_read(sink->fifo, buf, sizeof(*buf), NULL); |
|
74 |
+ *buf = s->cur_buf; |
|
75 |
+ s->cur_buf = NULL; |
|
117 | 76 |
|
118 | 77 |
return 0; |
119 | 78 |
} |
... | ... |
@@ -182,13 +141,13 @@ AVFilter avfilter_vsink_buffer = { |
182 | 182 |
.name = "buffersink", |
183 | 183 |
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."), |
184 | 184 |
.priv_size = sizeof(BufferSinkContext), |
185 |
- .init = init, |
|
186 | 185 |
.uninit = uninit, |
187 | 186 |
|
188 | 187 |
.inputs = (AVFilterPad[]) {{ .name = "default", |
189 | 188 |
.type = AVMEDIA_TYPE_VIDEO, |
190 |
- .end_frame = end_frame, |
|
191 |
- .min_perms = AV_PERM_READ, }, |
|
189 |
+ .start_frame = start_frame, |
|
190 |
+ .min_perms = AV_PERM_READ, |
|
191 |
+ .needs_fifo = 1 }, |
|
192 | 192 |
{ .name = NULL }}, |
193 | 193 |
.outputs = (AVFilterPad[]) {{ .name = NULL }}, |
194 | 194 |
}; |
... | ... |
@@ -197,13 +156,13 @@ AVFilter avfilter_asink_abuffer = { |
197 | 197 |
.name = "abuffersink", |
198 | 198 |
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."), |
199 | 199 |
.priv_size = sizeof(BufferSinkContext), |
200 |
- .init = init, |
|
201 | 200 |
.uninit = uninit, |
202 | 201 |
|
203 | 202 |
.inputs = (AVFilterPad[]) {{ .name = "default", |
204 | 203 |
.type = AVMEDIA_TYPE_AUDIO, |
205 |
- .filter_samples = filter_samples, |
|
206 |
- .min_perms = AV_PERM_READ, }, |
|
204 |
+ .filter_samples = start_frame, |
|
205 |
+ .min_perms = AV_PERM_READ, |
|
206 |
+ .needs_fifo = 1 }, |
|
207 | 207 |
{ .name = NULL }}, |
208 | 208 |
.outputs = (AVFilterPad[]) {{ .name = NULL }}, |
209 | 209 |
}; |
... | ... |
@@ -149,6 +149,14 @@ struct AVFilterPad { |
149 | 149 |
* and another value on error. |
150 | 150 |
*/ |
151 | 151 |
int (*config_props)(AVFilterLink *link); |
152 |
+ |
|
153 |
+ /** |
|
154 |
+ * The filter expects a fifo to be inserted on its input link, |
|
155 |
+ * typically because it has a delay. |
|
156 |
+ * |
|
157 |
+ * input pads only. |
|
158 |
+ */ |
|
159 |
+ int needs_fifo; |
|
152 | 160 |
}; |
153 | 161 |
#endif |
154 | 162 |
|
... | ... |
@@ -28,8 +28,8 @@ |
28 | 28 |
|
29 | 29 |
#include "libavutil/avutil.h" |
30 | 30 |
|
31 |
-#define LIBAVFILTER_VERSION_MAJOR 2 |
|
32 |
-#define LIBAVFILTER_VERSION_MINOR 23 |
|
31 |
+#define LIBAVFILTER_VERSION_MAJOR 3 |
|
32 |
+#define LIBAVFILTER_VERSION_MINOR 0 |
|
33 | 33 |
#define LIBAVFILTER_VERSION_MICRO 0 |
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |