avfilter.c 16.7 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 "libavcodec/audioconvert.c"
25
#include "libavutil/pixdesc.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;
}

V
Vitor Sessak 已提交
45 46 47 48
/** 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]

49
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
V
Vitor Sessak 已提交
50
{
51
    AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
52 53
    if (!ret)
        return NULL;
V
Vitor Sessak 已提交
54
    *ret = *ref;
55 56
    if (ref->type == AVMEDIA_TYPE_VIDEO) {
        ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
57 58 59 60
        if (!ret->video) {
            av_free(ret);
            return NULL;
        }
61
        *ret->video = *ref->video;
62 63 64 65 66 67 68
    } 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;
69
    }
70
    ret->perms &= pmask;
71
    ret->buf->refcount ++;
V
Vitor Sessak 已提交
72 73 74
    return ret;
}

75
void avfilter_unref_buffer(AVFilterBufferRef *ref)
V
Vitor Sessak 已提交
76
{
77
    if (!(--ref->buf->refcount))
78
        ref->buf->free(ref->buf);
79
    av_free(ref->video);
80
    av_free(ref->audio);
V
Vitor Sessak 已提交
81 82 83
    av_free(ref);
}

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
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;

99 100 101 102
    (*count)++;
    for (i = idx+1; i < *count; i++)
        if (*links[i])
            (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
103 104
}

V
Vitor Sessak 已提交
105 106 107 108 109
int avfilter_link(AVFilterContext *src, unsigned srcpad,
                  AVFilterContext *dst, unsigned dstpad)
{
    AVFilterLink *link;

110 111
    if (src->output_count <= srcpad || dst->input_count <= dstpad ||
        src->outputs[srcpad]        || dst->inputs[dstpad])
V
Vitor Sessak 已提交
112 113 114
        return -1;

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

V
Vitor Sessak 已提交
117 118 119 120
    link->src     = src;
    link->dst     = dst;
    link->srcpad  = srcpad;
    link->dstpad  = dstpad;
121 122 123
    link->type    = src->output_pads[srcpad].type;
    assert(PIX_FMT_NONE == -1 && SAMPLE_FMT_NONE == -1);
    link->format  = -1;
124 125 126 127

    return 0;
}

128 129 130
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
                           unsigned in, unsigned out)
{
131 132 133
    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);
134 135

    link->dst->inputs[link->dstpad] = NULL;
136
    if (avfilter_link(filt, out, link->dst, link->dstpad)) {
137 138 139 140 141 142 143 144 145 146
        /* failed to link output filter to new filter */
        link->dst->inputs[link->dstpad] = link;
        return -1;
    }

    /* re-hookup the link to the new destination filter we inserted */
    link->dst = filt;
    link->dstpad = in;
    filt->inputs[in] = link;

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

153 154 155
    return 0;
}

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

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
            if (avfilter_config_links(link->src))
176
                return -1;
V
Vitor Sessak 已提交
177

178
            if (!(config_link = link_spad(link).config_props))
V
Vitor Sessak 已提交
179
                config_link  = avfilter_default_config_output_link;
180
            if (config_link(link))
V
Vitor Sessak 已提交
181
                return -1;
182

183 184
            if ((config_link = link_dpad(link).config_props))
                if (config_link(link))
V
Vitor Sessak 已提交
185
                    return -1;
186

187 188 189 190
            link->init_state = AVLINK_INIT;
        }
    }

V
Vitor Sessak 已提交
191 192 193
    return 0;
}

194
void ff_dprintf_picref(void *ctx, AVFilterBufferRef *picref, int end)
195 196
{
    dprintf(ctx,
197
            "picref[%p data[%p, %p, %p, %p] linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64" a:%d/%d s:%dx%d]%s",
198 199 200
            picref,
            picref->data    [0], picref->data    [1], picref->data    [2], picref->data    [3],
            picref->linesize[0], picref->linesize[1], picref->linesize[2], picref->linesize[3],
201
            picref->pts, picref->pos,
202
            picref->video->pixel_aspect.num, picref->video->pixel_aspect.den, picref->video->w, picref->video->h,
203 204 205
            end ? "\n" : "");
}

206
void ff_dprintf_link(void *ctx, AVFilterLink *link, int end)
207 208
{
    dprintf(ctx,
209
            "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
210
            link, link->w, link->h,
211
            av_pix_fmt_descriptors[link->format].name,
212 213 214 215 216
            link->src ? link->src->filter->name : "",
            link->dst ? link->dst->filter->name : "",
            end ? "\n" : "");
}

217
AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
V
Vitor Sessak 已提交
218
{
219
    AVFilterBufferRef *ret = NULL;
V
Vitor Sessak 已提交
220

221
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h);
222

223
    if (link_dpad(link).get_video_buffer)
224 225
        ret = link_dpad(link).get_video_buffer(link, perms, w, h);

226
    if (!ret)
227
        ret = avfilter_default_get_video_buffer(link, perms, w, h);
V
Vitor Sessak 已提交
228

229 230 231
    if (ret)
        ret->type = AVMEDIA_TYPE_VIDEO;

