]> git.sesse.net Git - vlc/blob - plugins/yuv/transforms_yuvmmx.c
78eba8dbc604581dd4a38c5dfd1a46d48abc3e42
[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  * $Id: transforms_yuvmmx.c,v 1.4 2001/03/21 13:42:34 sam Exp $
7  *
8  * Authors: Samuel Hocevar <sam@zoy.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this program; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include "defs.h"
30
31 #include <math.h>                                            /* exp(), pow() */
32 #include <errno.h>                                                 /* ENOMEM */
33 #include <stdlib.h>                                                /* free() */
34 #include <string.h>                                            /* strerror() */
35
36 #include "config.h"
37 #include "common.h"
38 #include "threads.h"
39 #include "mtime.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         p_pic_start =   p_pic;
173         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
174
175         for ( i_x = i_width / 8; i_x--; )
176         {
177             __asm__( MMX_INIT_16
178                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
179
180             __asm__( ".align 8"
181                      MMX_YUV_MUL
182                      MMX_YUV_ADD
183                      MMX_UNPACK_16
184                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
185
186             p_y += 8;
187             p_u += 4;
188             p_v += 4;
189             p_buffer += 8;
190         }
191         SCALE_WIDTH;
192         SCALE_HEIGHT( 420, 2 );
193       }
194 }
195
196
197 /*****************************************************************************
198  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
199  *****************************************************************************/
200 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
201 {
202     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16" );
203 }
204
205 /*****************************************************************************
206  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
207  *****************************************************************************/
208 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
209 {
210     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16" );
211 }
212
213 /*****************************************************************************
214  * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
215  *****************************************************************************/
216 void ConvertY4Gray24( YUV_ARGS_24BPP )
217 {
218     intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 24" );
219 }
220
221 /*****************************************************************************
222  * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
223  *****************************************************************************/
224 void ConvertYUV420RGB24( YUV_ARGS_24BPP )
225 {
226     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, bpp = 24" );
227 }
228
229 /*****************************************************************************
230  * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
231  *****************************************************************************/
232 void ConvertYUV422RGB24( YUV_ARGS_24BPP )
233 {
234     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 24" );
235 }
236
237 /*****************************************************************************
238  * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
239  *****************************************************************************/
240 void ConvertYUV444RGB24( YUV_ARGS_24BPP )
241 {
242     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 24" );
243 }
244
245 /*****************************************************************************
246  * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
247  *****************************************************************************/
248 void ConvertY4Gray32( YUV_ARGS_32BPP )
249 {
250     intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32" );
251 }
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     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
281     for( i_y = 0; i_y < i_height; i_y++ )
282     {
283         p_pic_start =   p_pic;
284         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
285
286         for ( i_x = i_width / 8; i_x--; )
287         {
288             __asm__( ".align 8"
289                      MMX_INIT_32
290                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
291
292             __asm__( ".align 8"
293                      MMX_YUV_MUL
294                      MMX_YUV_ADD
295                      MMX_UNPACK_32
296                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
297
298             p_y += 8;
299             p_u += 4;
300             p_v += 4;
301             p_buffer += 8;
302         }
303
304         SCALE_WIDTH;
305         SCALE_HEIGHT( 420, 4 );
306     }
307
308 }
309
310 /*****************************************************************************
311  * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
312  *****************************************************************************/
313 void ConvertYUV422RGB32( YUV_ARGS_32BPP )
314 {
315     intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 32" );
316 }
317
318 /*****************************************************************************
319  * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
320  *****************************************************************************/
321 void ConvertYUV444RGB32( YUV_ARGS_32BPP )
322 {
323     intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32" );
324 }
325
326 /*****************************************************************************
327  * ConvertYUV420YCbr8: color YUV 4:2:0 to YCbr 8 Bpp
328  *****************************************************************************/
329
330 void ConvertYUV420YCbr8    ( YUV_ARGS_8BPP )
331 {
332     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 8" );
333 }
334 /*****************************************************************************
335  * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 8 Bpp
336  *****************************************************************************/
337
338 void ConvertYUV422YCbr8    ( YUV_ARGS_8BPP )
339 {
340     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 8" );
341
342 }
343 /*****************************************************************************
344  * ConvertYUV444YCbr8: color YUV 4:4:4 to YCbr 8 Bpp
345  *****************************************************************************/
346 void ConvertYUV444YCbr8    ( YUV_ARGS_8BPP )
347 {
348     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 8" );
349
350 }
351 /*****************************************************************************
352  * ConvertYUV420YCbr16: color YUV 4:2:0 to YCbr 16 Bpp
353  *****************************************************************************/
354 void ConvertYUV420YCbr16    ( YUV_ARGS_16BPP )
355 {
356     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
357     int         i_vertical_scaling;                 /* vertical scaling type */
358     int         i_x, i_y;                 /* horizontal and vertical indexes */
359     int         i_scale_count;                       /* scale modulo counter */
360     int         i_chroma_width;                              /* chroma width */
361     u16 *       p_pic_start;       /* beginning of the current line for copy */
362     u16 *       p_buffer_start;                   /* conversion buffer start */
363     u16 *       p_buffer;                       /* conversion buffer pointer */
364     int *       p_offset_start;                        /* offset array start */
365     int *       p_offset;                            /* offset array pointer */
366
367     i_pic_line_width -= i_pic_width;
368     i_chroma_width =    i_width / 2;
369     p_buffer_start =    p_vout->yuv.p_buffer;
370     p_offset_start =    p_vout->yuv.p_offset;
371     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
372                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
373
374     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
375     for( i_y = 0; i_y < i_height; i_y++ )
376     {
377         p_pic_start =   p_pic;
378         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
379
380         for ( i_x = i_width / 8; i_x--; )
381         {
382             __asm__( MMX_INIT_16
383                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
384
385             __asm__( ".align 8"
386                      MMX_YUV_YCBR_422
387                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
388
389             p_y += 8;
390             p_u += 4;
391             p_v += 4;
392             p_buffer += 8;
393         }
394         SCALE_WIDTH;
395         SCALE_HEIGHT( 420, 2 );
396   
397       }
398
399 }
400 /*****************************************************************************
401  * ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 16 Bpp
402  *****************************************************************************/
403
404 void ConvertYUV422YCbr16    ( YUV_ARGS_16BPP )
405 {
406     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 16" );
407
408 }
409 /*****************************************************************************
410  * ConvertYUV424YCbr8: color YUV 4:4:4 to YCbr 16 Bpp
411  *****************************************************************************/
412
413 void ConvertYUV444YCbr16    ( YUV_ARGS_16BPP )
414 {
415     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 16" );
416
417 }
418 /*****************************************************************************
419  * ConvertYUV420YCbr24: color YUV 4:2:0 to YCbr 24 Bpp
420  *****************************************************************************/
421
422 void ConvertYUV420YCbr24    ( YUV_ARGS_24BPP )
423 {
424     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 24" );
425
426 }
427 /*****************************************************************************
428  * ConvertYUV422YCbr24: color YUV 4:2:2 to YCbr 24 Bpp
429  *****************************************************************************/
430
431 void ConvertYUV422YCbr24    ( YUV_ARGS_24BPP )
432 {
433     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 24" );
434
435 }
436 /*****************************************************************************
437  * ConvertYUV444YCbr24: color YUV 4:4:4 to YCbr 24 Bpp
438  *****************************************************************************/
439
440 void ConvertYUV444YCbr24    ( YUV_ARGS_24BPP )
441 {
442     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 24" );
443
444 }
445 /*****************************************************************************
446  * ConvertYUV420YCbr32: color YUV 4:2:0 to YCbr 32 Bpp
447  *****************************************************************************/
448
449 void ConvertYUV420YCbr32    ( YUV_ARGS_32BPP )
450 {
451     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 32" );
452
453 }
454 /*****************************************************************************
455  * ConvertYUV422YCbr32: color YUV 4:2:2 to YCbr 32 Bpp
456  *****************************************************************************/
457
458 void ConvertYUV422YCbr32    ( YUV_ARGS_32BPP )
459 {
460     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 32" );
461
462 }
463 /*****************************************************************************
464  * ConvertYUV444YCbr32: color YUV 4:4:4 to YCbr 32 Bpp
465  *****************************************************************************/
466 void ConvertYUV444YCbr32    ( YUV_ARGS_32BPP )
467 {
468     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 32" );
469
470 }
471
472