Statistics
| Branch: | Revision:

ffmpeg / libavfilter / avfilter.c @ f60208f4

History | View | Annotate | Download (10.5 KB)

1 4dbbcdee Vitor Sessak
/*
2
 * Filter layer
3
 * copyright (c) 2007 Bobby Bingham
4
 *
5
 * This file is part of FFmpeg.
6
 *
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.
11
 *
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.
16
 *
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
20
 */
21
22 e0752603 Vitor Sessak
#include <stdarg.h>
23 4dbbcdee Vitor Sessak
#include <stdlib.h>
24
#include <string.h>
25
#include <stdio.h>
26
27
#include "avfilter.h"
28 d72a138e Vitor Sessak
#include "allfilters.h"
29 4dbbcdee Vitor Sessak
30
/** list of registered filters, sorted by name */
31
static int filter_count = 0;
32
static AVFilter **filters = NULL;
33
34 f60208f4 Vitor Sessak
struct AVFilterGraph {
35
    unsigned filter_count;
36
    AVFilterContext **filters;
37
};
38
39
AVFilterGraph *avfilter_create_graph(void)
40
{
41
    return av_mallocz(sizeof(AVFilterGraph));
42
}
43
44
void avfilter_destroy_graph(AVFilterGraph *graph)
45
{
46
    unsigned i;
47
48
    for(i = 0; i < graph->filter_count; i ++)
49
        avfilter_destroy(graph->filters[i]);
50
    av_free(graph->filters);
51
    av_free(graph);
52
}
53
54
void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
55
{
56
    graph->filters = av_realloc(graph->filters,
57
                                sizeof(AVFilterContext*) * ++graph->filter_count);
58
    graph->filters[graph->filter_count - 1] = filter;
59
}
60
61 4dbbcdee Vitor Sessak
/* TODO: buffer pool.  see comment for avfilter_default_get_video_buffer() */
62
void avfilter_default_free_video_buffer(AVFilterPic *pic)
63
{
64
    avpicture_free((AVPicture *) pic);
65
    av_free(pic);
66
}
67
68
/* TODO: set the buffer's priv member to a context structure for the whole
69
 * filter chain.  This will allow for a buffer pool instead of the constant
70
 * alloc & free cycle currently implemented. */
71
AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms)
72
{
73
    AVFilterPic *pic = av_mallocz(sizeof(AVFilterPic));
74
    AVFilterPicRef *ref = av_mallocz(sizeof(AVFilterPicRef));
75
76 1653c11f Vitor Sessak
    ref->pic   = pic;
77
    ref->w     = link->w;
78
    ref->h     = link->h;
79 4dbbcdee Vitor Sessak
    ref->perms = perms;
80
81
    pic->refcount = 1;
82 1653c11f Vitor Sessak
    pic->format   = link->format;
83
    pic->free     = avfilter_default_free_video_buffer;
84 4dbbcdee Vitor Sessak
    avpicture_alloc((AVPicture *)pic, pic->format, ref->w, ref->h);
85
86 92beffdc Vitor Sessak
    memcpy(ref->data,     pic->data,     sizeof(pic->data));
87 a4ca7389 Vitor Sessak
    memcpy(ref->linesize, pic->linesize, sizeof(pic->linesize));
88 4dbbcdee Vitor Sessak
89
    return ref;
90
}
91
92
void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
93
{
94 3628fbe0 Vitor Sessak
    AVFilterLink *out = link->dst->outputs[0];
95
96 4dbbcdee Vitor Sessak
    link->cur_pic = picref;
97 3628fbe0 Vitor Sessak
98
    if(out) {
99 1653c11f Vitor Sessak
        out->outpic      = avfilter_get_video_buffer(out, AV_PERM_WRITE);
100 af838d4c Vitor Sessak
        out->outpic->pts = picref->pts;
101 3628fbe0 Vitor Sessak
        avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0));
102
    }
103 4dbbcdee Vitor Sessak
}
104
105
void avfilter_default_end_frame(AVFilterLink *link)
106
{
107 3628fbe0 Vitor Sessak
    AVFilterLink *out = link->dst->outputs[0];
108
109 4dbbcdee Vitor Sessak
    avfilter_unref_pic(link->cur_pic);
110
    link->cur_pic = NULL;
111 3628fbe0 Vitor Sessak
112
    if(out) {
113
        avfilter_unref_pic(out->outpic);
114
        out->outpic = NULL;
115
        avfilter_end_frame(out);
116
    }
117 4dbbcdee Vitor Sessak
}
118
119 efb36bfc Vitor Sessak
AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
120 4dbbcdee Vitor Sessak
{
121
    AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
122
    memcpy(ret, ref, sizeof(AVFilterPicRef));
123 efb36bfc Vitor Sessak
    ret->perms &= pmask;
124 4dbbcdee Vitor Sessak
    ret->pic->refcount ++;
125
    return ret;
126
}
127
128
void avfilter_unref_pic(AVFilterPicRef *ref)
129
{
130
    if(-- ref->pic->refcount == 0)
131
        ref->pic->free(ref->pic);
132
    av_free(ref);
133
}
134
135 102fb0e3 Vitor Sessak
/**
136
 * default config_link() implementation for output video links to simplify
137
 * the implementation of one input one output video filters */
