Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2017/07/04 00:42:03... | ... |
@@ -26,6 +26,7 @@ version <next>: |
26 | 26 |
--x86asmexe=yasm to configure to restore the old behavior. |
27 | 27 |
- additional frame format support for Interplay MVE movies |
28 | 28 |
- support for decoding through D3D11VA in ffmpeg |
29 |
+- limiter video filter |
|
29 | 30 |
|
30 | 31 |
version 3.3: |
31 | 32 |
- CrystalHD decoder moved to new decode API |
... | ... |
@@ -9639,6 +9639,23 @@ The formula that generates the correction is: |
9639 | 9639 |
where @var{r_0} is halve of the image diagonal and @var{r_src} and @var{r_tgt} are the |
9640 | 9640 |
distances from the focal point in the source and target images, respectively. |
9641 | 9641 |
|
9642 |
+@section limiter |
|
9643 |
+ |
|
9644 |
+Limits the pixel components values to the specified range [min, max]. |
|
9645 |
+ |
|
9646 |
+The filter accepts the following options: |
|
9647 |
+ |
|
9648 |
+@table @option |
|
9649 |
+@item min |
|
9650 |
+Lower bound. Defaults to the lowest allowed value for the input. |
|
9651 |
+ |
|
9652 |
+@item max |
|
9653 |
+Upper bound. Defaults to the highest allowed value for the input. |
|
9654 |
+ |
|
9655 |
+@item planes |
|
9656 |
+Specify which planes will be processed. Defaults to all available. |
|
9657 |
+@end table |
|
9658 |
+ |
|
9642 | 9659 |
@section loop |
9643 | 9660 |
|
9644 | 9661 |
Loop video frames. |
... | ... |
@@ -216,6 +216,7 @@ OBJS-$(CONFIG_INTERLACE_FILTER) += vf_interlace.o |
216 | 216 |
OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o |
217 | 217 |
OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o |
218 | 218 |
OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o |
219 |
+OBJS-$(CONFIG_LIMITER_FILTER) += vf_limiter.o |
|
219 | 220 |
OBJS-$(CONFIG_LOOP_FILTER) += f_loop.o |
220 | 221 |
OBJS-$(CONFIG_LUMAKEY_FILTER) += vf_lumakey.o |
221 | 222 |
OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o |
... | ... |
@@ -228,6 +228,7 @@ static void register_all(void) |
228 | 228 |
REGISTER_FILTER(INTERLEAVE, interleave, vf); |
229 | 229 |
REGISTER_FILTER(KERNDEINT, kerndeint, vf); |
230 | 230 |
REGISTER_FILTER(LENSCORRECTION, lenscorrection, vf); |
231 |
+ REGISTER_FILTER(LIMITER, limiter, vf); |
|
231 | 232 |
REGISTER_FILTER(LOOP, loop, vf); |
232 | 233 |
REGISTER_FILTER(LUMAKEY, lumakey, vf); |
233 | 234 |
REGISTER_FILTER(LUT, lut, vf); |
234 | 235 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,33 @@ |
0 |
+/* |
|
1 |
+ * This file is part of FFmpeg. |
|
2 |
+ * |
|
3 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#ifndef AVFILTER_LIMITER_H |
|
19 |
+#define AVFILTER_LIMITER_H |
|
20 |
+ |
|
21 |
+#include <stddef.h> |
|
22 |
+#include <stdint.h> |
|
23 |
+ |
|
24 |
+typedef struct LimiterDSPContext { |
|
25 |
+ void (*limiter)(const uint8_t *src, uint8_t *dst, |
|
26 |
+ ptrdiff_t slinesize, ptrdiff_t dlinesize, |
|
27 |
+ int w, int h, int min, int max); |
|
28 |
+} LimiterDSPContext; |
|
29 |
+ |
|
30 |
+void ff_limiter_init_x86(LimiterDSPContext *dsp, int bpp); |
|
31 |
+ |
|
32 |
+#endif /* AVFILTER_LIMITER_H */ |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
#include "libavutil/version.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFILTER_VERSION_MAJOR 6 |
33 |
-#define LIBAVFILTER_VERSION_MINOR 94 |
|
33 |
+#define LIBAVFILTER_VERSION_MINOR 95 |
|
34 | 34 |
#define LIBAVFILTER_VERSION_MICRO 100 |
35 | 35 |
|
36 | 36 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
37 | 37 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,231 @@ |
0 |
+/* |
|
1 |
+ * This file is part of FFmpeg. |
|
2 |
+ * |
|
3 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#include "libavutil/attributes.h" |
|
19 |
+#include "libavutil/common.h" |
|
20 |
+#include "libavutil/eval.h" |
|
21 |
+#include "libavutil/imgutils.h" |
|
22 |
+#include "libavutil/opt.h" |
|
23 |
+#include "libavutil/pixdesc.h" |
|
24 |
+#include "avfilter.h" |
|
25 |
+#include "formats.h" |
|
26 |
+#include "internal.h" |
|
27 |
+#include "limiter.h" |
|
28 |
+#include "video.h" |
|
29 |
+ |
|
30 |
+typedef struct LimiterContext { |
|
31 |
+ const AVClass *class; |
|
32 |
+ int min; |
|
33 |
+ int max; |
|
34 |
+ int planes; |
|
35 |
+ int nb_planes; |
|
36 |
+ int linesize[4]; |
|
37 |
+ int width[4]; |
|
38 |
+ int height[4]; |
|
39 |
+ |
|
40 |
+ LimiterDSPContext dsp; |
|
41 |
+} LimiterContext; |
|
42 |
+ |
|
43 |
+#define OFFSET(x) offsetof(LimiterContext, x) |
|
44 |
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
|
45 |
+ |
|
46 |
+static const AVOption limiter_options[] = { |
|
47 |
+ { "min", "set min value", OFFSET(min), AV_OPT_TYPE_INT, {.i64=0}, 0, 65535, .flags = FLAGS }, |
|
48 |
+ { "max", "set max value", OFFSET(max), AV_OPT_TYPE_INT, {.i64=65535}, 0, 65535, .flags = FLAGS }, |
|
49 |
+ { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15}, 0, 15, .flags = FLAGS }, |
|
50 |
+ { NULL } |
|
51 |
+}; |
|
52 |
+ |
|
53 |
+AVFILTER_DEFINE_CLASS(limiter); |
|
54 |
+ |
|
55 |
+static av_cold int init(AVFilterContext *ctx) |
|
56 |
+{ |
|
57 |
+ LimiterContext *s = ctx->priv; |
|
58 |
+ |
|
59 |
+ if (s->min > s->max) |
|
60 |
+ return AVERROR(EINVAL); |
|
61 |
+ return 0; |
|
62 |
+} |
|
63 |
+ |
|
64 |
+static int query_formats(AVFilterContext *ctx) |
|
65 |
+{ |
|
66 |
+ static const enum AVPixelFormat pix_fmts[] = { |
|
67 |
+ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, |
|
68 |
+ AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, |
|
69 |
+ AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, |
|
70 |
+ AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, |
|
71 |
+ AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, |
|
72 |
+ AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, |
|
73 |
+ AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, |
|
74 |
+ AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, |
|
75 |
+ AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, |
|
76 |
+ AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, |
|
77 |
+ AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, |
|
78 |
+ AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, |
|
79 |
+ AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, |
|
80 |
+ AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, |
|
81 |
+ AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, |
|
82 |
+ AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, |
|
83 |
+ AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, |
|
84 |
+ AV_PIX_FMT_NONE |
|
85 |
+ }; |
|
86 |
+ |
|
87 |
+ AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); |
|
88 |
+ if (!fmts_list) |
|
89 |
+ return AVERROR(ENOMEM); |
|
90 |
+ return ff_set_common_formats(ctx, fmts_list); |
|
91 |
+} |
|
92 |
+ |
|
93 |
+static void limiter8(const uint8_t *src, uint8_t *dst, |
|
94 |
+ ptrdiff_t slinesize, ptrdiff_t dlinesize, |
|
95 |
+ int w, int h, int min, int max) |
|
96 |
+{ |
|
97 |
+ int x, y; |
|
98 |
+ |
|
99 |
+ for (y = 0; y < h; y++) { |
|
100 |
+ for (x = 0; x < w; x++) { |
|
101 |
+ dst[x] = av_clip(src[x], min, max); |
|
102 |
+ } |
|
103 |
+ |
|
104 |
+ dst += dlinesize; |
|
105 |
+ src += slinesize; |
|
106 |
+ } |
|
107 |
+} |
|
108 |
+ |
|
109 |
+static void limiter16(const uint8_t *ssrc, uint8_t *ddst, |
|
110 |
+ ptrdiff_t slinesize, ptrdiff_t dlinesize, |
|
111 |
+ int w, int h, int min, int max) |
|
112 |
+{ |
|
113 |
+ const uint16_t *src = (const uint16_t *)ssrc; |
|
114 |
+ uint16_t *dst = (uint16_t *)ddst; |
|
115 |
+ int x, y; |
|
116 |
+ |
|
117 |
+ dlinesize /= 2; |
|
118 |
+ slinesize /= 2; |
|
119 |
+ |
|
120 |
+ for (y = 0; y < h; y++) { |
|
121 |
+ for (x = 0; x < w; x++) { |
|
122 |
+ dst[x] = av_clip(src[x], min, max); |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ dst += dlinesize; |
|
126 |
+ src += slinesize; |
|
127 |
+ } |
|
128 |
+} |
|
129 |
+ |
|
130 |
+static int config_props(AVFilterLink *inlink) |
|
131 |
+{ |
|
132 |
+ AVFilterContext *ctx = inlink->dst; |
|
133 |
+ LimiterContext *s = ctx->priv; |
|
134 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
|
135 |
+ int vsub, hsub, ret; |
|
136 |
+ |
|
137 |
+ s->nb_planes = av_pix_fmt_count_planes(inlink->format); |
|
138 |
+ |
|
139 |
+ if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) |
|
140 |
+ return ret; |
|
141 |
+ |
|
142 |
+ hsub = desc->log2_chroma_w; |
|
143 |
+ vsub = desc->log2_chroma_h; |
|
144 |
+ s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub); |
|
145 |
+ s->height[0] = s->height[3] = inlink->h; |
|
146 |
+ s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); |
|
147 |
+ s->width[0] = s->width[3] = inlink->w; |
|
148 |
+ |
|
149 |
+ if (desc->comp[0].depth == 8) { |
|
150 |
+ s->dsp.limiter = limiter8; |
|
151 |
+ s->max = FFMIN(s->max, 255); |
|
152 |
+ s->min = FFMIN(s->min, 255); |
|
153 |
+ } else { |
|
154 |
+ s->dsp.limiter = limiter16; |
|
155 |
+ } |
|
156 |
+ |
|
157 |
+ if (ARCH_X86) |
|
158 |
+ ff_limiter_init_x86(&s->dsp, desc->comp[0].depth); |
|
159 |
+ |
|
160 |
+ return 0; |
|
161 |
+} |
|
162 |
+ |
|
163 |
+static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
|
164 |
+{ |
|
165 |
+ AVFilterContext *ctx = inlink->dst; |
|
166 |
+ LimiterContext *s = ctx->priv; |
|
167 |
+ AVFilterLink *outlink = ctx->outputs[0]; |
|
168 |
+ AVFrame *out; |
|
169 |
+ int p; |
|
170 |
+ |
|
171 |
+ if (av_frame_is_writable(in)) { |
|
172 |
+ out = in; |
|
173 |
+ } else { |
|
174 |
+ out = ff_get_video_buffer(outlink, outlink->w, outlink->h); |
|
175 |
+ if (!out) { |
|
176 |
+ av_frame_free(&in); |
|
177 |
+ return AVERROR(ENOMEM); |
|
178 |
+ } |
|
179 |
+ av_frame_copy_props(out, in); |
|
180 |
+ } |
|
181 |
+ |
|
182 |
+ for (p = 0; p < s->nb_planes; p++) { |
|
183 |
+ if (!((1 << p) & s->planes)) { |
|
184 |
+ if (out != in) |
|
185 |
+ av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], |
|
186 |
+ s->linesize[p], s->height[p]); |
|
187 |
+ continue; |
|
188 |
+ } |
|
189 |
+ |
|
190 |
+ s->dsp.limiter(in->data[p], out->data[p], |
|
191 |
+ in->linesize[p], out->linesize[p], |
|
192 |
+ s->width[p], s->height[p], |
|
193 |
+ s->min, s->max); |
|
194 |
+ } |
|
195 |
+ |
|
196 |
+ if (out != in) |
|
197 |
+ av_frame_free(&in); |
|
198 |
+ |
|
199 |
+ return ff_filter_frame(outlink, out); |
|
200 |
+} |
|
201 |
+ |
|
202 |
+static const AVFilterPad inputs[] = { |
|
203 |
+ { |
|
204 |
+ .name = "default", |
|
205 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
206 |
+ .filter_frame = filter_frame, |
|
207 |
+ .config_props = config_props, |
|
208 |
+ }, |
|
209 |
+ { NULL } |
|
210 |
+}; |
|
211 |
+ |
|
212 |
+static const AVFilterPad outputs[] = { |
|
213 |
+ { |
|
214 |
+ .name = "default", |
|
215 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
216 |
+ }, |
|
217 |
+ { NULL } |
|
218 |
+}; |
|
219 |
+ |
|
220 |
+AVFilter ff_vf_limiter = { |
|
221 |
+ .name = "limiter", |
|
222 |
+ .description = NULL_IF_CONFIG_SMALL("Limit pixels components to the specified range."), |
|
223 |
+ .priv_size = sizeof(LimiterContext), |
|
224 |
+ .priv_class = &limiter_class, |
|
225 |
+ .init = init, |
|
226 |
+ .query_formats = query_formats, |
|
227 |
+ .inputs = inputs, |
|
228 |
+ .outputs = outputs, |
|
229 |
+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, |
|
230 |
+}; |
... | ... |
@@ -8,6 +8,7 @@ OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun_init.o |
8 | 8 |
OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d_init.o |
9 | 9 |
OBJS-$(CONFIG_IDET_FILTER) += x86/vf_idet_init.o |
10 | 10 |
OBJS-$(CONFIG_INTERLACE_FILTER) += x86/vf_interlace_init.o |
11 |
+OBJS-$(CONFIG_LIMITER_FILTER) += x86/vf_limiter_init.o |
|
11 | 12 |
OBJS-$(CONFIG_MASKEDMERGE_FILTER) += x86/vf_maskedmerge_init.o |
12 | 13 |
OBJS-$(CONFIG_NOISE_FILTER) += x86/vf_noise.o |
13 | 14 |
OBJS-$(CONFIG_PP7_FILTER) += x86/vf_pp7_init.o |
... | ... |
@@ -33,6 +34,7 @@ X86ASM-OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun.o |
33 | 33 |
X86ASM-OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d.o |
34 | 34 |
X86ASM-OBJS-$(CONFIG_IDET_FILTER) += x86/vf_idet.o |
35 | 35 |
X86ASM-OBJS-$(CONFIG_INTERLACE_FILTER) += x86/vf_interlace.o |
36 |
+X86ASM-OBJS-$(CONFIG_LIMITER_FILTER) += x86/vf_limiter.o |
|
36 | 37 |
X86ASM-OBJS-$(CONFIG_MASKEDMERGE_FILTER) += x86/vf_maskedmerge.o |
37 | 38 |
X86ASM-OBJS-$(CONFIG_PP7_FILTER) += x86/vf_pp7.o |
38 | 39 |
X86ASM-OBJS-$(CONFIG_PSNR_FILTER) += x86/vf_psnr.o |
39 | 40 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,84 @@ |
0 |
+;***************************************************************************** |
|
1 |
+;* x86-optimized functions for limiter filter |
|
2 |
+;* |
|
3 |
+;* This file is part of FFmpeg. |
|
4 |
+;* |
|
5 |
+;* FFmpeg is free software; you can redistribute it and/or |
|
6 |
+;* modify it under the terms of the GNU Lesser General Public |
|
7 |
+;* License as published by the Free Software Foundation; either |
|
8 |
+;* version 2.1 of the License, or (at your option) any later version. |
|
9 |
+;* |
|
10 |
+;* FFmpeg is distributed in the hope that it will be useful, |
|
11 |
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 |
+;* Lesser General Public License for more details. |
|
14 |
+;* |
|
15 |
+;* You should have received a copy of the GNU Lesser General Public |
|
16 |
+;* License along with FFmpeg; if not, write to the Free Software |
|
17 |
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
18 |
+;****************************************************************************** |
|
19 |
+ |
|
20 |
+%include "libavutil/x86/x86util.asm" |
|
21 |
+ |
|
22 |
+%if ARCH_X86_64 |
|
23 |
+ |
|
24 |
+SECTION_RODATA |
|
25 |
+ |
|
26 |
+pb_0: times 16 db 0 |
|
27 |
+ |
|
28 |
+SECTION .text |
|
29 |
+ |
|
30 |
+INIT_XMM sse2 |
|
31 |
+ |
|
32 |
+cglobal limiter_8bit, 8, 9, 3, src, dst, slinesize, dlinesize, w, h, min, max, x |
|
33 |
+ movsxdifnidn wq, wd |
|
34 |
+ add srcq, wq |
|
35 |
+ add dstq, wq |
|
36 |
+ neg wq |
|
37 |
+ SPLATB_REG m1, min, [pb_0] |
|
38 |
+ SPLATB_REG m2, max, [pb_0] |
|
39 |
+.nextrow: |
|
40 |
+ mov xq, wq |
|
41 |
+ |
|
42 |
+ .loop: |
|
43 |
+ movu m0, [srcq + xq] |
|
44 |
+ CLIPUB m0, m1, m2 |
|
45 |
+ mova [dstq+xq], m0 |
|
46 |
+ add xq, mmsize |
|
47 |
+ jl .loop |
|
48 |
+ |
|
49 |
+ add srcq, slinesizeq |
|
50 |
+ add dstq, dlinesizeq |
|
51 |
+ sub hd, 1 |
|
52 |
+ jg .nextrow |
|
53 |
+ ret |
|
54 |
+ |
|
55 |
+INIT_XMM sse4 |
|
56 |
+ |
|
57 |
+cglobal limiter_16bit, 8, 9, 3, src, dst, slinesize, dlinesize, w, h, min, max, x |
|
58 |
+ shl wd, 1 |
|
59 |
+ add srcq, wq |
|
60 |
+ add dstq, wq |
|
61 |
+ neg wq |
|
62 |
+ movd m1, mind |
|
63 |
+ SPLATW m1, m1 |
|
64 |
+ movd m2, maxd |
|
65 |
+ SPLATW m2, m2 |
|
66 |
+.nextrow: |
|
67 |
+ mov xq, wq |
|
68 |
+ |
|
69 |
+ .loop: |
|
70 |
+ movu m0, [srcq + xq] |
|
71 |
+ pmaxuw m0, m1 |
|
72 |
+ pminuw m0, m2 |
|
73 |
+ mova [dstq+xq], m0 |
|
74 |
+ add xq, mmsize |
|
75 |
+ jl .loop |
|
76 |
+ |
|
77 |
+ add srcq, slinesizeq |
|
78 |
+ add dstq, dlinesizeq |
|
79 |
+ sub hd, 1 |
|
80 |
+ jg .nextrow |
|
81 |
+ ret |
|
82 |
+ |
|
83 |
+%endif |
0 | 84 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,44 @@ |
0 |
+/* |
|
1 |
+ * This file is part of FFmpeg. |
|
2 |
+ * |
|
3 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#include "libavutil/x86/cpu.h" |
|
19 |
+ |
|
20 |
+#include "libavfilter/limiter.h" |
|
21 |
+ |
|
22 |
+void ff_limiter_8bit_sse2(const uint8_t *src, uint8_t *dst, |
|
23 |
+ ptrdiff_t slinesize, ptrdiff_t dlinesize, |
|
24 |
+ int w, int h, int min, int max); |
|
25 |
+void ff_limiter_16bit_sse4(const uint8_t *src, uint8_t *dst, |
|
26 |
+ ptrdiff_t slinesize, ptrdiff_t dlinesize, |
|
27 |
+ int w, int h, int min, int max); |
|
28 |
+ |
|
29 |
+void ff_limiter_init_x86(LimiterDSPContext *dsp, int bpp) |
|
30 |
+{ |
|
31 |
+ int cpu_flags = av_get_cpu_flags(); |
|
32 |
+ |
|
33 |
+ if (ARCH_X86_64 && EXTERNAL_SSE2(cpu_flags)) { |
|
34 |
+ if (bpp <= 8) { |
|
35 |
+ dsp->limiter = ff_limiter_8bit_sse2; |
|
36 |
+ } |
|
37 |
+ } |
|
38 |
+ if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags)) { |
|
39 |
+ if (bpp > 8) { |
|
40 |
+ dsp->limiter = ff_limiter_16bit_sse4; |
|
41 |
+ } |
|
42 |
+ } |
|
43 |
+} |