Revision 46847a33

View differences:

ffmpeg.c
43 43
#include "libavutil/libm.h"
44 44
#include "libavformat/os_support.h"
45 45

  
46
#if CONFIG_AVFILTER
47
# include "libavfilter/avfilter.h"
48
# include "libavfilter/avfiltergraph.h"
49
# include "libavfilter/graphparser.h"
50
# include "libavfilter/vsrc_buffer.h"
51
#endif
52

  
46 53
#if HAVE_SYS_RESOURCE_H
47 54
#include <sys/types.h>
48 55
#include <sys/time.h>
......
147 154
static int loop_input = 0;
148 155
static int loop_output = AVFMT_NOOUTPUTLOOP;
149 156
static int qp_hist = 0;
157
#if CONFIG_AVFILTER
158
static char *vfilters = NULL;
159
AVFilterGraph *filt_graph_all = NULL;
160
#endif
150 161

  
151 162
static int intra_only = 0;
152 163
static int audio_sample_rate = 44100;
......
305 316
    int is_start;            /* is 1 at the start and after a discontinuity */
306 317
    int showed_multi_packet_warning;
307 318
    int is_past_recording_time;
319
#if CONFIG_AVFILTER
320
    AVFilterContext *out_video_filter;
321
    AVFilterContext *input_video_filter;
322
    AVFrame *filter_frame;
323
    int has_filter_frame;
324
    AVFilterPicRef *picref;
