1/* 2 * Copyright (c) 2007 Bobby Bingham 3 * 4 * This file is part of Libav. 5 * 6 * Libav is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * Libav is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with Libav; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21/** 22 * @file 23 * FIFO buffering video filter 24 */ 25 26#include "avfilter.h" 27 28typedef struct BufPic { 29 AVFilterBufferRef *picref; 30 struct BufPic *next; 31} BufPic; 32 33typedef struct { 34 BufPic root; 35 BufPic *last; ///< last buffered picture 36} FifoContext; 37 38static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) 39{ 40 FifoContext *fifo = ctx->priv; 41 fifo->last = &fifo->root; 42 43 av_log(ctx, AV_LOG_INFO, "\n"); 44 return 0; 45} 46 47static av_cold void uninit(AVFilterContext *ctx) 48{ 49 FifoContext *fifo = ctx->priv; 50 BufPic *pic, *tmp; 51 52 for (pic = fifo->root.next; pic; pic = tmp) { 53 tmp = pic->next; 54 avfilter_unref_buffer(pic->picref); 55 av_free(pic); 56 } 57} 58 59static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) 60{ 61 FifoContext *fifo = inlink->dst->priv; 62 63 fifo->last->next = av_mallocz(sizeof(BufPic)); 64 fifo->last = fifo->last->next; 65 fifo->last->picref = picref; 66} 67 68static void end_frame(AVFilterLink *inlink) { } 69 70static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } 71 72static int request_frame(AVFilterLink *outlink) 73{ 74 FifoContext *fifo = outlink->src->priv; 75 BufPic *tmp; 76 int ret; 77 78 if (!fifo->root.next) { 79 if ((ret = avfilter_request_frame(outlink->src->inputs[0]) < 0)) 80 return ret; 81 } 82 83 /* by doing this, we give ownership of the reference to the next filter, 84 * so we don't have to worry about dereferencing it ourselves. */ 85 avfilter_start_frame(outlink, fifo->root.next->picref); 86 avfilter_draw_slice (outlink, 0, outlink->h, 1); 87 avfilter_end_frame (outlink); 88 89 if (fifo->last == fifo->root.next) 90 fifo->last = &fifo->root; 91 tmp = fifo->root.next->next; 92 av_free(fifo->root.next); 93 fifo->root.next = tmp; 94 95 return 0; 96} 97 98AVFilter avfilter_vf_fifo = { 99 .name = "fifo", 100 .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."), 101 102 .init = init, 103 .uninit = uninit, 104 105 .priv_size = sizeof(FifoContext), 106 107 .inputs = (AVFilterPad[]) {{ .name = "default", 108 .type = AVMEDIA_TYPE_VIDEO, 109 .get_video_buffer= avfilter_null_get_video_buffer, 110 .start_frame = start_frame, 111 .draw_slice = draw_slice, 112 .end_frame = end_frame, 113 .rej_perms = AV_PERM_REUSE2, }, 114 { .name = NULL}}, 115 .outputs = (AVFilterPad[]) {{ .name = "default", 116 .type = AVMEDIA_TYPE_VIDEO, 117 .request_frame = request_frame, }, 118 { .name = NULL}}, 119}; 120