138
static int default_config_output_link(AVFilterLink *link)
139
{
140
    link->w = link->src->inputs[0]->w;
141
    link->h = link->src->inputs[0]->h;
142
143
    return 0;
144
}
145
146
/**
147
 * default query_formats() implementation for output video links to simplify
148
 * the implementation of one input one output video filters */
149
static int *default_query_output_formats(AVFilterLink *link)
150
{
151
    return avfilter_make_format_list(1, link->src->inputs[0]->format);
152
}
153
154 4dbbcdee Vitor Sessak
int avfilter_link(AVFilterContext *src, unsigned srcpad,
155
                  AVFilterContext *dst, unsigned dstpad)
156
{
157
    AVFilterLink *link;
158 e0752603 Vitor Sessak
    int *fmts[2], i, j;
159 4dbbcdee Vitor Sessak
160
    if(src->outputs[srcpad] || dst->inputs[dstpad])
161
        return -1;
162
163
    src->outputs[srcpad] =
164
    dst->inputs[dstpad]  = link = av_malloc(sizeof(AVFilterLink));
165
166 1653c11f Vitor Sessak
    link->src     = src;
167
    link->dst     = dst;
168
    link->srcpad  = srcpad;
169
    link->dstpad  = dstpad;
170 4dbbcdee Vitor Sessak
    link->cur_pic = NULL;
171
172 e0752603 Vitor Sessak
    /* find a format both filters support - TODO: auto-insert conversion filter */
173 998a7aa3 Vitor Sessak
    link->format = -1;
174 102fb0e3 Vitor Sessak
    if(src->filter->outputs[srcpad].query_formats)
175
        fmts[0] = src->filter->outputs[srcpad].query_formats(link);
176
    else
177
        fmts[0] = default_query_output_formats(link);
178 ba6b9035 Vitor Sessak
    fmts[1] = dst->filter-> inputs[dstpad].query_formats(link);
179 e0752603 Vitor Sessak
    for(i = 0; fmts[0][i] != -1; i ++)
180
        for(j = 0; fmts[1][j] != -1; j ++)
181
            if(fmts[0][i] == fmts[1][j]) {
182
                link->format = fmts[0][i];
183
                goto format_done;
184
            }
185
186
format_done:
187
    av_free(fmts[0]);
188
    av_free(fmts[1]);
189
    if(link->format == -1) {
190
        /* failed to find a format.  fail at creating the link */
191
        av_free(link);
192
        src->outputs[srcpad] = NULL;
193
        dst->inputs[dstpad]  = NULL;
194
        return -1;
195
    }
196
197 102fb0e3 Vitor Sessak
    if (src->filter->outputs[srcpad].config_props)
198
        src->filter->outputs[srcpad].config_props(link);
199
    else
200
        default_config_output_link(link);
201
202
    if (dst->filter->inputs[dstpad].config_props)
203
        dst->filter->inputs[dstpad].config_props(link);
204
205 4dbbcdee Vitor Sessak
    return 0;
206
}
207
208
AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms)
209
{
210
    AVFilterPicRef *ret = NULL;
211
212
    if(link->dst->filter->inputs[link->dstpad].get_video_buffer)
213
        ret = link->dst->filter->inputs[link->dstpad].get_video_buffer(link, perms);
214
215
    if(!ret)
216
        ret = avfilter_default_get_video_buffer(link, perms);
217
218
    return ret;
219
}
220
221
void avfilter_request_frame(AVFilterLink *link)
222
{
223 9586ba3a Vitor Sessak
    const AVFilterPad *pad = &link->src->filter->outputs[link->srcpad];
224
225
    if(pad->request_frame)
226
        pad->request_frame(link);
227
    else if(link->src->inputs[0])
228
        avfilter_request_frame(link->src->inputs[0]);
229 4dbbcdee Vitor Sessak
}
230
231
/* XXX: should we do the duplicating of the picture ref here, instead of
232
 * forcing the source filter to do it? */
