avfilter.c 19.1 KB
Newer Older
V
Vitor Sessak 已提交
1
/*
2
 * filter layer
V
Vitor Sessak 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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 23
/* #define DEBUG */

24
#include "libavutil/pixdesc.h"
25
#include "libavutil/rational.h"
26
#include "libavcore/imgutils.h"
V
Vitor Sessak 已提交
27
#include "avfilter.h"
28
#include "internal.h"
V
Vitor Sessak 已提交
29

S
Stefano Sabatini 已提交
30 31 32 33
unsigned avfilter_version(void) {
    return LIBAVFILTER_VERSION_INT;
}

34
const char *avfilter_configuration(void)
35 36 37 38
{
    return FFMPEG_CONFIGURATION;
}

39
const char *avfilter_license(void)
40 41 42 43 44
{
#define LICENSE_PREFIX "libavfilter license: "
    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}

45
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
V
Vitor Sessak 已提交
46
{
47
    AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
48 49
    if (!ret)
        return NULL;
V
Vitor Sessak 已提交
50
    *ret = *ref;
51 52
    if (ref->type == AVMEDIA_TYPE_VIDEO) {
        ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
53 54 55 56
        if (!ret->video) {
            av_free(ret);
            return NULL;
        }
57
        *ret->video = *ref->video;
58 59 60 61 62 63 64
    } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
        ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
        if (!ret->audio) {
            av_free(ret);
            return NULL;
        }
        *ret->audio = *ref->audio;
65
    }
66
    ret->perms &= pmask;
67
    ret->buf->refcount ++;
V
Vitor Sessak 已提交
68 69 70
    return ret;
}

71
void avfilter_unref_buffer(AVFilterBufferRef *ref)
V
Vitor Sessak 已提交
72
{
73
    if (!(--ref->buf->refcount))
74
        ref->buf->free(ref->buf);
75
    av_free(ref->video);
76
    av_free(ref->audio);
V
Vitor Sessak 已提交
77 78 79
    av_free(ref);
}

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
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;

95 96 97 98
    (*count)++;
    for (i = idx+1; i < *count; i++)
        if (*links[i])
            (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
99 100
}

V
Vitor Sessak 已提交
101 102 103 104 105
int avfilter_link(AVFilterContext *src, unsigned srcpad,
                  AVFilterContext *dst, unsigned dstpad)
{
    AVFilterLink *link;

106 107
    if (src->output_count <= srcpad || dst->input_count <= dstpad ||
        src->outputs[srcpad]        || dst->inputs[dstpad])
V
Vitor Sessak 已提交
108 109 110
        return -1;

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

V
Vitor Sessak 已提交
113 114
    link->src     = src;
    link->dst     = dst;
115 116
    link->srcpad  = &src->output_pads[srcpad];
    link->dstpad  = &dst->input_pads[dstpad];
117
    link->type    = src->output_pads[srcpad].type;
118
    assert(PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
119
    link->format  = -1;
120 121 122 123

    return 0;
}

124
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
125
                           unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
126
{
127
    int ret;
128 129
    unsigned dstpad_idx = link->dstpad - link->dst->input_pads;

130 131 132
    av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
           "between the filter '%s' and the filter '%s'\n",
           filt->name, link->src->name, link->dst->name);
133

134
    link->dst->inputs[dstpad_idx] = NULL;
135
    if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
136
        /* failed to link output filter to new filter */
137
        link->dst->inputs[dstpad_idx] = link;
138
        return ret;
139 140 141 142
    }

    /* re-hookup the link to the new destination filter we inserted */
    link->dst = filt;
143 144
    link->dstpad = &filt->input_pads[filt_srcpad_idx];
    filt->inputs[filt_srcpad_idx] = link;
145

146
    /* if any information on supported media formats already exists on the
147
     * link, we need to preserve that */
148
    if (link->out_formats)
149
        avfilter_formats_changeref(&link->out_formats,
150
                                   &filt->outputs[filt_dstpad_idx]->out_formats);
151

152 153 154
    return 0;
}

