]> git.sesse.net Git - vlc/blob - contrib/src/libmpeg2/libmpeg2-mc-neon.patch
contrib: add libmpeg2
[vlc] / contrib / src / libmpeg2 / libmpeg2-mc-neon.patch
1 diff -ruN libmpeg2.orig//configure.ac libmpeg2/configure.ac
2 --- libmpeg2.orig//configure.ac 2011-11-06 22:25:07.273694621 -0500
3 +++ libmpeg2/configure.ac       2011-11-06 22:25:19.033752939 -0500
4 @@ -103,7 +103,14 @@
5         AC_DEFINE([ARCH_ALPHA],,[alpha architecture]);;
6      arm*)
7         arm_conditional=:
8 -       AC_DEFINE([ARCH_ARM],,[ARM architecture]);;
9 +       AC_DEFINE([ARCH_ARM],,[ARM architecture])
10 +        AC_MSG_CHECKING([if inline ARM Advanced SIMD assembly is supported])
11 +        AC_TRY_COMPILE([],
12 +           [asm ("vqmovun.s64 d0, q1":::"d0");],
13 +           [AC_DEFINE([ARCH_ARM_NEON],, [ARM Advanced SIMD assembly])
14 +            AC_MSG_RESULT(yes)],
15 +           [AC_MSG_RESULT(no)])
16 +        ;;
17      esac
18  elif test x"$CC" = x"tendracc"; then
19      dnl TenDRA portability checking compiler
20 diff -ruN libmpeg2.orig//include/mpeg2.h libmpeg2/include/mpeg2.h
21 --- libmpeg2.orig//include/mpeg2.h      2011-11-06 22:25:07.297694741 -0500
22 +++ libmpeg2/include/mpeg2.h    2011-11-06 22:25:19.025752913 -0500
23 @@ -164,6 +164,7 @@
24  #define MPEG2_ACCEL_SPARC_VIS 1
25  #define MPEG2_ACCEL_SPARC_VIS2 2
26  #define MPEG2_ACCEL_ARM 1
27 +#define MPEG2_ACCEL_ARM_NEON 2
28  #define MPEG2_ACCEL_DETECT 0x80000000
29  
30  uint32_t mpeg2_accel (uint32_t accel);
31 diff -ruN libmpeg2.orig//libmpeg2/Makefile.am libmpeg2/libmpeg2/Makefile.am
32 --- libmpeg2.orig//libmpeg2/Makefile.am 2011-11-06 22:25:07.289694707 -0500
33 +++ libmpeg2/libmpeg2/Makefile.am       2011-11-06 22:25:19.033752939 -0500
34 @@ -14,7 +14,7 @@
35                           motion_comp_vis.c motion_comp_arm.c \
36                           cpu_accel.c cpu_state.c
37  if ARCH_ARM
38 -libmpeg2arch_la_SOURCES += motion_comp_arm_s.S
39 +libmpeg2arch_la_SOURCES += motion_comp_arm_s.S motion_comp_neon.c
40  endif
41  libmpeg2arch_la_CFLAGS = $(OPT_CFLAGS) $(ARCH_OPT_CFLAGS) $(LIBMPEG2_CFLAGS)
42  
43 diff -ruN libmpeg2.orig//libmpeg2/motion_comp.c libmpeg2/libmpeg2/motion_comp.c
44 --- libmpeg2.orig//libmpeg2/motion_comp.c       2011-11-06 22:25:07.289694707 -0500
45 +++ libmpeg2/libmpeg2/motion_comp.c     2011-11-06 22:25:19.029752924 -0500
46 @@ -58,6 +58,11 @@
47      else
48  #endif
49  #ifdef ARCH_ARM
50 +#ifdef ARCH_ARM_NEON
51 +    if (accel & MPEG2_ACCEL_ARM_NEON)
52 +        mpeg2_mc = mpeg2_mc_neon;
53 +    else
54 +#endif
55      if (accel & MPEG2_ACCEL_ARM) {
56         mpeg2_mc = mpeg2_mc_arm;
57      } else
58 diff -ruN libmpeg2.orig//libmpeg2/motion_comp_neon.c libmpeg2/libmpeg2/motion_comp_neon.c
59 --- libmpeg2.orig//libmpeg2/motion_comp_neon.c  1969-12-31 19:00:00.000000000 -0500
60 +++ libmpeg2/libmpeg2/motion_comp_neon.c        2011-11-06 22:25:19.029752924 -0500
61 @@ -0,0 +1,302 @@
62 +/*
63 + * motion_comp_neon.c
64 + * Copyright (C) 2009 RĂ©mi Denis-Courmont
65 + *
66 + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
67 + * See http://libmpeg2.sourceforge.net/ for updates.
68 + *
69 + * mpeg2dec is free software; you can redistribute it and/or modify
70 + * it under the terms of the GNU General Public License as published by
71 + * the Free Software Foundation; either version 2 of the License, or
72 + * (at your option) any later version.
73 + *
74 + * mpeg2dec is distributed in the hope that it will be useful,
75 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
76 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
77 + * GNU General Public License for more details.
78 + *
79 + * You should have received a copy of the GNU General Public License along
80 + * with mpeg2dec; if not, write to the Free Software Foundation, Inc.,
81 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
82 + */
83 +
84 +#include "config.h"
85 +
86 +#if defined(ARCH_ARM_NEON)
87 +
88 +#include <stdint.h>
89 +#include <string.h>
90 +
91 +#include "mpeg2.h"
92 +#include "attributes.h"
93 +#include "mpeg2_internal.h"
94 +
95 +/* dest = ref */
96 +static void MC_put_o_16_neon (uint8_t * dest, const uint8_t * ref,
97 +                             const int stride, int height)
98 +{
99 +    do {
100 +       memcpy (dest, ref, 16);
101 +       ref += stride;
102 +       dest += stride;
103 +    } while (--height);
104 +}
105 +
106 +static void MC_put_o_8_neon (uint8_t * dest, const uint8_t * ref,
107 +                            const int stride, int height)
108 +{
109 +    do {
110 +       memcpy (dest, ref, 8);
111 +       ref += stride;
112 +       dest += stride;
113 +    } while (--height);
114 +}
115 +
116 +/* dest = (src1 + src2 + 1) / 2 */
117 +static void MC_avg_1_16_neon (uint8_t * dest, const uint8_t * src1,
118 +                             const uint8_t * src2,
119 +                             const int stride, unsigned height)
120 +{
121 +    do {
122 +       asm volatile (
123 +           "vld1.u8 {q0}, [%[src1]]\n"
124 +           "vld1.u8 {q1}, [%[src2]]\n"
125 +           "vrhadd.u8 q0, q0, q1\n"
126 +           /* XXX: three cycles stall */
127 +           "vst1.u8 {q0}, [%[dest]]\n"
128 +           :
129 +           : [dest]"r"(dest), [src1]"r"(src1), [src2]"r"(src2)
130 +           : "memory", "q0", "q1");
131 +       src1 += stride;
132 +       src2 += stride;
133 +       dest += stride;
134 +    } while (--height);
135 +}
136 +
137 +static void MC_avg_1_8_neon (uint8_t * dest, const uint8_t * src1,
138 +                            const uint8_t * src2,
139 +                            const int stride, unsigned height)
140 +{
141 +    do {
142 +       asm volatile (
143 +           "vld1.u8 {d0}, [%[src1]]\n"
144 +           "vld1.u8 {d1}, [%[src2]]\n"
145 +           "vrhadd.u8 d0, d0, d1\n"
146 +           "vst1.u8 {d0}, [%[dest]]\n"
147 +           :
148 +           : [dest]"r"(dest), [src1]"r"(src1), [src2]"r"(src2)
149 +           : "memory", "q0");
150 +       
151 +       src1 += stride;
152 +       src2 += stride;
153 +       dest += stride;
154 +    } while (--height);
155 +}
156 +
157 +/* dest = (dest + ((src1 + src2 + 1) / 2) + 1) / 2 */
158 +static void MC_avg_2_16_neon (uint8_t * dest, const uint8_t * src1,
159 +                             const uint8_t * src2,
160 +                             const int stride, unsigned height)
161 +{
162 +    do {
163 +       asm volatile (
164 +           "vld1.u8 {q0}, [%[src1]]\n"
165 +           "vld1.u8 {q1}, [%[src2]]\n"
166 +           "vrhadd.u8 q0, q0, q1\n"
167 +           "vld1.u8 {q2}, [%[dest]]\n"
168 +           /* XXX: one cycle stall */
169 +           "vrhadd.u8 q0, q0, q2\n"
170 +           /* XXX: three cycles stall */
171 +           "vst1.u8 {q0}, [%[dest]]\n"
172 +           :
173 +           : [dest]"r"(dest), [src1]"r"(src1), [src2]"r"(src2)
174 +           : "memory", "q0", "q1", "q2");
175 +       src1 += stride;
176 +       src2 += stride;
177 +       dest += stride;
178 +    } while (--height);
179 +}
180 +
181 +static void MC_avg_2_8_neon (uint8_t * dest, const uint8_t * src1,
182 +                            const uint8_t * src2,
183 +                            const int stride, unsigned height)
184 +{
185 +    do {
186 +       asm volatile (
187 +           "vld1.u8 {d0}, [%[src1]]\n"
188 +           "vld1.u8 {d1}, [%[src2]]\n"
189 +           "vrhadd.u8 d0, d0, d1\n"
190 +           "vld1.u8 {d2}, [%[dest]]\n"
191 +           "vrhadd.u8 d0, d0, d2\n"
192 +           "vst1.u8 {d0}, [%[dest]]\n"
193 +           :
194 +           : [dest]"r"(dest), [src1]"r"(src1), [src2]"r"(src2)
195 +           : "memory", "q0", "d2");
196 +       src1 += stride;
197 +       src2 += stride;
198 +       dest += stride;
199 +    } while (--height);
200 +}
201 +
202 +static void MC_avg_o_16_neon (uint8_t * dest, const uint8_t * ref,
203 +                             const int stride, int height)
204 +{
205 +    MC_avg_1_16_neon (dest, dest, ref, stride, height);
206 +}
207 +
208 +static void MC_avg_o_8_neon (uint8_t * dest, const uint8_t * ref,
209 +                            const int stride, int height)
210 +{
211 +    MC_avg_1_8_neon (dest, dest, ref, stride, height);
212 +}
213 +
214 +static void MC_put_x_16_neon (uint8_t * dest, const uint8_t * ref,
215 +                             const int stride, int height)
216 +{
217 +    MC_avg_1_16_neon (dest, ref, ref + 1, stride, height);
218 +}
219 +
220 +static void MC_put_x_8_neon (uint8_t * dest, const uint8_t * ref,
221 +                            const int stride, int height)
222 +{
223 +    MC_avg_1_8_neon (dest, ref, ref + 1, stride, height);
224 +}
225 +
226 +static void MC_avg_x_16_neon (uint8_t * dest, const uint8_t * ref,
227 +                             const int stride, int height)
228 +{
229 +    MC_avg_2_16_neon (dest, ref, ref + 1, stride, height);
230 +}
231 +
232 +static void MC_avg_x_8_neon (uint8_t * dest, const uint8_t * ref,
233 +                            const int stride, int height)
234 +{
235 +    MC_avg_2_8_neon (dest, ref, ref + 1, stride, height);
236 +}
237 +
238 +static void MC_put_y_16_neon (uint8_t * dest, const uint8_t * ref,
239 +                             const int stride, int height)
240 +{
241 +    MC_avg_1_16_neon (dest, ref, ref + stride, stride, height);
242 +}
243 +static void MC_put_y_8_neon (uint8_t * dest, const uint8_t * ref,
244 +                            const int stride, int height)
245 +{
246 +    MC_avg_1_8_neon (dest, ref, ref + stride, stride, height);
247 +}
248 +
249 +static void MC_avg_y_16_neon (uint8_t * dest, const uint8_t * ref,
250 +                             const int stride, int height)
251 +{
252 +    MC_avg_2_16_neon (dest, ref, ref + stride, stride, height);
253 +}
254 +
255 +static void MC_avg_y_8_neon (uint8_t * dest, const uint8_t * ref,
256 +                            const int stride, int height)
257 +{
258 +    MC_avg_2_8_neon (dest, ref, ref + stride, stride, height);
259 +}
260 +
261 +static void MC_put_xy_16_neon (uint8_t * dest, const uint8_t * ref,
262 +                              const int stride, int height)
263 +{
264 +    do {
265 +       asm volatile (
266 +           "vld1.u8 {q0}, [%[ref]]\n"
267 +           "vld1.u8 {q1}, [%[refx]]\n"
268 +           "vrhadd.u8 q0, q0, q1\n"
269 +           "vld1.u8 {q2}, [%[refy]]\n"
270 +           "vld1.u8 {q3}, [%[refxy]]\n"
271 +           "vrhadd.u8 q2, q2, q3\n"
272 +           /* XXX: three cycles stall */
273 +           "vrhadd.u8 q0, q0, q2\n"
274 +           /* XXX: three cycles stall */
275 +           "vst1.u8 {q0}, [%[dest]]\n"
276 +           :
277 +           : [dest]"r"(dest), [ref]"r"(ref), [refx]"r"(ref + 1),
278 +                      [refy]"r"(ref + stride), [refxy]"r"(ref + stride + 1)
279 +           : "memory", "q0", "q1", "q2", "q3");
280 +       ref += stride;
281 +       dest += stride;
282 +    } while (--height);
283 +}
284 +
285 +static void MC_put_xy_8_neon (uint8_t * dest, const uint8_t * ref,
286 +                             const int stride, int height)
287 +{
288 +    do {
289 +       asm volatile (
290 +           "vld1.u8 {d0}, [%[ref]]\n"
291 +           "vld1.u8 {d1}, [%[refx]]\n"
292 +           "vrhadd.u8 d0, d0, d1\n"
293 +           "vld1.u8 {d2}, [%[refy]]\n"
294 +           "vld1.u8 {d3}, [%[refxy]]\n"
295 +           "vrhadd.u8 d2, d2, d3\n"
296 +           /* XXX: three cycles stall */
297 +           "vrhadd.u8 d0, d0, d2\n"
298 +           /* XXX: three cycles stall */
299 +           "vst1.u8 {d0}, [%[dest]]\n"
300 +           :
301 +           : [dest]"r"(dest), [ref]"r"(ref), [refx]"r"(ref + 1),
302 +                      [refy]"r"(ref + stride), [refxy]"r"(ref + stride + 1)
303 +           : "memory", "q0", "q1");
304 +       ref += stride;
305 +       dest += stride;
306 +    } while (--height);
307 +}
308 +
309 +static void MC_avg_xy_16_neon (uint8_t * dest, const uint8_t * ref,
310 +                              const int stride, int height)
311 +{
312 +    do {
313 +       asm volatile (
314 +           "vld1.u8 {q0}, [%[ref]]\n"
315 +           "vld1.u8 {q1}, [%[refx]]\n"
316 +           "vrhadd.u8 q0, q0, q1\n"
317 +           "vld1.u8 {q2}, [%[refy]]\n"
318 +           "vld1.u8 {q3}, [%[refxy]]\n"
319 +           "vrhadd.u8 q2, q2, q3\n"
320 +           "vld1.u8 {q4}, [%[dest]]\n"
321 +           /* XXX: one cycle stall */
322 +           "vrhadd.u8 q0, q0, q2\n"
323 +           /* XXX: three cycles stall */
324 +           "vrhadd.u8 q0, q4, q0\n"
325 +           "vst1.u8 {q0}, [%[dest]]\n"
326 +           :
327 +           : [dest]"r"(dest), [ref]"r"(ref), [refx]"r"(ref + 1),
328 +                      [refy]"r"(ref + stride), [refxy]"r"(ref + stride + 1)
329 +           : "memory", "q0", "q1", "q2", "q3", "q4");
330 +       ref += stride;
331 +       dest += stride;
332 +    } while (--height);
333 +}
334 +
335 +static void MC_avg_xy_8_neon (uint8_t * dest, const uint8_t * ref,
336 +                             const int stride, int height)
337 +{
338 +    do {
339 +       asm volatile (
340 +           "vld1.u8 {d0}, [%[ref]]\n"
341 +           "vld1.u8 {d1}, [%[refx]]\n"
342 +           "vrhadd.u8 d0, d0, d1\n"
343 +           "vld1.u8 {d2}, [%[refy]]\n"
344 +           "vld1.u8 {d3}, [%[refxy]]\n"
345 +           "vrhadd.u8 d2, d2, d3\n"
346 +           "vld1.u8 {d4}, [%[dest]]\n"
347 +           /* XXX: one cycle stall */
348 +           "vrhadd.u8 d0, d0, d2\n"
349 +           /* XXX: three cycles stall */
350 +           "vrhadd.u8 d0, d4, d0\n"
351 +           "vst1.u8 {d0}, [%[dest]]\n"
352 +           :
353 +           : [dest]"r"(dest), [ref]"r"(ref), [refx]"r"(ref + 1),
354 +                      [refy]"r"(ref + stride), [refxy]"r"(ref + stride + 1)
355 +           : "memory", "q0", "q1", "d4");
356 +       ref += stride;
357 +       dest += stride;
358 +    } while (--height);
359 +}
360 +
361 +MPEG2_MC_EXTERN (neon)
362 +
363 +#endif /* ARCH_ARM_NEON */
364 diff -ruN libmpeg2.orig//libmpeg2/mpeg2_internal.h libmpeg2/libmpeg2/mpeg2_internal.h
365 --- libmpeg2.orig//libmpeg2/mpeg2_internal.h    2011-11-06 22:25:07.293694722 -0500
366 +++ libmpeg2/libmpeg2/mpeg2_internal.h  2011-11-06 22:25:19.029752924 -0500
367 @@ -313,5 +313,6 @@
368  extern mpeg2_mc_t mpeg2_mc_alpha;
369  extern mpeg2_mc_t mpeg2_mc_vis;
370  extern mpeg2_mc_t mpeg2_mc_arm;
371 +extern mpeg2_mc_t mpeg2_mc_neon;
372  
373  #endif /* LIBMPEG2_MPEG2_INTERNAL_H */