History

avfilter/interlace: add complex vertical low-pass filter

This complex (-1 2 6 2 -1) filter slightly less reduces interlace 'twitter' but better retain detail and subjective sharpness impression compared to the linear (1 2 1) filter.

Thomas Mundt committed 9 years ago

Commit 2da5bf41 parent 20da41310 files · +246 −24Browse files

Unified · Split

10 files
  1. doc/filters.texi +23 −4
  2. libavfilter/interlace.h +6 −0
  3. libavfilter/tinterlace.h +4 −0
  4. libavfilter/vf_interlace.c +46 −3
  5. libavfilter/vf_tinterlace.c +50 −11
  6. libavfilter/x86/vf_interlace.asm +60 −0
  7. libavfilter/x86/vf_interlace_init.c +12 −3
  8. libavfilter/x86/vf_tinterlace_init.c +12 −3
  9. tests/fate/filter-video.mak +3 −0
  10. tests/ref/fate/filter-interlace-complex +30 −0
doc/filters.texi+23−4
@@ -9158,8 +9158,21 @@ This determines whether the interlaced frame is taken from the even · 9157 unmodified lines
9158(tff - default) or odd (bff) lines of the progressive frame.9158(tff - default) or odd (bff) lines of the progressive frame.
9159 9159
9160@item lowpass9160@item lowpass
9161Enable (default) or disable the vertical lowpass filter to avoid twitter9161Vertical lowpass filter to avoid twitter interlacing and
9162interlacing and reduce moire patterns.9162reduce moire patterns.
9163
9164@table @samp
9165@item 0, off
9166Disable vertical lowpass filter
9167
9168@item 1, linear
9169Enable linear filter (default)
9170
9171@item 2, complex
9172Enable complex filter. This will slightly less reduce twitter and moire
9173but better retain detail and subjective sharpness impression.
9174
9175@end table
9163@end table9176@end table
9164 9177
9165@section kerndeint9178@section kerndeint
@@ -13857,16 +13870,22 @@ Available value for @var{flags} is: · 4691 unmodified lines
13857 13870
13858@table @option13871@table @option
13859@item low_pass_filter, vlfp13872@item low_pass_filter, vlfp
13860Enable vertical low-pass filtering in the filter.13873Enable linear vertical low-pass filtering in the filter.
13861Vertical low-pass filtering is required when creating an interlaced13874Vertical low-pass filtering is required when creating an interlaced
13862destination from a progressive source which contains high-frequency13875destination from a progressive source which contains high-frequency
13863vertical detail. Filtering will reduce interlace 'twitter' and Moire13876vertical detail. Filtering will reduce interlace 'twitter' and Moire
13864patterning.13877patterning.
13865 13878
13879@item complex_filter, cvlfp
13880Enable complex vertical low-pass filtering.
13881This will slightly less reduce interlace 'twitter' and Moire
13882patterning but better retain detail and subjective sharpness impression.
13883
13884@end table
13885
13866Vertical low-pass filtering can only be enabled for @option{mode}13886Vertical low-pass filtering can only be enabled for @option{mode}
13867@var{interleave_top} and @var{interleave_bottom}.13887@var{interleave_top} and @var{interleave_bottom}.
13868 13888
13869@end table
13870@end table13889@end table
13871 13890
13872@section transpose13891@section transpose
libavfilter/interlace.h+6−0
@@ -44,6 +44,12 @@ enum FieldType { · 43 unmodified lines
44 FIELD_LOWER = 1,44 FIELD_LOWER = 1,
45};45};
46 46
47enum VLPFilter {
48 VLPF_OFF = 0,
49 VLPF_LIN = 1,
50 VLPF_CMP = 2,
51};
52
47typedef struct InterlaceContext {53typedef struct InterlaceContext {
48 const AVClass *class;54 const AVClass *class;
49 enum ScanMode scan; // top or bottom field first scanning55 enum ScanMode scan; // top or bottom field first scanning
libavfilter/tinterlace.h+4−0
@@ -30,6 +30,10 @@ · 29 unmodified lines
30#include "libavutil/opt.h"30#include "libavutil/opt.h"
31#include "avfilter.h"31#include "avfilter.h"
32 32
33#define TINTERLACE_FLAG_VLPF 01
34#define TINTERLACE_FLAG_EXACT_TB 2
35#define TINTERLACE_FLAG_CVLPF 4
36
33enum TInterlaceMode {37enum TInterlaceMode {
34 MODE_MERGE = 0,38 MODE_MERGE = 0,
35 MODE_DROP_EVEN,39 MODE_DROP_EVEN,
libavfilter/vf_interlace.c+46−3
@@ -3,6 +3,7 @@ · 2 unmodified lines
3 * Copyright (c) 2010 Baptiste Coudurier3 * Copyright (c) 2010 Baptiste Coudurier
4 * Copyright (c) 2011 Stefano Sabatini4 * Copyright (c) 2011 Stefano Sabatini
5 * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara@gmail.com>5 * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara@gmail.com>
6 * Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
6 *7 *
7 * This file is part of FFmpeg.8 * This file is part of FFmpeg.
8 *9 *
@@ -47,7 +48,13 @@ static const AVOption interlace_options[] = { · 38 unmodified lines
47 { "bff", "bottom field first", 0,48 { "bff", "bottom field first", 0,
48 AV_OPT_TYPE_CONST, {.i64 = MODE_BFF }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "scan" },49 AV_OPT_TYPE_CONST, {.i64 = MODE_BFF }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "scan" },
49 { "lowpass", "set vertical low-pass filter", OFFSET(lowpass),50 { "lowpass", "set vertical low-pass filter", OFFSET(lowpass),
50 AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = FLAGS },51 AV_OPT_TYPE_INT, {.i64 = VLPF_LIN }, 0, 2, .flags = FLAGS, .unit = "lowpass" },
52 { "off", "disable vertical low-pass filter", 0,
53 AV_OPT_TYPE_CONST, {.i64 = VLPF_OFF }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
54 { "linear", "linear vertical low-pass filter", 0,
55 AV_OPT_TYPE_CONST, {.i64 = VLPF_LIN }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
56 { "complex", "complex vertical low-pass filter", 0,
57 AV_OPT_TYPE_CONST, {.i64 = VLPF_CMP }, INT_MIN, INT_MAX, .flags = FLAGS, .unit = "lowpass" },
51 { NULL }58 { NULL }
52};59};
53 60
@@ -68,6 +75,25 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize, · 14 unmodified lines
68 }75 }
69}76}
70 77
78static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t linesize,
79 const uint8_t *srcp,
80 ptrdiff_t mref, ptrdiff_t pref)
81{
82 const uint8_t *srcp_above = srcp + mref;
83 const uint8_t *srcp_below = srcp + pref;
84 const uint8_t *srcp_above2 = srcp + mref * 2;
85 const uint8_t *srcp_below2 = srcp + pref * 2;
86 int i;
87 for (i = 0; i < linesize; i++) {
88 // this calculation is an integer representation of
89 // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
90 // '4 +' is for rounding.
91 dstp[i] = av_clip_uint8((4 + (srcp[i] << 2)
92 + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1)
93 - srcp_above2[i] - srcp_below2[i]) >> 3);
94 }
95}
96
71static const enum AVPixelFormat formats_supported[] = {97static const enum AVPixelFormat formats_supported[] = {
72 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,98 AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
73 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,99 AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
@@ -117,7 +143,10 @@ static int config_out_props(AVFilterLink *outlink) · 43 unmodified lines
117 143
118 144
119 if (s->lowpass) {145 if (s->lowpass) {
120 s->lowpass_line = lowpass_line_c;146 if (s->lowpass == VLPF_LIN)
147 s->lowpass_line = lowpass_line_c;
148 else if (s->lowpass == VLPF_CMP)
149 s->lowpass_line = lowpass_line_complex_c;
121 if (ARCH_X86)150 if (ARCH_X86)
122 ff_interlace_init_x86(s);151 ff_interlace_init_x86(s);
123 }152 }
@@ -151,7 +180,7 @@ static void copy_picture_field(InterlaceContext *s, · 27 unmodified lines
151 srcp += src_frame->linesize[plane];180 srcp += src_frame->linesize[plane];
152 dstp += dst_frame->linesize[plane];181 dstp += dst_frame->linesize[plane];
153 }182 }
154 if (lowpass) {183 if (lowpass == VLPF_LIN) {
155 int srcp_linesize = src_frame->linesize[plane] * 2;184 int srcp_linesize = src_frame->linesize[plane] * 2;
156 int dstp_linesize = dst_frame->linesize[plane] * 2;185 int dstp_linesize = dst_frame->linesize[plane] * 2;
157 for (j = lines; j > 0; j--) {186 for (j = lines; j > 0; j--) {
@@ -165,6 +194,20 @@ static void copy_picture_field(InterlaceContext *s, · 7 unmodified lines
165 dstp += dstp_linesize;194 dstp += dstp_linesize;
166 srcp += srcp_linesize;195 srcp += srcp_linesize;
167 }196 }
197 } else if (lowpass == VLPF_CMP) {
198 int srcp_linesize = src_frame->linesize[plane] * 2;
199 int dstp_linesize = dst_frame->linesize[plane] * 2;
200 for (j = lines; j > 0; j--) {
201 ptrdiff_t pref = src_frame->linesize[plane];
202 ptrdiff_t mref = -pref;
203 if (j >= (lines - 1))
204 mref = 0;
205 else if (j <= 2)
206 pref = 0;
207 s->lowpass_line(dstp, cols, srcp, mref, pref);
208 dstp += dstp_linesize;
209 srcp += srcp_linesize;
210 }
168 } else {211 } else {
169 av_image_copy_plane(dstp, dst_frame->linesize[plane] * 2,212 av_image_copy_plane(dstp, dst_frame->linesize[plane] * 2,
170 srcp, src_frame->linesize[plane] * 2,213 srcp, src_frame->linesize[plane] * 2,
libavfilter/vf_tinterlace.c+50−11
@@ -1,4 +1,5 @@
1/*1/*
2 * Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
2 * Copyright (c) 2011 Stefano Sabatini3 * Copyright (c) 2011 Stefano Sabatini
3 * Copyright (c) 2010 Baptiste Coudurier4 * Copyright (c) 2010 Baptiste Coudurier
4 * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>5 * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>
@@ -34,8 +35,6 @@ · 29 unmodified lines
34 35
35#define OFFSET(x) offsetof(TInterlaceContext, x)36#define OFFSET(x) offsetof(TInterlaceContext, x)
36#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM37#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
37#define TINTERLACE_FLAG_VLPF 01
38#define TINTERLACE_FLAG_EXACT_TB 2
39 38
40static const AVOption tinterlace_options[] = {39static const AVOption tinterlace_options[] = {
41 {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},40 {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},
@@ -51,6 +50,8 @@ static const AVOption tinterlace_options[] = { · 9 unmodified lines
51 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },50 {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
52 {"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },51 {"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
53 {"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },52 {"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
53 {"complex_filter", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
54 {"cvlpf", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
54 {"exact_tb", "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },55 {"exact_tb", "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },
55 56
56 {NULL}57 {NULL}
@@ -102,6 +103,24 @@ static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, · 45 unmodified lines
102 }103 }
103}104}
104 105
106static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
107 ptrdiff_t mref, ptrdiff_t pref)
108{
109 const uint8_t *srcp_above = srcp + mref;
110 const uint8_t *srcp_below = srcp + pref;
111 const uint8_t *srcp_above2 = srcp + mref * 2;
112 const uint8_t *srcp_below2 = srcp + pref * 2;
113 int i;
114 for (i = 0; i < width; i++) {
115 // this calculation is an integer representation of
116 // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
117 // '4 +' is for rounding.
118 dstp[i] = av_clip_uint8((4 + (srcp[i] << 2)
119 + ((srcp[i] + srcp_above[i] + srcp_below[i]) << 1)
120 - srcp_above2[i] - srcp_below2[i]) >> 3);
121 }
122}
123
105static av_cold void uninit(AVFilterContext *ctx)124static av_cold void uninit(AVFilterContext *ctx)
106{125{
107 TInterlaceContext *tinterlace = ctx->priv;126 TInterlaceContext *tinterlace = ctx->priv;
@@ -144,12 +163,14 @@ static int config_out_props(AVFilterLink *outlink) · 36 unmodified lines
144 tinterlace->black_linesize[i] * h);163 tinterlace->black_linesize[i] * h);
145 }164 }
146 }165 }
147 if ((tinterlace->flags & TINTERLACE_FLAG_VLPF)166 if ((tinterlace->flags & TINTERLACE_FLAG_VLPF
167 || tinterlace->flags & TINTERLACE_FLAG_CVLPF)
148 && !(tinterlace->mode == MODE_INTERLEAVE_TOP168 && !(tinterlace->mode == MODE_INTERLEAVE_TOP
149 || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {169 || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {
150 av_log(ctx, AV_LOG_WARNING, "low_pass_filter flag ignored with mode %d\n",170 av_log(ctx, AV_LOG_WARNING, "low_pass_filter flags ignored with mode %d\n",
151 tinterlace->mode);171 tinterlace->mode);
152 tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;172 tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
173 tinterlace->flags &= ~TINTERLACE_FLAG_CVLPF;
153 }174 }
154 tinterlace->preout_time_base = inlink->time_base;175 tinterlace->preout_time_base = inlink->time_base;
155 if (tinterlace->mode == MODE_INTERLACEX2) {176 if (tinterlace->mode == MODE_INTERLACEX2) {
@@ -172,14 +193,19 @@ static int config_out_props(AVFilterLink *outlink) · 16 unmodified lines
172 (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))193 (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))
173 outlink->time_base = tinterlace->preout_time_base;194 outlink->time_base = tinterlace->preout_time_base;
174 195
175 if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {196 if (tinterlace->flags & TINTERLACE_FLAG_CVLPF) {
197 tinterlace->lowpass_line = lowpass_line_complex_c;
198 if (ARCH_X86)
199 ff_tinterlace_init_x86(tinterlace);
200 } else if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
176 tinterlace->lowpass_line = lowpass_line_c;201 tinterlace->lowpass_line = lowpass_line_c;
177 if (ARCH_X86)202 if (ARCH_X86)
178 ff_tinterlace_init_x86(tinterlace);203 ff_tinterlace_init_x86(tinterlace);
179 }204 }
180 205
181 av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",206 av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", tinterlace->mode,
182 tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off",207 (tinterlace->flags & TINTERLACE_FLAG_CVLPF) ? "complex" :
208 (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "linear" : "off",
183 inlink->h, outlink->h);209 inlink->h, outlink->h);
184 210
185 return 0;211 return 0;
@@ -223,10 +249,23 @@ void copy_picture_field(TInterlaceContext *tinterlace, · 37 unmodified lines
223 srcp += src_linesize[plane];249 srcp += src_linesize[plane];
224 if (interleave && dst_field == FIELD_LOWER)250 if (interleave && dst_field == FIELD_LOWER)
225 dstp += dst_linesize[plane];251 dstp += dst_linesize[plane];
226 if (flags & TINTERLACE_FLAG_VLPF) {252 // Low-pass filtering is required when creating an interlaced destination from
227 // Low-pass filtering is required when creating an interlaced destination from253 // a progressive source which contains high-frequency vertical detail.
228 // a progressive source which contains high-frequency vertical detail.254 // Filtering will reduce interlace 'twitter' and Moire patterning.
229 // Filtering will reduce interlace 'twitter' and Moire patterning.255 if (flags & TINTERLACE_FLAG_CVLPF) {
256 int srcp_linesize = src_linesize[plane] * k;
257 int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
258 for (h = lines; h > 0; h--) {
259 ptrdiff_t pref = src_linesize[plane];
260 ptrdiff_t mref = -pref;
261 if (h >= (lines - 1)) mref = 0;
262 else if (h <= 2) pref = 0;
263
264 tinterlace->lowpass_line(dstp, cols, srcp, mref, pref);
265 dstp += dstp_linesize;
266 srcp += srcp_linesize;
267 }
268 } else if (flags & TINTERLACE_FLAG_VLPF) {
230 int srcp_linesize = src_linesize[plane] * k;269 int srcp_linesize = src_linesize[plane] * k;
231 int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);270 int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
232 for (h = lines; h > 0; h--) {271 for (h = lines; h > 0; h--) {
libavfilter/x86/vf_interlace.asm+60−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
3;*3;*
4;* Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>4;* Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>
5;* Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>5;* Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>
6;* Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
6;*7;*
7;* This file is part of FFmpeg.8;* This file is part of FFmpeg.
8;*9;*
@@ -25,6 +26,8 @@ · 16 unmodified lines
25 26
26SECTION_RODATA27SECTION_RODATA
27 28
29pw_4: times 8 dw 4
30
28SECTION .text31SECTION .text
29 32
30%macro LOWPASS_LINE 033%macro LOWPASS_LINE 0
@@ -56,6 +59,60 @@ cglobal lowpass_line, 5, 5, 7, dst, h, src, mref, pref · 25 unmodified lines
56 add hq, 2*mmsize59 add hq, 2*mmsize
57 jl .loop60 jl .loop
58REP_RET61REP_RET
62
63%endmacro
64
65%macro LOWPASS_LINE_COMPLEX 0
66cglobal lowpass_line_complex, 5, 5, 7, dst, h, src, mref, pref
67 pxor m6, m6
68.loop:
69 mova m0, [srcq+mrefq]
70 mova m2, [srcq+prefq]
71 mova m1, m0
72 mova m3, m2
73 punpcklbw m0, m6
74 punpcklbw m2, m6
75 punpckhbw m1, m6
76 punpckhbw m3, m6
77 paddw m0, m2
78 paddw m1, m3
79 mova m2, [srcq+mrefq*2]
80 mova m4, [srcq+prefq*2]
81 mova m3, m2
82 mova m5, m4
83 punpcklbw m2, m6
84 punpcklbw m4, m6
85 punpckhbw m3, m6
86 punpckhbw m5, m6
87 paddw m2, m4
88 paddw m3, m5
89 mova m4, [srcq]
90 mova m5, m4
91 punpcklbw m4, m6
92 punpckhbw m5, m6
93 paddw m0, m4
94 paddw m1, m5
95 psllw m0, 1
96 psllw m1, 1
97 psllw m4, 2
98 psllw m5, 2
99 paddw m0, m4
100 paddw m1, m5
101 paddw m0, [pw_4]
102 paddw m1, [pw_4]
103 psubusw m0, m2
104 psubusw m1, m3
105 psrlw m0, 3
106 psrlw m1, 3
107 packuswb m0, m1
108 mova [dstq], m0
109
110 add dstq, mmsize
111 add srcq, mmsize
112 sub hd, mmsize
113 jg .loop
114REP_RET
115
59%endmacro116%endmacro
60 117
61INIT_XMM sse2118INIT_XMM sse2
@@ -63,3 +120,6 @@ LOWPASS_LINE · 1 unmodified line
63 120
64INIT_XMM avx121INIT_XMM avx
65LOWPASS_LINE122LOWPASS_LINE
123
124INIT_XMM sse2
125LOWPASS_LINE_COMPLEX
libavfilter/x86/vf_interlace_init.c+12−3
@@ -33,12 +33,21 @@ void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize, · 32 unmodified lines
33 const uint8_t *srcp,33 const uint8_t *srcp,
34 ptrdiff_t mref, ptrdiff_t pref);34 ptrdiff_t mref, ptrdiff_t pref);
35 35
36void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize,
37 const uint8_t *srcp,
38 ptrdiff_t mref, ptrdiff_t pref);
39
36av_cold void ff_interlace_init_x86(InterlaceContext *s)40av_cold void ff_interlace_init_x86(InterlaceContext *s)
37{41{
38 int cpu_flags = av_get_cpu_flags();42 int cpu_flags = av_get_cpu_flags();
39 43
40 if (EXTERNAL_SSE2(cpu_flags))44 if (EXTERNAL_SSE2(cpu_flags)) {
41 s->lowpass_line = ff_lowpass_line_sse2;45 if (s->lowpass == VLPF_LIN)
46 s->lowpass_line = ff_lowpass_line_sse2;
47 else if (s->lowpass == VLPF_CMP)
48 s->lowpass_line = ff_lowpass_line_complex_sse2;
49 }
42 if (EXTERNAL_AVX(cpu_flags))50 if (EXTERNAL_AVX(cpu_flags))
43 s->lowpass_line = ff_lowpass_line_avx;51 if (s->lowpass == VLPF_LIN)
52 s->lowpass_line = ff_lowpass_line_avx;
44}53}
libavfilter/x86/vf_tinterlace_init.c+12−3
@@ -34,12 +34,21 @@ void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize, · 33 unmodified lines
34 const uint8_t *srcp,34 const uint8_t *srcp,
35 ptrdiff_t mref, ptrdiff_t pref);35 ptrdiff_t mref, ptrdiff_t pref);
36 36
37void ff_lowpass_line_complex_sse2(uint8_t *dstp, ptrdiff_t linesize,
38 const uint8_t *srcp,
39 ptrdiff_t mref, ptrdiff_t pref);
40
37av_cold void ff_tinterlace_init_x86(TInterlaceContext *s)41av_cold void ff_tinterlace_init_x86(TInterlaceContext *s)
38{42{
39 int cpu_flags = av_get_cpu_flags();43 int cpu_flags = av_get_cpu_flags();
40 44
41 if (EXTERNAL_SSE2(cpu_flags))45 if (EXTERNAL_SSE2(cpu_flags)) {
42 s->lowpass_line = ff_lowpass_line_sse2;46 if (!(s->flags & TINTERLACE_FLAG_CVLPF))
47 s->lowpass_line = ff_lowpass_line_sse2;
48 else
49 s->lowpass_line = ff_lowpass_line_complex_sse2;
50 }
43 if (EXTERNAL_AVX(cpu_flags))51 if (EXTERNAL_AVX(cpu_flags))
44 s->lowpass_line = ff_lowpass_line_avx;52 if (!(s->flags & TINTERLACE_FLAG_CVLPF))
53 s->lowpass_line = ff_lowpass_line_avx;
45}54}
tests/fate/filter-video.mak+3−0
@@ -123,6 +123,9 @@ fate-filter-hqdn3d: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf hqdn3d · 122 unmodified lines
123FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace123FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace
124fate-filter-interlace: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace124fate-filter-interlace: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace
125 125
126FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace-complex
127fate-filter-interlace-complex: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=lowpass=complex
128
126FATE_FILTER_VSYNTH-$(call ALLYES, NEGATE_FILTER PERMS_FILTER) += fate-filter-negate129FATE_FILTER_VSYNTH-$(call ALLYES, NEGATE_FILTER PERMS_FILTER) += fate-filter-negate
127fate-filter-negate: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf perms=random,negate130fate-filter-negate: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf perms=random,negate
128 131
tests/ref/fate/filter-interlace-complex+30−0
@@ -0,0 +1,30 @@
1#tb 0: 2/25
2#media_type 0: video
3#codec_id 0: rawvideo
4#dimensions 0: 352x288
5#sar 0: 0/1
60, 0, 0, 1, 152064, 0x91290ae6
70, 1, 1, 1, 152064, 0x24f34baf
80, 2, 2, 1, 152064, 0x799fc436
90, 3, 3, 1, 152064, 0xfe42c0a9
100, 4, 4, 1, 152064, 0xb496f879
110, 5, 5, 1, 152064, 0xc43b36c9
120, 6, 6, 1, 152064, 0xb65abbf4
130, 7, 7, 1, 152064, 0xd1806312
140, 8, 8, 1, 152064, 0x0faf56c1
150, 9, 9, 1, 152064, 0x4de73b75
160, 10, 10, 1, 152064, 0xf90f24ce
170, 11, 11, 1, 152064, 0xc1efd6e0
180, 12, 12, 1, 152064, 0xeb8e5894
190, 13, 13, 1, 152064, 0xe8aacabc
200, 14, 14, 1, 152064, 0x8bd2163c
210, 15, 15, 1, 152064, 0xbfc72ac2
220, 16, 16, 1, 152064, 0x1e8f6f56
230, 17, 17, 1, 152064, 0xe3d19450
240, 18, 18, 1, 152064, 0x3872af32
250, 19, 19, 1, 152064, 0xf23be72a
260, 20, 20, 1, 152064, 0x024f8f2b
270, 21, 21, 1, 152064, 0xb49301ea
280, 22, 22, 1, 152064, 0x84f5d056
290, 23, 23, 1, 152064, 0xd2c09ca5
300, 24, 24, 1, 152064, 0xe9b5ddfd

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t