Browse code

lavfi: add pp filter.

Ported from MPlayer. Original author is A'rpi, with various
contributions from Michael Niedermayer. The original documentation was
mostly written by Diego Biurrun. See the MPlayer history for full
credits.

The filter is under GPL like the original filter, even if it differs
quite a lot. There is not much point in making it LGPL since pp is under
GPL.

Clément Bœsch authored on 2012/11/23 02:19:12
Showing 9 changed files
... ...
@@ -48,6 +48,7 @@ version <next>:
48 48
 - apad filter
49 49
 - adaptive frame-level multithreading for H.264
50 50
 - documentation split into per-component manuals
51
+- pp (postproc) filter ported from MPlayer
51 52
 
52 53
 
53 54
 version 1.0:
... ...
@@ -34,6 +34,7 @@ Specifically, the GPL parts of FFmpeg are
34 34
     - vf_hqdn3d.c
35 35
     - vf_hue.c
36 36
     - vf_mp.c
37
+    - vf_pp.c
37 38
     - vf_smartblur.c
38 39
     - vf_super2xsai.c
39 40
     - vf_tinterlace.c
... ...
@@ -1991,6 +1991,7 @@ negate_filter_deps="lut_filter"
1991 1991
 resample_filter_deps="avresample"
1992 1992
 ocv_filter_deps="libopencv"
1993 1993
 pan_filter_deps="swresample"
1994
+pp_filter_deps="gpl postproc"
1994 1995
 removelogo_filter_deps="avcodec avformat swscale"
1995 1996
 scale_filter_deps="swscale"
1996 1997
 smartblur_filter_deps="gpl swscale"
... ...
@@ -3423,6 +3423,174 @@ format=monow, pixdesctest
3423 3423
 
3424 3424
 can be used to test the monowhite pixel format descriptor definition.
3425 3425
 
