avfilter.c 10.9 KB
Newer Older
V
Vitor Sessak 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Filter layer
 * copyright (c) 2007 Bobby Bingham
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

22
#include <stdarg.h>
V
Vitor Sessak 已提交
23 24 25 26 27
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "avfilter.h"
V
Vitor Sessak 已提交
28
#include "allfilters.h"
V
Vitor Sessak 已提交
29

30 31 32 33 34 35
/** list of registered filters */
struct FilterList
{
    AVFilter *filter;
    struct FilterList *next;
} *filters = NULL;
V
Vitor Sessak 已提交
36

V
Vitor Sessak 已提交
37 38 39 40
/** helper macros to get the in/out pad on the dst/src filter */
#define link_dpad(link)     link->dst-> input_pads[link->dstpad]
#define link_spad(link)     link->src->output_pads[link->srcpad]

41
AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
V
Vitor Sessak 已提交
42 43
{
    AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
V
Vitor Sessak 已提交
44
    *ret = *ref;
45
    ret->perms &= pmask;
V
Vitor Sessak 已提交
46 47 48 49 50 51
    ret->pic->refcount ++;
    return ret;
}

void avfilter_unref_pic(AVFilterPicRef *ref)
{
52
    if(-- ref->pic->refcount == 0)
V
Vitor Sessak 已提交
53 54 55 56
        ref->pic->free(ref->pic);
    av_free(ref);
}

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
                         AVFilterPad **pads, AVFilterLink ***links,
                         AVFilterPad *newpad)
{
    unsigned i;

    idx = FFMIN(idx, *count);

    *pads  = av_realloc(*pads,  sizeof(AVFilterPad)   * (*count + 1));
    *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
    memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad)   * (*count-idx));
    memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
    memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
    (*links)[idx] = NULL;

    (*count) ++;
    for(i = idx+1; i < *count; i ++)
        if(*links[i])
            (*(unsigned *)((uint8_t *)(*links[i]) + padidx_off)) ++;
}

V
Vitor Sessak 已提交
78 79 80 81 82
int avfilter_link(AVFilterContext *src, unsigned srcpad,
                  AVFilterContext *dst, unsigned dstpad)
{
    AVFilterLink *link;

V
Vitor Sessak 已提交
83 84
    if(src->output_count <= srcpad || dst->input_count <= dstpad ||
       src->outputs[srcpad]        || dst->inputs[dstpad])
V
Vitor Sessak 已提交
85 86 87
        return -1;

    src->outputs[srcpad] =
88
    dst->inputs[dstpad]  = link = av_mallocz(sizeof(AVFilterLink));
V
Vitor Sessak 已提交
89

V
Vitor Sessak 已提交
90 91 92 93
    link->src     = src;
    link->dst     = dst;
    link->srcpad  = srcpad;
    link->dstpad  = dstpad;
94 95 96 97 98 99 100 101 102
    link->format  = -1;

    return 0;
}

int avfilter_config_link(AVFilterLink *link)
{
    int *fmts[2], i, j;
    int (*config_link)(AVFilterLink *);
103
    int *(*query_formats)(AVFilterLink *link);
104 105 106

    if(!link)
        return 0;
V
Vitor Sessak 已提交
107

108
    /* find a format both filters support - TODO: auto-insert conversion filter */
109
    link->format = -1;
110 111 112
    if(!(query_formats = link_spad(link).query_formats))
        query_formats = avfilter_default_query_output_formats;
    fmts[0] = query_formats(link);
V
Vitor Sessak 已提交
113
    fmts[1] = link_dpad(link).query_formats(link);
114 115 116 117 118 119 120 121 122 123
    for(i = 0; fmts[0][i] != -1; i ++)
        for(j = 0; fmts[1][j] != -1; j ++)
            if(fmts[0][i] == fmts[1][j]) {
                link->format = fmts[0][i];
                goto format_done;
            }

format_done:
    av_free(fmts[0]);
    av_free(fmts[1]);
124
    if(link->format == -1)
125 126
        return -1;

V
Vitor Sessak 已提交
127
    if(!(config_link = link_spad(link).config_props))
128 129 130
        config_link  = avfilter_default_config_output_link;
    if(config_link(link))
            return -1;
131

V
Vitor Sessak 已提交
132
    if(!(config_link = link_dpad(link).config_props))
133 134 135
        config_link  = avfilter_default_config_input_link;
    if(config_link(link))
            return -1;
136

V
Vitor Sessak 已提交
137 138 139 140 141 142 143
    return 0;
}

AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms)
{
    AVFilterPicRef *ret = NULL;

V
Vitor Sessak 已提交
144 145
    if(link_dpad(link).get_video_buffer)
        ret = link_dpad(link).get_video_buffer(link, perms);
V
Vitor Sessak 已提交
146 147 148 149 150 151 152

    if(!ret)
        ret = avfilter_default_get_video_buffer(link, perms);

    return ret;
}

153
int avfilter_request_frame(AVFilterLink *link)
V
Vitor Sessak 已提交
154
{
V
Vitor Sessak 已提交
155 156
    if(link_spad(link).request_frame)
        return link_spad(link).request_frame(link);
157
    else if(link->src->inputs[0])
158 159
        return avfilter_request_frame(link->src->inputs[0]);
    else return -1;
V
Vitor Sessak 已提交
160 161 162 163 164 165 166 167
}

/* XXX: should we do the duplicating of the picture ref here, instead of
 * forcing the source filter to do it? */
void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
{
    void (*start_frame)(AVFilterLink *, AVFilterPicRef *);

168
    if(!(start_frame = link_dpad(link).start_frame))
V
Vitor Sessak 已提交
169 170
        start_frame = avfilter_default_start_frame;

171
    /* prepare to copy the picture if it has insufficient permissions */
172 173
    if((link_dpad(link).min_perms & picref->perms) != link_dpad(link).min_perms ||
        link_dpad(link).rej_perms & picref->perms) {
174 175
        av_log(link->dst, AV_LOG_INFO,
                "frame copy needed (have perms %x, need %x, reject %x)\n",
176
                picref->perms,
177 178 179 180 181 182 183 184 185
                link_dpad(link).min_perms, link_dpad(link).rej_perms);

        link->cur_pic = avfilter_default_get_video_buffer(link, link_dpad(link).min_perms);
        link->srcpic = picref;
    }
    else
        link->cur_pic = picref;

    start_frame(link, link->cur_pic);
V
Vitor Sessak 已提交
186 187 188 189 190 191
}

void avfilter_end_frame(AVFilterLink *link)
{
    void (*end_frame)(AVFilterLink *);

192 193 194 195 196 197 198
    /* unreference the source picture if we're feeding the destination filter
     * a copied version dues to permission issues */
    if(link->srcpic) {
        avfilter_unref_pic(link->srcpic);
        link->srcpic = NULL;
    }

199
    if(!(end_frame = link_dpad(link).end_frame))
V
Vitor Sessak 已提交
200 201 202 203 204
        end_frame = avfilter_default_end_frame;

    end_frame(link);
}

205
void avfilter_draw_slice(AVFilterLink *link, int y, int h)
V
Vitor Sessak 已提交
206
{
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    uint8_t *src[4], *dst[4];
    int i, j, hsub, vsub;

    /* copy the slice if needed for permission reasons */
    if(link->srcpic) {
        avcodec_get_chroma_sub_sample(link->format, &hsub, &vsub);

        src[0] = link->srcpic-> data[0] + y * link->srcpic-> linesize[0];
        dst[0] = link->cur_pic->data[0] + y * link->cur_pic->linesize[0];
        for(i = 1; i < 4; i ++) {
            if(link->srcpic->data[i]) {
                src[i] = link->srcpic-> data[i] + (y >> vsub) * link->srcpic-> linesize[i];
                dst[i] = link->cur_pic->data[i] + (y >> vsub) * link->cur_pic->linesize[i];
            } else
                src[i] = dst[i] = NULL;
        }
        for(j = 0; j < h; j ++) {
            memcpy(dst[0], src[0], link->cur_pic->linesize[0]);
            src[0] += link->srcpic ->linesize[0];
            dst[0] += link->cur_pic->linesize[0];
        }
        for(i = 1; i < 4; i ++) {
            if(!src[i]) continue;

            for(j = 0; j < h >> vsub; j ++) {
                memcpy(dst[i], src[i], link->cur_pic->linesize[i]);
                src[i] += link->srcpic ->linesize[i];
                dst[i] += link->cur_pic->linesize[i];
            }
        }
    }

V
Vitor Sessak 已提交
239
    if(!link_dpad(link).draw_slice)
V
Vitor Sessak 已提交
240 241
        return;

V
Vitor Sessak 已提交
242
    link_dpad(link).draw_slice(link, y, h);
V
Vitor Sessak 已提交
243 244 245 246
}

AVFilter *avfilter_get_by_name(char *name)
{
247 248 249 250 251
    struct FilterList *filt;

    for(filt = filters; filt; filt = filt->next)
        if(!strcmp(filt->filter->name, name))
            return filt->filter;
V
Vitor Sessak 已提交
252 253 254 255 256 257 258

    return NULL;
}

