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
28 #include "allfilters.h"
30 /** list of registered filters, sorted by name */
31 static int filter_count
= 0;
32 static AVFilter
**filters
= NULL
;
34 AVFilterPicRef
*avfilter_ref_pic(AVFilterPicRef
*ref
, int pmask
)
36 AVFilterPicRef
*ret
= av_malloc(sizeof(AVFilterPicRef
));
37 memcpy(ret
, ref
, sizeof(AVFilterPicRef
));
39 ret
->pic
->refcount
++;
43 void avfilter_unref_pic(AVFilterPicRef
*ref
)
45 if(-- ref
->pic
->refcount
== 0)
46 ref
->pic
->free(ref
->pic
);
50 void avfilter_insert_pad(unsigned idx
, unsigned *count
, size_t padidx_off
,
51 AVFilterPad
**pads
, AVFilterLink
***links
,
56 idx
= FFMIN(idx
, *count
);
58 *pads
= av_realloc(*pads
, sizeof(AVFilterPad
) * (*count
+ 1));
59 *links
= av_realloc(*links
, sizeof(AVFilterLink
*) * (*count
+ 1));
60 memmove(*pads
+idx
+1, *pads
+idx
, sizeof(AVFilterPad
) * (*count
-idx
));
61 memmove(*links
+idx
+1, *links
+idx
, sizeof(AVFilterLink
*) * (*count
-idx
));
62 memcpy(*pads
+idx
, newpad
, sizeof(AVFilterPad
));
66 for(i
= idx
+1; i
< *count
; i
++)
68 (*(unsigned *)((uint8_t *)(*links
[i
]) + padidx_off
)) ++;
71 int avfilter_link(AVFilterContext
*src
, unsigned srcpad
,
72 AVFilterContext
*dst
, unsigned dstpad
)
76 if(src
->output_count
<= srcpad
|| dst
->input_count
<= dstpad
||
77 src
->outputs
[srcpad
] || dst
->inputs
[dstpad
])
80 src
->outputs
[srcpad
] =
81 dst
->inputs
[dstpad
] = link
= av_malloc(sizeof(AVFilterLink
));
85 link
->srcpad
= srcpad
;
86 link
->dstpad
= dstpad
;
93 int avfilter_config_link(AVFilterLink
*link
)
96 int (*config_link
)(AVFilterLink
*);
101 /* find a format both filters support - TODO: auto-insert conversion filter */
103 if(link
->src
->output_pads
[link
->srcpad
].query_formats
)
104 fmts
[0] = link
->src
->output_pads
[link
->srcpad
].query_formats(link
);
106 fmts
[0] = avfilter_default_query_output_formats(link
);
107 fmts
[1] = link
->dst
->input_pads
[link
->dstpad
].query_formats(link
);
108 for(i
= 0; fmts
[0][i
] != -1; i
++)
109 for(j
= 0; fmts
[1][j
] != -1; j
++)
110 if(fmts
[0][i
] == fmts
[1][j
]) {
111 link
->format
= fmts
[0][i
];
118 if(link
->format
== -1)
121 if(!(config_link
= link
->src
->output_pads
[link
->srcpad
].config_props
))
122 config_link
= avfilter_default_config_output_link
;
123 if(config_link(link
))
126 if(!(config_link
= link
->dst
->input_pads
[link
->dstpad
].config_props
))
127 config_link
= avfilter_default_config_input_link
;
128 if(config_link(link
))
134 AVFilterPicRef
*avfilter_get_video_buffer(AVFilterLink
*link
, int perms
)
136 AVFilterPicRef
*ret
= NULL
;
138 if(link
->dst
->input_pads
[link
->dstpad
].get_video_buffer
)
139 ret
= link
->dst
->input_pads
[link
->dstpad
].get_video_buffer(link
, perms
);
142 ret
= avfilter_default_get_video_buffer(link
, perms
);
147 void avfilter_request_frame(AVFilterLink
*link
)
149 const AVFilterPad
*pad
= &link
->src
->output_pads
[link
->srcpad
];
151 if(pad
->request_frame
)
152 pad
->request_frame(link
);
153 else if(link
->src
->inputs
[0])
154 avfilter_request_frame(link
->src
->inputs
[0]);
157 /* XXX: should we do the duplicating of the picture ref here, instead of
158 * forcing the source filter to do it? */
159 void avfilter_start_frame(AVFilterLink
*link
, AVFilterPicRef
*picref
)
161 void (*start_frame
)(AVFilterLink
*, AVFilterPicRef
*);
163 start_frame
= link
->dst
->input_pads
[link
->dstpad
].start_frame
;
165 start_frame
= avfilter_default_start_frame
;
167 start_frame(link
, picref
);
170 void avfilter_end_frame(AVFilterLink
*link
)
172 void (*end_frame
)(AVFilterLink
*);
174 end_frame
= link
->dst
->input_pads
[link
->dstpad
].end_frame
;
176 end_frame
= avfilter_default_end_frame
;
181 void avfilter_draw_slice(AVFilterLink
*link
, uint8_t *data
[4], int y
, int h
)
183 if(!link
->dst
->input_pads
[link
->dstpad
].draw_slice
)
186 link
->dst
->input_pads
[link
->dstpad
].draw_slice(link
, data
, y
, h
);
189 static int filter_cmp(const void *aa
, const void *bb
)
191 const AVFilter
*a
= *(const AVFilter
**)aa
, *b
= *(const AVFilter
**)bb
;
192 return strcmp(a
->name
, b
->name
);
195 AVFilter
*avfilter_get_by_name(char *name
)
197 AVFilter key
= { .name
= name
, };
198 AVFilter
*key2
= &key
;
201 ret
= bsearch(&key2
, filters
, filter_count
, sizeof(AVFilter
**), filter_cmp
);
207 /* FIXME: insert in order, rather than insert at end + resort */
208 void avfilter_register(AVFilter
*filter
)
210 filters
= av_realloc(filters
, sizeof(AVFilter
*) * (filter_count
+1));
211 filters
[filter_count
] = filter
;
212 qsort(filters
, ++filter_count
, sizeof(AVFilter
**), filter_cmp
);
215 void avfilter_init(void)
217 avfilter_register(&vsrc_dummy
);
218 avfilter_register(&vsrc_ppm
);
219 avfilter_register(&vf_crop
);
220 avfilter_register(&vf_graph
);
221 avfilter_register(&vf_passthrough
);
222 avfilter_register(&vf_rgb2bgr
);
223 avfilter_register(&vf_slicify
);
224 avfilter_register(&vo_sdl
);
227 void avfilter_uninit(void)
233 static int pad_count(const AVFilterPad
*pads
)
235 AVFilterPad
*p
= (AVFilterPad
*) pads
;
238 for(count
= 0; p
->name
; count
++) p
++;
242 static const char *filter_name(void *p
)
244 AVFilterContext
*filter
= p
;
245 return filter
->filter
->name
;
248 AVFilterContext
*avfilter_create(AVFilter
*filter
, char *inst_name
)
250 AVFilterContext
*ret
= av_malloc(sizeof(AVFilterContext
));
252 ret
->av_class
= av_mallocz(sizeof(AVClass
));
253 ret
->av_class
->item_name
= filter_name
;
254 ret
->filter
= filter
;
255 ret
->name
= inst_name ?
av_strdup(inst_name
) : NULL
;
256 ret
->priv
= av_mallocz(filter
->priv_size
);
258 ret
->input_count
= pad_count(filter
->inputs
);
259 ret
->input_pads
= av_malloc(sizeof(AVFilterPad
) * ret
->input_count
);
260 memcpy(ret
->input_pads
, filter
->inputs
, sizeof(AVFilterPad
)*ret
->input_count
);
261 ret
->inputs
= av_mallocz(sizeof(AVFilterLink
*) * ret
->input_count
);
263 ret
->output_count
= pad_count(filter
->outputs
);
264 ret
->output_pads
= av_malloc(sizeof(AVFilterPad
) * ret
->output_count
);
265 memcpy(ret
->output_pads
, filter
->outputs
, sizeof(AVFilterPad
)*ret
->output_count
);
266 ret
->outputs
= av_mallocz(sizeof(AVFilterLink
*) * ret
->output_count
);
271 void avfilter_destroy(AVFilterContext
*filter
)
275 if(filter
->filter
->uninit
)
276 filter
->filter
->uninit(filter
);
278 for(i
= 0; i
< filter
->input_count
; i
++) {
279 if(filter
->inputs
[i
])
280 filter
->inputs
[i
]->src
->outputs
[filter
->inputs
[i
]->srcpad
] = NULL
;
281 av_free(filter
->inputs
[i
]);
283 for(i
= 0; i
< filter
->output_count
; i
++) {
284 if(filter
->outputs
[i
])
285 filter
->outputs
[i
]->dst
->inputs
[filter
->outputs
[i
]->dstpad
] = NULL
;
286 av_free(filter
->outputs
[i
]);
289 av_free(filter
->name
);
290 av_free(filter
->input_pads
);
291 av_free(filter
->output_pads
);
292 av_free(filter
->inputs
);
293 av_free(filter
->outputs
);
294 av_free(filter
->priv
);
295 av_free(filter
->av_class
);
299 AVFilterContext
*avfilter_create_by_name(char *name
, char *inst_name
)
303 if(!(filt
= avfilter_get_by_name(name
))) return NULL
;
304 return avfilter_create(filt
, inst_name
);
307 int avfilter_init_filter(AVFilterContext
*filter
, const char *args
, void *opaque
)
311 if(filter
->filter
->init
)
312 if((ret
= filter
->filter
->init(filter
, args
, opaque
))) return ret
;
316 int *avfilter_make_format_list(int len
, ...)
321 ret
= av_malloc(sizeof(int) * (len
+ 1));
323 for(i
= 0; i
< len
; i
++)
324 ret
[i
] = va_arg(vl
, int);