155
int avfilter_config_links(AVFilterContext *filter)
156 157
{
    int (*config_link)(AVFilterLink *);
158
    unsigned i;
159
    int ret;
160

161
    for (i = 0; i < filter->input_count; i ++) {
V
Vitor Sessak 已提交
162
        AVFilterLink *link = filter->inputs[i];
163

164
        if (!link) continue;
165

166
        switch (link->init_state) {
167 168 169
        case AVLINK_INIT:
            continue;
        case AVLINK_STARTINIT:
170 171
            av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
            return 0;
172 173 174
        case AVLINK_UNINIT:
            link->init_state = AVLINK_STARTINIT;

175 176
            if ((ret = avfilter_config_links(link->src)) < 0)
                return ret;
V
Vitor Sessak 已提交
177

178
            if (!(config_link = link->srcpad->config_props))
V
Vitor Sessak 已提交
179
                config_link  = avfilter_default_config_output_link;
180 181
            if ((ret = config_link(link)) < 0)
                return ret;
182

183
            if (link->time_base.num == 0 && link->time_base.den == 0)
184 185
                link->time_base = link->src && link->src->input_count ?
                    link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
186

187
            if ((config_link = link->dstpad->config_props))
188 189
                if ((ret = config_link(link)) < 0)
                    return ret;
190

191 192 193 194
            link->init_state = AVLINK_INIT;
        }
    }

V
Vitor Sessak 已提交
195 196 197
    return 0;
}

198 199 200 201 202 203
char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
{
    snprintf(buf, buf_size, "%s%s%s%s%s",
             perms & AV_PERM_READ      ? "r" : "",
             perms & AV_PERM_WRITE     ? "w" : "",
             perms & AV_PERM_PRESERVE  ? "p" : "",
204 205
             perms & AV_PERM_REUSE     ? "u" : "",
             perms & AV_PERM_REUSE2    ? "U" : "");
206 207 208
    return buf;
}

209
void ff_dprintf_ref(void *ctx, AVFilterBufferRef *ref, int end)
210
{
211
    av_unused char buf[16];
212
    dprintf(ctx,
213 214
            "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
            ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
215 216
            ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
            ref->pts, ref->pos);
217

218
    if (ref->video) {
219
        dprintf(ctx, " a:%d/%d s:%dx%d i:%c",
220 221 222 223
                ref->video->pixel_aspect.num, ref->video->pixel_aspect.den,
                ref->video->w, ref->video->h,
                !ref->video->interlaced     ? 'P' :         /* Progressive  */
                ref->video->top_field_first ? 'T' : 'B');   /* Top / Bottom */
224
    }
225 226 227 228 229 230 231 232 233
    if (ref->audio) {
        dprintf(ctx, " cl:%"PRId64"d sn:%d s:%d sr:%d p:%d",
                ref->audio->channel_layout,
                ref->audio->samples_nb,
                ref->audio->size,
                ref->audio->sample_rate,
                ref->audio->planar);
    }

234
    dprintf(ctx, "]%s", end ? "\n" : "");
235 236
}

237
void ff_dprintf_link(void *ctx, AVFilterLink *link, int end)
238 239
{
    dprintf(ctx,
240
            "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
241
            link, link->w, link->h,
242
            av_pix_fmt_descriptors[link->format].name,
243 244 245 246 247
            link->src ? link->src->filter->name : "",
            link->dst ? link->dst->filter->name : "",
            end ? "\n" : "");
}

248
AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
V
Vitor Sessak 已提交
249
{
250
    AVFilterBufferRef *ret = NULL;
V
Vitor Sessak 已提交
251

252 253 254
    av_unused char buf[16];
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0);
    dprintf(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
255

256 257
    if (link->dstpad->get_video_buffer)
        ret = link->dstpad->get_video_buffer(link, perms, w, h);
258

259
    if (!ret)
260
        ret = avfilter_default_get_video_buffer(link, perms, w, h);
V
Vitor Sessak 已提交
261

262 263 264
    if (ret)
        ret->type = AVMEDIA_TYPE_VIDEO;

265
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); ff_dprintf_ref(NULL, ret, 1);
266

