avfilter.c 27.8 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"
V
Vitor Sessak 已提交
29
#include "avfilter.h"
30
#include "internal.h"
V
Vitor Sessak 已提交
31

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

36
const char *avfilter_configuration(void)
37
{
38
    return LIBAV_CONFIGURATION;
39 40
}

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

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

        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;
81
    }
82
    ret->perms &= pmask;
83
    ret->buf->refcount ++;
V
Vitor Sessak 已提交
84 85 86
    return ret;
}

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

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

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

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

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

130 131 132 133 134 135 136
    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 已提交
137
    src->outputs[srcpad] =
V
Vitor Sessak 已提交
138
    dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
V
Vitor Sessak 已提交
139

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

    return 0;
}

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

157 158 159
    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);
160

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

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

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

179 180 181
    return 0;
}

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

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

191
        if (!link) continue;
192

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

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

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

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

214 215 216 217
            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};

218 219 220 221 222 223
            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;

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

228 229 230 231
            link->init_state = AVLINK_INIT;
        }
    }

V
Vitor Sessak 已提交
232 233 234
    return 0;
}

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

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

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

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

L
Luca Barbato 已提交
278
static void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
279
{
280
    if (link->type == AVMEDIA_TYPE_VIDEO) {
L
Luca Barbato 已提交
281
        av_dlog(ctx,
S
Stefano Sabatini 已提交
282 283 284 285 286 287
                "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" : "");
288 289 290 291
    } else {
        char buf[128];
        av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);

L
Luca Barbato 已提交
292
        av_dlog(ctx,
293 294 295 296 297 298 299
                "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" : "");
    }
300 301
}

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

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

308
    av_unused char buf[16];
L
Luca Barbato 已提交
309 310
    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);
311

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

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

318 319 320
    if (ret)
        ret->type = AVMEDIA_TYPE_VIDEO;

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

V
Vitor Sessak 已提交
323 324 325
    return ret;
}

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

341 342
    pic->w = picref->video->w = w;
    pic->h = picref->video->h = h;
343 344 345 346 347 348

    /* 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;
349
    pic->format = picref->format = format;
350

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

356 357 358
    pic->   extended_data = pic->data;
    picref->extended_data = picref->data;

359 360 361 362 363 364 365 366 367 368
    return picref;

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

369
AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,
370 371
                                             enum AVSampleFormat sample_fmt, int nb_samples,
                                             uint64_t channel_layout)
372 373 374
{
    AVFilterBufferRef *ret = NULL;

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

    if (!ret)
379
        ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, nb_samples, channel_layout);
380 381 382 383 384 385 386

    if (ret)
        ret->type = AVMEDIA_TYPE_AUDIO;

    return ret;
}

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

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

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

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

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

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

    return min;
}

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

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

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

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

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

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

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

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

    end_frame(link);

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

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

L
Luca Barbato 已提交
539
    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);
540

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

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

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

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

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

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

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

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

581 582 583 584 585 586
    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) {
587 588 589
        int  i, planar = av_sample_fmt_is_planar(samplesref->format);
        int planes = !planar ? 1:
                     av_get_channel_layout_nb_channels(samplesref->audio->channel_layout);
590 591 592

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

        link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
                                                          samplesref->format,
597 598
                                                          samplesref->audio->nb_samples,
                                                          samplesref->audio->channel_layout);
599 600 601 602
        link->cur_buf->pts                = samplesref->pts;
        link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;

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

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

    filter_samples(link, link->cur_buf);
}

613 614 615 616 617
#define MAX_REGISTERED_AVFILTERS_NB 64

static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];

static int next_registered_avfilter_idx = 0;
618

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

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

    return NULL;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 已提交
727 728
}

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

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

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

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

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

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

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

779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
    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);
    }
796 797 798

    return 0;
}
799

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

804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
    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:
821 822 823 824 825 826 827 828 829 830 831 832
        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;

833 834 835 836 837 838 839 840 841 842 843
        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;
}

844 845 846 847 848 849 850 851 852 853 854 855
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;
    }
}