233
void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
234
{
235
    void (*start_frame)(AVFilterLink *, AVFilterPicRef *);
236
237
    start_frame = link->dst->filter->inputs[link->dstpad].start_frame;
238
    if(!start_frame)
239
        start_frame = avfilter_default_start_frame;
240
241
    start_frame(link, picref);
242
}
243
244
void avfilter_end_frame(AVFilterLink *link)
245
{
246
    void (*end_frame)(AVFilterLink *);
247
248
    end_frame = link->dst->filter->inputs[link->dstpad].end_frame;
249
    if(!end_frame)
250
        end_frame = avfilter_default_end_frame;
251
252
    end_frame(link);
253
}
254
255
void avfilter_draw_slice(AVFilterLink *link, uint8_t *data[4], int y, int h)
256
{
257
    link->dst->filter->inputs[link->dstpad].draw_slice(link, data, y, h);
258
}
259
260
static int filter_cmp(const void *aa, const void *bb)
261
{
262
    const AVFilter *a = *(const AVFilter **)aa, *b = *(const AVFilter **)bb;
263
    return strcmp(a->name, b->name);
264
}
265
266
AVFilter *avfilter_get_by_name(char *name)
267
{
268
    AVFilter key = { .name = name, };
269
    AVFilter *key2 = &key;
270
    AVFilter **ret;
271
272
    ret = bsearch(&key2, filters, filter_count, sizeof(AVFilter **), filter_cmp);
273
    if(ret)
274
        return *ret;
275
    return NULL;
276
}
277
278
/* FIXME: insert in order, rather than insert at end + resort */
279
void avfilter_register(AVFilter *filter)
280
{
281
    filters = av_realloc(filters, sizeof(AVFilter*) * (filter_count+1));
282
    filters[filter_count] = filter;
283
    qsort(filters, ++filter_count, sizeof(AVFilter **), filter_cmp);
284
}
285
286
void avfilter_init(void)
287
{
288 d72a138e Vitor Sessak
    avfilter_register(&vsrc_dummy);
289 eaf7eb66 Vitor Sessak
    avfilter_register(&vsrc_ppm);
290 d72a138e Vitor Sessak
    avfilter_register(&vf_crop);
291
    avfilter_register(&vf_passthrough);
292 72e3037a Vitor Sessak
    avfilter_register(&vf_rgb2bgr);
293 ce356b09 Vitor Sessak
    avfilter_register(&vf_slicify);
294 d72a138e Vitor Sessak
    avfilter_register(&vo_sdl);
295 4dbbcdee Vitor Sessak
}
296
297
void avfilter_uninit(void)
298
{
299
    av_freep(&filters);
300
    filter_count = 0;
301
}
302
303
static int pad_count(const AVFilterPad *pads)
304
{
305
    AVFilterPad *p = (AVFilterPad *) pads;
306
    int count;
307
308
    for(count = 0; p->name; count ++) p ++;
309
    return count;
310
}
311
312
static const char *filter_name(void *p)
313
{
314
    AVFilterContext *filter = p;
315
    return filter->filter->name;
316
}
317
318 6ae82d1e Vitor Sessak
AVFilterContext *avfilter_create(AVFilter *filter, char *inst_name)
319 4dbbcdee Vitor Sessak
{
320
    AVFilterContext *ret = av_malloc(sizeof(AVFilterContext));
321
322
    ret->av_class = av_mallocz(sizeof(AVClass));
323
    ret->av_class->item_name = filter_name;
324
    ret->filter   = filter;
325 6ae82d1e Vitor Sessak
    ret->name     = inst_name ? strdup(inst_name) : NULL;
326 4dbbcdee Vitor Sessak
    ret->inputs   = av_mallocz(sizeof(AVFilterLink*) * pad_count(filter->inputs));
327
    ret->outputs  = av_mallocz(sizeof(AVFilterLink*) * pad_count(filter->outputs));
328
    ret->priv     = av_mallocz(filter->priv_size);
329
330
    return ret;
331
}
332
333
void avfilter_destroy(AVFilterContext *filter)
334
{
335
    int i;
336
337
    if(filter->filter->uninit)
338
        filter->filter->uninit(filter);
339
340
    for(i = 0; i < pad_count(filter->filter->inputs); i ++) {
341
        if(filter->inputs[i])
342
            filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
343
        av_free(filter->inputs[i]);
344
    }
345
    for(i = 0; i < pad_count(filter->filter->outputs); i ++) {
346
        if(filter->outputs[i])
347
            filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
348
        av_free(filter->outputs[i]);
349
    }
350
351 6ae82d1e Vitor Sessak
    free   (filter->name);
352 4dbbcdee Vitor Sessak
    av_free(filter->inputs);
353
    av_free(filter->outputs);
354
    av_free(filter->priv);
355
    av_free(filter->av_class);
356
    av_free(filter);
357
}
358
359 6ae82d1e Vitor Sessak
AVFilterContext *avfilter_create_by_name(char *name, char *inst_name)
360 4dbbcdee Vitor Sessak
{
361
    AVFilter *filt;
362
363
    if(!(filt = avfilter_get_by_name(name))) return NULL;
364 6ae82d1e Vitor Sessak
    return avfilter_create(filt, inst_name);
365 4dbbcdee Vitor Sessak
}
366
367 89e64908 Vitor Sessak
int avfilter_init_filter(AVFilterContext *filter, const char *args)
368 4dbbcdee Vitor Sessak
{
369
    int ret, i;
370
371
    if(filter->filter->init)
372 89e64908 Vitor Sessak
        if((ret = filter->filter->init(filter, args))) return ret;
373 4dbbcdee Vitor Sessak
    return 0;
374
}
375
376 e0752603 Vitor Sessak
int *avfilter_make_format_list(int len, ...)
377
{
378
    int *ret, i;
379
    va_list vl;
380
381
    ret = av_malloc(sizeof(int) * (len + 1));
382
    va_start(vl, len);
383
    for(i = 0; i < len; i ++)
384
        ret[i] = va_arg(vl, int);
385
    va_end(vl);
386
    ret[len] = -1;
387
388
    return ret;
389
}