2 * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
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.
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.
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.
26 # define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
27 # if VLC_GCC_VERSION(3,1)
28 # define DECLARE_ASM_CONST(n,t,v) static const t __attribute__((used)) __attribute__ ((aligned (n))) v
30 # define DECLARE_ASM_CONST(n,t,v) static const t __attribute__ ((aligned (n))) v
34 typedef intptr_t x86_reg;
35 typedef struct { uint64_t a, b; } xmm_reg;
37 DECLARE_ASM_CONST(16, const xmm_reg, pb_1) = {0x0101010101010101ULL, 0x0101010101010101ULL};
38 DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x0001000100010001ULL};
41 #ifdef CAN_COMPILE_SSSE3
42 #if defined(__SSE__) || VLC_GCC_VERSION(4, 4) || defined(__clang__)
43 // ================ SSSE3 =================
44 #define HAVE_YADIF_SSSE3
45 #define COMPILE_TEMPLATE_SSE 1
46 #define COMPILE_TEMPLATE_SSSE3 1
47 #define VLC_TARGET VLC_SSE
48 #define RENAME(a) a ## _ssse3
49 #include "yadif_template.h"
50 #undef COMPILE_TEMPLATE_SSE
51 #undef COMPILE_TEMPLATE_SSSE3
57 #ifdef CAN_COMPILE_SSE2
58 #if defined(__SSE__) || VLC_GCC_VERSION(4, 4) || defined(__clang__)
59 // ================= SSE2 =================
60 #define HAVE_YADIF_SSE2
61 #define COMPILE_TEMPLATE_SSE 1
62 #define VLC_TARGET VLC_SSE
63 #define RENAME(a) a ## _sse2
64 #include "yadif_template.h"
65 #undef COMPILE_TEMPLATE_SSE
71 #ifdef CAN_COMPILE_MMX
72 #if defined(__MMX__) || VLC_GCC_VERSION(4, 4) || defined(__clang__)
73 // ================ MMX =================
74 #define HAVE_YADIF_MMX
75 #define VLC_TARGET VLC_MMX
76 #define RENAME(a) a ## _mmx
77 #include "yadif_template.h"
86 { int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\
87 + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\
88 + FFABS(cur[mrefs+1+(j)] - cur[prefs+1-(j)]);\
89 if (score < spatial_score) {\
90 spatial_score= score;\
91 spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\
94 for (x = 0; x < w; x++) { \
96 int d = (prev2[0] + next2[0])>>1; \
98 int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
99 int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \
100 int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \
101 int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); \
102 int spatial_pred = (c+e)>>1; \
103 int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e) \
104 + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1; \
106 CHECK(-1) CHECK(-2) }} }} \
107 CHECK( 1) CHECK( 2) }} }} \
110 int b = (prev2[2*mrefs] + next2[2*mrefs])>>1; \
111 int f = (prev2[2*prefs] + next2[2*prefs])>>1; \
112 int max = FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); \
113 int min = FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); \
115 diff = FFMAX3(diff, min, -max); \
118 if (spatial_pred > d + diff) \
119 spatial_pred = d + diff; \
120 else if (spatial_pred < d - diff) \
121 spatial_pred = d - diff; \
123 dst[0] = spatial_pred; \
133 static void yadif_filter_line_c(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int prefs, int mrefs, int parity, int mode) {
135 uint8_t *prev2= parity ? prev : cur ;
136 uint8_t *next2= parity ? cur : next;
140 static void yadif_filter_line_c_16bit(uint16_t *dst, uint16_t *prev, uint16_t *cur, uint16_t *next, int w, int prefs, int mrefs, int parity, int mode) {
142 uint16_t *prev2= parity ? prev : cur ;
143 uint16_t *next2= parity ? cur : next;