avfilter.c 11.1 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

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

V
Vitor Sessak 已提交
34 35 36 37
/** 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]

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

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

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
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 已提交
75 76 77 78 79
int avfilter_link(AVFilterContext *src, unsigned srcpad,
                  AVFilterContext *dst, unsigned dstpad)
{
    AVFilterLink *link;

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

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

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

    return 0;
}

int avfilter_config_link(AVFilterLink *link)
{
    int *fmts[2], i, j;
    int (*config_link)(AVFilterLink *);
100
    int *(*query_formats)(AVFilterLink *link);
101 102 103

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

105
    /* find a format both filters support - TODO: auto-insert conversion filter */
106
    link->format = -1;
107 108 109
    if(!(query_formats = link_spad(link).query_formats))
        query_formats = avfilter_default_query_output_formats;
    fmts[0] = query_formats(link);
V
Vitor Sessak 已提交
110
    fmts[1] = link_dpad(link).query_formats(link);
111 112 113 114 115 116 117 118 119 120
    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]);
121
    if(link->format == -1)
122 123
        return -1;

V
Vitor Sessak 已提交
124
    if(!(config_link = link_spad(link).config_props))
125 126 127
        config_link  = avfilter_default_config_output_link;
    if(config_link(link))
            return -1;
128

V
Vitor Sessak 已提交
129
    if(!(config_link = link_dpad(link).config_props))
130 131 132
        config_link  = avfilter_default_config_input_link;
    if(config_link(link))
            return -1;
133

V
Vitor Sessak 已提交
134 135 136 137 138 139 140
    return 0;
}

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

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

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

    return ret;
}

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

/* 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 *);

165
    if(!(start_frame = link_dpad(link).start_frame))
V
Vitor Sessak 已提交
166 167
        start_frame = avfilter_default_start_frame;

168
    /* prepare to copy the picture if it has insufficient permissions */
169 170
    if((link_dpad(link).min_perms & picref->perms) != link_dpad(link).min_perms ||
        link_dpad(link).rej_perms & picref->perms) {
171 172
        av_log(link->dst, AV_LOG_INFO,
                "frame copy needed (have perms %x, need %x, reject %x)\n",
173
                picref->perms,
174 175 176 177 178 179 180 181 182
                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 已提交
183 184 185 186 187 188
}

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

189 190 191 192 193 194 195
    /* 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;
    }

196
    if(!(end_frame = link_dpad(link).end_frame))
V
Vitor Sessak 已提交
197 198 199 200 201
        end_frame = avfilter_default_end_frame;

    end_frame(link);
}

202
void avfilter_draw_slice(AVFilterLink *link, int y, int h)
V
Vitor Sessak 已提交
203
{
204 205 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
    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 已提交
236
    if(!link_dpad(link).draw_slice)
V
Vitor Sessak 已提交
237 238
        return;

V
Vitor Sessak 已提交
239
    link_dpad(link).draw_slice(link, y, h);
V
Vitor Sessak 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
}

static int filter_cmp(const void *aa, const void *bb)
{
    const AVFilter *a = *(const AVFilter **)aa, *b = *(const AVFilter **)bb;
    return strcmp(a->name, b->name);
}

AVFilter *avfilter_get_by_name(char *name)
{
    AVFilter key = { .name = name, };
    AVFilter *key2 = &key;
    AVFilter **ret;

    ret = bsearch(&key2, filters, filter_count, sizeof(AVFilter **), filter_cmp);
    if(ret)
        return *ret;
    return NULL;
}

/* FIXME: insert in order, rather than insert at end + resort */
void avfilter_register(AVFilter *filter)
{
    filters = av_realloc(filters, sizeof(AVFilter*) * (filter_count+1));
    filters[filter_count] = filter;
    qsort(filters, ++filter_count, sizeof(AVFilter **), filter_cmp);
}

void avfilter_init(void)
{
V
Vitor Sessak 已提交
270
    avfilter_register(&vsrc_dummy);
271
    avfilter_register(&vsrc_ppm);
V
Vitor Sessak 已提交
272
    avfilter_register(&vf_crop);
273
    avfilter_register(&vf_fps);
274
    avfilter_register(&vf_graph);
275 276
    avfilter_register(&vf_graphdesc);
    avfilter_register(&vf_graphfile);
277
    avfilter_register(&vf_overlay);
V
Vitor Sessak 已提交
278
    avfilter_register(&vf_passthrough);
V
Vitor Sessak 已提交
279
    avfilter_register(&vf_rgb2bgr);
280
    avfilter_register(&vf_slicify);
V
Vitor Sessak 已提交
281
    avfilter_register(&vf_vflip);
V
Vitor Sessak 已提交
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
}

void avfilter_uninit(void)
{
    av_freep(&filters);
    filter_count = 0;
}

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;
}

305
AVFilterContext *avfilter_create(AVFilter *filter, char *inst_name)
V
Vitor Sessak 已提交
306 307 308 309 310 311
{
    AVFilterContext *ret = av_malloc(sizeof(AVFilterContext));

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

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

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

V
Vitor Sessak 已提交
325 326 327 328 329 330 331 332 333 334
    return ret;
}

void avfilter_destroy(AVFilterContext *filter)
{
    int i;

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

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

346
    av_free(filter->name);
347 348
    av_free(filter->input_pads);
    av_free(filter->output_pads);
V
Vitor Sessak 已提交
349 350 351 352 353 354 355
    av_free(filter->inputs);
    av_free(filter->outputs);
    av_free(filter->priv);
    av_free(filter->av_class);
    av_free(filter);
}

356
AVFilterContext *avfilter_create_by_name(char *name, char *inst_name)
V
Vitor Sessak 已提交
357 358 359 360
{
    AVFilter *filt;

    if(!(filt = avfilter_get_by_name(name))) return NULL;
361
    return avfilter_create(filt, inst_name);
V
Vitor Sessak 已提交
362 363
}

364
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
365
{
V
Vitor Sessak 已提交
366
    int ret;
V
Vitor Sessak 已提交
367 368

    if(filter->filter->init)
369
        if((ret = filter->filter->init(filter, args, opaque))) return ret;
V
Vitor Sessak 已提交
370 371 372
    return 0;
}

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
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;
}