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