/* FIXME: insert in order, rather than insert at end + resort */
void avfilter_register(AVFilter *filter)
{
259 260 261 262 263
    struct FilterList *newfilt = av_malloc(sizeof(struct FilterList));

    newfilt->filter = filter;
    newfilt->next   = filters;
    filters         = newfilt;
V
Vitor Sessak 已提交
264 265 266 267
}

void avfilter_init(void)
{
V
Vitor Sessak 已提交
268
    avfilter_register(&vsrc_dummy);
269
    avfilter_register(&vsrc_ppm);
270
    avfilter_register(&vf_buffer);
V
Vitor Sessak 已提交
271
    avfilter_register(&vf_crop);
272
    avfilter_register(&vf_fps);
273
    avfilter_register(&vf_graph);
274 275
    avfilter_register(&vf_graphdesc);
    avfilter_register(&vf_graphfile);
276
    avfilter_register(&vf_overlay);
V
Vitor Sessak 已提交
277
    avfilter_register(&vf_passthrough);
V
Vitor Sessak 已提交
278
    avfilter_register(&vf_rgb2bgr);
279
    avfilter_register(&vf_slicify);
V
Vitor Sessak 已提交
280
    avfilter_register(&vf_vflip);
V
Vitor Sessak 已提交
281 282 283 284
}

void avfilter_uninit(void)
{
285 286 287 288 289 290
    struct FilterList *tmp;

    for(; filters; filters = tmp) {
        tmp = filters->next;
        av_free(filters);
    }
V
Vitor Sessak 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
}

static int pad_count(const AVFilterPad *pads)
{
    AVFilterPad *p = (AVFilterPad *) pads;
    int count;

    for(count = 0; p->name; count ++) p ++;
    return count;
}

static const char *filter_name(void *p)
{
    AVFilterContext *filter = p;
    return filter->filter->name;
}

308
AVFilterContext *avfilter_open(AVFilter *filter, char *inst_name)
V
Vitor Sessak 已提交
309 310 311 312 313 314
{
    AVFilterContext *ret = av_malloc(sizeof(AVFilterContext));

    ret->av_class = av_mallocz(sizeof(AVClass));
    ret->av_class->item_name = filter_name;
    ret->filter   = filter;
315
    ret->name     = inst_name ? av_strdup(inst_name) : NULL;
V
Vitor Sessak 已提交
316 317
    ret->priv     = av_mallocz(filter->priv_size);

V
Vitor Sessak 已提交
318
    ret->input_count  = pad_count(filter->inputs);
319 320
    ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->input_count);
    memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad)*ret->input_count);
V
Vitor Sessak 已提交
321
    ret->inputs       = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
322

V
Vitor Sessak 已提交
323
    ret->output_count = pad_count(filter->outputs);
324 325
    ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->output_count);
    memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad)*ret->output_count);
V
Vitor Sessak 已提交
326 327
    ret->outputs      = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);

V
Vitor Sessak 已提交
328 329 330 331 332 333 334 335 336 337
    return ret;
}

void avfilter_destroy(AVFilterContext *filter)
{
    int i;

    if(filter->filter->uninit)
        filter->filter->uninit(filter);

338
    for(i = 0; i < filter->input_count; i ++) {
V
Vitor Sessak 已提交
339 340
        if(filter->inputs[i])
            filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
V
Vitor Sessak 已提交
341
        av_freep(&filter->inputs[i]);
V
Vitor Sessak 已提交
342
    }
343
    for(i = 0; i < filter->output_count; i ++) {
V
Vitor Sessak 已提交
344 345
        if(filter->outputs[i])
            filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
V
Vitor Sessak 已提交
346
        av_freep(&filter->outputs[i]);
V
Vitor Sessak 已提交
347 348
    }

V
Vitor Sessak 已提交
349 350 351 352 353 354 355
    av_freep(&filter->name);
    av_freep(&filter->input_pads);
    av_freep(&filter->output_pads);
    av_freep(&filter->inputs);
    av_freep(&filter->outputs);
    av_freep(&filter->priv);
    av_freep(&filter->av_class);
V
Vitor Sessak 已提交
356 357 358
    av_free(filter);
}

359
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
360
{
V
Vitor Sessak 已提交
361
    int ret;
V
Vitor Sessak 已提交
362 363

    if(filter->filter->init)
364
        if((ret = filter->filter->init(filter, args, opaque))) return ret;
V
Vitor Sessak 已提交
365 366 367
    return 0;
}

368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
int *avfilter_make_format_list(int len, ...)
{
    int *ret, i;
    va_list vl;

    ret = av_malloc(sizeof(int) * (len + 1));
    va_start(vl, len);
    for(i = 0; i < len; i ++)
        ret[i] = va_arg(vl, int);
    va_end(vl);
    ret[len] = -1;

    return ret;
}