avfilter.c 27.5 KB
Newer Older
V
Vitor Sessak 已提交
1
/*
2
 * filter layer
3
 * Copyright (c) 2007 Bobby Bingham
V
Vitor Sessak 已提交
4
 *
5
 * This file is part of Libav.
V
Vitor Sessak 已提交
6
 *
7
 * Libav is free software; you can redistribute it and/or
V
Vitor Sessak 已提交
8 9 10 11
 * 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.
 *
12
 * Libav is distributed in the hope that it will be useful,
V
Vitor Sessak 已提交
13 14 15 16 17
 * 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
18
 * License along with Libav; if not, write to the Free Software
V
Vitor Sessak 已提交
19 20 21
 * 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 27
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
28
#include "libavcodec/avcodec.h"
29 30

#include "audio.h"
V
Vitor Sessak 已提交
31
#include "avfilter.h"
32
#include "internal.h"
V
Vitor Sessak 已提交
33

S
Stefano Sabatini 已提交
34 35 36 37
unsigned avfilter_version(void) {
    return LIBAVFILTER_VERSION_INT;
}

38
const char *avfilter_configuration(void)
39
{
40
    return LIBAV_CONFIGURATION;
41 42
}

43
const char *avfilter_license(void)
44 45
{
#define LICENSE_PREFIX "libavfilter license: "
46
    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
47 48
}

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
        ret->extended_data = ret->data;
63 64 65 66 67 68 69
    } 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;
70 71 72 73 74 75 76 77 78 79 80 81 82

        if (ref->extended_data != ref->data) {
            int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
            if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
                                                 nb_channels))) {
                av_freep(&ret->audio);
                av_freep(&ret);
                return NULL;
            }
            memcpy(ret->extended_data, ref->extended_data,
                   sizeof(*ret->extended_data) * nb_channels);
        } else
            ret->extended_data = ret->data;
83
    }
84
    ret->perms &= pmask;
85
    ret->buf->refcount ++;
V
Vitor Sessak 已提交
86 87 88
    return ret;
}

89
void avfilter_unref_buffer(AVFilterBufferRef *ref)
V
Vitor Sessak 已提交
90
{
91 92
    if (!ref)
        return;
93
    if (!(--ref->buf->refcount))
94
        ref->buf->free(ref->buf);
95 96
    if (ref->extended_data != ref->data)
        av_freep(&ref->extended_data);
97
    av_free(ref->video);
98
    av_free(ref->audio);
V
Vitor Sessak 已提交
99 100 101
    av_free(ref);
}

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
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;

117 118 119 120
    (*count)++;
    for (i = idx+1; i < *count; i++)
        if (*links[i])
            (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
121 122
}

V
Vitor Sessak 已提交
123 124 125 126 127
int avfilter_link(AVFilterContext *src, unsigned srcpad,
                  AVFilterContext *dst, unsigned dstpad)
{
    AVFilterLink *link;

128 129
    if (src->output_count <= srcpad || dst->input_count <= dstpad ||
        src->outputs[srcpad]        || dst->inputs[dstpad])
V
Vitor Sessak 已提交
130 131
        return -1;

132 133 134 135 136 137 138
    if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
        av_log(src, AV_LOG_ERROR,
               "Media type mismatch between the '%s' filter output pad %d and the '%s' filter input pad %d\n",
               src->name, srcpad, dst->name, dstpad);
        return AVERROR(EINVAL);
    }

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

V
Vitor Sessak 已提交
142 143
    link->src     = src;
    link->dst     = dst;
144 145
    link->srcpad  = &src->output_pads[srcpad];
    link->dstpad  = &dst->input_pads[dstpad];
146
    link->type    = src->output_pads[srcpad].type;
147
    assert(PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
148
    link->format  = -1;
149 150 151 152

    return 0;
}

153
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
154
                           unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
155
{
156
    int ret;
157 158
    unsigned dstpad_idx = link->dstpad - link->dst->input_pads;

159 160 161
    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);
162

163
    link->dst->inputs[dstpad_idx] = NULL;
164
    if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
165
        /* failed to link output filter to new filter */
166
        link->dst->inputs[dstpad_idx] = link;
167
        return ret;
168 169 170 171
    }

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

175
    /* if any information on supported media formats already exists on the
176
     * link, we need to preserve that */
177
    if (link->out_formats)
178
        avfilter_formats_changeref(&link->out_formats,
179
                                   &filt->outputs[filt_dstpad_idx]->out_formats);
