Statistics
| Branch: | Revision:

ffmpeg / libavfilter / avfilter.c @ f60208f4

History | View | Annotate | Download (10.5 KB)

1
/*
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
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <stdio.h>
26

    
27
#include "avfilter.h"
28
#include "allfilters.h"
29

    
30
/** list of registered filters, sorted by name */
31
static int filter_count = 0;
32
static AVFilter **filters = NULL;
33

    
34
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
/* 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
    ref->pic   = pic;
77
    ref->w     = link->w;
78
    ref->h     = link->h;
79
    ref->perms = perms;
80

    
81
    pic->refcount = 1;
82
    pic->format   = link->format;
83
    pic->free     = avfilter_default_free_video_buffer;
84
    avpicture_alloc((AVPicture *)pic, pic->format, ref->w, ref->h);
85

    
86
    memcpy(ref->data,     pic->data,     sizeof(pic->data));
87
    memcpy(ref->linesize, pic->linesize, sizeof(pic->linesize));
88

    
89
    return ref;
90
}
91

    
92
void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
93
{
94
    AVFilterLink *out = link->dst->outputs[0];
95

    
96
    link->cur_pic = picref;
97

    
98
    if(out) {
99
        out->outpic      = avfilter_get_video_buffer(out, AV_PERM_WRITE);
100
        out->outpic->pts = picref->pts;
101
        avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0));
102
    }
103
}
104

    
105
void avfilter_default_end_frame(AVFilterLink *link)
106
{
107
    AVFilterLink *out = link->dst->outputs[0];
108

    
109
    avfilter_unref_pic(link->cur_pic);
110
    link->cur_pic = NULL;
111

    
112
    if(out) {
113
        avfilter_unref_pic(out->outpic);
114
        out->outpic = NULL;
115
        avfilter_end_frame(out);
116
    }
117
}
118

    
119
AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
120
{
121
    AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
122
    memcpy(ret, ref, sizeof(AVFilterPicRef));
123
    ret->perms &= pmask;
124
    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
/**
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
int avfilter_link(AVFilterContext *src, unsigned srcpad,
155
                  AVFilterContext *dst, unsigned dstpad)
156
{
157
    AVFilterLink *link;
158
    int *fmts[2], i, j;
159

    
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
    link->src     = src;
167
    link->dst     = dst;
168
    link->srcpad  = srcpad;
169
    link->dstpad  = dstpad;
170
    link->cur_pic = NULL;
171

    
172
    /* find a format both filters support - TODO: auto-insert conversion filter */
173
    link->format = -1;
174
    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
    fmts[1] = dst->filter-> inputs[dstpad].query_formats(link);
179
    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
    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
    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
    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
}
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
    avfilter_register(&vsrc_dummy);
289
    avfilter_register(&vsrc_ppm);
290
    avfilter_register(&vf_crop);
291
    avfilter_register(&vf_passthrough);
292
    avfilter_register(&vf_rgb2bgr);
293
    avfilter_register(&vf_slicify);
294
    avfilter_register(&vo_sdl);
295
}
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
AVFilterContext *avfilter_create(AVFilter *filter, char *inst_name)
319
{
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
    ret->name     = inst_name ? strdup(inst_name) : NULL;
326
    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
    free   (filter->name);
352
    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
AVFilterContext *avfilter_create_by_name(char *name, char *inst_name)
360
{
361
    AVFilter *filt;
362

    
363
    if(!(filt = avfilter_get_by_name(name))) return NULL;
364
    return avfilter_create(filt, inst_name);
365
}
366

    
367
int avfilter_init_filter(AVFilterContext *filter, const char *args)
368
{
369
    int ret, i;
370

    
371
    if(filter->filter->init)
372
        if((ret = filter->filter->init(filter, args))) return ret;
373
    return 0;
374
}
375

    
376
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
}
390