FFmpeg
vf_blend_init.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/attributes.h"
22 #include "libavutil/cpu.h"
23 #include "libavutil/x86/cpu.h"
24 #include "libavfilter/blend.h"
25 
26 #define BLEND_FUNC(name, opt) \
27 void ff_blend_##name##_##opt(const uint8_t *top, ptrdiff_t top_linesize, \
28  const uint8_t *bottom, ptrdiff_t bottom_linesize, \
29  uint8_t *dst, ptrdiff_t dst_linesize, \
30  ptrdiff_t width, ptrdiff_t height, \
31  struct FilterParams *param, double *values, int starty);
32 
33 BLEND_FUNC(addition, sse2)
34 BLEND_FUNC(addition, avx2)
35 BLEND_FUNC(grainmerge, sse2)
36 BLEND_FUNC(grainmerge, avx2)
37 BLEND_FUNC(average, sse2)
38 BLEND_FUNC(average, avx2)
39 BLEND_FUNC(and, sse2)
40 BLEND_FUNC(and, avx2)
41 BLEND_FUNC(darken, sse2)
42 BLEND_FUNC(darken, avx2)
43 BLEND_FUNC(grainextract, sse2)
44 BLEND_FUNC(grainextract, avx2)
45 BLEND_FUNC(multiply, sse2)
46 BLEND_FUNC(multiply, avx2)
47 BLEND_FUNC(screen, sse2)
48 BLEND_FUNC(screen, avx2)
49 BLEND_FUNC(hardmix, sse2)
50 BLEND_FUNC(hardmix, avx2)
51 BLEND_FUNC(divide, sse2)
52 BLEND_FUNC(lighten, sse2)
53 BLEND_FUNC(lighten, avx2)
54 BLEND_FUNC(or, sse2)
55 BLEND_FUNC(or, avx2)
56 BLEND_FUNC(phoenix, sse2)
57 BLEND_FUNC(phoenix, avx2)
58 BLEND_FUNC(subtract, sse2)
59 BLEND_FUNC(subtract, avx2)
60 BLEND_FUNC(xor, sse2)
61 BLEND_FUNC(xor, avx2)
63 BLEND_FUNC(difference, ssse3)
65 BLEND_FUNC(extremity, sse2)
66 BLEND_FUNC(extremity, ssse3)
67 BLEND_FUNC(extremity, avx2)
68 BLEND_FUNC(negation, sse2)
69 BLEND_FUNC(negation, ssse3)
70 BLEND_FUNC(negation, avx2)
71 
72 #if ARCH_X86_64
73 BLEND_FUNC(addition_16, sse2)
74 BLEND_FUNC(addition_16, avx2)
75 BLEND_FUNC(grainmerge_16, sse4)
76 BLEND_FUNC(grainmerge_16, avx2)
77 BLEND_FUNC(average_16, sse2)
78 BLEND_FUNC(average_16, avx2)
79 BLEND_FUNC(and_16, sse2)
80 BLEND_FUNC(and_16, avx2)
81 BLEND_FUNC(darken_16, sse4)
82 BLEND_FUNC(darken_16, avx2)
83 BLEND_FUNC(grainextract_16, sse4)
84 BLEND_FUNC(grainextract_16, avx2)
85 BLEND_FUNC(difference_16, sse4)
86 BLEND_FUNC(difference_16, avx2)
87 BLEND_FUNC(extremity_16, sse4)
88 BLEND_FUNC(extremity_16, avx2)
89 BLEND_FUNC(negation_16, sse4)
90 BLEND_FUNC(negation_16, avx2)
91 BLEND_FUNC(lighten_16, sse4)
92 BLEND_FUNC(lighten_16, avx2)
93 BLEND_FUNC(or_16, sse2)
94 BLEND_FUNC(or_16, avx2)
95 BLEND_FUNC(phoenix_16, sse4)
96 BLEND_FUNC(phoenix_16, avx2)
97 BLEND_FUNC(subtract_16, sse2)
98 BLEND_FUNC(subtract_16, avx2)
99 BLEND_FUNC(xor_16, sse2)
100 BLEND_FUNC(xor_16, avx2)
101 #endif /* ARCH_X86_64 */
102 
103 av_cold void ff_blend_init_x86(FilterParams *param, int depth)
104 {
105  int cpu_flags = av_get_cpu_flags();
106 
107  if (depth == 8) {
108  if (EXTERNAL_SSE2(cpu_flags) && param->opacity == 1) {
109  switch (param->mode) {
110  case BLEND_ADDITION: param->blend = ff_blend_addition_sse2; break;
111  case BLEND_GRAINMERGE: param->blend = ff_blend_grainmerge_sse2; break;
112  case BLEND_AND: param->blend = ff_blend_and_sse2; break;
113  case BLEND_AVERAGE: param->blend = ff_blend_average_sse2; break;
114  case BLEND_DARKEN: param->blend = ff_blend_darken_sse2; break;
115  case BLEND_GRAINEXTRACT: param->blend = ff_blend_grainextract_sse2; break;
116  case BLEND_DIVIDE: param->blend = ff_blend_divide_sse2; break;
117  case BLEND_HARDMIX: param->blend = ff_blend_hardmix_sse2; break;
118  case BLEND_LIGHTEN: param->blend = ff_blend_lighten_sse2; break;
119  case BLEND_MULTIPLY: param->blend = ff_blend_multiply_sse2; break;
120  case BLEND_OR: param->blend = ff_blend_or_sse2; break;
121  case BLEND_PHOENIX: param->blend = ff_blend_phoenix_sse2; break;
122  case BLEND_SCREEN: param->blend = ff_blend_screen_sse2; break;
123  case BLEND_SUBTRACT: param->blend = ff_blend_subtract_sse2; break;
124  case BLEND_XOR: param->blend = ff_blend_xor_sse2; break;
125  case BLEND_DIFFERENCE: param->blend = ff_blend_difference_sse2; break;
126  case BLEND_EXTREMITY: param->blend = ff_blend_extremity_sse2; break;
127  case BLEND_NEGATION: param->blend = ff_blend_negation_sse2; break;
128  }
129  }
130  if (EXTERNAL_SSSE3(cpu_flags) && param->opacity == 1) {
131  switch (param->mode) {
132  case BLEND_DIFFERENCE: param->blend = ff_blend_difference_ssse3; break;
133  case BLEND_EXTREMITY: param->blend = ff_blend_extremity_ssse3; break;
134  case BLEND_NEGATION: param->blend = ff_blend_negation_ssse3; break;
135  }
136  }
137 
138  if (EXTERNAL_AVX2_FAST(cpu_flags) && param->opacity == 1) {
139  switch (param->mode) {
140  case BLEND_ADDITION: param->blend = ff_blend_addition_avx2; break;
141  case BLEND_GRAINMERGE: param->blend = ff_blend_grainmerge_avx2; break;
142  case BLEND_AND: param->blend = ff_blend_and_avx2; break;
143  case BLEND_AVERAGE: param->blend = ff_blend_average_avx2; break;
144  case BLEND_DARKEN: param->blend = ff_blend_darken_avx2; break;
145  case BLEND_GRAINEXTRACT: param->blend = ff_blend_grainextract_avx2; break;
146  case BLEND_HARDMIX: param->blend = ff_blend_hardmix_avx2; break;
147  case BLEND_LIGHTEN: param->blend = ff_blend_lighten_avx2; break;
148  case BLEND_MULTIPLY: param->blend = ff_blend_multiply_avx2; break;
149  case BLEND_OR: param->blend = ff_blend_or_avx2; break;
150  case BLEND_PHOENIX: param->blend = ff_blend_phoenix_avx2; break;
151  case BLEND_SCREEN: param->blend = ff_blend_screen_avx2; break;
152  case BLEND_SUBTRACT: param->blend = ff_blend_subtract_avx2; break;
153  case BLEND_XOR: param->blend = ff_blend_xor_avx2; break;
154  case BLEND_DIFFERENCE: param->blend = ff_blend_difference_avx2; break;
155  case BLEND_EXTREMITY: param->blend = ff_blend_extremity_avx2; break;
156  case BLEND_NEGATION: param->blend = ff_blend_negation_avx2; break;
157  }
158  }
159  } else if (depth == 16) {
160 #if ARCH_X86_64
161  if (EXTERNAL_SSE2(cpu_flags) && param->opacity == 1) {
162  switch (param->mode) {
163  case BLEND_ADDITION: param->blend = ff_blend_addition_16_sse2; break;
164  case BLEND_AND: param->blend = ff_blend_and_16_sse2; break;
165  case BLEND_AVERAGE: param->blend = ff_blend_average_16_sse2; break;
166  case BLEND_OR: param->blend = ff_blend_or_16_sse2; break;
167  case BLEND_SUBTRACT: param->blend = ff_blend_subtract_16_sse2; break;
168  case BLEND_XOR: param->blend = ff_blend_xor_16_sse2; break;
169  }
170  }
171  if (EXTERNAL_SSE4(cpu_flags) && param->opacity == 1) {
172  switch (param->mode) {
173  case BLEND_GRAINMERGE: param->blend = ff_blend_grainmerge_16_sse4; break;
174  case BLEND_DARKEN: param->blend = ff_blend_darken_16_sse4; break;
175  case BLEND_GRAINEXTRACT: param->blend = ff_blend_grainextract_16_sse4; break;
176  case BLEND_DIFFERENCE: param->blend = ff_blend_difference_16_sse4; break;
177  case BLEND_EXTREMITY: param->blend = ff_blend_extremity_16_sse4; break;
178  case BLEND_NEGATION: param->blend = ff_blend_negation_16_sse4; break;
179  case BLEND_LIGHTEN: param->blend = ff_blend_lighten_16_sse4; break;
180  case BLEND_PHOENIX: param->blend = ff_blend_phoenix_16_sse4; break;
181  }
182  }
183  if (EXTERNAL_AVX2_FAST(cpu_flags) && param->opacity == 1) {
184  switch (param->mode) {
185  case BLEND_ADDITION: param->blend = ff_blend_addition_16_avx2; break;
186  case BLEND_GRAINMERGE: param->blend = ff_blend_grainmerge_16_avx2; break;
187  case BLEND_AND: param->blend = ff_blend_and_16_avx2; break;
188  case BLEND_AVERAGE: param->blend = ff_blend_average_16_avx2; break;
189  case BLEND_DARKEN: param->blend = ff_blend_darken_16_avx2; break;
190  case BLEND_GRAINEXTRACT: param->blend = ff_blend_grainextract_16_avx2; break;
191  case BLEND_DIFFERENCE: param->blend = ff_blend_difference_16_avx2; break;
192  case BLEND_EXTREMITY: param->blend = ff_blend_extremity_16_avx2; break;
193  case BLEND_NEGATION: param->blend = ff_blend_negation_16_avx2; break;
194  case BLEND_LIGHTEN: param->blend = ff_blend_lighten_16_avx2; break;
195  case BLEND_OR: param->blend = ff_blend_or_16_avx2; break;
196  case BLEND_PHOENIX: param->blend = ff_blend_phoenix_16_avx2; break;
197  case BLEND_SUBTRACT: param->blend = ff_blend_subtract_16_avx2; break;
198  case BLEND_XOR: param->blend = ff_blend_xor_16_avx2; break;
199  }
200  }
201 #endif /* ARCH_X86_64 */
202  }
203 }
cpu.h
EXTERNAL_AVX2_FAST
#define EXTERNAL_AVX2_FAST(flags)
Definition: cpu.h:79
BLEND_NEGATION
@ BLEND_NEGATION
Definition: blend.h:43
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:98
BLEND_ADDITION
@ BLEND_ADDITION
Definition: blend.h:30
cpu_flags
static atomic_int cpu_flags
Definition: cpu.c:50
BLEND_DIVIDE
@ BLEND_DIVIDE
Definition: blend.h:37
BLEND_PHOENIX
@ BLEND_PHOENIX
Definition: blend.h:46
BLEND_AND
@ BLEND_AND
Definition: blend.h:31
av_cold
#define av_cold
Definition: attributes.h:90
BLEND_FUNC
#define BLEND_FUNC(name, opt)
Definition: vf_blend_init.c:26
BLEND_OR
@ BLEND_OR
Definition: blend.h:44
BLEND_SCREEN
@ BLEND_SCREEN
Definition: blend.h:49
multiply
static SoftFloat_IEEE754 multiply(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b)
multiply two softfloats and handle the rounding off
Definition: alsdec.c:1387
BLEND_EXTREMITY
@ BLEND_EXTREMITY
Definition: blend.h:61
FilterParams::mode
enum BlendMode mode
Definition: blend.h:73
BLEND_MULTIPLY
@ BLEND_MULTIPLY
Definition: blend.h:42
BLEND_SUBTRACT
@ BLEND_SUBTRACT
Definition: blend.h:51
ff_blend_init_x86
av_cold void ff_blend_init_x86(FilterParams *param, int depth)
Definition: vf_blend_init.c:103
FilterParams
filter data
Definition: mlp.h:75
BLEND_LIGHTEN
@ BLEND_LIGHTEN
Definition: blend.h:41
cpu.h
attributes.h
EXTERNAL_SSE2
#define EXTERNAL_SSE2(flags)
Definition: cpu.h:59
blend.h
BLEND_DIFFERENCE
@ BLEND_DIFFERENCE
Definition: blend.h:35
BLEND_HARDMIX
@ BLEND_HARDMIX
Definition: blend.h:54
BLEND_GRAINMERGE
@ BLEND_GRAINMERGE
Definition: blend.h:57
EXTERNAL_SSE4
#define EXTERNAL_SSE4(flags)
Definition: cpu.h:68
BLEND_XOR
@ BLEND_XOR
Definition: blend.h:53
BLEND_DARKEN
@ BLEND_DARKEN
Definition: blend.h:34
BLEND_AVERAGE
@ BLEND_AVERAGE
Definition: blend.h:32
FilterParams::opacity
double opacity
Definition: blend.h:74
FilterParams::blend
void(* blend)(const uint8_t *top, ptrdiff_t top_linesize, const uint8_t *bottom, ptrdiff_t bottom_linesize, uint8_t *dst, ptrdiff_t dst_linesize, ptrdiff_t width, ptrdiff_t height, struct FilterParams *param, double *values, int starty)
Definition: blend.h:77
difference
static void difference(IPlane *g, IPlane *f)
Definition: vf_morpho.c:493
EXTERNAL_SSSE3
#define EXTERNAL_SSSE3(flags)
Definition: cpu.h:65
BLEND_GRAINEXTRACT
@ BLEND_GRAINEXTRACT
Definition: blend.h:36