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