325
#endif
308 326
} AVInputStream;
309 327

  
310 328
typedef struct AVInputFile {
......
320 338
static struct termios oldtty;
321 339
#endif
322 340

  
341
#if CONFIG_AVFILTER
342
typedef struct {
343
    int pix_fmt;
344
} FilterOutPriv;
345

  
346

  
347
static int output_init(AVFilterContext *ctx, const char *args, void *opaque)
348
{
349
    FilterOutPriv *priv = ctx->priv;
350

  
351
    if(!opaque) return -1;
352

  
353
    priv->pix_fmt = *((int *)opaque);
354

  
355
    return 0;
356
}
357

  
358
static void output_end_frame(AVFilterLink *link)
359
{
360
}
361

  
362
static int output_query_formats(AVFilterContext *ctx)
363
{
364
    FilterOutPriv *priv = ctx->priv;
365
    enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
366

  
367
    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
368
    return 0;
369
}
370

  
371
static int get_filtered_video_pic(AVFilterContext *ctx,
372
                                  AVFilterPicRef **picref, AVFrame *pic2,
373
                                  uint64_t *pts)
374
{
375
    AVFilterPicRef *pic;
376

  
377
    if(avfilter_request_frame(ctx->inputs[0]))
378
        return -1;
379
    if(!(pic = ctx->inputs[0]->cur_pic))
380
        return -1;
381
    *picref = pic;
382
    ctx->inputs[0]->cur_pic = NULL;
383

  
384
    *pts          = pic->pts;
385

  
386
    memcpy(pic2->data,     pic->data,     sizeof(pic->data));
387
    memcpy(pic2->linesize, pic->linesize, sizeof(pic->linesize));
388

  
389
    return 1;
390
}
391

  
392
static AVFilter output_filter =
393
{
394
    .name      = "ffmpeg_output",
395

  
396
    .priv_size = sizeof(FilterOutPriv),
397
    .init      = output_init,
398

  
399
    .query_formats = output_query_formats,
400

  
401
    .inputs    = (AVFilterPad[]) {{ .name          = "default",
402
                                    .type          = AVMEDIA_TYPE_VIDEO,
403
                                    .end_frame     = output_end_frame,
404
                                    .min_perms     = AV_PERM_READ, },
405
                                  { .name = NULL }},
406
    .outputs   = (AVFilterPad[]) {{ .name = NULL }},
407
};
408

  
409
static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
410
{
411
    AVFilterContext *curr_filter;
412
    /** filter graph containing all filters including input & output */
413
    AVCodecContext *codec = ost->st->codec;
414
    AVCodecContext *icodec = ist->st->codec;
415
    char args[255];
416

  
417
    filt_graph_all = av_mallocz(sizeof(AVFilterGraph));
418

  
419
    if(!(ist->input_video_filter = avfilter_open(avfilter_get_by_name("buffer"), "src")))
420
        return -1;
421
    if(!(ist->out_video_filter = avfilter_open(&output_filter, "out")))
422
        return -1;
423

  
424
    snprintf(args, 255, "%d:%d:%d", ist->st->codec->width,
425
             ist->st->codec->height, ist->st->codec->pix_fmt);
426
    if(avfilter_init_filter(ist->input_video_filter, args, NULL))
427
        return -1;
428
    if(avfilter_init_filter(ist->out_video_filter, NULL, &codec->pix_fmt))
429
        return -1;
430

  
431
    /* add input and output filters to the overall graph */
432
    avfilter_graph_add_filter(filt_graph_all, ist->input_video_filter);
433
    avfilter_graph_add_filter(filt_graph_all, ist->out_video_filter);
434

  
435
    curr_filter = ist->input_video_filter;
436

  
437
    if(ost->video_crop) {
438
        char crop_args[255];
439
        AVFilterContext *filt_crop;
440
        snprintf(crop_args, 255, "%d:%d:%d:%d", ost->leftBand, ost->topBand,
441
                 codec->width -  (frame_padleft + frame_padright),
442
                 codec->height - (frame_padtop + frame_padbottom));
443
        filt_crop = avfilter_open(avfilter_get_by_name("crop"), NULL);
444
        if (!filt_crop)
445
            return -1;
446
        if (avfilter_init_filter(filt_crop, crop_args, NULL))
447
            return -1;
448
        if (avfilter_link(curr_filter, 0, filt_crop, 0))
449
            return -1;
450
        curr_filter = filt_crop;
451
        avfilter_graph_add_filter(filt_graph_all, curr_filter);
452
    }
453

  
454
    if((codec->width !=
455
        icodec->width - (frame_leftBand + frame_rightBand) +
456
        (frame_padleft + frame_padright)) ||
457
       (codec->height != icodec->height - (frame_topBand  + frame_bottomBand) +
458
        (frame_padtop + frame_padbottom))) {
459
        char scale_args[255];
460
        AVFilterContext *filt_scale;
461
        snprintf(scale_args, 255, "%d:%d:flags=0x%X",
462
                 codec->width  - (frame_padleft + frame_padright),
463
                 codec->height - (frame_padtop  + frame_padbottom),
464
                 (int)av_get_int(sws_opts, "sws_flags", NULL));
465
        filt_scale = avfilter_open(avfilter_get_by_name("scale"), NULL);
466
        if (!filt_scale)
467
            return -1;
468
        if (avfilter_init_filter(filt_scale, scale_args, NULL))
469
            return -1;
470
        if (avfilter_link(curr_filter, 0, filt_scale, 0))
471
            return -1;
472
        curr_filter = filt_scale;
473
        avfilter_graph_add_filter(filt_graph_all, curr_filter);
474
    }
475

  
476
    if(vfilters) {
477
        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
478
        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
479

  
480
        outputs->name    = av_strdup("in");
481
        outputs->filter  = curr_filter;
482
        outputs->pad_idx = 0;
483
        outputs->next    = NULL;
484

  
485
        inputs->name    = av_strdup("out");
486
        inputs->filter  = ist->out_video_filter;
487
        inputs->pad_idx = 0;
488
        inputs->next    = NULL;
489

  
490
        if (avfilter_graph_parse(filt_graph_all, vfilters, inputs, outputs, NULL) < 0)
491
            return -1;
492
        av_freep(&vfilters);
493
    } else {
494
        if(avfilter_link(curr_filter, 0, ist->out_video_filter, 0) < 0)
495
            return -1;
496
    }
497

  
498
    {
499
        char scale_sws_opts[128];
500
        snprintf(scale_sws_opts, sizeof(scale_sws_opts), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
501
        filt_graph_all->scale_sws_opts = av_strdup(scale_sws_opts);
502
    }
503

  
504
    /* configure all the filter links */
505
    if(avfilter_graph_check_validity(filt_graph_all, NULL))
506
        return -1;
507
    if(avfilter_graph_config_formats(filt_graph_all, NULL))
508
        return -1;
509
    if(avfilter_graph_config_links(filt_graph_all, NULL))
510
        return -1;
511

  
512
    codec->width = ist->out_video_filter->inputs[0]->w;
513
    codec->height = ist->out_video_filter->inputs[0]->h;
514

  
515
    return 0;
516
}
517
#endif /* CONFIG_AVFILTER */
518

  
323 519
static void term_exit(void)
324 520
{
325 521
#if HAVE_TERMIOS_H
......
461 657
    allocated_audio_buf_size= allocated_audio_out_size= 0;
462 658
    av_free(samples);
463 659

  
660
#if CONFIG_AVFILTER
661
    avfilter_uninit();
662
#endif
663

  
464 664
    if (received_sigterm) {
465 665
        fprintf(stderr,
466 666
            "Received signal %d: terminating.\n",
......
952 1152
                         int *frame_size)
953 1153
{
954 1154
    int nb_frames, i, ret;
1155
#if !CONFIG_AVFILTER
955 1156
    int64_t topBand, bottomBand, leftBand, rightBand;
1157
#endif
956 1158
    AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
957 1159
    AVFrame picture_crop_temp, picture_pad_temp;
958 1160
    AVCodecContext *enc, *dec;
......
1000 1202
    if (nb_frames <= 0)
1001 1203
        return;
1002 1204

  
1205
#if CONFIG_AVFILTER
1206
    formatted_picture = in_picture;
1207
#else
1003 1208
    if (ost->video_crop) {
1004 1209
        if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
1005 1210
            fprintf(stderr, "error cropping picture\n");
......
1011 1216
    } else {
1012 1217
        formatted_picture = in_picture;
1013 1218
    }
1219
#endif
1014 1220

  
1015 1221
    final_picture = formatted_picture;
1016 1222
    padding_src = formatted_picture;
......
1037 1243
            av_exit(1);
1038 1244
    }
1039 1245

  
1246
#if !CONFIG_AVFILTER
1040 1247
    if (ost->video_resample) {
1041 1248
        padding_src = NULL;
1042 1249
        final_picture = &ost->pict_tmp;
......
1084 1291
        sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
1085 1292
              0, ost->resample_height, resampling_dst->data, resampling_dst->linesize);
1086 1293
    }
1294
#endif
1087 1295

  
1088 1296
    if (ost->video_pad) {
1089 1297
        av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
......
1349 1557
    static unsigned int samples_size= 0;
1350 1558
    AVSubtitle subtitle, *subtitle_to_free;
1351 1559
    int got_subtitle;
1560
#if CONFIG_AVFILTER
1561
    int loop;
1562
#endif
1563

  
1352 1564
    AVPacket avpkt;
1353 1565
    int bps = av_get_bits_per_sample_format(ist->st->codec->sample_fmt)>>3;
1354 1566

  
......
1476 1688
                                    &buffer_to_free);
1477 1689
        }
1478 1690

  
1691
#if CONFIG_AVFILTER
1692
        if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) {
1693
            // add it to be filtered
1694
            av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
1695
                                     ist->pts,
1696
                                     ist->st->codec->sample_aspect_ratio);
1697
        }
