00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "avfilter.h"
00027
00028 typedef struct BufPic {
00029 AVFilterBufferRef *picref;
00030 struct BufPic *next;
00031 } BufPic;
00032
00033 typedef struct {
00034 BufPic root;
00035 BufPic *last;
00036 } FifoContext;
00037
00038 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
00039 {
00040 FifoContext *fifo = ctx->priv;
00041 fifo->last = &fifo->root;
00042
00043 av_log(ctx, AV_LOG_INFO, "\n");
00044 return 0;
00045 }
00046
00047 static av_cold void uninit(AVFilterContext *ctx)
00048 {
00049 FifoContext *fifo = ctx->priv;
00050 BufPic *pic, *tmp;
00051
00052 for (pic = fifo->root.next; pic; pic = tmp) {
00053 tmp = pic->next;
00054 avfilter_unref_buffer(pic->picref);
00055 av_free(pic);
00056 }
00057 }
00058
00059 static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
00060 {
00061 FifoContext *fifo = inlink->dst->priv;
00062
00063 fifo->last->next = av_mallocz(sizeof(BufPic));
00064 fifo->last = fifo->last->next;
00065 fifo->last->picref = picref;
00066 }
00067
00068 static void end_frame(AVFilterLink *inlink) { }
00069
00070 static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }
00071
00072 static int request_frame(AVFilterLink *outlink)
00073 {
00074 FifoContext *fifo = outlink->src->priv;
00075 BufPic *tmp;
00076 int ret;
00077
00078 if (!fifo->root.next) {
00079 if ((ret = avfilter_request_frame(outlink->src->inputs[0]) < 0))
00080 return ret;
00081 }
00082
00083
00084
00085 avfilter_start_frame(outlink, fifo->root.next->picref);
00086 avfilter_draw_slice (outlink, 0, outlink->h, 1);
00087 avfilter_end_frame (outlink);
00088
00089 if (fifo->last == fifo->root.next)
00090 fifo->last = &fifo->root;
00091 tmp = fifo->root.next->next;
00092 av_free(fifo->root.next);
00093 fifo->root.next = tmp;
00094
00095 return 0;
00096 }
00097
00098 AVFilter avfilter_vf_fifo = {
00099 .name = "fifo",
00100 .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."),
00101
00102 .init = init,
00103 .uninit = uninit,
00104
00105 .priv_size = sizeof(FifoContext),
00106
00107 .inputs = (AVFilterPad[]) {{ .name = "default",
00108 .type = AVMEDIA_TYPE_VIDEO,
00109 .get_video_buffer= avfilter_null_get_video_buffer,
00110 .start_frame = start_frame,
00111 .draw_slice = draw_slice,
00112 .end_frame = end_frame,
00113 .rej_perms = AV_PERM_REUSE2, },
00114 { .name = NULL}},
00115 .outputs = (AVFilterPad[]) {{ .name = "default",
00116 .type = AVMEDIA_TYPE_VIDEO,
00117 .request_frame = request_frame, },
00118 { .name = NULL}},
00119 };