26a03fee1f8baabeaa47fb89e87e1ae08f8cf7cc
[vlc.git] / modules / video_filter / deinterlace / merge.h
1 /*****************************************************************************
2  * merge.h : Merge (line blending) routines for the VLC deinterlacer
3  *****************************************************************************
4  * Copyright (C) 2011 VLC authors and VideoLAN
5  *
6  * Author: Sam Hocevar <sam@zoy.org>                      (generic C routine)
7  *         Sigmund Augdal Helberg <sigmunau@videolan.org> (MMXEXT, 3DNow, SSE2)
8  *         Eric Petit <eric.petit@lapsus.org>             (Altivec)
9  *         RĂ©mi Denis-Courmont                            (ARM NEON)
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation; either version 2.1 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifndef VLC_DEINTERLACE_MERGE_H
27 #define VLC_DEINTERLACE_MERGE_H 1
28
29 /**
30  * \file
31  * Merge (line blending) routines for the VLC deinterlacer.
32  */
33
34 /*****************************************************************************
35  * Macros
36  *****************************************************************************/
37
38 /* Convenient Merge() and EndMerge() macros to pick the most appropriate
39    merge implementation automatically.
40
41    Note that you'll need to include vlc_filter.h and deinterlace.h
42    to use these.
43
44  * Note that the Open() call of the deinterlace filter automatically selects
45  * the most appropriate merge routine based on the CPU capabilities.
46  * You can call the most appropriate version automatically, from a function
47  * in the deinterlace filter, by using the Merge() macro.
48  *
49  * Note that the filter instance (p_filter) must be available for the Merge()
50  * macro to work, because it needs the detection result from the filter's
51  * Open().
52  *
53  * Macro syntax:
54  *   Merge( _p_dest, _p_s1, _p_s2, i_bytes );
55  *
56   * i_bytes > 0; no other restrictions. This holds for all versions of the
57  * merge routine.
58  *
59  */
60 #define Merge p_sys->pf_merge
61
62 /*
63  * EndMerge() macro, which must be called after the merge is
64  * finished, if the Merge() macro was used to perform the merge.
65  */
66 #if defined(__i386__) || defined(__x86_64__)
67 # define EndMerge() \
68     if(p_sys->pf_end_merge) (p_sys->pf_end_merge)()
69 #else
70 # define EndMerge() (void)0
71 #endif
72
73 /*****************************************************************************
74  * Merge routines
75  *****************************************************************************/
76
77 /**
78  * Generic routine to blend 8 bit pixels from two picture lines.
79  * No inline assembler acceleration.
80  *
81  * @param _p_dest Target line. Blend result = (A + B)/2.
82  * @param _p_s1 Source line A.
83  * @param _p_s2 Source line B.
84  * @param i_bytes Number of bytes to merge.
85  * @see Open()
86  */
87 void Merge8BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
88                        size_t i_bytes );
89
90 /**
91  * Generic routine to blend 16 bit pixels from two picture lines.
92  * No inline assembler acceleration.
93  *
94  * @param _p_dest Target line. Blend result = (A + B)/2.
95  * @param _p_s1 Source line A.
96  * @param _p_s2 Source line B.
97  * @param i_bytes Number of *bytes* to merge.
98  * @see Open()
99  */
100 void Merge16BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2,
101                         size_t i_bytes );
102
103 #if defined(CAN_COMPILE_C_ALTIVEC)
104 /**
105  * Altivec routine to blend pixels from two picture lines.
106  *
107  * @param _p_dest Target
108  * @param _p_s1 Source line A
109  * @param _p_s2 Source line B
110  * @param i_bytes Number of bytes to merge
111  */
112 void MergeAltivec ( void *, const void *, const void *, size_t );
113 #endif
114
115 #if defined(CAN_COMPILE_MMXEXT)
116 /**
117  * MMXEXT routine to blend pixels from two picture lines.
118  *
119  * @param _p_dest Target
120  * @param _p_s1 Source line A
121  * @param _p_s2 Source line B
122  * @param i_bytes Number of bytes to merge
123  */
124 void MergeMMXEXT  ( void *, const void *, const void *, size_t );
125 #endif
126
127 #if defined(CAN_COMPILE_3DNOW)
128 /**
129  * 3DNow routine to blend pixels from two picture lines.
130  *
131  * @param _p_dest Target
132  * @param _p_s1 Source line A
133  * @param _p_s2 Source line B
134  * @param i_bytes Number of bytes to merge
135  */
136 void Merge3DNow   ( void *, const void *, const void *, size_t );
137 #endif
138
139 #if defined(CAN_COMPILE_SSE)
140 /**
141  * SSE2 routine to blend pixels from two picture lines.
142  *
143  * @param _p_dest Target
144  * @param _p_s1 Source line A
145  * @param _p_s2 Source line B
146  * @param i_bytes Number of bytes to merge
147  */
148 void Merge8BitSSE2( void *, const void *, const void *, size_t );
149 /**
150  * SSE2 routine to blend pixels from two picture lines.
151  *
152  * @param _p_dest Target
153  * @param _p_s1 Source line A
154  * @param _p_s2 Source line B
155  * @param i_bytes Number of bytes to merge
156  */
157 void Merge16BitSSE2( void *, const void *, const void *, size_t );
158 #endif
159
160 #if defined(CAN_COMPILE_ARM)
161 /**
162  * ARM NEON routine to blend pixels from two picture lines.
163  */
164 void merge8_arm_neon (void *, const void *, const void *, size_t);
165 void merge16_arm_neon (void *, const void *, const void *, size_t);
166
167 /**
168  * ARMv6 SIMD routine to blend pixels from two picture lines.
169  */
170 void merge8_armv6 (void *, const void *, const void *, size_t);
171 void merge16_armv6 (void *, const void *, const void *, size_t);
172 #endif
173
174 #if defined(CAN_COMPILE_ARM64)
175 /**
176  * ARM64 NEON routine to blend pixels from two picture lines.
177  */
178 void merge8_arm64_neon (void *, const void *, const void *, size_t);
179 void merge16_arm64_neon (void *, const void *, const void *, size_t);
180
181 #endif
182
183 void merge8_arm_sve(void *, const void *, const void *, size_t);
184 void merge16_arm_sve(void *, const void *, const void *, size_t);
185
186 /*****************************************************************************
187  * EndMerge routines
188  *****************************************************************************/
189
190 #if defined(CAN_COMPILE_MMXEXT) || defined(CAN_COMPILE_SSE)
191 /**
192  * MMX merge finalization routine.
193  *
194  * Must be called after an MMX merge is finished.
195  * This exits MMX mode (by executing the "emms" instruction).
196  *
197  * The EndMerge() macro detects whether this is needed, and calls if it is,
198  * so just use that.
199  */
200 void EndMMX       ( void );
201 #endif
202
203 #if defined(CAN_COMPILE_3DNOW)
204 /**
205  * 3DNow merge finalization routine.
206  *
207  * Must be called after a 3DNow merge is finished.
208  * This exits 3DNow mode (by executing the "femms" instruction).
209  *
210  * The EndMerge() macro detects whether this is needed, and calls if it is,
211  * so just use that.
212  */
213 void End3DNow     ( void );
214 #endif
215
216 #endif