]> git.sesse.net Git - vlc/blob - plugins/yuv/transforms_yuvmmx.c
1e8dbb987da248b735c72b2ee00d690a3a84204d
[vlc] / plugins / yuv / transforms_yuvmmx.c
1 /*****************************************************************************
2  * transforms_yuvmmx.c: MMX YUV transformation functions
3  * Provides functions to perform the YUV conversion.
4  *****************************************************************************
5  * Copyright (C) 1999, 2000 VideoLAN
6  *
7  * Authors:
8  *
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.
13  *
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 GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public
20  * License along with this program; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <math.h>                                            /* exp(), pow() */
31 #include <errno.h>                                                 /* ENOMEM */
32 #include <stdlib.h>                                                /* free() */
33 #include <string.h>                                            /* strerror() */
34
35 #include "config.h"
36 #include "common.h"
37 #include "threads.h"
38 #include "mtime.h"
39 #include "plugins.h"
40
41 #include "video.h"
42 #include "video_output.h"
43
44 #include "video_common.h"
45 #include "transforms_common.h"
46 #include "transforms_yuvmmx.h"
47
48 #include "intf_msg.h"
49
50 /*****************************************************************************
51  * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
52  *****************************************************************************/
53 void ConvertY4Gray8( YUV_ARGS_8BPP )
54 {
55     intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 8" );
56 }
57
58 /*****************************************************************************
59  * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
60  *****************************************************************************/
61 void ConvertYUV420RGB8( YUV_ARGS_8BPP )
62 {
63     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 8" );
64 }
65
66 /*****************************************************************************
67  * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
68  *****************************************************************************/
69 void ConvertYUV422RGB8( YUV_ARGS_8BPP )
70 {
71     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 8" );
72 }
73
74 /*****************************************************************************
75  * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
76  *****************************************************************************/
77 void ConvertYUV444RGB8( YUV_ARGS_8BPP )
78 {
79     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 8" );
80 }
81
82 /*****************************************************************************
83  * ConvertY4Gray16: color YUV 4:4:4 to RGB 2 Bpp
84  *****************************************************************************/
85 void ConvertY4Gray16( YUV_ARGS_16BPP )
86 {
87     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
88     int         i_vertical_scaling;                 /* vertical scaling type */
89     int         i_x, i_y;                 /* horizontal and vertical indexes */
90     int         i_scale_count;                       /* scale modulo counter */
91     int         i_chroma_width;                              /* chroma width */
92     u16 *       p_pic_start;       /* beginning of the current line for copy */
93     u16 *       p_buffer_start;                   /* conversion buffer start */
94     u16 *       p_buffer;                       /* conversion buffer pointer */
95     int *       p_offset_start;                        /* offset array start */
96     int *       p_offset;                            /* offset array pointer */
97
98     /*
99      * Initialize some values  - i_pic_line_width will store the line skip
100      */
101     i_pic_line_width -= i_pic_width;
102     i_chroma_width =    i_width / 2;
103     p_buffer_start =    p_vout->yuv.p_buffer;
104     p_offset_start =    p_vout->yuv.p_offset;
105     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
106                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
107
108     /*
109      * Perform conversion
110      */
111     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
112     for( i_y = 0; i_y < i_height; i_y++ )
113     {
114         /* Mark beginnning of line for possible later line copy, and initialize
115          * buffer */
116         p_pic_start =   p_pic;
117         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
118
119         for ( i_x = i_width / 8; i_x--; )
120         {
121             __asm__( MMX_INIT_16_GRAY
122                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
123
124             __asm__( ".align 8"
125                      MMX_YUV_GRAY
126                      MMX_UNPACK_16_GRAY
127                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
128
129             p_y += 8;
130             p_u += 4;
131             p_v += 4;
132             p_buffer += 8;
133         }
134
135         SCALE_WIDTH;
136         SCALE_HEIGHT( 420, 2 );
137     }
138 }
139
140 /*****************************************************************************
141  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
142  *****************************************************************************/
143 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
144 {
145     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
146     int         i_vertical_scaling;                 /* vertical scaling type */
147     int         i_x, i_y;                 /* horizontal and vertical indexes */
148     int         i_scale_count;                       /* scale modulo counter */
149     int         i_chroma_width;                              /* chroma width */
150     u16 *       p_pic_start;       /* beginning of the current line for copy */
151     u16 *       p_buffer_start;                   /* conversion buffer start */
152     u16 *       p_buffer;                       /* conversion buffer pointer */
153     int *       p_offset_start;                        /* offset array start */
154     int *       p_offset;                            /* offset array pointer */
155
156     /*
157      * Initialize some values  - i_pic_line_width will store the line skip
158      */
159     i_pic_line_width -= i_pic_width;
160     i_chroma_width =    i_width / 2;
161     p_buffer_start =    p_vout->yuv.p_buffer;
162     p_offset_start =    p_vout->yuv.p_offset;
163     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
164                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
165
166     /*
167      * Perform conversion
168      */
169     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
170     for( i_y = 0; i_y < i_height; i_y++ )
171     {
172         /* Mark beginnning of line for possible later line copy, and initialize
173          * buffer */
174         p_pic_start =   p_pic;
175         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
176
177         for ( i_x = i_width / 8; i_x--; )
178         {
179             __asm__( MMX_INIT_16
180                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
181
182             __asm__( ".align 8"
183                      MMX_YUV_MUL
184                      MMX_YUV_ADD
185                      MMX_UNPACK_16
186                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
187
188             p_y += 8;
189             p_u += 4;
190             p_v += 4;
191             p_buffer += 8;
192         }
193
194         SCALE_WIDTH;
195         SCALE_HEIGHT( 420, 2 );
196     }
197 }
198
199 /*****************************************************************************
200  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
201  *****************************************************************************/
202 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
203 {
204     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16" );
205 }
206
207 /*****************************************************************************
208  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
209  *****************************************************************************/
210 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
211 {
212     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16" );
213 }
214
215 /*****************************************************************************
216  * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
217  *****************************************************************************/
218 void ConvertY4Gray24( YUV_ARGS_24BPP )
219 {
220     intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 24" );
221 }
222
223 /*****************************************************************************
224  * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
225  *****************************************************************************/
226 void ConvertYUV420RGB24( YUV_ARGS_24BPP )
227 {
228     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 24" );
229 }
230
231 /*****************************************************************************
232  * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
233  *****************************************************************************/
234 void ConvertYUV422RGB24( YUV_ARGS_24BPP )
235 {
236     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 24" );
237 }
238
239 /*****************************************************************************
240  * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
241  *****************************************************************************/
242 void ConvertYUV444RGB24( YUV_ARGS_24BPP )
243 {
244     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 24" );
245 }
246
247 /*****************************************************************************
248  * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
249  *****************************************************************************/
250 void ConvertY4Gray32( YUV_ARGS_32BPP )
251 {
252     intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32" );
253 }
254
255 /*****************************************************************************
256  * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
257  *****************************************************************************/
258 void ConvertYUV420RGB32( YUV_ARGS_32BPP )
259 {
260     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
261     int         i_vertical_scaling;                 /* vertical scaling type */
262     int         i_x, i_y;                 /* horizontal and vertical indexes */
263     int         i_scale_count;                       /* scale modulo counter */
264     int         i_chroma_width;                              /* chroma width */
265     u32 *       p_pic_start;       /* beginning of the current line for copy */
266     u32 *       p_buffer_start;                   /* conversion buffer start */
267     u32 *       p_buffer;                       /* conversion buffer pointer */
268     int *       p_offset_start;                        /* offset array start */
269     int *       p_offset;                            /* offset array pointer */
270
271     /*
272      * Initialize some values  - i_pic_line_width will store the line skip
273      */
274     i_pic_line_width -= i_pic_width;
275     i_chroma_width =    i_width / 2;
276     p_buffer_start =    p_vout->yuv.p_buffer;
277     p_offset_start =    p_vout->yuv.p_offset;
278     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
279                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
280
281     /*
282      * Perform conversion
283      */
284     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
285     for( i_y = 0; i_y < i_height; i_y++ )
286     {
287         /* Mark beginnning of line for possible later line copy, and initialize
288          * buffer */
289         p_pic_start =   p_pic;
290         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
291
292         for ( i_x = i_width / 8; i_x--; )
293         {
294             __asm__( ".align 8"
295                      MMX_INIT_32
296                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
297
298             __asm__( ".align 8"
299                      MMX_YUV_MUL
300                      MMX_YUV_ADD
301                      MMX_UNPACK_32
302                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
303
304             p_y += 8;
305             p_u += 4;
306             p_v += 4;
307             p_buffer += 8;
308         }
309
310         SCALE_WIDTH;
311         SCALE_HEIGHT( 420, 4 );
312     }
313 }
314
315 /*****************************************************************************
316  * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
317  *****************************************************************************/
318 void ConvertYUV422RGB32( YUV_ARGS_32BPP )
319 {
320     intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 32" );
321 }
322
323 /*****************************************************************************
324  * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
325  *****************************************************************************/
326 void ConvertYUV444RGB32( YUV_ARGS_32BPP )
327 {
328     intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32" );
329 }
330