3426
+@section pp
3427
+
3428
+Enable the specified chain of postprocessing subfilters using libpostproc. This
3429
+library should be automatically selected with a GPL build (@code{--enable-gpl}).
3430
+Subfilters must be separated by '/' and can be disabled by prepending a '-'.
3431
+Each subfilter and some options have a short and a long name that can be used
3432
+interchangeably, i.e. dr/dering are the same.
3433
+
3434
+All subfilters share common options to determine their scope:
3435
+
3436
+@table @option
3437
+@item a/autoq
3438
+Honor the quality commands for this subfilter.
3439
+
3440
+@item c/chrom
3441
+Do chrominance filtering, too (default).
3442
+
3443
+@item y/nochrom
3444
+Do luminance filtering only (no chrominance).
3445
+
3446
+@item n/noluma
3447
+Do chrominance filtering only (no luminance).
3448
+@end table
3449
+
3450
+These options can be appended after the subfilter name, separated by a ':'.
3451
+
3452
+Available subfilters are:
3453
+
3454
+@table @option
3455
+@item hb/hdeblock[:difference[:flatness]]
3456
+Horizontal deblocking filter
3457
+@table @option
3458
+@item difference
3459
+Difference factor where higher values mean more deblocking (default: @code{32}).
3460
+@item flatness
3461
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
3462
+@end table
3463
+
3464
+@item vb/vdeblock[:difference[:flatness]]
3465
+Vertical deblocking filter
3466
+@table @option
3467
+@item difference
3468
+Difference factor where higher values mean more deblocking (default: @code{32}).
3469
+@item flatness
3470
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
3471
+@end table
3472
+
3473
+@item ha/hadeblock[:difference[:flatness]]
3474
+Accurate horizontal deblocking filter
3475
+@table @option
3476
+@item difference
3477
+Difference factor where higher values mean more deblocking (default: @code{32}).
3478
+@item flatness
3479
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
3480
+@end table
3481
+
3482
+@item va/vadeblock[:difference[:flatness]]
3483
+Accurate vertical deblocking filter
3484
+@table @option
3485
+@item difference
3486
+Difference factor where higher values mean more deblocking (default: @code{32}).
3487
+@item flatness
3488
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
3489
+@end table
3490
+@end table
3491
+
3492
+The horizontal and vertical deblocking filters share the difference and
3493
+flatness values so you cannot set different horizontal and vertical
3494
+thresholds.
3495
+
3496
+@table @option
3497
+@item h1/x1hdeblock
3498
+Experimental horizontal deblocking filter
3499
+
3500
+@item v1/x1vdeblock
3501
+Experimental vertical deblocking filter
3502
+
3503
+@item dr/dering
3504
+Deringing filter
3505
+
3506
+@item tn/tmpnoise[:threshold1[:threshold2[:threshold3]]], temporal noise reducer
3507
+@table @option
3508
+@item threshold1
3509
+larger -> stronger filtering
3510
+@item threshold2
3511
+larger -> stronger filtering
3512
+@item threshold3
3513
+larger -> stronger filtering
3514
+@end table
3515
+
3516
+@item al/autolevels[:f/fullyrange], automatic brightness / contrast correction
3517
+@table @option
3518
+@item f/fullyrange
3519
+Stretch luminance to @code{0-255}.
3520
+@end table
3521
+
3522
+@item lb/linblenddeint
3523
+Linear blend deinterlacing filter that deinterlaces the given block by
3524
+filtering all lines with a @code{(1 2 1)} filter.
3525
+
3526
+@item li/linipoldeint
3527
+Linear interpolating deinterlacing filter that deinterlaces the given block by
3528
+linearly interpolating every second line.
3529
+
3530
+@item ci/cubicipoldeint
3531
+Cubic interpolating deinterlacing filter deinterlaces the given block by
3532
+cubically interpolating every second line.
3533
+
3534
+@item md/mediandeint
3535
+Median deinterlacing filter that deinterlaces the given block by applying a
3536
+median filter to every second line.
3537
+
3538
+@item fd/ffmpegdeint
3539
+FFmpeg deinterlacing filter that deinterlaces the given block by filtering every
3540
+second line with a @code{(-1 4 2 4 -1)} filter.
3541
+
3542
+@item l5/lowpass5
3543
+Vertically applied FIR lowpass deinterlacing filter that deinterlaces the given
3544
+block by filtering all lines with a @code{(-1 2 6 2 -1)} filter.
3545
+
3546
+@item fq/forceQuant[:quantizer]
3547
+Overrides the quantizer table from the input with the constant quantizer you
3548
+specify.
3549
+@table @option
3550
+@item quantizer
3551
+Quantizer to use
3552
+@end table
3553
+
3554
+@item de/default
3555
+Default pp filter combination (@code{hb:a,vb:a,dr:a})
3556
+
3557
+@item fa/fast
3558
+Fast pp filter combination (@code{h1:a,v1:a,dr:a})
3559
+
3560
+@item ac
3561
+High quality pp filter combination (@code{ha:a:128:7,va:a,dr:a})
3562
+@end table
3563
+
3564
+@subsection Examples
3565
+
3566
+@itemize
3567
+@item
3568
+Apply horizontal and vertical deblocking, deringing and automatic
3569
+brightness/contrast:
3570
+@example
3571
+pp=hb/vb/dr/al
3572
+@end example
3573
+
3574
+@item
3575
+Apply default filters without brightness/contrast correction:
3576
+@example
3577
+pp=de/-al
3578
+@end example
3579
+
3580
+@item
3581
+Apply default filters and temporal denoiser:
3582
+@example
3583
+pp=default/tmpnoise:1:2:3
3584
+@end example
3585
+
3586
+@item
3587
+Apply deblocking on luminance only, and switch vertical deblocking on or off
3588
+automatically depending on available CPU time:
3589
+@example
3590
+pp=hb:y/vb:a
3591
+@end example
3592
+@end itemize
3593
+
3426 3594
 @section removelogo
3427 3595
 
3428 3596
 Suppress a TV station logo, using an image file to determine which
... ...
@@ -123,6 +123,7 @@ OBJS-$(CONFIG_OCV_FILTER)                    += vf_libopencv.o
123 123
 OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o
124 124
 OBJS-$(CONFIG_PAD_FILTER)                    += vf_pad.o
125 125
 OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.o
126
+OBJS-$(CONFIG_PP_FILTER)                     += vf_pp.o
126 127
 OBJS-$(CONFIG_REMOVELOGO_FILTER)             += bbox.o lswsutils.o lavfutils.o vf_removelogo.o
127 128
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
128 129
 OBJS-$(CONFIG_SELECT_FILTER)                 += f_select.o
... ...
@@ -116,6 +116,7 @@ void avfilter_register_all(void)
116 116
     REGISTER_FILTER (OVERLAY,     overlay,     vf);