180

181 182 183
    return 0;
}

184
int avfilter_config_links(AVFilterContext *filter)
185 186
{
    int (*config_link)(AVFilterLink *);
187
    unsigned i;
188
    int ret;
189

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

193
        if (!link) continue;
194

195
        switch (link->init_state) {
196 197 198
        case AVLINK_INIT:
            continue;
        case AVLINK_STARTINIT:
199 200
            av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
            return 0;
201 202 203
        case AVLINK_UNINIT:
            link->init_state = AVLINK_STARTINIT;

204 205
            if ((ret = avfilter_config_links(link->src)) < 0)
                return ret;
V
Vitor Sessak 已提交
206

207
            if (!(config_link = link->srcpad->config_props))
V
Vitor Sessak 已提交
208
                config_link  = avfilter_default_config_output_link;
209 210
            if ((ret = config_link(link)) < 0)
                return ret;
211

212
            if (link->time_base.num == 0 && link->time_base.den == 0)
213 214
                link->time_base = link->src && link->src->input_count ?
                    link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
215

216 217 218 219
            if (link->sample_aspect_ratio.num == 0 && link->sample_aspect_ratio.den == 0)
                link->sample_aspect_ratio = link->src->input_count ?
                    link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};

220 221 222 223 224 225
            if (link->sample_rate == 0 && link->src && link->src->input_count)
                link->sample_rate = link->src->inputs[0]->sample_rate;

            if (link->channel_layout == 0 && link->src && link->src->input_count)
                link->channel_layout = link->src->inputs[0]->channel_layout;

226
            if ((config_link = link->dstpad->config_props))
227 228
                if ((ret = config_link(link)) < 0)
                    return ret;
229

230 231 232 233
            link->init_state = AVLINK_INIT;
        }
    }

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

237
#ifdef DEBUG
238
static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
239
{
240
    snprintf(buf, buf_size, "%s%s%s%s%s%s",
241 242 243
             perms & AV_PERM_READ      ? "r" : "",
             perms & AV_PERM_WRITE     ? "w" : "",
             perms & AV_PERM_PRESERVE  ? "p" : "",
244
             perms & AV_PERM_REUSE     ? "u" : "",
245 246
             perms & AV_PERM_REUSE2    ? "U" : "",
             perms & AV_PERM_NEG_LINESIZES ? "n" : "");
247 248
    return buf;
}
249
#endif
250

L
Luca Barbato 已提交
251
static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
252
{
253
    av_unused char buf[16];
L
Luca Barbato 已提交
254
    av_dlog(ctx,
255 256
            "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],
257 258
            ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
            ref->pts, ref->pos);
259

260
    if (ref->video) {
261
        av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
262 263 264
                ref->video->pixel_aspect.num, ref->video->pixel_aspect.den,
                ref->video->w, ref->video->h,
                !ref->video->interlaced     ? 'P' :         /* Progressive  */
265 266 267
                ref->video->top_field_first ? 'T' : 'B',    /* Top / Bottom */
                ref->video->key_frame,
                av_get_picture_type_char(ref->video->pict_type));
268
    }
269
    if (ref->audio) {
270
        av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
271
                ref->audio->channel_layout,
272
                ref->audio->nb_samples,
273 274 275 276
                ref->audio->sample_rate,
                ref->audio->planar);
    }

L
Luca Barbato 已提交
277
    av_dlog(ctx, "]%s", end ? "\n" : "");
278 279
}

L
Luca Barbato 已提交
280
static void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
281
{
282
    if (link->type == AVMEDIA_TYPE_VIDEO) {
L
Luca Barbato 已提交
283
        av_dlog(ctx,
S
Stefano Sabatini 已提交
284 285 286 287 288 289
                "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
                link, link->w, link->h,
                av_pix_fmt_descriptors[link->format].name,
                link->src ? link->src->filter->name : "",
                link->dst ? link->dst->filter->name : "",
                end ? "\n" : "");
290 291 292 293
    } else {
        char buf[128];
        av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);

L
Luca Barbato 已提交
294
        av_dlog(ctx,
295 296 297 298 299 300 301
                "link[%p r:%"PRId64" cl:%s fmt:%-16s %-16s->%-16s]%s",
                link, link->sample_rate, buf,
                av_get_sample_fmt_name(link->format),
                link->src ? link->src->filter->name : "",
                link->dst ? link->dst->filter->name : "",
                end ? "\n" : "");
    }
