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 linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
198
            picref,
199
            picref->data[0],
200
            picref->linesize[0], picref->linesize[1], picref->linesize[2], picref->linesize[3],
201 202 203 204 205 206 207 208
            picref->pts, picref->pos);

    if (picref->video) {
        dprintf(ctx, " a:%d/%d s:%dx%d",
                picref->video->pixel_aspect.num, picref->video->pixel_aspect.den,
                picref->video->w, picref->video->h);
    }
    dprintf(ctx, "]%s", end ? "\n" : "");
209 210
}

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

222
AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
V
Vitor Sessak 已提交
223
{
224
    AVFilterBufferRef *ret = NULL;
V
Vitor Sessak 已提交
225

226
    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);
227

228
    if (link_dpad(link).get_video_buffer)
229 230
        ret = link_dpad(link).get_video_buffer(link, perms, w, h);

231
    if (!ret)
232
        ret = avfilter_default_get_video_buffer(link, perms, w, h);
V
Vitor Sessak 已提交
233

234 235 236
    if (ret)
        ret->type = AVMEDIA_TYPE_VIDEO;

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

V
Vitor Sessak 已提交
239 240 241
    return ret;
}

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
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;
}

260
int avfilter_request_frame(AVFilterLink *link)
V
Vitor Sessak 已提交
261
{
262
    FF_DPRINTF_START(NULL, request_frame); ff_dprintf_link(NULL, link, 1);
263

264
    if (link_spad(link).request_frame)
V
Vitor Sessak 已提交
265
        return link_spad(link).request_frame(link);
266
    else if (link->src->inputs[0])
267 268
        return avfilter_request_frame(link->src->inputs[0]);
    else return -1;
V
Vitor Sessak 已提交
269 270
}

271 272
int avfilter_poll_frame(AVFilterLink *link)
{
273
    int i, min = INT_MAX;
274

275
    if (link_spad(link).poll_frame)
276
        return link_spad(link).poll_frame(link);
V
Vitor Sessak 已提交
277

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

    return min;
}

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

296
    FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_picref(NULL, picref, 1);
297

298
    if (!(start_frame = dst->start_frame))
V
Vitor Sessak 已提交
299 300
        start_frame = avfilter_default_start_frame;

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

S
S.N. Hemanth Meenakshisundaram 已提交
309 310 311
        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);
312 313
    }
    else
S
S.N. Hemanth Meenakshisundaram 已提交
314
        link->cur_buf = picref;
315

S
S.N. Hemanth Meenakshisundaram 已提交
316
    start_frame(link, link->cur_buf);
V
Vitor Sessak 已提交
317 318 319 320 321 322
}

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

323
    if (!(end_frame = link_dpad(link).end_frame))
324 325 326 327
        end_frame = avfilter_default_end_frame;

    end_frame(link);

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

336
void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
V
Vitor Sessak 已提交
337
{
338
    uint8_t *src[4], *dst[4];
339
    int i, j, vsub;
340
    void (*draw_slice)(AVFilterLink *, int, int, int);
341

342
    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);
343

344
    /* copy the slice if needed for permission reasons */
345
    if (link->src_buf) {
346
        vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
347

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

358
        for (i = 0; i < 4; i++) {
V
Vitor Sessak 已提交
359
            int planew =
360
                av_get_image_linesize(link->format, link->cur_buf->video->w, i);
V
Vitor Sessak 已提交
361

362
            if (!src[i]) continue;
363

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

372
    if (!(draw_slice = link_dpad(link).draw_slice))
373
        draw_slice = avfilter_default_draw_slice;
374
    draw_slice(link, y, h, slice_dir);
V
Vitor Sessak 已提交
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 406 407 408 409 410
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);
}

411 412 413 414 415
#define MAX_REGISTERED_AVFILTERS_NB 64

static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];

static int next_registered_avfilter_idx = 0;
416

V
Vitor Sessak 已提交
417
AVFilter *avfilter_get_by_name(const char *name)
V
Vitor Sessak 已提交
418
{
419
    int i;
420

421 422 423
    for (i = 0; registered_avfilters[i]; i++)
        if (!strcmp(registered_avfilters[i]->name, name))
            return registered_avfilters[i];
V
Vitor Sessak 已提交
424 425 426 427

    return NULL;
}

428
int avfilter_register(AVFilter *filter)
V
Vitor Sessak 已提交
429
{
430 431
    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
        return -1;
432

433 434
    registered_avfilters[next_registered_avfilter_idx++] = filter;
    return 0;
V
Vitor Sessak 已提交
435 436
}

S
Stefano Sabatini 已提交
437 438 439 440 441
AVFilter **av_filter_next(AVFilter **filter)
{
    return filter ? ++filter : &registered_avfilters[0];
}

V
Vitor Sessak 已提交
442 443
void avfilter_uninit(void)
{
444 445
    memset(registered_avfilters, 0, sizeof(registered_avfilters));
    next_registered_avfilter_idx = 0;
V
Vitor Sessak 已提交
446 447 448 449 450 451
}

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

V
Vitor Sessak 已提交
452
    for(count = 0; pads->name; count ++) pads ++;
V
Vitor Sessak 已提交
453 454 455 456 457 458 459 460 461
    return count;
}

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

M
Måns Rullgård 已提交
462 463
static const AVClass avfilter_class = {
    "AVFilter",
464 465 466
    filter_name,
    NULL,
    LIBAVUTIL_VERSION_INT,
M
Måns Rullgård 已提交
467 468
};

469
int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
V
Vitor Sessak 已提交
470
{
V
Vitor Sessak 已提交
471
    AVFilterContext *ret;
472
    *filter_ctx = NULL;
V
Vitor Sessak 已提交
473 474

    if (!filter)
475
        return AVERROR(EINVAL);
V
Vitor Sessak 已提交
476

477
    ret = av_mallocz(sizeof(AVFilterContext));
V
Vitor Sessak 已提交
478

M
Måns Rullgård 已提交
479
    ret->av_class = &avfilter_class;
V
Vitor Sessak 已提交
480
    ret->filter   = filter;
481
    ret->name     = inst_name ? av_strdup(inst_name) : NULL;
V
Vitor Sessak 已提交
482 483
    ret->priv     = av_mallocz(filter->priv_size);

V
Vitor Sessak 已提交
484
    ret->input_count  = pad_count(filter->inputs);
485
    if (ret->input_count) {
486 487 488
        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);
489
    }
490

V
Vitor Sessak 已提交
491
    ret->output_count = pad_count(filter->outputs);
492
    if (ret->output_count) {
493 494 495
        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);
496
    }
V
Vitor Sessak 已提交
497

498 499
    *filter_ctx = ret;
    return 0;
V
Vitor Sessak 已提交
500 501 502 503 504 505
}

void avfilter_destroy(AVFilterContext *filter)
{
    int i;

506
    if (filter->filter->uninit)
V
Vitor Sessak 已提交
507 508
        filter->filter->uninit(filter);

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

V
Vitor Sessak 已提交
528 529 530 531 532 533
    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 已提交
534 535 536
    av_free(filter);
}

537
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
538
{
V
Vitor Sessak 已提交
539
    int ret=0;
V
Vitor Sessak 已提交
540

541
    if (filter->filter->init)
V
Vitor Sessak 已提交
542 543
        ret = filter->filter->init(filter, args, opaque);
    return ret;
V
Vitor Sessak 已提交
544 545
}