1698
#endif
1699

  
1479 1700
        // preprocess audio (volume)
1480 1701
        if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
1481 1702
            if (audio_volume != 256) {
......
1497 1718
            if (pts > now)
1498 1719
                usleep(pts - now);
1499 1720
        }
1500

  
1721
#if CONFIG_AVFILTER
1722
        loop = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
1723
            !ist->out_video_filter || avfilter_poll_frame(ist->out_video_filter->inputs[0]);
1724
#endif
1501 1725
        /* if output time reached then transcode raw format,
1502 1726
           encode packets and output them */
1503 1727
        if (start_time == 0 || ist->pts >= start_time)
1728
#if CONFIG_AVFILTER
1729
        while(loop) {
1730
            if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->out_video_filter)
1731
                get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
1732
#endif
1504 1733
            for(i=0;i<nb_ostreams;i++) {
1505 1734
                int frame_size;
1506 1735

  
......
1518 1747
                            do_audio_out(os, ost, ist, decoded_data_buf, decoded_data_size);
1519 1748
                            break;
1520 1749
                        case AVMEDIA_TYPE_VIDEO:
1750
#if CONFIG_AVFILTER
1751
                            ost->st->codec->sample_aspect_ratio = ist->picref->pixel_aspect;
1752
#endif
1521 1753
                            do_video_out(os, ost, ist, &picture, &frame_size);
1522 1754
                            if (vstats_filename && frame_size)
1523 1755
                                do_video_stats(os, ost, frame_size);
......
1586 1818
                        av_free_packet(&opkt);
1587 1819
                    }
