qt: playlist: use item title if available
[vlc.git] / modules / video_chroma / i422_yuy2.c
blob9e4ecb729d3c8e0c8aef11ff3f442b661faba42d
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 ( filter_t * );
52 /*****************************************************************************
53 * Module descriptor
54 *****************************************************************************/
55 vlc_module_begin ()
56 #if defined (MODULE_NAME_IS_i422_yuy2)
57 set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
58 set_callback_video_converter( Activate, 80 )
59 # define vlc_CPU_capable() (true)
60 # define VLC_TARGET
61 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
62 set_description( N_("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) )
63 set_callback_video_converter( Activate, 100 )
64 # define vlc_CPU_capable() vlc_CPU_MMX()
65 # define VLC_TARGET VLC_MMX
66 #elif defined (MODULE_NAME_IS_i422_yuy2_sse2)
67 set_description( N_("SSE2 conversions from " SRC_FOURCC " to " DEST_FOURCC) )
68 set_callback_video_converter( Activate, 120 )
69 # define vlc_CPU_capable() vlc_CPU_SSE2()
70 # define VLC_TARGET VLC_SSE
71 #endif
72 vlc_module_end ()
75 VIDEO_FILTER_WRAPPER( I422_YUY2 )
76 VIDEO_FILTER_WRAPPER( I422_YVYU )
77 VIDEO_FILTER_WRAPPER( I422_UYVY )
78 VIDEO_FILTER_WRAPPER( I422_IUYV )
79 #if defined (MODULE_NAME_IS_i422_yuy2)
80 VIDEO_FILTER_WRAPPER( I422_Y211 )
81 #endif
84 static const struct vlc_filter_operations*
85 GetFilterOperations(filter_t *filter)
87 switch( filter->fmt_out.video.i_chroma )
89 case VLC_CODEC_YUYV:
90 return &I422_YUY2_ops;
92 case VLC_CODEC_YVYU:
93 return &I422_YVYU_ops;
95 case VLC_CODEC_UYVY:
96 return &I422_UYVY_ops;
98 case VLC_FOURCC('I','U','Y','V'):
99 return &I422_IUYV_ops;
101 #if defined (MODULE_NAME_IS_i422_yuy2)
102 case VLC_CODEC_Y211:
103 return &I422_Y211_ops;
104 #endif
106 default:
107 return NULL;
112 /*****************************************************************************
113 * Activate: allocate a chroma function
114 *****************************************************************************
115 * This function allocates and initializes a chroma function
116 *****************************************************************************/
117 static int Activate( filter_t *p_filter )
119 if( !vlc_CPU_capable() )
120 return VLC_EGENERIC;
121 if( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) & 1
122 || (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) & 1 )
124 return VLC_EGENERIC;
127 if( p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation )
129 return VLC_EGENERIC;
132 /* This is a i422 -> * converter. */
133 if( p_filter->fmt_in.video.i_chroma != VLC_CODEC_I422 )
134 return VLC_EGENERIC;
137 p_filter->ops = GetFilterOperations( p_filter );
138 if( p_filter->ops == NULL)
139 return VLC_EGENERIC;
141 return VLC_SUCCESS;
144 /* Following functions are local */
146 /*****************************************************************************
147 * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
148 *****************************************************************************/
149 VLC_TARGET
150 static void I422_YUY2( filter_t *p_filter, picture_t *p_source,
151 picture_t *p_dest )
153 uint8_t *p_line = p_dest->p->p_pixels;
154 uint8_t *p_y = p_source->Y_PIXELS;
155 uint8_t *p_u = p_source->U_PIXELS;
156 uint8_t *p_v = p_source->V_PIXELS;
158 int i_x, i_y;
160 const int i_source_margin = p_source->p[0].i_pitch
161 - p_source->p[0].i_visible_pitch
162 - p_filter->fmt_in.video.i_x_offset;
163 const int i_source_margin_c = p_source->p[1].i_pitch
164 - p_source->p[1].i_visible_pitch
165 - ( p_filter->fmt_in.video.i_x_offset );
166 const int i_dest_margin = p_dest->p->i_pitch
167 - p_dest->p->i_visible_pitch
168 - ( p_filter->fmt_out.video.i_x_offset * 2 );
170 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
172 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
173 ((intptr_t)p_line|(intptr_t)p_y))) )
175 /* use faster SSE2 aligned fetch and store */
176 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
178 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
180 SSE2_CALL( SSE2_YUV422_YUYV_ALIGNED );
182 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
184 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
186 p_y += i_source_margin;
187 p_u += i_source_margin_c;
188 p_v += i_source_margin_c;
189 p_line += i_dest_margin;
192 else {
193 /* use slower SSE2 unaligned fetch and store */
194 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
196 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
198 SSE2_CALL( SSE2_YUV422_YUYV_UNALIGNED );
200 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
202 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
204 p_y += i_source_margin;
205 p_u += i_source_margin_c;
206 p_v += i_source_margin_c;
207 p_line += i_dest_margin;
210 SSE2_END;
212 #else
214 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
216 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
218 #if defined (MODULE_NAME_IS_i422_yuy2)
219 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
220 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
221 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
222 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
223 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
224 MMX_CALL( MMX_YUV422_YUYV );
225 #endif
227 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
229 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
231 p_y += i_source_margin;
232 p_u += i_source_margin_c;
233 p_v += i_source_margin_c;
234 p_line += i_dest_margin;
236 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
237 MMX_END;
238 #endif
240 #endif
243 /*****************************************************************************
244 * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
245 *****************************************************************************/
246 VLC_TARGET
247 static void I422_YVYU( filter_t *p_filter, picture_t *p_source,
248 picture_t *p_dest )
250 uint8_t *p_line = p_dest->p->p_pixels;
251 uint8_t *p_y = p_source->Y_PIXELS;
252 uint8_t *p_u = p_source->U_PIXELS;
253 uint8_t *p_v = p_source->V_PIXELS;
255 int i_x, i_y;
257 const int i_source_margin = p_source->p[0].i_pitch
258 - p_source->p[0].i_visible_pitch
259 - p_filter->fmt_in.video.i_x_offset;
260 const int i_source_margin_c = p_source->p[1].i_pitch
261 - p_source->p[1].i_visible_pitch
262 - ( p_filter->fmt_in.video.i_x_offset );
263 const int i_dest_margin = p_dest->p->i_pitch
264 - p_dest->p->i_visible_pitch
265 - ( p_filter->fmt_out.video.i_x_offset * 2 );
267 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
269 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
270 ((intptr_t)p_line|(intptr_t)p_y))) )
272 /* use faster SSE2 aligned fetch and store */
273 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
275 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
277 SSE2_CALL( SSE2_YUV422_YVYU_ALIGNED );
279 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
281 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
283 p_y += i_source_margin;
284 p_u += i_source_margin_c;
285 p_v += i_source_margin_c;
286 p_line += i_dest_margin;
289 else {
290 /* use slower SSE2 unaligned fetch and store */
291 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
293 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
295 SSE2_CALL( SSE2_YUV422_YVYU_UNALIGNED );
297 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
299 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
301 p_y += i_source_margin;
302 p_u += i_source_margin_c;
303 p_v += i_source_margin_c;
304 p_line += i_dest_margin;
307 SSE2_END;
309 #else
311 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
313 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
315 #if defined (MODULE_NAME_IS_i422_yuy2)
316 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
317 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
318 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
319 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
320 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
321 MMX_CALL( MMX_YUV422_YVYU );
322 #endif
324 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
326 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
328 p_y += i_source_margin;
329 p_u += i_source_margin_c;
330 p_v += i_source_margin_c;
331 p_line += i_dest_margin;
333 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
334 MMX_END;
335 #endif
337 #endif
340 /*****************************************************************************
341 * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
342 *****************************************************************************/
343 VLC_TARGET
344 static void I422_UYVY( filter_t *p_filter, picture_t *p_source,
345 picture_t *p_dest )
347 uint8_t *p_line = p_dest->p->p_pixels;
348 uint8_t *p_y = p_source->Y_PIXELS;
349 uint8_t *p_u = p_source->U_PIXELS;
350 uint8_t *p_v = p_source->V_PIXELS;
352 int i_x, i_y;
354 const int i_source_margin = p_source->p[0].i_pitch
355 - p_source->p[0].i_visible_pitch
356 - p_filter->fmt_in.video.i_x_offset;
357 const int i_source_margin_c = p_source->p[1].i_pitch
358 - p_source->p[1].i_visible_pitch
359 - ( p_filter->fmt_in.video.i_x_offset );
360 const int i_dest_margin = p_dest->p->i_pitch
361 - p_dest->p->i_visible_pitch
362 - ( p_filter->fmt_out.video.i_x_offset * 2 );
364 #if defined (MODULE_NAME_IS_i422_yuy2_sse2)
366 if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch|
367 ((intptr_t)p_line|(intptr_t)p_y))) )
369 /* use faster SSE2 aligned fetch and store */
370 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
372 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
374 SSE2_CALL( SSE2_YUV422_UYVY_ALIGNED );
376 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
378 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
380 p_y += i_source_margin;
381 p_u += i_source_margin_c;
382 p_v += i_source_margin_c;
383 p_line += i_dest_margin;
386 else {
387 /* use slower SSE2 unaligned fetch and store */
388 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
390 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 16 ; i_x-- ; )
392 SSE2_CALL( SSE2_YUV422_UYVY_UNALIGNED );
394 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 16 ) / 2; i_x-- ; )
396 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
398 p_y += i_source_margin;
399 p_u += i_source_margin_c;
400 p_v += i_source_margin_c;
401 p_line += i_dest_margin;
404 SSE2_END;
406 #else
408 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
410 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
412 #if defined (MODULE_NAME_IS_i422_yuy2)
413 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
414 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
415 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
416 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
417 #elif defined (MODULE_NAME_IS_i422_yuy2_mmx)
418 MMX_CALL( MMX_YUV422_UYVY );
419 #endif
421 for( i_x = ( (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) % 8 ) / 2; i_x-- ; )
423 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
425 p_y += i_source_margin;
426 p_u += i_source_margin_c;
427 p_v += i_source_margin_c;
428 p_line += i_dest_margin;
430 #if defined (MODULE_NAME_IS_i422_yuy2_mmx)
431 MMX_END;
432 #endif
434 #endif
437 /*****************************************************************************
438 * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
439 *****************************************************************************/
440 static void I422_IUYV( filter_t *p_filter, picture_t *p_source,
441 picture_t *p_dest )
443 VLC_UNUSED(p_source); VLC_UNUSED(p_dest);
444 /* FIXME: TODO ! */
445 msg_Err( p_filter, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
448 /*****************************************************************************
449 * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
450 *****************************************************************************/
451 #if defined (MODULE_NAME_IS_i422_yuy2)
452 static void I422_Y211( filter_t *p_filter, picture_t *p_source,
453 picture_t *p_dest )
455 uint8_t *p_line = p_dest->p->p_pixels + p_dest->p->i_visible_lines * p_dest->p->i_pitch;
456 uint8_t *p_y = p_source->Y_PIXELS;
457 uint8_t *p_u = p_source->U_PIXELS;
458 uint8_t *p_v = p_source->V_PIXELS;
460 int i_x, i_y;
462 for( i_y = (p_filter->fmt_in.video.i_y_offset + p_filter->fmt_in.video.i_visible_height) ; i_y-- ; )
464 for( i_x = (p_filter->fmt_in.video.i_x_offset + p_filter->fmt_in.video.i_visible_width) / 8 ; i_x-- ; )
466 C_YUV422_Y211( p_line, p_y, p_u, p_v );
467 C_YUV422_Y211( p_line, p_y, p_u, p_v );
471 #endif