302 303
}

L
Luca Barbato 已提交
304
#define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
305

306
AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
V
Vitor Sessak 已提交
307
{
308
    AVFilterBufferRef *ret = NULL;
V
Vitor Sessak 已提交
309

310
    av_unused char buf[16];
L
Luca Barbato 已提交
311 312
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
    av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
313

314 315
    if (link->dstpad->get_video_buffer)
        ret = link->dstpad->get_video_buffer(link, perms, w, h);
316

317
    if (!ret)
318
        ret = avfilter_default_get_video_buffer(link, perms, w, h);
V
Vitor Sessak 已提交
319

320 321 322
    if (ret)
        ret->type = AVMEDIA_TYPE_VIDEO;

L
Luca Barbato 已提交
323
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
324

V
Vitor Sessak 已提交
325 326 327
    return ret;
}

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
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;

343 344
    pic->w = picref->video->w = w;
    pic->h = picref->video->h = h;
345 346 347 348 349 350

    /* 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;
351
    pic->format = picref->format = format;
352

353 354
    memcpy(pic->data,        data,          4*sizeof(data[0]));
    memcpy(pic->linesize,    linesize,      4*sizeof(linesize[0]));
355 356 357
    memcpy(picref->data,     pic->data,     sizeof(picref->data));
    memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));

358 359 360
    pic->   extended_data = pic->data;
    picref->extended_data = picref->data;

361 362 363 364 365 366 367 368 369 370
    return picref;

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

371 372
AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
                                       int nb_samples)
373 374 375
{
    AVFilterBufferRef *ret = NULL;

376
    if (link->dstpad->get_audio_buffer)
377
        ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
378 379

    if (!ret)
380
        ret = ff_default_get_audio_buffer(link, perms, nb_samples);
381 382 383 384 385 386 387

    if (ret)
        ret->type = AVMEDIA_TYPE_AUDIO;

    return ret;
}

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
                                                             int linesize, int perms,
                                                             int nb_samples,
                                                             enum AVSampleFormat sample_fmt,
                                                             uint64_t channel_layout)
{
    int planes;
    AVFilterBuffer    *samples    = av_mallocz(sizeof(*samples));
    AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));

    if (!samples || !samplesref)
        goto fail;

    samplesref->buf         = samples;
    samplesref->buf->free   = ff_avfilter_default_free_buffer;
    if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
        goto fail;

    samplesref->audio->nb_samples     = nb_samples;
    samplesref->audio->channel_layout = channel_layout;
    samplesref->audio->planar         = av_sample_fmt_is_planar(sample_fmt);

    planes = samplesref->audio->planar ? av_get_channel_layout_nb_channels(channel_layout) : 1;

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

    samples->refcount  = 1;
    samplesref->type   = AVMEDIA_TYPE_AUDIO;
    samplesref->format = sample_fmt;

    memcpy(samples->data, data,
           FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
    memcpy(samplesref->data, samples->data, sizeof(samples->data));

    samples->linesize[0] = samplesref->linesize[0] = linesize;

    if (planes > FF_ARRAY_ELEMS(samples->data)) {
        samples->   extended_data = av_mallocz(sizeof(*samples->extended_data) *
                                               planes);
        samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) *
                                               planes);

        if (!samples->extended_data || !samplesref->extended_data)
            goto fail;

        memcpy(samples->   extended_data, data, sizeof(*data)*planes);
        memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
    } else {
        samples->extended_data    = samples->data;
        samplesref->extended_data = samplesref->data;
    }

    return samplesref;

fail:
    if (samples && samples->extended_data != samples->data)
        av_freep(&samples->extended_data);
    if (samplesref) {
        av_freep(&samplesref->audio);
        if (samplesref->extended_data != samplesref->data)
            av_freep(&samplesref->extended_data);
    }
    av_freep(&samplesref);
    av_freep(&samples);
    return NULL;
}

456
int avfilter_request_frame(AVFilterLink *link)
V
Vitor Sessak 已提交
457
{
L
Luca Barbato 已提交
458
    FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
459

460 461
    if (link->srcpad->request_frame)
        return link->srcpad->request_frame(link);
462
    else if (link->src->inputs[0])
463 464
        return avfilter_request_frame(link->src->inputs[0]);
    else return -1;
V
Vitor Sessak 已提交
465 466
}

467 468
int avfilter_poll_frame(AVFilterLink *link)
{
469
    int i, min = INT_MAX;
470

471 472
    if (link->srcpad->poll_frame)
        return link->srcpad->poll_frame(link);
V
Vitor Sessak 已提交
473

474
    for (i = 0; i < link->src->input_count; i++) {
475
        int val;
476
        if (!link->src->inputs[i])
V
Vitor Sessak 已提交
477
            return -1;
478 479
        val = avfilter_poll_frame(link->src->inputs[i]);
        min = FFMIN(min, val);
V
Vitor Sessak 已提交
480
    }
481 482 483 484

    return min;
}

V
Vitor Sessak 已提交
485 486
/* XXX: should we do the duplicating of the picture ref here, instead of
 * forcing the source filter to do it? */
