GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 251 / 0 / 251
Functions: 100.0% 14 / 0 / 14
Branches: 100.0% 56 / 0 / 56

filters/intel/planeswap_sse.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
2 // http://avisynth.nl
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35
36 // Avisynth filter: Swap planes
37 // by Klaus Post
38 // adapted by Richard Berg (avisynth-dev@richardberg.net)
39 // iSSE code by Ian Brabham
40
41 #include <avs/config.h>
42 #ifdef AVS_WINDOWS
43 #include <avs/win.h>
44 #else
45 #include <avs/posix.h>
46 #endif
47 #include "planeswap_sse.h"
48
49 // Intrinsics base header + really required extension headers
50 #if defined(_MSC_VER)
51 #include <intrin.h> // MSVC
52 #else
53 #include <x86intrin.h> // GCC/MinGW/Clang/LLVM
54 #endif
55 #include <tmmintrin.h> // SSSE3
56
57 #include "stdint.h"
58 #include <type_traits>
59
60 // ---------------------------------------------------------------------------
61 // Packed RGB32 channel extraction — SSE2, 16 pixels per iteration.
62 //
63 // Source layout (per pixel, 4 bytes): B G R A (channel_index: B=0 G=1 R=2 A=3)
64 // Source rows are bottom-up; srcp must already point at the last (bottom) row.
65 // Pitch is positive; we step backwards (srcp -= src_pitch) each row.
66 //
67 // Strategy: shift each 32-bit pixel right by channel_index*8, mask the low byte,
68 // pack 4+4+4+4 = 16 values through packs_epi32 + packus_epi16.
69 // Width is guaranteed a multiple of 16 (64-byte pitch / 4 bytes per pixel).
70 // ---------------------------------------------------------------------------
71 template<int channel_index>
72 8 void extract_packed_rgb32_channel_sse2(
73 const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)
74 {
75 8 const __m128i mask = _mm_set1_epi32(0xFF);
76
8/8
void extract_packed_rgb32_channel_sse2<0>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 34 → 7 taken 12 times.
✓ Branch 34 → 35 taken 2 times.
void extract_packed_rgb32_channel_sse2<1>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 42 → 7 taken 12 times.
✓ Branch 42 → 43 taken 2 times.
void extract_packed_rgb32_channel_sse2<2>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 42 → 7 taken 12 times.
✓ Branch 42 → 43 taken 2 times.
void extract_packed_rgb32_channel_sse2<3>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 42 → 7 taken 12 times.
✓ Branch 42 → 43 taken 2 times.
56 for (int y = 0; y < height; ++y) {
77
8/8
void extract_packed_rgb32_channel_sse2<0>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 32 → 8 taken 36 times.
✓ Branch 32 → 33 taken 12 times.
void extract_packed_rgb32_channel_sse2<1>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 40 → 8 taken 36 times.
✓ Branch 40 → 41 taken 12 times.
void extract_packed_rgb32_channel_sse2<2>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 40 → 8 taken 36 times.
✓ Branch 40 → 41 taken 12 times.
void extract_packed_rgb32_channel_sse2<3>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 40 → 8 taken 36 times.
✓ Branch 40 → 41 taken 12 times.
192 for (int x = 0; x < width; x += 16) {
78 144 __m128i v0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 0));
79 144 __m128i v1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 16));
80 144 __m128i v2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 32));
81 288 __m128i v3 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 48));
82 // Move requested byte to the low byte of each 32-bit dword
83 if constexpr (channel_index > 0) {
84 108 v0 = _mm_srli_epi32(v0, channel_index * 8);
85 108 v1 = _mm_srli_epi32(v1, channel_index * 8);
86 108 v2 = _mm_srli_epi32(v2, channel_index * 8);
87 108 v3 = _mm_srli_epi32(v3, channel_index * 8);
88 }
89 144 v0 = _mm_and_si128(v0, mask);
90 144 v1 = _mm_and_si128(v1, mask);
91 144 v2 = _mm_and_si128(v2, mask);
92 144 v3 = _mm_and_si128(v3, mask);
93 // Pack 4 × 32-bit (values 0-255) → 8 × 16-bit → 16 × 8-bit
94 432 _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x),
95 _mm_packus_epi16(_mm_packs_epi32(v0, v1), _mm_packs_epi32(v2, v3)));
96 }
97 48 srcp -= src_pitch;
98 48 dstp += dst_pitch;
99 }
100 8 }
101
102 template void extract_packed_rgb32_channel_sse2<0>(const BYTE*, BYTE*, int, int, int, int);
103 template void extract_packed_rgb32_channel_sse2<1>(const BYTE*, BYTE*, int, int, int, int);
104 template void extract_packed_rgb32_channel_sse2<2>(const BYTE*, BYTE*, int, int, int, int);
105 template void extract_packed_rgb32_channel_sse2<3>(const BYTE*, BYTE*, int, int, int, int);
106
107 // ---------------------------------------------------------------------------
108 // Packed RGB64 channel extraction — SSE2, 8 pixels per iteration.
109 //
110 // Source layout (per pixel, 8 bytes): B G R A (uint16_t each; B=0 G=1 R=2 A=3)
111 // Source rows are bottom-up; srcp must already point at the last (bottom) row.
112 //
113 // Strategy: 3-stage deinterleave using unpacklo/hi_epi16, unpacklo/hi_epi32,
114 // unpacklo/hi_epi64, then unscramble with shufflelo/hi_epi16.
115 //
116 // Two register pairs (a,b) and (c,d) each hold 4 pixels:
117 // a = [B0 G0 R0 A0 | B1 G1 R1 A1] (pixel 0, pixel 1 — 8 uint16_t)
118 // b = [B2 G2 R2 A2 | B3 G3 R3 A3]
119 // c = pixels 4-5, d = pixels 6-7
120 //
121 // After unpacklo_epi16(a,b): [B0 B2 | G0 G2 | R0 R2 | A0 A2]
122 // After unpackhi_epi16(a,b): [B1 B3 | G1 G3 | R1 R3 | A1 A3]
123 // unpacklo_epi32 of those: [B0 B2 B1 B3 | G0 G2 G1 G3] (ch 0,1 in lo/hi 64-bit lanes)
124 // unpackhi_epi32 of those: [R0 R2 R1 R3 | A0 A2 A1 A3] (ch 2,3 in lo/hi 64-bit lanes)
125 // unpacklo/hi_epi64 selects the right channel across both pairs → [C0 C2 C1 C3 | C4 C6 C5 C7]
126 // shufflelo + shufflehi with _MM_SHUFFLE(3,1,2,0) unscrambles to [C0 C1 C2 C3 | C4 C5 C6 C7].
127 //
128 // Width is guaranteed a multiple of 8 (64-byte pitch / 8 bytes per pixel).
129 // ---------------------------------------------------------------------------
130 template<int channel_index>
131 8 void extract_packed_rgb64_channel_sse2(
132 const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)
133 {
134
8/8
void extract_packed_rgb64_channel_sse2<0>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 30 → 3 taken 12 times.
✓ Branch 30 → 31 taken 2 times.
void extract_packed_rgb64_channel_sse2<1>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 30 → 3 taken 12 times.
✓ Branch 30 → 31 taken 2 times.
void extract_packed_rgb64_channel_sse2<2>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 30 → 3 taken 12 times.
✓ Branch 30 → 31 taken 2 times.
void extract_packed_rgb64_channel_sse2<3>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 30 → 3 taken 12 times.
✓ Branch 30 → 31 taken 2 times.
56 for (int y = 0; y < height; ++y) {
135
8/8
void extract_packed_rgb64_channel_sse2<0>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 28 → 4 taken 36 times.
✓ Branch 28 → 29 taken 12 times.
void extract_packed_rgb64_channel_sse2<1>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 28 → 4 taken 36 times.
✓ Branch 28 → 29 taken 12 times.
void extract_packed_rgb64_channel_sse2<2>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 28 → 4 taken 36 times.
✓ Branch 28 → 29 taken 12 times.
void extract_packed_rgb64_channel_sse2<3>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 28 → 4 taken 36 times.
✓ Branch 28 → 29 taken 12 times.
192 for (int x = 0; x < width; x += 8) {
136 144 __m128i a = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 8 + 0)); // px 0-1
137 144 __m128i b = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 8 + 16)); // px 2-3
138 144 __m128i c = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 8 + 32)); // px 4-5
139 288 __m128i d = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 8 + 48)); // px 6-7
140
141 // Stage 1: interleave same-index pixels from each pair
142 // t0/t1 from pair (a,b); t4/t5 from pair (c,d)
143 144 __m128i t0 = _mm_unpacklo_epi16(a, b); // [B0 B2 | G0 G2 | R0 R2 | A0 A2]
144 144 __m128i t1 = _mm_unpackhi_epi16(a, b); // [B1 B3 | G1 G3 | R1 R3 | A1 A3]
145 144 __m128i t4 = _mm_unpacklo_epi16(c, d); // [B4 B6 | G4 G6 | R4 R6 | A4 A6]
146 144 __m128i t5 = _mm_unpackhi_epi16(c, d); // [B5 B7 | G5 G7 | R5 R7 | A5 A7]
147
148 // Stage 2: gather channel into 64-bit lanes
149 // ch 0,1: lo qword = channel ch%2==0, hi qword = channel ch%2==1
150 // ch 2,3: same but from the hi 32-bit positions
151 __m128i lo, hi;
152 if constexpr (channel_index <= 1) {
153 72 lo = _mm_unpacklo_epi32(t0, t1); // [B0 B2 B1 B3 | G0 G2 G1 G3]
154 72 hi = _mm_unpacklo_epi32(t4, t5); // [B4 B6 B5 B7 | G4 G6 G5 G7]
155 } else {
156 72 lo = _mm_unpackhi_epi32(t0, t1); // [R0 R2 R1 R3 | A0 A2 A1 A3]
157 72 hi = _mm_unpackhi_epi32(t4, t5); // [R4 R6 R5 R7 | A4 A6 A5 A7]
158 }
159
160 // Stage 3: select even-indexed (ch 0,2) or odd-indexed (ch 1,3) channel lane
161 __m128i v;
162 if constexpr (channel_index == 0 || channel_index == 2) {
163 72 v = _mm_unpacklo_epi64(lo, hi); // [C0 C2 C1 C3 | C4 C6 C5 C7]
164 } else {
165 72 v = _mm_unpackhi_epi64(lo, hi); // [C0 C2 C1 C3 | C4 C6 C5 C7]
166 }
167
168 // Stage 4: unscramble [C0 C2 C1 C3 | C4 C6 C5 C7] → [C0 C1 C2 C3 | C4 C5 C6 C7]
169 144 v = _mm_shufflelo_epi16(v, _MM_SHUFFLE(3,1,2,0));
170 144 v = _mm_shufflehi_epi16(v, _MM_SHUFFLE(3,1,2,0));
171
172 144 _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 2), v);
173 }
174 48 srcp -= src_pitch;
175 48 dstp += dst_pitch;
176 }
177 8 }
178
179 template void extract_packed_rgb64_channel_sse2<0>(const BYTE*, BYTE*, int, int, int, int);
180 template void extract_packed_rgb64_channel_sse2<1>(const BYTE*, BYTE*, int, int, int, int);
181 template void extract_packed_rgb64_channel_sse2<2>(const BYTE*, BYTE*, int, int, int, int);
182 template void extract_packed_rgb64_channel_sse2<3>(const BYTE*, BYTE*, int, int, int, int);
183
184
185
186 /**************************************
187 * Swap - swaps UV on planar maps
188 **************************************/
189
190 2 void yuy2_swap_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)
191 {
192 2 const __m128i mask = _mm_set1_epi16(0x00FF);
193
194
2/2
✓ Branch 20 → 7 taken 12 times.
✓ Branch 20 → 21 taken 2 times.
14 for (int y = 0; y < height; ++y ) {
195
2/2
✓ Branch 18 → 8 taken 50 times.
✓ Branch 18 → 19 taken 12 times.
62 for (int x = 0; x < width; x += 16) {
196 50 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));
197 50 __m128i swapped = _mm_shufflelo_epi16(src, _MM_SHUFFLE(2, 3, 0, 1));
198 50 swapped = _mm_shufflehi_epi16(swapped, _MM_SHUFFLE(2, 3, 0, 1));
199 100 swapped = _mm_or_si128(_mm_and_si128(mask, src), _mm_andnot_si128(mask, swapped));
200 50 _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), swapped);
201 }
202
203 12 dstp += dst_pitch;
204 12 srcp += src_pitch;
205 }
206 2 }
207
208 #if defined(GCC) || defined(CLANG)
209 __attribute__((__target__("ssse3")))
210 #endif
211 2 void yuy2_swap_ssse3(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)
212 {
213 2 const __m128i mask = _mm_set_epi8(13, 14, 15, 12, 9, 10, 11, 8, 5, 6, 7, 4, 1, 2, 3, 0);
214
215
2/2
✓ Branch 14 → 5 taken 12 times.
✓ Branch 14 → 15 taken 2 times.
14 for (int y = 0; y < height; ++y) {
216
2/2
✓ Branch 12 → 6 taken 50 times.
✓ Branch 12 → 13 taken 12 times.
62 for (int x = 0; x < width; x += 16) {
217 100 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));
218 50 __m128i dst = _mm_shuffle_epi8(src, mask);
219 50 _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), dst);
220 }
221
222 12 dstp += dst_pitch;
223 12 srcp += src_pitch;
224 }
225 2 }
226
227 #ifdef X86_32
228 void yuy2_swap_isse(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)
229 {
230 __m64 mask = _mm_set1_pi16(0x00FF);
231
232 for (int y = 0; y < height; ++y) {
233 for (int x = 0; x < width; x+= 8) {
234 __m64 src = *reinterpret_cast<const __m64*>(srcp+x);
235 __m64 swapped = _mm_shuffle_pi16(src, _MM_SHUFFLE(2, 3, 0, 1));
236 swapped = _mm_or_si64(_mm_and_si64(mask, src), _mm_andnot_si64(mask, swapped));
237 *reinterpret_cast<__m64*>(dstp + x) = swapped;
238 }
239
240 dstp += dst_pitch;
241 srcp += src_pitch;
242 }
243 _mm_empty();
244 }
245 #endif
246
247 2 void yuy2_uvtoy_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos)
248 {
249 2 const __m128i chroma = _mm_set1_epi32(0x80008000);
250 2 const __m128i mask = _mm_set1_epi32(0x000000FF);
251 2 pos *= 8;
252
253
2/2
✓ Branch 32 → 11 taken 10 times.
✓ Branch 32 → 33 taken 2 times.
12 for (int y = 0; y < height; ++y) {
254
2/2
✓ Branch 30 → 12 taken 20 times.
✓ Branch 30 → 31 taken 10 times.
30 for (int x = 0; x < dst_width; x += 16) {
255 20 __m128i s0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 2 * x));
256 40 __m128i s1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 2 * x + 16));
257 40 s0 = _mm_and_si128(mask, _mm_srli_epi32(s0, pos));
258 40 s1 = _mm_and_si128(mask, _mm_srli_epi32(s1, pos));
259 20 s0 = _mm_packs_epi32(s0, s1);
260 20 s0 = _mm_or_si128(s0, chroma);
261 20 _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), s0);
262 }
263 10 srcp += src_pitch;
264 10 dstp += dst_pitch;
265 }
266 2 }
267
268 2 void yuy2_uvtoy8_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos)
269 {
270 2 const __m128i mask = _mm_set1_epi32(0x000000FF);
271 2 pos *= 8;
272
273
2/2
✓ Branch 28 → 7 taken 10 times.
✓ Branch 28 → 29 taken 2 times.
12 for (int y = 0; y < height; ++y) {
274
2/2
✓ Branch 26 → 8 taken 40 times.
✓ Branch 26 → 27 taken 10 times.
50 for (int x = 0; x < dst_width; x += 8) {
275 40 __m128i s0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4 * x));
276 80 __m128i s1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4 * x + 16));
277 80 s0 = _mm_and_si128(mask, _mm_srli_epi32(s0, pos));
278 80 s1 = _mm_and_si128(mask, _mm_srli_epi32(s1, pos));
279 40 s0 = _mm_packs_epi32(s0, s1);
280 40 s0 = _mm_packus_epi16(s0, s0);
281 40 _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x), s0);
282 }
283 10 srcp += src_pitch;
284 10 dstp += dst_pitch;
285 }
286 2 }
287
288 template <bool has_clipY>
289 2 void yuy2_ytouv_sse2(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height)
290 {
291 2 const __m128i mask = _mm_set1_epi16(0x00FF);
292 2 const __m128i zero = _mm_setzero_si128();
293 2 const __m128i fill = _mm_set1_epi16(0x007e);
294
295
4/4
void yuy2_ytouv_sse2<false>(unsigned char const*, unsigned char const*, unsigned char const*, unsigned char*, int, int, int, int, int, int):
✓ Branch 38 → 13 taken 5 times.
✓ Branch 38 → 39 taken 1 time.
void yuy2_ytouv_sse2<true>(unsigned char const*, unsigned char const*, unsigned char const*, unsigned char*, int, int, int, int, int, int):
✓ Branch 47 → 13 taken 5 times.
✓ Branch 47 → 48 taken 1 time.
12 for (int y = 0; y < height; ++y) {
296
4/4
void yuy2_ytouv_sse2<false>(unsigned char const*, unsigned char const*, unsigned char const*, unsigned char*, int, int, int, int, int, int):
✓ Branch 36 → 14 taken 10 times.
✓ Branch 36 → 37 taken 5 times.
void yuy2_ytouv_sse2<true>(unsigned char const*, unsigned char const*, unsigned char const*, unsigned char*, int, int, int, int, int, int):
✓ Branch 45 → 14 taken 10 times.
✓ Branch 45 → 46 taken 5 times.
30 for (int x = 0; x < dst_rowsize; x += 32) {
297 20 __m128i u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_u + x / 2));
298 40 __m128i v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_v + x / 2));
299 60 __m128i uv = _mm_or_si128(_mm_and_si128(u, mask), _mm_slli_epi16(v, 8));
300 20 __m128i uv_lo = _mm_unpacklo_epi8(zero, uv);
301 20 __m128i uv_hi = _mm_unpackhi_epi8(zero, uv);
302 if (has_clipY) {
303 10 __m128i y_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_y + x));
304 20 __m128i y_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_y + x + 16));
305 20 uv_lo = _mm_or_si128(uv_lo, _mm_and_si128(y_lo, mask));
306 20 uv_hi = _mm_or_si128(uv_hi, _mm_and_si128(y_hi, mask));
307 }
308 else {
309 10 uv_lo = _mm_or_si128(uv_lo, fill);
310 10 uv_hi = _mm_or_si128(uv_hi, fill);
311 }
312 20 _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), uv_lo);
313 20 _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x + 16), uv_hi);
314 }
315 10 srcp_y += pitch_y;
316 10 srcp_u += pitch_u;
317 10 srcp_v += pitch_v;
318 10 dstp += dst_pitch;
319 }
320 2 }
321
322 template void yuy2_ytouv_sse2<false>(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height);
323 template void yuy2_ytouv_sse2<true>(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height);
324