232
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); ff_dprintf_picref(NULL, ret, 1);
233

V
Vitor Sessak 已提交
234 235 236
    return ret;
}

237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
                                             enum SampleFormat sample_fmt, int size,
                                             int64_t channel_layout, int planar)
{
    AVFilterBufferRef *ret = NULL;

    if (link_dpad(link).get_audio_buffer)
        ret = link_dpad(link).get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);

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

255
int avfilter_request_frame(AVFilterLink *link)
V
Vitor Sessak 已提交
256
{
257
    FF_DPRINTF_START(NULL, request_frame); ff_dprintf_link(NULL, link, 1);
258

259
    if (link_spad(link).request_frame)
V
Vitor Sessak 已提交
260
        return link_spad(link).request_frame(link);
261
    else if (link->src->inputs[0])
262 263
        return avfilter_request_frame(link->src->inputs[0]);
    else return -1;
V
Vitor Sessak 已提交
264 265
}

266 267
int avfilter_poll_frame(AVFilterLink *link)
{
268
    int i, min = INT_MAX;
269

270
    if (link_spad(link).poll_frame)
271
        return link_spad(link).poll_frame(link);
V
Vitor Sessak 已提交
272

273
    for (i = 0; i < link->src->input_count; i++) {
274
        int val;
275
        if (!link->src->inputs[i])
V
Vitor Sessak 已提交
276
            return -1;
277 278
        val = avfilter_poll_frame(link->src->inputs[i]);
        min = FFMIN(min, val);
V
Vitor Sessak 已提交
279
    }
280 281 282 283

    return min;
}

V
Vitor Sessak 已提交
284 285
/* XXX: should we do the duplicating of the picture ref here, instead of
 * forcing the source filter to do it? */
286
void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
V
Vitor Sessak 已提交
287
{
288
    void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
289
    AVFilterPad *dst = &link_dpad(link);
V
Vitor Sessak 已提交
290

291
    FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_picref(NULL, picref, 1);
292

293
    if (!(start_frame = dst->start_frame))
V
Vitor Sessak 已提交
294 295
        start_frame = avfilter_default_start_frame;

296
    /* prepare to copy the picture if it has insufficient permissions */
297 298
    if ((dst->min_perms & picref->perms) != dst->min_perms ||
         dst->rej_perms & picref->perms) {
299
        av_log(link->dst, AV_LOG_DEBUG,
300
                "frame copy needed (have perms %x, need %x, reject %x)\n",
301
                picref->perms,
302 303
                link_dpad(link).min_perms, link_dpad(link).rej_perms);

S
S.N. Hemanth Meenakshisundaram 已提交
304 305 306
        link->cur_buf = avfilter_default_get_video_buffer(link, dst->min_perms, link->w, link->h);
        link->src_buf = picref;
        avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
307 308
    }
    else
S
S.N. Hemanth Meenakshisundaram 已提交
309
        link->cur_buf = picref;
310

S
S.N. Hemanth Meenakshisundaram 已提交
311
    start_frame(link, link->cur_buf);
V
Vitor Sessak 已提交
312 313 314 315 316 317
}

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

318
    if (!(end_frame = link_dpad(link).end_frame))
319 320 321 322
        end_frame = avfilter_default_end_frame;

    end_frame(link);

323 324
    /* unreference the source picture if we're feeding the destination filter
     * a copied version dues to permission issues */
325
    if (link->src_buf) {
S
S.N. Hemanth Meenakshisundaram 已提交
326 327
        avfilter_unref_buffer(link->src_buf);
        link->src_buf = NULL;
328
    }
V
Vitor Sessak 已提交
329 330
}

331
void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
V
Vitor Sessak 已提交
332
{
333
    uint8_t *src[4], *dst[4];
334
    int i, j, vsub;
335
    void (*draw_slice)(AVFilterLink *, int, int, int);
336

337
    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);
338

339
    /* copy the slice if needed for permission reasons */
340
    if (link->src_buf) {
341
        vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
342

343 344
        for (i = 0; i < 4; i++) {
            if (link->src_buf->data[i]) {
S
S.N. Hemanth Meenakshisundaram 已提交
345 346 347 348
                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];
349 350 351
            } else
                src[i] = dst[i] = NULL;
        }
V
Vitor Sessak 已提交
352

353
        for (i = 0; i < 4; i++) {
V
Vitor Sessak 已提交
354
            int planew =
355
                av_get_image_linesize(link->format, link->cur_buf->video->w, i);
V
Vitor Sessak 已提交
356

357
            if (!src[i]) continue;
358

359
            for (j = 0; j < h >> (i==0 ? 0 : vsub); j++) {
V
Vitor Sessak 已提交
360
                memcpy(dst[i], src[i], planew);
361
                src[i] += link->src_buf->linesize[i];
S
S.N. Hemanth Meenakshisundaram 已提交
362
                dst[i] += link->cur_buf->linesize[i];
363 364 365 366
            }
        }
    }

367
    if (!(draw_slice = link_dpad(link).draw_slice))
368
        draw_slice = avfilter_default_draw_slice;