487
void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
V
Vitor Sessak 已提交
488
{
489
    void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
490
    AVFilterPad *dst = link->dstpad;
491
    int perms = picref->perms;
V
Vitor Sessak 已提交
492

L
Luca Barbato 已提交
493
    FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
494

495
    if (!(start_frame = dst->start_frame))
V
Vitor Sessak 已提交
496 497
        start_frame = avfilter_default_start_frame;

498 499
    if (picref->linesize[0] < 0)
        perms |= AV_PERM_NEG_LINESIZES;
500
    /* prepare to copy the picture if it has insufficient permissions */
501
    if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
502
        av_log(link->dst, AV_LOG_DEBUG,
503
                "frame copy needed (have perms %x, need %x, reject %x)\n",
504
                picref->perms,
505
                link->dstpad->min_perms, link->dstpad->rej_perms);
506

507
        link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
S
S.N. Hemanth Meenakshisundaram 已提交
508 509
        link->src_buf = picref;
        avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
510 511
    }
    else
S
S.N. Hemanth Meenakshisundaram 已提交
512
        link->cur_buf = picref;
513

S
S.N. Hemanth Meenakshisundaram 已提交
514
    start_frame(link, link->cur_buf);
V
Vitor Sessak 已提交
515 516 517 518 519 520
}

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

521
    if (!(end_frame = link->dstpad->end_frame))
522 523 524 525
        end_frame = avfilter_default_end_frame;

    end_frame(link);

526 527
    /* unreference the source picture if we're feeding the destination filter
     * a copied version dues to permission issues */
528
    if (link->src_buf) {
S
S.N. Hemanth Meenakshisundaram 已提交
529 530
        avfilter_unref_buffer(link->src_buf);
        link->src_buf = NULL;
531
    }
V
Vitor Sessak 已提交
532 533
}

534
void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
V
Vitor Sessak 已提交
535
{
536
    uint8_t *src[4], *dst[4];
537
    int i, j, vsub;
538
    void (*draw_slice)(AVFilterLink *, int, int, int);
539

L
Luca Barbato 已提交
540
    FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
541

542
    /* copy the slice if needed for permission reasons */
543
    if (link->src_buf) {
544
        vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
545

546 547
        for (i = 0; i < 4; i++) {
            if (link->src_buf->data[i]) {
S
S.N. Hemanth Meenakshisundaram 已提交
548
                src[i] = link->src_buf-> data[i] +
549
                    (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
S
S.N. Hemanth Meenakshisundaram 已提交
550
                dst[i] = link->cur_buf->data[i] +
551
                    (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf->linesize[i];
552 553 554
            } else
                src[i] = dst[i] = NULL;
        }
V
Vitor Sessak 已提交
555

556
        for (i = 0; i < 4; i++) {
V
Vitor Sessak 已提交
557
            int planew =
558
                av_image_get_linesize(link->format, link->cur_buf->video->w, i);
V
Vitor Sessak 已提交
559

560
            if (!src[i]) continue;
561

562
            for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
V
Vitor Sessak 已提交
563
                memcpy(dst[i], src[i], planew);
564
                src[i] += link->src_buf->linesize[i];
S
S.N. Hemanth Meenakshisundaram 已提交
565
                dst[i] += link->cur_buf->linesize[i];
566 567 568 569
            }
        }
    }

570
    if (!(draw_slice = link->dstpad->draw_slice))
571
        draw_slice = avfilter_default_draw_slice;
572
    draw_slice(link, y, h, slice_dir);
V
Vitor Sessak 已提交
573 574
}

575
void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
576 577
{
    void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
578
    AVFilterPad *dst = link->dstpad;
579

580 581
    FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);

582
    if (!(filter_samples = dst->filter_samples))
583
        filter_samples = ff_default_filter_samples;
584 585 586 587

    /* 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) {
588 589 590
        int  i, planar = av_sample_fmt_is_planar(samplesref->format);
        int planes = !planar ? 1:
                     av_get_channel_layout_nb_channels(samplesref->audio->channel_layout);
591 592 593

        av_log(link->dst, AV_LOG_DEBUG,
               "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
594
               samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
595

596 597
        link->cur_buf = ff_default_get_audio_buffer(link, dst->min_perms,
                                                    samplesref->audio->nb_samples);
598 599 600 601
        link->cur_buf->pts                = samplesref->pts;
        link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;

        /* Copy actual data into new samples buffer */
602 603
        for (i = 0; i < planes; i++)
            memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], samplesref->linesize[0]);