V
Vitor Sessak 已提交
267 268 269
    return ret;
}

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
AVFilterBufferRef *
avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
                                          int w, int h, enum PixelFormat format)
{
    AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
    AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));

    if (!pic || !picref)
        goto fail;

    picref->buf = pic;
    picref->buf->free = ff_avfilter_default_free_buffer;
    if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
        goto fail;

    picref->video->w = w;
    picref->video->h = h;

    /* make sure the buffer gets read permission or it's useless for output */
    picref->perms = perms | AV_PERM_READ;

    pic->refcount = 1;
    picref->type = AVMEDIA_TYPE_VIDEO;
    picref->format = format;

    memcpy(pic->data,        data,          sizeof(pic->data));
    memcpy(pic->linesize,    linesize,      sizeof(pic->linesize));
    memcpy(picref->data,     pic->data,     sizeof(picref->data));
    memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));

    return picref;

fail:
    if (picref && picref->video)
        av_free(picref->video);
    av_free(picref);
    av_free(pic);
    return NULL;
}

310
AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
311
                                             enum AVSampleFormat sample_fmt, int size,
312 313 314 315
                                             int64_t channel_layout, int planar)
{
    AVFilterBufferRef *ret = NULL;

316 317
    if (link->dstpad->get_audio_buffer)
        ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
318 319 320 321 322 323 324 325 326 327

    if (!ret)
        ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);

    if (ret)
        ret->type = AVMEDIA_TYPE_AUDIO;

    return ret;
}

328
int avfilter_request_frame(AVFilterLink *link)
V
Vitor Sessak 已提交
329
{
330
    FF_DPRINTF_START(NULL, request_frame); ff_dprintf_link(NULL, link, 1);
331

332 333
    if (link->srcpad->request_frame)
        return link->srcpad->request_frame(link);
334
    else if (link->src->inputs[0])
335 336
        return avfilter_request_frame(link->src->inputs[0]);
    else return -1;
V
Vitor Sessak 已提交
337 338
}

339 340
int avfilter_poll_frame(AVFilterLink *link)
{
341
    int i, min = INT_MAX;
342

343 344
    if (link->srcpad->poll_frame)
        return link->srcpad->poll_frame(link);
V
Vitor Sessak 已提交
345

346
    for (i = 0; i < link->src->input_count; i++) {
347
        int val;
348
        if (!link->src->inputs[i])
V
Vitor Sessak 已提交
349
            return -1;
350 351
        val = avfilter_poll_frame(link->src->inputs[i]);
        min = FFMIN(min, val);
V
Vitor Sessak 已提交
352
    }
353 354 355 356

    return min;
}

V
Vitor Sessak 已提交
357 358
/* XXX: should we do the duplicating of the picture ref here, instead of
 * forcing the source filter to do it? */
359
void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
V
Vitor Sessak 已提交
360
{
361
    void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
362
    AVFilterPad *dst = link->dstpad;
V
Vitor Sessak 已提交
363

364
    FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_ref(NULL, picref, 1);
365

366
    if (!(start_frame = dst->start_frame))
V
Vitor Sessak 已提交
367 368
        start_frame = avfilter_default_start_frame;

369
    /* prepare to copy the picture if it has insufficient permissions */
370 371
    if ((dst->min_perms & picref->perms) != dst->min_perms ||
         dst->rej_perms & picref->perms) {
372
        av_log(link->dst, AV_LOG_DEBUG,
373
                "frame copy needed (have perms %x, need %x, reject %x)\n",
374
                picref->perms,
375
                link->dstpad->min_perms, link->dstpad->rej_perms);
376

377
        link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
S
S.N. Hemanth Meenakshisundaram 已提交
378 379
        link->src_buf = picref;
        avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
380 381
    }
    else
S
S.N. Hemanth Meenakshisundaram 已提交
382
        link->cur_buf = picref;
383

S
S.N. Hemanth Meenakshisundaram 已提交
384
    start_frame(link, link->cur_buf);
V
Vitor Sessak 已提交
385 386 387 388 389 390
}

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

