demux:mkv: fix wrong value reset after clean of an array
[vlc.git] / modules / video_chroma / i422_yuy2.c
blobbc19810eb34174a1374d4ad9bd73583f588919e5
1 /*****************************************************************************
2 * i422_yuy2.c : Planar YUV 4:2:2 to Packed YUV conversion module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VLC authors and VideoLAN
6 * Authors: Samuel Hocevar <sam@zoy.org>
7 * Damien Fouilleul <damienf@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_filter.h>
35 #include <vlc_picture.h>
36 #include <vlc_cpu.h>
38 #include "i422_yuy2.h"
40 #define SRC_FOURCC "I422"
41 #if defined (MODULE_NAME_IS_i422_yuy2)
42 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,Y211"
43 #else
44 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV"
45 #endif
47 /*****************************************************************************
48 * Local and extern prototypes.
49 *****************************************************************************/
50 static int Activate ( vlc_object_t * );
52 static void I422_YUY2 ( filter_t *, picture_t *, picture_t * );
53 static void I422_YVYU ( filter_t *, picture_t *, picture_t * );
54 static void I422_UYVY ( filter_t *, picture_t *, picture_t * );
55 static void I422_IUYV ( filter_t *, picture_t *, picture_t * );
56 static picture_t *I422_YUY2_Filter ( filter_t *, picture_t * );
57 static picture_t *I422_YVYU_Filter ( filter_t *, picture_t * );
58 static picture_t *I422_UYVY_Filter ( filter_t *, picture_t * );
59 static picture_t *I422_IUYV_Filter ( filter_t *, picture_t * );
60 #if defined (MODULE_NAME_IS_i422_yuy2)
61 static void I422_Y211 ( filter_t *, picture_t *, picture_t * );
62 static picture_t *I422_Y211_Filter ( filter_t *, picture_t * );
63 #endif
65 /*****************************************************************************
66 * Module descriptor
67 *****************************************************************************/
68 vlc_module_begin ()
69 #if defined (MODULE_NAME_IS_i422_yuy2)
70 set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
71 set_capability( "video converter", 80 )
72 # define vlc_CPU_capable() (true)
73 # define VLC_TARGET
74 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
75 set_description( N_("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) )
76 set_capability( "video converter", 100 )
77 # define vlc_CPU_capable() vlc_CPU_MMX()
78 # define VLC_TARGET VLC_MMX
79 #elif defined (MODULE_NAME_IS_i422_yuy2_sse2)
80 set_description( N_("SSE2 conversions from " SRC_FOURCC " to " DEST_FOURCC) )
81 set_capability( "video converter", 120 )
82 # define vlc_CPU_capable() vlc_CPU_SSE2()
83 # define VLC_TARGET VLC_SSE
84 #endif
85 set_callbacks( Activate, NULL )
86 vlc_module_end ()
88 /*****************************************************************************
89 * Activate: allocate a chroma function
90 *****************************************************************************
91 * This function allocates and initializes a chroma function
92 *****************************************************************************/
93 static int Activate( vlc_object_t *p_this )
95 filter_t *p_filter = (filter_t *)p_this;
97 if( !vlc_CPU_capable() )
98 return VLC_EGENERIC;
99 if( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) & 1
100 || (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) & 1 )
102 return -1;
105 if( p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation )
107 return VLC_EGENERIC;
110 switch( p_filter->fmt_in.video.i_chroma )
112 case VLC_CODEC_I422:
113 switch( p_filter->fmt_out.video.i_chroma )
115 case VLC_CODEC_YUYV:
116 p_filter->pf_video_filter = I422_YUY2_Filter;
117 break;
119 case VLC_CODEC_YVYU:
120 p_filter->pf_video_filter = I422_YVYU_Filter;
121 break;
123 case VLC_CODEC_UYVY:
124 p_filter->pf_video_filter = I422_UYVY_Filter;
125 break;
127 case VLC_FOURCC('I','U','Y','V'):
128 p_filter->pf_video_filter = I422_IUYV_Filter;
129 break;
131 #if defined (MODULE_NAME_IS_i422_yuy2)
132 case VLC_CODEC_Y211:
133 p_filter->pf_video_filter = I422_Y211_Filter;
134 break;
135 #endif
137 default:
138 return -1;
140 break;
142 default:
143 return -1;
145 return 0;
148 /* Following functions are local */
150 VIDEO_FILTER_WRAPPER( I422_YUY2 )
151 VIDEO_FILTER_WRAPPER( I422_YVYU )
152 VIDEO_FILTER_WRAPPER( I422_UYVY )
153 VIDEO_FILTER_WRAPPER( I422_IUYV )
154 #if defined (MODULE_NAME_IS_i422_yuy2)
155 VIDEO_FILTER_WRAPPER( I422_Y211 )
156 #endif
158 /*****************************************************************************
159 * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
160 *****************************************************************************/
161 VLC_TARGET
162 static void I422_YUY2( filter_t *p_filter, picture_t *p_source,
163 picture_t *p_dest )
165 uint8_t *p_line = p_dest->p->p_pixels;
166 uint8_t *p_y = p_source->Y_PIXELS;
167 uint8_t *p_u = p_source->U_PIXELS;
168 uint8_t *p_v = p_source->V_PIXELS;
170 int i_x, i_y;
172 const int i_source_margin = p_source->p[0].i_pitch
173 - p_source->p[0].i_visible_pitch
174 - p_filter->fmt_in.video.i_x_offset;
175 const int i_source_margin_c = p_source->p[1].i_pitch
176 - p_source->p[1].i_visible_pitch
177 - ( p_filter->fmt_in.video.i_x_offset );
178 const int i_dest_margin = p_dest->p->i_pitch
179 - p_dest->p->i_visible_pitch
180 - ( p_filter->fmt_out.video.i_x_offset * 2 );
182 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
184 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
185 ((intptr_t)p_line|(intptr_t)p_y))) )
187 /* use faster SSE2 aligned fetch and store */
188 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
190 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
192 SSE2_CALL( SSE2_YUV422_YUYV_ALIGNED );
194 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
196 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
198 p_y += i_source_margin;
199 p_u += i_source_margin_c;
200 p_v += i_source_margin_c;
201 p_line += i_dest_margin;
204 else {
205 /* use slower SSE2 unaligned fetch and store */
206 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
208 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
210 SSE2_CALL( SSE2_YUV422_YUYV_UNALIGNED );
212 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
214 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
216 p_y += i_source_margin;
217 p_u += i_source_margin_c;
218 p_v += i_source_margin_c;
219 p_line += i_dest_margin;
222 SSE2_END;
224 #else
226 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
228 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
230 #if defined (MODULE_NAME_IS_i422_yuy2)
231 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
232 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
233 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
234 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
235 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
236 MMX_CALL( MMX_YUV422_YUYV );
237 #endif
239 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
241 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
243 p_y += i_source_margin;
244 p_u += i_source_margin_c;
245 p_v += i_source_margin_c;
246 p_line += i_dest_margin;
248 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
249 MMX_END;
250 #endif
252 #endif
255 /*****************************************************************************
256 * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
257 *****************************************************************************/
258 VLC_TARGET
259 static void I422_YVYU( filter_t *p_filter, picture_t *p_source,
260 picture_t *p_dest )
262 uint8_t *p_line = p_dest->p->p_pixels;
263 uint8_t *p_y = p_source->Y_PIXELS;
264 uint8_t *p_u = p_source->U_PIXELS;
265 uint8_t *p_v = p_source->V_PIXELS;
267 int i_x, i_y;
269 const int i_source_margin = p_source->p[0].i_pitch
270 - p_source->p[0].i_visible_pitch
271 - p_filter->fmt_in.video.i_x_offset;
272 const int i_source_margin_c = p_source->p[1].i_pitch
273 - p_source->p[1].i_visible_pitch
274 - ( p_filter->fmt_in.video.i_x_offset );
275 const int i_dest_margin = p_dest->p->i_pitch
276 - p_dest->p->i_visible_pitch
277 - ( p_filter->fmt_out.video.i_x_offset * 2 );
279 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
281 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
282 ((intptr_t)p_line|(intptr_t)p_y))) )
284 /* use faster SSE2 aligned fetch and store */
285 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
287 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
289 SSE2_CALL( SSE2_YUV422_YVYU_ALIGNED );
291 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
293 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
295 p_y += i_source_margin;
296 p_u += i_source_margin_c;
297 p_v += i_source_margin_c;
298 p_line += i_dest_margin;
301 else {
302 /* use slower SSE2 unaligned fetch and store */
303 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
305 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
307 SSE2_CALL( SSE2_YUV422_YVYU_UNALIGNED );
309 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
311 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
313 p_y += i_source_margin;
314 p_u += i_source_margin_c;
315 p_v += i_source_margin_c;
316 p_line += i_dest_margin;
319 SSE2_END;
321 #else
323 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
325 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
327 #if defined (MODULE_NAME_IS_i422_yuy2)
328 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
329 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
330 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
331 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
332 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
333 MMX_CALL( MMX_YUV422_YVYU );
334 #endif
336 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
338 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
340 p_y += i_source_margin;
341 p_u += i_source_margin_c;
342 p_v += i_source_margin_c;
343 p_line += i_dest_margin;
345 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
346 MMX_END;
347 #endif
349 #endif
352 /*****************************************************************************
353 * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
354 *****************************************************************************/
355 VLC_TARGET
356 static void I422_UYVY( filter_t *p_filter, picture_t *p_source,
357 picture_t *p_dest )
359 uint8_t *p_line = p_dest->p->p_pixels;
360 uint8_t *p_y = p_source->Y_PIXELS;
361 uint8_t *p_u = p_source->U_PIXELS;
362 uint8_t *p_v = p_source->V_PIXELS;
364 int i_x, i_y;
366 const int i_source_margin = p_source->p[0].i_pitch
367 - p_source->p[0].i_visible_pitch
368 - p_filter->fmt_in.video.i_x_offset;
369 const int i_source_margin_c = p_source->p[1].i_pitch
370 - p_source->p[1].i_visible_pitch
371 - ( p_filter->fmt_in.video.i_x_offset );
372 const int i_dest_margin = p_dest->p->i_pitch
373 - p_dest->p->i_visible_pitch
374 - ( p_filter->fmt_out.video.i_x_offset * 2 );
376 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
378 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
379 ((intptr_t)p_line|(intptr_t)p_y))) )
381 /* use faster SSE2 aligned fetch and store */
382 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
384 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
386 SSE2_CALL( SSE2_YUV422_UYVY_ALIGNED );
388 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
390 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
392 p_y += i_source_margin;
393 p_u += i_source_margin_c;
394 p_v += i_source_margin_c;
395 p_line += i_dest_margin;
398 else {
399 /* use slower SSE2 unaligned fetch and store */
400 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
402 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
404 SSE2_CALL( SSE2_YUV422_UYVY_UNALIGNED );
406 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
408 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
410 p_y += i_source_margin;
411 p_u += i_source_margin_c;
412 p_v += i_source_margin_c;
413 p_line += i_dest_margin;
416 SSE2_END;
418 #else
420 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
422 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
424 #if defined (MODULE_NAME_IS_i422_yuy2)
425 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
426 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
427 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
428 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
429 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
430 MMX_CALL( MMX_YUV422_UYVY );
431 #endif
433 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
435 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
437 p_y += i_source_margin;
438 p_u += i_source_margin_c;
439 p_v += i_source_margin_c;
440 p_line += i_dest_margin;
442 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
443 MMX_END;
444 #endif
446 #endif
449 /*****************************************************************************
450 * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
451 *****************************************************************************/
452 static void I422_IUYV( filter_t *p_filter, picture_t *p_source,
453 picture_t *p_dest )
455 VLC_UNUSED(p_source); VLC_UNUSED(p_dest);
456 /* FIXME: TODO ! */
457 msg_Err( p_filter, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
460 /*****************************************************************************
461 * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
462 *****************************************************************************/
463 #if defined (MODULE_NAME_IS_i422_yuy2)
464 static void I422_Y211( filter_t *p_filter, picture_t *p_source,
465 picture_t *p_dest )
467 uint8_t *p_line = p_dest->p->p_pixels + p_dest->p->i_visible_lines * p_dest->p->i_pitch;
468 uint8_t *p_y = p_source->Y_PIXELS;
469 uint8_t *p_u = p_source->U_PIXELS;
470 uint8_t *p_v = p_source->V_PIXELS;
472 int i_x, i_y;
474 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
476 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
478 C_YUV422_Y211( p_line, p_y, p_u, p_v );
479 C_YUV422_Y211( p_line, p_y, p_u, p_v );
483 #endif