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