369
    draw_slice(link, y, h, slice_dir);
V
Vitor Sessak 已提交
370 371
}

372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
    void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
    AVFilterPad *dst = &link_dpad(link);

    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",
               samplesref->perms, link_dpad(link).min_perms, link_dpad(link).rej_perms);

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

406 407 408 409 410
#define MAX_REGISTERED_AVFILTERS_NB 64

static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];

static int next_registered_avfilter_idx = 0;
411

V
Vitor Sessak 已提交
412
AVFilter *avfilter_get_by_name(const char *name)
V
Vitor Sessak 已提交
413
{
414
    int i;
415

416 417 418
    for (i = 0; registered_avfilters[i]; i++)
        if (!strcmp(registered_avfilters[i]->name, name))
            return registered_avfilters[i];
V
Vitor Sessak 已提交
419 420 421 422

    return NULL;
}

423
int avfilter_register(AVFilter *filter)
V
Vitor Sessak 已提交
424
{
425 426
    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
        return -1;
427

428 429
    registered_avfilters[next_registered_avfilter_idx++] = filter;
    return 0;
V
Vitor Sessak 已提交
430 431
}

S
Stefano Sabatini 已提交
432 433 434 435 436
AVFilter **av_filter_next(AVFilter **filter)
{
    return filter ? ++filter : &registered_avfilters[0];
}

V
Vitor Sessak 已提交
437 438
void avfilter_uninit(void)
{
439 440
    memset(registered_avfilters, 0, sizeof(registered_avfilters));
    next_registered_avfilter_idx = 0;
V
Vitor Sessak 已提交
441 442 443 444 445 446
}

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

V
Vitor Sessak 已提交
447
    for(count = 0; pads->name; count ++) pads ++;
V
Vitor Sessak 已提交
448 449 450 451 452 453 454 455 456
    return count;
}

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

M
Måns Rullgård 已提交
457 458
static const AVClass avfilter_class = {
    "AVFilter",
459 460 461
    filter_name,
    NULL,
    LIBAVUTIL_VERSION_INT,
M
Måns Rullgård 已提交
462 463
};

464
int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
V
Vitor Sessak 已提交
465
{
V
Vitor Sessak 已提交
466
    AVFilterContext *ret;
467
    *filter_ctx = NULL;
V
Vitor Sessak 已提交
468 469

    if (!filter)
470
        return AVERROR(EINVAL);
V
Vitor Sessak 已提交
471

472
    ret = av_mallocz(sizeof(AVFilterContext));
V
Vitor Sessak 已提交
473

M
Måns Rullgård 已提交
474
    ret->av_class = &avfilter_class;
V
Vitor Sessak 已提交
475
    ret->filter   = filter;
476
    ret->name     = inst_name ? av_strdup(inst_name) : NULL;
V
Vitor Sessak 已提交
477 478
    ret->priv     = av_mallocz(filter->priv_size);

V
Vitor Sessak 已提交
479
    ret->input_count  = pad_count(filter->inputs);
480
    if (ret->input_count) {
481 482 483
        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);
484
    }
485

V
Vitor Sessak 已提交
486
    ret->output_count = pad_count(filter->outputs);
487
    if (ret->output_count) {
488 489 490
        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);
491
    }
V
Vitor Sessak 已提交
492

493 494
    *filter_ctx = ret;
    return 0;
V
Vitor Sessak 已提交
495 496 497 498 499 500
}

void avfilter_destroy(AVFilterContext *filter)
{
    int i;

501
    if (filter->filter->uninit)
V
Vitor Sessak 已提交
502 503
        filter->filter->uninit(filter);

504 505
    for (i = 0; i < filter->input_count; i++) {
        if (filter->inputs[i]) {
506
            if (filter->inputs[i]->src)
M
Måns Rullgård 已提交
507
                filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
508 509 510
            avfilter_formats_unref(&filter->inputs[i]->in_formats);
            avfilter_formats_unref(&filter->inputs[i]->out_formats);
        }
V
Vitor Sessak 已提交
511
        av_freep(&filter->inputs[i]);
V
Vitor Sessak 已提交
512
    }
513 514
    for (i = 0; i < filter->output_count; i++) {
        if (filter->outputs[i]) {
515
            if (filter->outputs[i]->dst)
M
Måns Rullgård 已提交
516
                filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
517 518 519
            avfilter_formats_unref(&filter->outputs[i]->in_formats);
            avfilter_formats_unref(&filter->outputs[i]->out_formats);
        }
V
Vitor Sessak 已提交
520
        av_freep(&filter->outputs[i]);
V
Vitor Sessak 已提交
521 522
    }

V
Vitor Sessak 已提交
523 524 525 526 527 528
    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 已提交
529 530 531
    av_free(filter);
}

532
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
533
{
V
Vitor Sessak 已提交
534
    int ret=0;
V
Vitor Sessak 已提交
535

536
    if (filter->filter->init)
V
Vitor Sessak 已提交
537 538
        ret = filter->filter->init(filter, args, opaque);
    return ret;
V
Vitor Sessak 已提交
539 540
}