604 605 606 607 608 609 610 611

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

    filter_samples(link, link->cur_buf);
}

612 613 614 615 616
#define MAX_REGISTERED_AVFILTERS_NB 64

static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];

static int next_registered_avfilter_idx = 0;
617

V
Vitor Sessak 已提交
618
AVFilter *avfilter_get_by_name(const char *name)
V
Vitor Sessak 已提交
619
{
620
    int i;
621

622 623 624
    for (i = 0; registered_avfilters[i]; i++)
        if (!strcmp(registered_avfilters[i]->name, name))
            return registered_avfilters[i];
V
Vitor Sessak 已提交
625 626 627 628

    return NULL;
}

629
int avfilter_register(AVFilter *filter)
V
Vitor Sessak 已提交
630
{
631 632
    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
        return -1;
633

634 635
    registered_avfilters[next_registered_avfilter_idx++] = filter;
    return 0;
V
Vitor Sessak 已提交
636 637
}

S
Stefano Sabatini 已提交
638 639 640 641 642
AVFilter **av_filter_next(AVFilter **filter)
{
    return filter ? ++filter : &registered_avfilters[0];
}

V
Vitor Sessak 已提交
643 644
void avfilter_uninit(void)
{
645 646
    memset(registered_avfilters, 0, sizeof(registered_avfilters));
    next_registered_avfilter_idx = 0;
V
Vitor Sessak 已提交
647 648 649 650 651 652
}

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

V
Vitor Sessak 已提交
653
    for(count = 0; pads->name; count ++) pads ++;
V
Vitor Sessak 已提交
654 655 656 657 658 659 660 661 662
    return count;
}

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

M
Måns Rullgård 已提交
663 664
static const AVClass avfilter_class = {
    "AVFilter",
665 666 667
    filter_name,
    NULL,
    LIBAVUTIL_VERSION_INT,
M
Måns Rullgård 已提交
668 669
};

670
int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
V
Vitor Sessak 已提交
671
{
V
Vitor Sessak 已提交
672
    AVFilterContext *ret;
673
    *filter_ctx = NULL;
V
Vitor Sessak 已提交
674 675

    if (!filter)
676
        return AVERROR(EINVAL);
V
Vitor Sessak 已提交
677

678
    ret = av_mallocz(sizeof(AVFilterContext));
679 680
    if (!ret)
        return AVERROR(ENOMEM);
V
Vitor Sessak 已提交
681

M
Måns Rullgård 已提交
682
    ret->av_class = &avfilter_class;
V
Vitor Sessak 已提交
683
    ret->filter   = filter;
684
    ret->name     = inst_name ? av_strdup(inst_name) : NULL;
685
    if (filter->priv_size) {
R
Ronald S. Bultje 已提交
686
        ret->priv     = av_mallocz(filter->priv_size);
687 688 689
        if (!ret->priv)
            goto err;
    }
V
Vitor Sessak 已提交
690

V
Vitor Sessak 已提交
691
    ret->input_count  = pad_count(filter->inputs);
692
    if (ret->input_count) {
693
        ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->input_count);
694 695
        if (!ret->input_pads)
            goto err;
696 697
        memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);
        ret->inputs       = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
698 699
        if (!ret->inputs)
            goto err;
700
    }
701

V
Vitor Sessak 已提交
702
    ret->output_count = pad_count(filter->outputs);
703
    if (ret->output_count) {
704
        ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->output_count);
705 706
        if (!ret->output_pads)
            goto err;
707 708
        memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);
        ret->outputs      = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
709 710
        if (!ret->outputs)
            goto err;
711
    }
V
Vitor Sessak 已提交
712

713 714
    *filter_ctx = ret;
    return 0;
715 716 717 718 719 720 721 722 723 724 725