391
    if (!(end_frame = link->dstpad->end_frame))
392 393 394 395
        end_frame = avfilter_default_end_frame;

    end_frame(link);

396 397
    /* unreference the source picture if we're feeding the destination filter
     * a copied version dues to permission issues */
398
    if (link->src_buf) {
S
S.N. Hemanth Meenakshisundaram 已提交
399 400
        avfilter_unref_buffer(link->src_buf);
        link->src_buf = NULL;
401
    }
V
Vitor Sessak 已提交
402 403
}

404
void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
V
Vitor Sessak 已提交
405
{
406
    uint8_t *src[4], *dst[4];
407
    int i, j, vsub;
408
    void (*draw_slice)(AVFilterLink *, int, int, int);
409

410
    FF_DPRINTF_START(NULL, draw_slice); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
411

412
    /* copy the slice if needed for permission reasons */
413
    if (link->src_buf) {
414
        vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
415

416 417
        for (i = 0; i < 4; i++) {
            if (link->src_buf->data[i]) {
S
S.N. Hemanth Meenakshisundaram 已提交
418 419 420 421
                src[i] = link->src_buf-> data[i] +
                    (y >> (i==0 ? 0 : vsub)) * link->src_buf-> linesize[i];
                dst[i] = link->cur_buf->data[i] +
                    (y >> (i==0 ? 0 : vsub)) * link->cur_buf->linesize[i];
422 423 424
            } else
                src[i] = dst[i] = NULL;
        }
V
Vitor Sessak 已提交
425

426
        for (i = 0; i < 4; i++) {
V
Vitor Sessak 已提交
427
            int planew =
428
                av_image_get_linesize(link->format, link->cur_buf->video->w, i);
V
Vitor Sessak 已提交
429

430
            if (!src[i]) continue;
431

432
            for (j = 0; j < h >> (i==0 ? 0 : vsub); j++) {
V
Vitor Sessak 已提交
433
                memcpy(dst[i], src[i], planew);
434
                src[i] += link->src_buf->linesize[i];
S
S.N. Hemanth Meenakshisundaram 已提交
435
                dst[i] += link->cur_buf->linesize[i];
436 437 438 439
            }
        }
    }

440
    if (!(draw_slice = link->dstpad->draw_slice))
441
        draw_slice = avfilter_default_draw_slice;
442
    draw_slice(link, y, h, slice_dir);
V
Vitor Sessak 已提交
443 444
}

445 446 447
void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
    void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
448
    AVFilterPad *dst = link->dstpad;
449 450 451 452 453 454 455 456 457 458

    if (!(filter_samples = dst->filter_samples))
        filter_samples = avfilter_default_filter_samples;

    /* prepare to copy the samples if the buffer has insufficient permissions */
    if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
        dst->rej_perms & samplesref->perms) {

        av_log(link->dst, AV_LOG_DEBUG,
               "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
459
               samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478

        link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
                                                          samplesref->format,
                                                          samplesref->audio->size,
                                                          samplesref->audio->channel_layout,
                                                          samplesref->audio->planar);
        link->cur_buf->pts                = samplesref->pts;
        link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;

        /* Copy actual data into new samples buffer */
        memcpy(link->cur_buf->data[0], samplesref->data[0], samplesref->audio->size);

        avfilter_unref_buffer(samplesref);
    } else
        link->cur_buf = samplesref;

    filter_samples(link, link->cur_buf);
}

479 480 481 482 483
#define MAX_REGISTERED_AVFILTERS_NB 64

static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];

static int next_registered_avfilter_idx = 0;
484

V
Vitor Sessak 已提交
485
AVFilter *avfilter_get_by_name(const char *name)
V
Vitor Sessak 已提交
486
{
487
    int i;
488

489 490 491
    for (i = 0; registered_avfilters[i]; i++)
        if (!strcmp(registered_avfilters[i]->name, name))
            return registered_avfilters[i];
V
Vitor Sessak 已提交
492 493 494 495

    return NULL;
}

