1 /*****************************************************************************
2 * i422_yuy2.c : YUV to YUV conversion module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: i422_yuy2.c,v 1.1 2002/01/04 14:01:34 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <math.h> /* exp(), pow() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
30 #include <stdlib.h> /* malloc(), free() */
32 #include <videolan/vlc.h>
35 #include "video_output.h"
37 #include "i422_yuy2.h"
39 #define SRC_FOURCC "I422"
40 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
41 # define DEST_FOURCC "YUY2/YUNV/YVYU/UYVY/UYNV/Y422/IUYV/cyuv/Y211"
43 # define DEST_FOURCC "YUY2/YUNV/YVYU/UYVY/UYNV/Y422/IUYV/cyuv"
46 /*****************************************************************************
47 * Local and extern prototypes.
48 *****************************************************************************/
49 static void chroma_getfunctions ( function_list_t * p_function_list );
51 static int chroma_Probe ( probedata_t *p_data );
52 static int chroma_Init ( vout_thread_t *p_vout );
53 static void chroma_End ( vout_thread_t *p_vout );
55 static void I422_YUY2 ( vout_thread_t *, picture_t *, picture_t * );
56 static void I422_YVYU ( vout_thread_t *, picture_t *, picture_t * );
57 static void I422_UYVY ( vout_thread_t *, picture_t *, picture_t * );
58 static void I422_IUYV ( vout_thread_t *, picture_t *, picture_t * );
59 static void I422_cyuv ( vout_thread_t *, picture_t *, picture_t * );
60 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
61 static void I422_Y211 ( vout_thread_t *, picture_t *, picture_t * );
64 /*****************************************************************************
65 * Build configuration tree.
66 *****************************************************************************/
71 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
72 SET_DESCRIPTION( "conversions from " SRC_FOURCC " to " DEST_FOURCC )
73 ADD_CAPABILITY( CHROMA, 80 )
74 #elif defined (MODULE_NAME_IS_chroma_i422_yuy2_mmx)
75 SET_DESCRIPTION( "MMX conversions from " SRC_FOURCC " to " DEST_FOURCC )
76 ADD_CAPABILITY( CHROMA, 100 )
77 ADD_REQUIREMENT( MMX )
82 chroma_getfunctions( &p_module->p_functions->chroma );
85 MODULE_DEACTIVATE_START
86 MODULE_DEACTIVATE_STOP
88 /*****************************************************************************
89 * Functions exported as capabilities. They are declared as static so that
90 * we don't pollute the namespace too much.
91 *****************************************************************************/
92 static void chroma_getfunctions( function_list_t * p_function_list )
94 p_function_list->pf_probe = chroma_Probe;
95 p_function_list->functions.chroma.pf_init = chroma_Init;
96 p_function_list->functions.chroma.pf_end = chroma_End;
99 /*****************************************************************************
100 * chroma_Probe: return a score
101 *****************************************************************************
102 * This function checks that we can handle the required data
103 *****************************************************************************/
104 static int chroma_Probe( probedata_t *p_data )
106 if( p_data->chroma.p_render->i_width & 1
107 || p_data->chroma.p_render->i_height & 1 )
112 switch( p_data->chroma.p_render->i_chroma )
115 switch( p_data->chroma.p_output->i_chroma )
135 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
152 /*****************************************************************************
153 * chroma_Init: allocate a chroma function
154 *****************************************************************************
155 * This function allocates and initializes a chroma function
156 *****************************************************************************/
157 static int chroma_Init( vout_thread_t *p_vout )
159 if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
164 switch( p_vout->render.i_chroma )
167 switch( p_vout->output.i_chroma )
171 p_vout->chroma.pf_convert = I422_YUY2;
175 p_vout->chroma.pf_convert = I422_YVYU;
181 p_vout->chroma.pf_convert = I422_UYVY;
185 p_vout->chroma.pf_convert = I422_IUYV;
189 p_vout->chroma.pf_convert = I422_cyuv;
192 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
194 p_vout->chroma.pf_convert = I422_Y211;
210 /*****************************************************************************
211 * chroma_End: free the chroma function
212 *****************************************************************************
213 * This function frees the previously allocated chroma function
214 *****************************************************************************/
215 static void chroma_End( vout_thread_t *p_vout )
220 /* Following functions are local */
222 /*****************************************************************************
223 * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
224 *****************************************************************************/
225 static void I422_YUY2( vout_thread_t *p_vout, picture_t *p_source,
228 u8 *p_line = p_dest->p->p_pixels;
229 u8 *p_y = p_source->Y_PIXELS;
230 u8 *p_u = p_source->U_PIXELS;
231 u8 *p_v = p_source->V_PIXELS;
235 for( i_y = p_vout->render.i_height ; i_y-- ; )
237 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
239 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
240 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
241 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
242 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
243 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
245 __asm__( ".align 8" MMX_YUV422_YUYV
246 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
248 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
250 __asm__( ".align 8" MMX_YUV422_YUYV
251 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
253 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
259 /*****************************************************************************
260 * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
261 *****************************************************************************/
262 static void I422_YVYU( vout_thread_t *p_vout, picture_t *p_source,
265 u8 *p_line = p_dest->p->p_pixels;
266 u8 *p_y = p_source->Y_PIXELS;
267 u8 *p_u = p_source->U_PIXELS;
268 u8 *p_v = p_source->V_PIXELS;
272 for( i_y = p_vout->render.i_height ; i_y-- ; )
274 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
276 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
277 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
278 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
279 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
280 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
282 __asm__( ".align 8" MMX_YUV422_YVYU
283 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
285 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
287 __asm__( ".align 8" MMX_YUV422_YVYU
288 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
290 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
296 /*****************************************************************************
297 * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
298 *****************************************************************************/
299 static void I422_UYVY( vout_thread_t *p_vout, picture_t *p_source,
302 u8 *p_line = p_dest->p->p_pixels;
303 u8 *p_y = p_source->Y_PIXELS;
304 u8 *p_u = p_source->U_PIXELS;
305 u8 *p_v = p_source->V_PIXELS;
309 for( i_y = p_vout->render.i_height ; i_y-- ; )
311 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
313 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
314 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
315 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
316 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
317 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
319 __asm__( ".align 8" MMX_YUV422_UYVY
320 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
322 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
324 __asm__( ".align 8" MMX_YUV422_UYVY
325 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
327 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
333 /*****************************************************************************
334 * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
335 *****************************************************************************/
336 static void I422_IUYV( vout_thread_t *p_vout, picture_t *p_source,
340 intf_ErrMsg( "chroma error: I422_IUYV unimplemented, "
341 "please harass <sam@zoy.org>" );
344 /*****************************************************************************
345 * I422_cyuv: planar YUV 4:2:2 to upside-down packed UYVY 4:2:2
346 *****************************************************************************/
347 static void I422_cyuv( vout_thread_t *p_vout, picture_t *p_source,
350 u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
351 u8 *p_y = p_source->Y_PIXELS;
352 u8 *p_u = p_source->U_PIXELS;
353 u8 *p_v = p_source->V_PIXELS;
357 for( i_y = p_vout->render.i_height ; i_y-- ; )
359 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
361 p_line -= 2 * p_dest->p->i_pitch;
363 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
364 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
365 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
366 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
367 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
369 __asm__( ".align 8" MMX_YUV422_UYVY
370 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
372 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
374 __asm__( ".align 8" MMX_YUV422_UYVY
375 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
377 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
383 /*****************************************************************************
384 * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
385 *****************************************************************************/
386 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
387 static void I422_Y211( vout_thread_t *p_vout, picture_t *p_source,
390 u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
391 u8 *p_y = p_source->Y_PIXELS;
392 u8 *p_u = p_source->U_PIXELS;
393 u8 *p_v = p_source->V_PIXELS;
397 for( i_y = p_vout->render.i_height ; i_y-- ; )
399 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
401 C_YUV422_Y211( p_line, p_y, p_u, p_v );
402 C_YUV422_Y211( p_line, p_y, p_u, p_v );