3 * copyright (c) 2007 Bobby Bingham
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "allfilters.h"
29 /** list of registered filters, sorted by name */
30 static int filter_count
= 0;
31 static AVFilter
**filters
= NULL
;
33 /* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
34 void avfilter_default_free_video_buffer(AVFilterPic
*pic
)
36 avpicture_free((AVPicture
*) pic
);
40 /* TODO: set the buffer's priv member to a context structure for the whole
41 * filter chain. This will allow for a buffer pool instead of the constant
42 * alloc & free cycle currently implemented. */
43 AVFilterPicRef
*avfilter_default_get_video_buffer(AVFilterLink
*link
, int perms
)
45 AVFilterPic
*pic
= av_mallocz(sizeof(AVFilterPic
));
46 AVFilterPicRef
*ref
= av_mallocz(sizeof(AVFilterPicRef
));
54 pic
->format
= link
->format
;
55 pic
->free
= avfilter_default_free_video_buffer
;
56 avpicture_alloc((AVPicture
*)pic
, pic
->format
, ref
->w
, ref
->h
);
58 memcpy(ref
->data
, pic
->data
, sizeof(uint8_t *) * 4);
59 memcpy(ref
->linesize
, pic
->linesize
, sizeof(int *) * 4);
64 void avfilter_default_start_frame(AVFilterLink
*link
, AVFilterPicRef
*picref
)
66 link
->cur_pic
= picref
;
69 void avfilter_default_end_frame(AVFilterLink
*link
)
71 avfilter_unref_pic(link
->cur_pic
);
75 AVFilterPicRef
*avfilter_ref_pic(AVFilterPicRef
*ref
)
77 AVFilterPicRef
*ret
= av_malloc(sizeof(AVFilterPicRef
));
78 memcpy(ret
, ref
, sizeof(AVFilterPicRef
));
79 ret
->pic
->refcount
++;
83 void avfilter_unref_pic(AVFilterPicRef
*ref
)
85 if(-- ref
->pic
->refcount
== 0)
86 ref
->pic
->free(ref
->pic
);
90 int avfilter_link(AVFilterContext
*src
, unsigned srcpad
,
91 AVFilterContext
*dst
, unsigned dstpad
)
95 if(src
->outputs
[srcpad
] || dst
->inputs
[dstpad
])
98 src
->outputs
[srcpad
] =
99 dst
->inputs
[dstpad
] = link
= av_malloc(sizeof(AVFilterLink
));
103 link
->srcpad
= srcpad
;
104 link
->dstpad
= dstpad
;
105 link
->cur_pic
= NULL
;
107 src
->filter
->outputs
[dstpad
].set_video_props(link
);
111 AVFilterPicRef
*avfilter_get_video_buffer(AVFilterLink
*link
, int perms
)
113 AVFilterPicRef
*ret
= NULL
;
115 if(link
->dst
->filter
->inputs
[link
->dstpad
].get_video_buffer
)
116 ret
= link
->dst
->filter
->inputs
[link
->dstpad
].get_video_buffer(link
, perms
);
119 ret
= avfilter_default_get_video_buffer(link
, perms
);
124 void avfilter_request_frame(AVFilterLink
*link
)
126 link
->src
->filter
->outputs
[link
->srcpad
].request_frame(link
);
129 /* XXX: should we do the duplicating of the picture ref here, instead of
130 * forcing the source filter to do it? */
131 void avfilter_start_frame(AVFilterLink
*link
, AVFilterPicRef
*picref
)
133 void (*start_frame
)(AVFilterLink
*, AVFilterPicRef
*);
135 start_frame
= link
->dst
->filter
->inputs
[link
->dstpad
].start_frame
;
137 start_frame
= avfilter_default_start_frame
;
139 start_frame(link
, picref
);
142 void avfilter_end_frame(AVFilterLink
*link
)
144 void (*end_frame
)(AVFilterLink
*);
146 end_frame
= link
->dst
->filter
->inputs
[link
->dstpad
].end_frame
;
148 end_frame
= avfilter_default_end_frame
;
153 void avfilter_draw_slice(AVFilterLink
*link
, uint8_t *data
[4], int y
, int h
)
155 link
->dst
->filter
->inputs
[link
->dstpad
].draw_slice(link
, data
, y
, h
);
158 static int filter_cmp(const void *aa
, const void *bb
)
160 const AVFilter
*a
= *(const AVFilter
**)aa
, *b
= *(const AVFilter
**)bb
;
161 return strcmp(a
->name
, b
->name
);
164 AVFilter
*avfilter_get_by_name(char *name
)
166 AVFilter key
= { .name
= name
, };
167 AVFilter
*key2
= &key
;
170 ret
= bsearch(&key2
, filters
, filter_count
, sizeof(AVFilter
**), filter_cmp
);
176 /* FIXME: insert in order, rather than insert at end + resort */
177 void avfilter_register(AVFilter
*filter
)
179 filters
= av_realloc(filters
, sizeof(AVFilter
*) * (filter_count
+1));
180 filters
[filter_count
] = filter
;
181 qsort(filters
, ++filter_count
, sizeof(AVFilter
**), filter_cmp
);
184 void avfilter_init(void)
186 avfilter_register(&vsrc_dummy
);
187 avfilter_register(&vf_crop
);
188 avfilter_register(&vf_passthrough
);
189 avfilter_register(&vo_sdl
);
192 void avfilter_uninit(void)
198 static int pad_count(const AVFilterPad
*pads
)
200 AVFilterPad
*p
= (AVFilterPad
*) pads
;
203 for(count
= 0; p
->name
; count
++) p
++;
207 static const char *filter_name(void *p
)
209 AVFilterContext
*filter
= p
;
210 return filter
->filter
->name
;
213 AVFilterContext
*avfilter_create(AVFilter
*filter
)
215 AVFilterContext
*ret
= av_malloc(sizeof(AVFilterContext
));
217 ret
->av_class
= av_mallocz(sizeof(AVClass
));
218 ret
->av_class
->item_name
= filter_name
;
219 ret
->filter
= filter
;
220 ret
->inputs
= av_mallocz(sizeof(AVFilterLink
*) * pad_count(filter
->inputs
));
221 ret
->outputs
= av_mallocz(sizeof(AVFilterLink
*) * pad_count(filter
->outputs
));
222 ret
->priv
= av_mallocz(filter
->priv_size
);
227 void avfilter_destroy(AVFilterContext
*filter
)
231 if(filter
->filter
->uninit
)
232 filter
->filter
->uninit(filter
);
234 for(i
= 0; i
< pad_count(filter
->filter
->inputs
); i
++) {
235 if(filter
->inputs
[i
])
236 filter
->inputs
[i
]->src
->outputs
[filter
->inputs
[i
]->srcpad
] = NULL
;
237 av_free(filter
->inputs
[i
]);
239 for(i
= 0; i
< pad_count(filter
->filter
->outputs
); i
++) {
240 if(filter
->outputs
[i
])
241 filter
->outputs
[i
]->dst
->inputs
[filter
->outputs
[i
]->dstpad
] = NULL
;
242 av_free(filter
->outputs
[i
]);
245 av_free(filter
->inputs
);
246 av_free(filter
->outputs
);
247 av_free(filter
->priv
);
248 av_free(filter
->av_class
);
252 AVFilterContext
*avfilter_create_by_name(char *name
)
256 if(!(filt
= avfilter_get_by_name(name
))) return NULL
;
257 return avfilter_create(filt
);
260 int avfilter_init_filter(AVFilterContext
*filter
)
264 if(filter
->filter
->init
)
265 if((ret
= filter
->filter
->init(filter
))) return ret
;
266 for(i
= 0; i
< pad_count(filter
->filter
->outputs
); i
++)
267 if(filter
->outputs
[i
])
268 filter
->filter
->outputs
[i
].set_video_props(filter
->outputs
[i
]);