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.6 2002/06/01 12:31:58 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 <errno.h> /* ENOMEM */
28 #include <string.h> /* strerror() */
29 #include <stdlib.h> /* malloc(), free() */
34 #include "i422_yuy2.h"
36 #define SRC_FOURCC "I422"
37 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
38 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv,Y211"
40 # define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv"
43 /*****************************************************************************
44 * Local and extern prototypes.
45 *****************************************************************************/
46 static void chroma_getfunctions ( function_list_t * p_function_list );
48 static int chroma_Init ( vout_thread_t *p_vout );
49 static void chroma_End ( vout_thread_t *p_vout );
51 static void I422_YUY2 ( vout_thread_t *, picture_t *, picture_t * );
52 static void I422_YVYU ( vout_thread_t *, picture_t *, picture_t * );
53 static void I422_UYVY ( vout_thread_t *, picture_t *, picture_t * );
54 static void I422_IUYV ( vout_thread_t *, picture_t *, picture_t * );
55 static void I422_cyuv ( vout_thread_t *, picture_t *, picture_t * );
56 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
57 static void I422_Y211 ( vout_thread_t *, picture_t *, picture_t * );
60 /*****************************************************************************
61 * Build configuration tree.
62 *****************************************************************************/
67 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
68 SET_DESCRIPTION( _("conversions from " SRC_FOURCC " to " DEST_FOURCC) )
69 ADD_CAPABILITY( CHROMA, 80 )
70 #elif defined (MODULE_NAME_IS_chroma_i422_yuy2_mmx)
71 SET_DESCRIPTION( _("MMX conversions from " SRC_FOURCC " to " DEST_FOURCC) )
72 ADD_CAPABILITY( CHROMA, 100 )
73 ADD_REQUIREMENT( MMX )
78 chroma_getfunctions( &p_module->p_functions->chroma );
81 MODULE_DEACTIVATE_START
82 MODULE_DEACTIVATE_STOP
84 /*****************************************************************************
85 * Functions exported as capabilities. They are declared as static so that
86 * we don't pollute the namespace too much.
87 *****************************************************************************/
88 static void chroma_getfunctions( function_list_t * p_function_list )
90 p_function_list->functions.chroma.pf_init = chroma_Init;
91 p_function_list->functions.chroma.pf_end = chroma_End;
94 /*****************************************************************************
95 * chroma_Init: allocate a chroma function
96 *****************************************************************************
97 * This function allocates and initializes a chroma function
98 *****************************************************************************/
99 static int chroma_Init( vout_thread_t *p_vout )
101 if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
106 switch( p_vout->render.i_chroma )
109 switch( p_vout->output.i_chroma )
113 p_vout->chroma.pf_convert = I422_YUY2;
117 p_vout->chroma.pf_convert = I422_YVYU;
123 p_vout->chroma.pf_convert = I422_UYVY;
127 p_vout->chroma.pf_convert = I422_IUYV;
131 p_vout->chroma.pf_convert = I422_cyuv;
134 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
136 p_vout->chroma.pf_convert = I422_Y211;
152 /*****************************************************************************
153 * chroma_End: free the chroma function
154 *****************************************************************************
155 * This function frees the previously allocated chroma function
156 *****************************************************************************/
157 static void chroma_End( vout_thread_t *p_vout )
162 /* Following functions are local */
164 /*****************************************************************************
165 * I422_YUY2: planar YUV 4:2:2 to packed YUY2 4:2:2
166 *****************************************************************************/
167 static void I422_YUY2( vout_thread_t *p_vout, picture_t *p_source,
170 u8 *p_line = p_dest->p->p_pixels;
171 u8 *p_y = p_source->Y_PIXELS;
172 u8 *p_u = p_source->U_PIXELS;
173 u8 *p_v = p_source->V_PIXELS;
177 for( i_y = p_vout->render.i_height ; i_y-- ; )
179 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
181 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
182 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
183 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
184 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
185 C_YUV422_YUYV( p_line, p_y, p_u, p_v );
187 __asm__( ".align 8" MMX_YUV422_YUYV
188 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
190 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
192 __asm__( ".align 8" MMX_YUV422_YUYV
193 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
195 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
201 /*****************************************************************************
202 * I422_YVYU: planar YUV 4:2:2 to packed YVYU 4:2:2
203 *****************************************************************************/
204 static void I422_YVYU( vout_thread_t *p_vout, picture_t *p_source,
207 u8 *p_line = p_dest->p->p_pixels;
208 u8 *p_y = p_source->Y_PIXELS;
209 u8 *p_u = p_source->U_PIXELS;
210 u8 *p_v = p_source->V_PIXELS;
214 for( i_y = p_vout->render.i_height ; i_y-- ; )
216 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
218 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
219 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
220 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
221 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
222 C_YUV422_YVYU( p_line, p_y, p_u, p_v );
224 __asm__( ".align 8" MMX_YUV422_YVYU
225 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
227 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
229 __asm__( ".align 8" MMX_YUV422_YVYU
230 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
232 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
238 /*****************************************************************************
239 * I422_UYVY: planar YUV 4:2:2 to packed UYVY 4:2:2
240 *****************************************************************************/
241 static void I422_UYVY( vout_thread_t *p_vout, picture_t *p_source,
244 u8 *p_line = p_dest->p->p_pixels;
245 u8 *p_y = p_source->Y_PIXELS;
246 u8 *p_u = p_source->U_PIXELS;
247 u8 *p_v = p_source->V_PIXELS;
251 for( i_y = p_vout->render.i_height ; i_y-- ; )
253 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
255 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
256 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
257 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
258 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
259 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
261 __asm__( ".align 8" MMX_YUV422_UYVY
262 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
264 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
266 __asm__( ".align 8" MMX_YUV422_UYVY
267 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
269 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
275 /*****************************************************************************
276 * I422_IUYV: planar YUV 4:2:2 to interleaved packed IUYV 4:2:2
277 *****************************************************************************/
278 static void I422_IUYV( vout_thread_t *p_vout, picture_t *p_source,
282 msg_Err( p_vout, "I422_IUYV unimplemented, please harass <sam@zoy.org>" );
285 /*****************************************************************************
286 * I422_cyuv: planar YUV 4:2:2 to upside-down packed UYVY 4:2:2
287 *****************************************************************************/
288 static void I422_cyuv( vout_thread_t *p_vout, picture_t *p_source,
291 u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
292 u8 *p_y = p_source->Y_PIXELS;
293 u8 *p_u = p_source->U_PIXELS;
294 u8 *p_v = p_source->V_PIXELS;
298 for( i_y = p_vout->render.i_height ; i_y-- ; )
300 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
302 p_line -= 2 * p_dest->p->i_pitch;
304 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
305 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
306 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
307 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
308 C_YUV422_UYVY( p_line, p_y, p_u, p_v );
310 __asm__( ".align 8" MMX_YUV422_UYVY
311 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
313 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
315 __asm__( ".align 8" MMX_YUV422_UYVY
316 : : "r" (p_line), "r" (p_y), "r" (p_u), "r" (p_v) );
318 p_line += 8; p_y += 4; p_u += 2; p_v += 2;
324 /*****************************************************************************
325 * I422_Y211: planar YUV 4:2:2 to packed YUYV 2:1:1
326 *****************************************************************************/
327 #if defined (MODULE_NAME_IS_chroma_i422_yuy2)
328 static void I422_Y211( vout_thread_t *p_vout, picture_t *p_source,
331 u8 *p_line = p_dest->p->p_pixels + p_dest->p->i_lines * p_dest->p->i_pitch;
332 u8 *p_y = p_source->Y_PIXELS;
333 u8 *p_u = p_source->U_PIXELS;
334 u8 *p_v = p_source->V_PIXELS;
338 for( i_y = p_vout->render.i_height ; i_y-- ; )
340 for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
342 C_YUV422_Y211( p_line, p_y, p_u, p_v );
343 C_YUV422_Y211( p_line, p_y, p_u, p_v );