1588 1820
                }
1821
#if CONFIG_AVFILTER
1822
                loop =  (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
1823
                        ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
1824
#endif
1589 1825
            }
1826

  
1827
#if CONFIG_AVFILTER
1828
            if(ist->picref)
1829
                avfilter_unref_pic(ist->picref);
1830
        }
1831
#endif
1590 1832
        av_free(buffer_to_free);
1591 1833
        /* XXX: allocate the subtitles in the codec ? */
1592 1834
        if (subtitle_to_free) {
......
2064 2306
                        av_exit(1);
2065 2307
                    }
2066 2308

  
2309
#if !CONFIG_AVFILTER
2067 2310
                    ost->original_height = icodec->height;
2068 2311
                    ost->original_width  = icodec->width;
2069

  
2312
#endif
2070 2313
                    codec->bits_per_raw_sample= 0;
2071 2314
                }
2072 2315
                ost->resample_height = icodec->height - (frame_topBand  + frame_bottomBand);
......
2074 2317
                ost->resample_pix_fmt= icodec->pix_fmt;
2075 2318
                ost->encoding_needed = 1;
2076 2319
                ist->decoding_needed = 1;
2320

  
2321
#if CONFIG_AVFILTER
2322
                if (configure_filters(ist, ost)) {
2323
                    fprintf(stderr, "Error opening filters!\n");
2324
                    exit(1);
2325
                }
2326
#endif
2077 2327
                break;
2078 2328
            case AVMEDIA_TYPE_SUBTITLE:
2079 2329
                ost->encoding_needed = 1;
......
2459 2709
            avcodec_close(ist->st->codec);
2460 2710
        }
2461 2711
    }
2712
#if CONFIG_AVFILTER
2713
    if (filt_graph_all) {
2714
        avfilter_graph_destroy(filt_graph_all);
2715
        av_freep(&filt_graph_all);
2716
    }
2717
#endif
2462 2718

  
2463 2719
    /* finished ! */
2464 2720
    ret = 0;
......
4040 4296
    { "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
4041 4297
    { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
4042 4298
    { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
4299
#if CONFIG_AVFILTER
4300
    { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
4301
#endif
4043 4302
    { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
4044 4303
    { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
4045 4304
    { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
......
4102 4361
#if CONFIG_AVDEVICE
4103 4362
    avdevice_register_all();
4104 4363
#endif
4364
#if CONFIG_AVFILTER
4365
    avfilter_register_all();
4366
#endif
4105 4367
    av_register_all();
4106 4368

  
4107 4369
#if HAVE_ISATTY

Also available in: Unified diff