496
int avfilter_register(AVFilter *filter)
V
Vitor Sessak 已提交
497
{
498 499
    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
        return -1;
500

501 502
    registered_avfilters[next_registered_avfilter_idx++] = filter;
    return 0;
V
Vitor Sessak 已提交
503 504
}

S
Stefano Sabatini 已提交
505 506 507 508 509
AVFilter **av_filter_next(AVFilter **filter)
{
    return filter ? ++filter : &registered_avfilters[0];
}

V
Vitor Sessak 已提交
510 511
void avfilter_uninit(void)
{
512 513
    memset(registered_avfilters, 0, sizeof(registered_avfilters));
    next_registered_avfilter_idx = 0;
V
Vitor Sessak 已提交
514 515 516 517 518 519
}

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

V
Vitor Sessak 已提交
520
    for(count = 0; pads->name; count ++) pads ++;
V
Vitor Sessak 已提交
521 522 523 524 525 526 527 528 529
    return count;
}

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

M
Måns Rullgård 已提交
530 531
static const AVClass avfilter_class = {
    "AVFilter",
532 533 534
    filter_name,
    NULL,
    LIBAVUTIL_VERSION_INT,
M
Måns Rullgård 已提交
535 536
};

537
int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
V
Vitor Sessak 已提交
538
{
V
Vitor Sessak 已提交
539
    AVFilterContext *ret;
540
    *filter_ctx = NULL;
V
Vitor Sessak 已提交
541 542

    if (!filter)
543
        return AVERROR(EINVAL);
V
Vitor Sessak 已提交
544

545
    ret = av_mallocz(sizeof(AVFilterContext));
V
Vitor Sessak 已提交
546

M
Måns Rullgård 已提交
547
    ret->av_class = &avfilter_class;
V
Vitor Sessak 已提交
548
    ret->filter   = filter;
549
    ret->name     = inst_name ? av_strdup(inst_name) : NULL;
V
Vitor Sessak 已提交
550 551
    ret->priv     = av_mallocz(filter->priv_size);

V
Vitor Sessak 已提交
552
    ret->input_count  = pad_count(filter->inputs);
553
    if (ret->input_count) {
554 555 556
        ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->input_count);
        memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);
        ret->inputs       = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
557
    }
558

V
Vitor Sessak 已提交
559
    ret->output_count = pad_count(filter->outputs);
560
    if (ret->output_count) {
561 562 563
        ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->output_count);
        memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);
        ret->outputs      = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
564
    }
V
Vitor Sessak 已提交
565

566 567
    *filter_ctx = ret;
    return 0;
V
Vitor Sessak 已提交
568 569
}

570
void avfilter_free(AVFilterContext *filter)
V
Vitor Sessak 已提交
571 572
{
    int i;
573
    AVFilterLink *link;
V
Vitor Sessak 已提交
574

575
    if (filter->filter->uninit)
V
Vitor Sessak 已提交
576 577
        filter->filter->uninit(filter);

578
    for (i = 0; i < filter->input_count; i++) {
579 580
        if ((link = filter->inputs[i])) {
            if (link->src)
581
                link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
582 583
            avfilter_formats_unref(&link->in_formats);
            avfilter_formats_unref(&link->out_formats);
584
        }
585
        av_freep(&link);
V
Vitor Sessak 已提交
586
    }
587
    for (i = 0; i < filter->output_count; i++) {
588 589
        if ((link = filter->outputs[i])) {
            if (link->dst)
590
                link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
591 592
            avfilter_formats_unref(&link->in_formats);
            avfilter_formats_unref(&link->out_formats);
593
        }
594
        av_freep(&link);
V
Vitor Sessak 已提交
595 596
    }

V
Vitor Sessak 已提交
597 598 599 600 601 602
    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);
V
Vitor Sessak 已提交
603 604 605
    av_free(filter);
}

606
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
607
{
V
Vitor Sessak 已提交
608
    int ret=0;
V
Vitor Sessak 已提交
609

610
    if (filter->filter->init)
V
Vitor Sessak 已提交
611 612
        ret = filter->filter->init(filter, args, opaque);
    return ret;
V
Vitor Sessak 已提交
613 614
}