err:
    av_freep(&ret->inputs);
    av_freep(&ret->input_pads);
    ret->input_count = 0;
    av_freep(&ret->outputs);
    av_freep(&ret->output_pads);
    ret->output_count = 0;
    av_freep(&ret->priv);
    av_free(ret);
    return AVERROR(ENOMEM);
V
Vitor Sessak 已提交
726 727
}

728
void avfilter_free(AVFilterContext *filter)
V
Vitor Sessak 已提交
729 730
{
    int i;
731
    AVFilterLink *link;
V
Vitor Sessak 已提交
732

733
    if (filter->filter->uninit)
V
Vitor Sessak 已提交
734 735
        filter->filter->uninit(filter);

736
    for (i = 0; i < filter->input_count; i++) {
737 738
        if ((link = filter->inputs[i])) {
            if (link->src)
739
                link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
740 741
            avfilter_formats_unref(&link->in_formats);
            avfilter_formats_unref(&link->out_formats);
742
        }
743
        av_freep(&link);
V
Vitor Sessak 已提交
744
    }
745
    for (i = 0; i < filter->output_count; i++) {
746 747
        if ((link = filter->outputs[i])) {
            if (link->dst)
748
                link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
749 750
            avfilter_formats_unref(&link->in_formats);
            avfilter_formats_unref(&link->out_formats);
751
        }
752
        av_freep(&link);
V
Vitor Sessak 已提交
753 754
    }

V
Vitor Sessak 已提交
755 756 757 758 759 760
    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 已提交
761 762 763
    av_free(filter);
}

764
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
V
Vitor Sessak 已提交
765
{
V
Vitor Sessak 已提交
766
    int ret=0;
V
Vitor Sessak 已提交
767

768
    if (filter->filter->init)
V
Vitor Sessak 已提交
769 770
        ret = filter->filter->init(filter, args, opaque);
    return ret;
V
Vitor Sessak 已提交
771 772
}

773 774 775 776 777
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
{
    dst->pts    = src->pts;
    dst->format = src->format;

778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
    switch (dst->type) {
    case AVMEDIA_TYPE_VIDEO:
        dst->video->w                   = src->width;
        dst->video->h                   = src->height;
        dst->video->pixel_aspect        = src->sample_aspect_ratio;
        dst->video->interlaced          = src->interlaced_frame;
        dst->video->top_field_first     = src->top_field_first;
        dst->video->key_frame           = src->key_frame;
        dst->video->pict_type           = src->pict_type;
        break;
    case AVMEDIA_TYPE_AUDIO:
        dst->audio->sample_rate         = src->sample_rate;
        dst->audio->channel_layout      = src->channel_layout;
        break;
    default:
        return AVERROR(EINVAL);
    }
795 796 797

    return 0;
}
798

799 800
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
{
801 802
    int planes, nb_channels;

803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
    memcpy(dst->data, src->data, sizeof(dst->data));
    memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));

    dst->pts     = src->pts;
    dst->format  = src->format;

    switch (src->type) {
    case AVMEDIA_TYPE_VIDEO:
        dst->width               = src->video->w;
        dst->height              = src->video->h;
        dst->sample_aspect_ratio = src->video->pixel_aspect;
        dst->interlaced_frame    = src->video->interlaced;
        dst->top_field_first     = src->video->top_field_first;
        dst->key_frame           = src->video->key_frame;
        dst->pict_type           = src->video->pict_type;
        break;
    case AVMEDIA_TYPE_AUDIO:
820 821 822 823 824 825 826 827 828 829 830 831
        nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
        planes      = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;

        if (planes > FF_ARRAY_ELEMS(dst->data)) {
            dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
            if (!dst->extended_data)
                return AVERROR(ENOMEM);
            memcpy(dst->extended_data, src->extended_data,
                   planes * sizeof(dst->extended_data));
        } else
            dst->extended_data = dst->data;

832 833 834 835 836 837 838 839 840 841 842
        dst->sample_rate         = src->audio->sample_rate;
        dst->channel_layout      = src->audio->channel_layout;
        dst->nb_samples          = src->audio->nb_samples;
        break;
    default:
        return AVERROR(EINVAL);
    }

    return 0;
}

843 844 845 846 847 848 849 850 851 852 853 854
void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
{
    // copy common properties
    dst->pts             = src->pts;
    dst->pos             = src->pos;

    switch (src->type) {
    case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
    case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
    default: break;
    }
}