... | ... |
@@ -20,21 +20,22 @@ |
20 | 20 |
|
21 | 21 |
/** |
22 | 22 |
* @file |
23 |
- * FIFO buffering video filter |
|
23 |
+ * FIFO buffering filter |
|
24 | 24 |
*/ |
25 | 25 |
|
26 |
+#include "audio.h" |
|
26 | 27 |
#include "avfilter.h" |
27 | 28 |
#include "internal.h" |
28 | 29 |
#include "video.h" |
29 | 30 |
|
30 |
-typedef struct BufPic { |
|
31 |
- AVFilterBufferRef *picref; |
|
32 |
- struct BufPic *next; |
|
33 |
-} BufPic; |
|
31 |
+typedef struct Buf { |
|
32 |
+ AVFilterBufferRef *buf; |
|
33 |
+ struct Buf *next; |
|
34 |
+} Buf; |
|
34 | 35 |
|
35 | 36 |
typedef struct { |
36 |
- BufPic root; |
|
37 |
- BufPic *last; ///< last buffered picture |
|
37 |
+ Buf root; |
|
38 |
+ Buf *last; ///< last buffered frame |
|
38 | 39 |
} FifoContext; |
39 | 40 |
|
40 | 41 |
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
... | ... |
@@ -49,22 +50,22 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
49 | 49 |
static av_cold void uninit(AVFilterContext *ctx) |
50 | 50 |
{ |
51 | 51 |
FifoContext *fifo = ctx->priv; |
52 |
- BufPic *pic, *tmp; |
|
52 |
+ Buf *buf, *tmp; |
|
53 | 53 |
|
54 |
- for (pic = fifo->root.next; pic; pic = tmp) { |
|
55 |
- tmp = pic->next; |
|
56 |
- avfilter_unref_buffer(pic->picref); |
|
57 |
- av_free(pic); |
|
54 |
+ for (buf = fifo->root.next; buf; buf = tmp) { |
|
55 |
+ tmp = buf->next; |
|
56 |
+ avfilter_unref_buffer(buf->buf); |
|
57 |
+ av_free(buf); |
|
58 | 58 |
} |
59 | 59 |
} |
60 | 60 |
|
61 |
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) |
|
61 |
+static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) |
|
62 | 62 |
{ |
63 | 63 |
FifoContext *fifo = inlink->dst->priv; |
64 | 64 |
|
65 |
- fifo->last->next = av_mallocz(sizeof(BufPic)); |
|
65 |
+ fifo->last->next = av_mallocz(sizeof(Buf)); |
|
66 | 66 |
fifo->last = fifo->last->next; |
67 |
- fifo->last->picref = picref; |
|
67 |
+ fifo->last->buf = buf; |
|
68 | 68 |
} |
69 | 69 |
|
70 | 70 |
static void end_frame(AVFilterLink *inlink) { } |
... | ... |
@@ -74,7 +75,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } |
74 | 74 |
static int request_frame(AVFilterLink *outlink) |
75 | 75 |
{ |
76 | 76 |
FifoContext *fifo = outlink->src->priv; |
77 |
- BufPic *tmp; |
|
77 |
+ Buf *tmp; |
|
78 | 78 |
int ret; |
79 | 79 |
|
80 | 80 |
if (!fifo->root.next) { |
... | ... |
@@ -84,9 +85,18 @@ static int request_frame(AVFilterLink *outlink) |
84 | 84 |
|
85 | 85 |
/* by doing this, we give ownership of the reference to the next filter, |
86 | 86 |
* so we don't have to worry about dereferencing it ourselves. */ |
87 |
- ff_start_frame(outlink, fifo->root.next->picref); |
|
88 |
- ff_draw_slice (outlink, 0, outlink->h, 1); |
|
89 |
- ff_end_frame (outlink); |
|
87 |
+ switch (outlink->type) { |
|
88 |
+ case AVMEDIA_TYPE_VIDEO: |
|
89 |
+ ff_start_frame(outlink, fifo->root.next->buf); |
|
90 |
+ ff_draw_slice (outlink, 0, outlink->h, 1); |
|
91 |
+ ff_end_frame (outlink); |
|
92 |
+ break; |
|
93 |
+ case AVMEDIA_TYPE_AUDIO: |
|
94 |
+ ff_filter_samples(outlink, fifo->root.next->buf); |
|
95 |
+ break; |
|
96 |
+ default: |
|
97 |
+ return AVERROR(EINVAL); |
|
98 |
+ } |
|
90 | 99 |
|
91 | 100 |
if (fifo->last == fifo->root.next) |
92 | 101 |
fifo->last = &fifo->root; |
... | ... |
@@ -109,7 +119,7 @@ AVFilter avfilter_vf_fifo = { |
109 | 109 |
.inputs = (AVFilterPad[]) {{ .name = "default", |
110 | 110 |
.type = AVMEDIA_TYPE_VIDEO, |
111 | 111 |
.get_video_buffer= ff_null_get_video_buffer, |
112 |
- .start_frame = start_frame, |
|
112 |
+ .start_frame = add_to_queue, |
|
113 | 113 |
.draw_slice = draw_slice, |
114 | 114 |
.end_frame = end_frame, |
115 | 115 |
.rej_perms = AV_PERM_REUSE2, }, |
... | ... |
@@ -119,3 +129,24 @@ AVFilter avfilter_vf_fifo = { |
119 | 119 |
.request_frame = request_frame, }, |
120 | 120 |
{ .name = NULL}}, |
121 | 121 |
}; |
122 |
+ |
|
123 |
+AVFilter avfilter_af_afifo = { |
|
124 |
+ .name = "afifo", |
|
125 |
+ .description = NULL_IF_CONFIG_SMALL("Buffer input frames and send them when they are requested."), |
|
126 |
+ |
|
127 |
+ .init = init, |
|
128 |
+ .uninit = uninit, |
|
129 |
+ |
|
130 |
+ .priv_size = sizeof(FifoContext), |
|
131 |
+ |
|
132 |
+ .inputs = (AVFilterPad[]) {{ .name = "default", |
|
133 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
134 |
+ .get_audio_buffer = ff_null_get_audio_buffer, |
|
135 |
+ .filter_samples = add_to_queue, |
|
136 |
+ .rej_perms = AV_PERM_REUSE2, }, |
|
137 |
+ { .name = NULL}}, |
|
138 |
+ .outputs = (AVFilterPad[]) {{ .name = "default", |
|
139 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
140 |
+ .request_frame = request_frame, }, |
|
141 |
+ { .name = NULL}}, |
|
142 |
+}; |