demux: wav: check implicit duration
[vlc.git] / modules / video_chroma / i422_yuy2.c
blobf71c9424806efc4ee23c6c93b66384f9e793d48e
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
5 * $Id$
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Damien Fouilleul <damienf@videolan.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_filter.h>
36 #include <vlc_picture.h>
37 #include <vlc_cpu.h>
39 #include "i422_yuy2.h"
41 #define SRC_FOURCC "I422"
42 #if defined (MODULE_NAME_IS_i422_yuy2)
43 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,Y211"
44 #else
45 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV"
46 #endif
48 /*****************************************************************************
49 * Local and extern prototypes.
50 *****************************************************************************/
51 static int Activate ( vlc_object_t * );
53 static void I422_YUY2 ( filter_t *, picture_t *, picture_t * );
54 static void I422_YVYU ( filter_t *, picture_t *, picture_t * );
55 static void I422_UYVY ( filter_t *, picture_t *, picture_t * );
56 static void I422_IUYV ( filter_t *, picture_t *, picture_t * );
57 static picture_t *I422_YUY2_Filter ( filter_t *, picture_t * );
58 static picture_t *I422_YVYU_Filter ( filter_t *, picture_t * );
59 static picture_t *I422_UYVY_Filter ( filter_t *, picture_t * );
60 static picture_t *I422_IUYV_Filter ( filter_t *, picture_t * );
61 #if defined (MODULE_NAME_IS_i422_yuy2)
62 static void I422_Y211 ( filter_t *, picture_t *, picture_t * );
63 static picture_t *I422_Y211_Filter ( filter_t *, picture_t * );
64 #endif
66 /*****************************************************************************
67 * Module descriptor
68 *****************************************************************************/
69 vlc_module_begin ()
70 #if defined (MODULE_NAME_IS_i422_yuy2)
71 set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
72 set_capability( "video converter", 80 )
73 # define vlc_CPU_capable() (true)
74 # define VLC_TARGET
75 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
76 set_description( N_("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) )
77 set_capability( "video converter", 100 )
78 # define vlc_CPU_capable() vlc_CPU_MMX()
79 # define VLC_TARGET VLC_MMX
80 #elif defined (MODULE_NAME_IS_i422_yuy2_sse2)
81 set_description( N_("SSE2 conversions from " SRC_FOURCC " to " DEST_FOURCC) )
82 set_capability( "video converter", 120 )
83 # define vlc_CPU_capable() vlc_CPU_SSE2()
84 # define VLC_TARGET VLC_SSE
85 #endif
86 set_callbacks( Activate, NULL )
87 vlc_module_end ()
89 /*****************************************************************************
90 * Activate: allocate a chroma function
91 *****************************************************************************
92 * This function allocates and initializes a chroma function
93 *****************************************************************************/
94 static int Activate( vlc_object_t *p_this )
96 filter_t *p_filter = (filter_t *)p_this;
98 if( !vlc_CPU_capable() )
99 return VLC_EGENERIC;
100 if( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) & 1
101 || (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) & 1 )
103 return -1;
106 if( p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation )
108 return VLC_EGENERIC;
111 switch( p_filter->fmt_in.video.i_chroma )
113 case VLC_CODEC_I422:
114 switch( p_filter->fmt_out.video.i_chroma )
116 case VLC_CODEC_YUYV:
117 p_filter->pf_video_filter = I422_YUY2_Filter;
118 break;
120 case VLC_CODEC_YVYU:
121 p_filter->pf_video_filter = I422_YVYU_Filter;
122 break;
124 case VLC_CODEC_UYVY:
125 p_filter->pf_video_filter = I422_UYVY_Filter;
126 break;
128 case VLC_FOURCC('I','U','Y','V'):
129 p_filter->pf_video_filter = I422_IUYV_Filter;
130 break;
132 #if defined (MODULE_NAME_IS_i422_yuy2)
133 case VLC_CODEC_Y211:
134 p_filter->pf_video_filter = I422_Y211_Filter;
135 break;
136 #endif
138 default:
139 return -1;
141 break;
143 default:
144 return -1;
146 return 0;
149 /* Following functions are local */
151 VIDEO_FILTER_WRAPPER( I422_YUY2 )
152 VIDEO_FILTER_WRAPPER( I422_YVYU )
153 VIDEO_FILTER_WRAPPER( I422_UYVY )
154 VIDEO_FILTER_WRAPPER( I422_IUYV )
155 #if defined (MODULE_NAME_IS_i422_yuy2)
156 VIDEO_FILTER_WRAPPER( I422_Y211 )
157 #endif
159 /*****************************************************************************
160 * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
161 *****************************************************************************/
162 VLC_TARGET
163 static void I422_YUY2( filter_t *p_filter, picture_t *p_source,
164 picture_t *p_dest )
166 uint8_t *p_line = p_dest->p->p_pixels;
167 uint8_t *p_y = p_source->Y_PIXELS;
168 uint8_t *p_u = p_source->U_PIXELS;
169 uint8_t *p_v = p_source->V_PIXELS;
171 int i_x, i_y;
173 const int i_source_margin = p_source->p[0].i_pitch
174 - p_source->p[0].i_visible_pitch
175 - p_filter->fmt_in.video.i_x_offset;
176 const int i_source_margin_c = p_source->p[1].i_pitch
177 - p_source->p[1].i_visible_pitch
178 - ( p_filter->fmt_in.video.i_x_offset );
179 const int i_dest_margin = p_dest->p->i_pitch
180 - p_dest->p->i_visible_pitch
181 - ( p_filter->fmt_out.video.i_x_offset * 2 );
183 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
185 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
186 ((intptr_t)p_line|(intptr_t)p_y))) )
188 /* use faster SSE2 aligned fetch and store */
189 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
191 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
193 SSE2_CALL( SSE2_YUV422_YUYV_ALIGNED );
195 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
197 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
199 p_y += i_source_margin;
200 p_u += i_source_margin_c;
201 p_v += i_source_margin_c;
202 p_line += i_dest_margin;
205 else {
206 /* use slower SSE2 unaligned fetch and store */
207 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
209 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
211 SSE2_CALL( SSE2_YUV422_YUYV_UNALIGNED );
213 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
215 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
217 p_y += i_source_margin;
218 p_u += i_source_margin_c;
219 p_v += i_source_margin_c;
220 p_line += i_dest_margin;
223 SSE2_END;
225 #else
227 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
229 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
231 #if defined (MODULE_NAME_IS_i422_yuy2)
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 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
236 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
237 MMX_CALL( MMX_YUV422_YUYV );
238 #endif
240 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
242 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
244 p_y += i_source_margin;
245 p_u += i_source_margin_c;
246 p_v += i_source_margin_c;
247 p_line += i_dest_margin;
249 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
250 MMX_END;
251 #endif
253 #endif
256 /*****************************************************************************
257 * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
258 *****************************************************************************/
259 VLC_TARGET
260 static void I422_YVYU( filter_t *p_filter, picture_t *p_source,
261 picture_t *p_dest )
263 uint8_t *p_line = p_dest->p->p_pixels;
264 uint8_t *p_y = p_source->Y_PIXELS;
265 uint8_t *p_u = p_source->U_PIXELS;
266 uint8_t *p_v = p_source->V_PIXELS;
268 int i_x, i_y;
270 const int i_source_margin = p_source->p[0].i_pitch
271 - p_source->p[0].i_visible_pitch
272 - p_filter->fmt_in.video.i_x_offset;
273 const int i_source_margin_c = p_source->p[1].i_pitch
274 - p_source->p[1].i_visible_pitch
275 - ( p_filter->fmt_in.video.i_x_offset );
276 const int i_dest_margin = p_dest->p->i_pitch
277 - p_dest->p->i_visible_pitch
278 - ( p_filter->fmt_out.video.i_x_offset * 2 );
280 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
282 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
283 ((intptr_t)p_line|(intptr_t)p_y))) )
285 /* use faster SSE2 aligned fetch and store */
286 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
288 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
290 SSE2_CALL( SSE2_YUV422_YVYU_ALIGNED );
292 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
294 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
296 p_y += i_source_margin;
297 p_u += i_source_margin_c;
298 p_v += i_source_margin_c;
299 p_line += i_dest_margin;
302 else {
303 /* use slower SSE2 unaligned fetch and store */
304 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
306 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
308 SSE2_CALL( SSE2_YUV422_YVYU_UNALIGNED );
310 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
312 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
314 p_y += i_source_margin;
315 p_u += i_source_margin_c;
316 p_v += i_source_margin_c;
317 p_line += i_dest_margin;
320 SSE2_END;
322 #else
324 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
326 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
328 #if defined (MODULE_NAME_IS_i422_yuy2)
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 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
333 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
334 MMX_CALL( MMX_YUV422_YVYU );
335 #endif
337 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
339 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
341 p_y += i_source_margin;
342 p_u += i_source_margin_c;
343 p_v += i_source_margin_c;
344 p_line += i_dest_margin;
346 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
347 MMX_END;
348 #endif
350 #endif
353 /*****************************************************************************
354 * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
355 *****************************************************************************/
356 VLC_TARGET
357 static void I422_UYVY( filter_t *p_filter, picture_t *p_source,
358 picture_t *p_dest )
360 uint8_t *p_line = p_dest->p->p_pixels;
361 uint8_t *p_y = p_source->Y_PIXELS;
362 uint8_t *p_u = p_source->U_PIXELS;
363 uint8_t *p_v = p_source->V_PIXELS;
365 int i_x, i_y;
367 const int i_source_margin = p_source->p[0].i_pitch
368 - p_source->p[0].i_visible_pitch
369 - p_filter->fmt_in.video.i_x_offset;
370 const int i_source_margin_c = p_source->p[1].i_pitch
371 - p_source->p[1].i_visible_pitch
372 - ( p_filter->fmt_in.video.i_x_offset );
373 const int i_dest_margin = p_dest->p->i_pitch
374 - p_dest->p->i_visible_pitch
375 - ( p_filter->fmt_out.video.i_x_offset * 2 );
377 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
379 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
380 ((intptr_t)p_line|(intptr_t)p_y))) )
382 /* use faster SSE2 aligned fetch and store */
383 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
385 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
387 SSE2_CALL( SSE2_YUV422_UYVY_ALIGNED );
389 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
391 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
393 p_y += i_source_margin;
394 p_u += i_source_margin_c;
395 p_v += i_source_margin_c;
396 p_line += i_dest_margin;
399 else {
400 /* use slower SSE2 unaligned fetch and store */
401 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
403 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
405 SSE2_CALL( SSE2_YUV422_UYVY_UNALIGNED );
407 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
409 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
411 p_y += i_source_margin;
412 p_u += i_source_margin_c;
413 p_v += i_source_margin_c;
414 p_line += i_dest_margin;
417 SSE2_END;
419 #else
421 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
423 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
425 #if defined (MODULE_NAME_IS_i422_yuy2)
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 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
430 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
431 MMX_CALL( MMX_YUV422_UYVY );
432 #endif
434 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
436 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
438 p_y += i_source_margin;
439 p_u += i_source_margin_c;
440 p_v += i_source_margin_c;
441 p_line += i_dest_margin;
443 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
444 MMX_END;
445 #endif
447 #endif
450 /*****************************************************************************
451 * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
452 *****************************************************************************/
453 static void I422_IUYV( filter_t *p_filter, picture_t *p_source,
454 picture_t *p_dest )
456 VLC_UNUSED(p_source); VLC_UNUSED(p_dest);
457 /* FIXME: TODO ! */
458 msg_Err( p_filter, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
461 /*****************************************************************************
462 * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
463 *****************************************************************************/
464 #if defined (MODULE_NAME_IS_i422_yuy2)
465 static void I422_Y211( filter_t *p_filter, picture_t *p_source,
466 picture_t *p_dest )
468 uint8_t *p_line = p_dest->p->p_pixels + p_dest->p->i_visible_lines * p_dest->p->i_pitch;
469 uint8_t *p_y = p_source->Y_PIXELS;
470 uint8_t *p_u = p_source->U_PIXELS;
471 uint8_t *p_v = p_source->V_PIXELS;
473 int i_x, i_y;
475 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
477 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
479 C_YUV422_Y211( p_line, p_y, p_u, p_v );
480 C_YUV422_Y211( p_line, p_y, p_u, p_v );
484 #endif