117 117
     REGISTER_FILTER (PAD,         pad,         vf);
118 118
     REGISTER_FILTER (PIXDESCTEST, pixdesctest, vf);
119
+    REGISTER_FILTER (PP,          pp,          vf);
119 120
     REGISTER_FILTER (REMOVELOGO,  removelogo,  vf);
120 121
     REGISTER_FILTER (SCALE,       scale,       vf);
121 122
     REGISTER_FILTER (SELECT,      select,      vf);
... ...
@@ -29,8 +29,8 @@
29 29
 #include "libavutil/avutil.h"
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  3
32
-#define LIBAVFILTER_VERSION_MINOR  29
33
-#define LIBAVFILTER_VERSION_MICRO 101
32
+#define LIBAVFILTER_VERSION_MINOR  30
33
+#define LIBAVFILTER_VERSION_MICRO 100
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
37 37
new file mode 100644
... ...
@@ -0,0 +1,172 @@
0
+/*
1
+ * Copyright (c) 2002 A'rpi
2
+ * Copyright (C) 2012 Clément Bœsch
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License along
17
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+
21
+/**
22
+ * @file
23
+ * libpostproc filter, ported from MPlayer.
24
+ */
25
+
26
+#include "libavutil/avassert.h"
27
+#include "libavutil/opt.h"
28
+#include "internal.h"
29
+
30
+#include "libpostproc/postprocess.h"
31
+
32
+typedef struct {
33
+    int mode_id;
34
+    pp_mode *modes[PP_QUALITY_MAX + 1];
35
+    void *pp_ctx;
36
+} PPFilterContext;
37
+
38
+static av_cold int pp_init(AVFilterContext *ctx, const char *args)
39
+{
40
+    int i;
41
+    PPFilterContext *pp = ctx->priv;
42
+
43
+    if (!args || !*args)
44
+        args = "de";
45
+
46
+    for (i = 0; i <= PP_QUALITY_MAX; i++) {
47
+        pp->modes[i] = pp_get_mode_by_name_and_quality(args, i);
48
+        if (!pp->modes[i])
49
+            return AVERROR_EXTERNAL;
50
+    }
51
+    pp->mode_id = PP_QUALITY_MAX;
52
+    return 0;
53
+}
54
+
55
+static int pp_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
56
+                              char *res, int res_len, int flags)
57
+{
58
+    PPFilterContext *pp = ctx->priv;
59
+
60
+    if (!strcmp(cmd, "quality")) {
61
+        pp->mode_id = av_clip(strtol(args, NULL, 10), 0, PP_QUALITY_MAX);
62
+        return 0;
63
+    }
64
+    return AVERROR(ENOSYS);
65
+}
66
+
67
+static int pp_query_formats(AVFilterContext *ctx)
68
+{
69
+    static const enum PixelFormat pix_fmts[] = {
70
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P,
71
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
72
+        AV_PIX_FMT_YUV411P,
73
+        AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
74
+        AV_PIX_FMT_NONE
75
+    };
76
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
77
+    return 0;
78
+}
79
+
80
+static int pp_config_props(AVFilterLink *inlink)
81
+{
82
+    int flags = PP_CPU_CAPS_AUTO;
83
+    PPFilterContext *pp = inlink->dst->priv;
84
+
85
+    switch (inlink->format) {
86
+    case AV_PIX_FMT_YUVJ420P:
87
+    case AV_PIX_FMT_YUV420P: flags |= PP_FORMAT_420; break;
88
+    case AV_PIX_FMT_YUVJ422P:
89
+    case AV_PIX_FMT_YUV422P: flags |= PP_FORMAT_422; break;
90
+    case AV_PIX_FMT_YUV411P: flags |= PP_FORMAT_411; break;
91
+    case AV_PIX_FMT_YUVJ444P:
92
+    case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; break;
93
+    default: av_assert0(0);
94
+    }
95
+
96
+    pp->pp_ctx = pp_get_context(inlink->w, inlink->h, flags);
97
+    if (!pp->pp_ctx)
98
+        return AVERROR(ENOMEM);
99
+    return 0;
100
+}
101
+
102
+static int pp_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inbuf)
103
+{
104
+    AVFilterContext *ctx = inlink->dst;
105
+    PPFilterContext *pp = ctx->priv;
106
+    AVFilterLink *outlink = ctx->outputs[0];
107
+    const int aligned_w = FFALIGN(outlink->w, 8);
108
+    const int aligned_h = FFALIGN(outlink->h, 8);
109
+    AVFilterBufferRef *outbuf;
110
+
111
+    outbuf = ff_get_video_buffer(outlink, AV_PERM_WRITE, aligned_w, aligned_h);
112
+    if (!outbuf) {
113
+        avfilter_unref_buffer(inbuf);
114
+        return AVERROR(ENOMEM);
115
+    }
116
+    avfilter_copy_buffer_ref_props(outbuf, inbuf);
117
+
118
+    pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize,
119
+                   outbuf->data,                 outbuf->linesize,
120
+                   aligned_w, outlink->h,
121
+                   outbuf->video->qp_table,
122
+                   outbuf->video->qp_table_linesize,
123
+                   pp->modes[pp->mode_id],
124
+                   pp->pp_ctx,
125
+                   outbuf->video->pict_type);
126
+
127
+    avfilter_unref_buffer(inbuf);
128
+    return ff_filter_frame(outlink, outbuf);
129
+}
130
+
131
+static av_cold void pp_uninit(AVFilterContext *ctx)
132
+{
133
+    int i;
134
+    PPFilterContext *pp = ctx->priv;
135
+
136
+    for (i = 0; i <= PP_QUALITY_MAX; i++)
137
+        pp_free_mode(pp->modes[i]);
138
+    if (pp->pp_ctx)
139
+        pp_free_context(pp->pp_ctx);
140
+}
141
+
142
+static const AVFilterPad pp_inputs[] = {
143
+    {
144
+        .name         = "default",
145
+        .type         = AVMEDIA_TYPE_VIDEO,
146
+        .config_props = pp_config_props,
147
+        .filter_frame = pp_filter_frame,
148
+        .min_perms    = AV_PERM_READ,
149
+    },
150
+    { NULL }
151
+};
152
+
153
+static const AVFilterPad pp_outputs[] = {
154
+    {
155
+        .name = "default",
156
+        .type = AVMEDIA_TYPE_VIDEO,
157
+    },
158
+    { NULL }
159
+};
160
+
161
+AVFilter avfilter_vf_pp = {
162
+    .name            = "pp",
163
+    .description     = NULL_IF_CONFIG_SMALL("Filter video using libpostproc."),
164
+    .priv_size       = sizeof(PPFilterContext),
165
+    .init            = pp_init,
166
+    .uninit          = pp_uninit,
167
+    .query_formats   = pp_query_formats,
168
+    .inputs          = pp_inputs,
169
+    .outputs         = pp_outputs,
170
+    .process_command = pp_process_command,
171
+};
... ...
@@ -49,12 +49,12 @@ do_lavfi "idet"               "idet"
49 49
 do_lavfi "null"               "null"
