]> git.sesse.net Git - vlc/blob - modules/video_filter/deinterlace/yadif.h
Qt: change tools accessor
[vlc] / modules / video_filter / deinterlace / yadif.h
1 /*
2  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
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.
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
14  * GNU General Public License for more details.
15  *
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.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #   include "config.h"
23 #endif
24
25 #if defined(__GNUC__)
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
29 #  else
30 #    define DECLARE_ASM_CONST(n,t,v)    static const t __attribute__ ((aligned (n))) v
31 #  endif
32 #endif
33
34 typedef intptr_t x86_reg;
35 typedef struct { uint64_t a, b; } xmm_reg;
36
37 DECLARE_ASM_CONST(16, const xmm_reg, pb_1) = {0x0101010101010101ULL, 0x0101010101010101ULL};
38 DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x0001000100010001ULL};
39
40
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
52 #undef VLC_TARGET
53 #undef RENAME
54 #endif
55 #endif
56
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
66 #undef VLC_TARGET
67 #undef RENAME
68 #endif
69 #endif
70
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"
78 #undef VLC_TARGET
79 #undef RENAME
80 #endif
81 #endif
82
83 #define FFABS abs
84
85 #define CHECK(j)\
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;\
92
93 #define FILTER \
94     for (x = 0;  x < w; x++) { \
95         int c = cur[mrefs]; \
96         int d = (prev2[0] + next2[0])>>1; \
97         int e = cur[prefs]; \
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; \
105  \
106         CHECK(-1) CHECK(-2) }} }} \
107         CHECK( 1) CHECK( 2) }} }} \
108  \
109         if (mode < 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)); \
114  \
115             diff = FFMAX3(diff, min, -max); \
116         } \
117  \
118         if (spatial_pred > d + diff) \
119            spatial_pred = d + diff; \
120         else if (spatial_pred < d - diff) \
121            spatial_pred = d - diff; \
122  \
123         dst[0] = spatial_pred; \
124  \
125         dst++; \
126         cur++; \
127         prev++; \
128         next++; \
129         prev2++; \
130         next2++; \
131     }
132
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) {
134     int x;
135     uint8_t *prev2= parity ? prev : cur ;
136     uint8_t *next2= parity ? cur  : next;
137     FILTER
138 }
139
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) {
141     int x;
142     uint16_t *prev2= parity ? prev : cur ;
143     uint16_t *next2= parity ? cur  : next;
144     mrefs /= 2;
145     prefs /= 2;
146     FILTER
147 }