50 50
 do_lavfi "overlay"            "split[m],scale=88:72,pad=96:80:4:4[o2];[m]fifo[o1],[o1][o2]overlay=240:16"
51 51
 do_lavfi "pad"                "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2"
52
-do_lavfi "pp"                 "mp=pp=be/hb/vb/tn/l5/al"
53
-do_lavfi "pp2"                "mp=pp=be/fq:16/h1/v1/lb"
54
-do_lavfi "pp3"                "mp=pp=be/fq:8/ha:128:7/va/li"
55
-do_lavfi "pp4"                "mp=pp=be/ci"
56
-do_lavfi "pp5"                "mp=pp=md"
57
-do_lavfi "pp6"                "mp=pp=be/fd"
52
+do_lavfi "pp"                 "pp=be/hb/vb/tn/l5/al"
53
+do_lavfi "pp2"                "pp=be/fq:16/h1/v1/lb"
54
+do_lavfi "pp3"                "pp=be/fq:8/ha:128:7/va/li"
55
+do_lavfi "pp4"                "pp=be/ci"
56
+do_lavfi "pp5"                "pp=md"
57
+do_lavfi "pp6"                "pp=be/fd"
58 58
 do_lavfi "scale200"           "scale=200:200"
59 59
 do_lavfi "scale500"           "scale=500:500"
60 60
 do_lavfi "select"             "select=not(eq(mod(n\,2)\,0)+eq(mod(n\,3)\,0))"