]> git.sesse.net Git - vlc/blob - plugins/yuvmmx/video_yuv16.c
. no need to add "\n" at the end of intf_*Msg() messages anymore.
[vlc] / plugins / yuvmmx / video_yuv16.c
1 /*****************************************************************************
2  * video_yuv16.c: YUV transformation functions for 16bpp
3  * Provides functions to perform the YUV conversion. The functions provided here
4  * are a complete and portable C implementation, and may be replaced in certain
5  * case by optimized functions.
6  *****************************************************************************
7  * Copyright (C) 1999, 2000 VideoLAN
8  *
9  * Authors:
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public
22  * License along with this program; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <math.h>                                            /* exp(), pow() */
33 #include <errno.h>                                                 /* ENOMEM */
34 #include <stdlib.h>                                                /* free() */
35 #include <string.h>                                            /* strerror() */
36
37 #include "config.h"
38 #include "common.h"
39 #include "threads.h"
40 #include "mtime.h"
41 #include "plugins.h"
42 #include "video.h"
43 #include "video_output.h"
44 #include "video_yuv.h"
45 #include "video_yuv_macros.h"
46 #include "video_yuv_asm.h"
47
48 #include "intf_msg.h"
49
50 /*****************************************************************************
51  * ConvertY4Gray16: color YUV 4:4:4 to RGB 2 Bpp
52  *****************************************************************************/
53 void ConvertY4Gray16( YUV_ARGS_16BPP )
54 {
55     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
56     int         i_vertical_scaling;                 /* vertical scaling type */
57     int         i_x, i_y;                 /* horizontal and vertical indexes */
58     int         i_scale_count;                       /* scale modulo counter */
59     int         i_chroma_width;                              /* chroma width */
60     u16 *       p_pic_start;       /* beginning of the current line for copy */
61     u16 *       p_buffer_start;                   /* conversion buffer start */
62     u16 *       p_buffer;                       /* conversion buffer pointer */
63     int *       p_offset_start;                        /* offset array start */
64     int *       p_offset;                            /* offset array pointer */
65
66     /*
67      * Initialize some values  - i_pic_line_width will store the line skip
68      */
69     i_pic_line_width -= i_pic_width;
70     i_chroma_width =    i_width / 2;
71     p_buffer_start =    p_vout->yuv.p_buffer;
72     p_offset_start =    p_vout->yuv.p_offset;
73     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
74                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
75
76     /*
77      * Perform conversion
78      */
79     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
80     for( i_y = 0; i_y < i_height; i_y++ )
81     {
82         /* Mark beginnning of line for possible later line copy, and initialize
83          * buffer */
84         p_pic_start =   p_pic;
85         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
86
87         for ( i_x = i_width / 8; i_x--; )
88         {
89             __asm__( MMX_INIT_16_GRAY
90                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
91
92             __asm__( ".align 8"
93                      MMX_YUV_GRAY
94                      MMX_UNPACK_16_GRAY
95                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
96
97             p_y += 8;
98             p_u += 4;
99             p_v += 4;
100             p_buffer += 8;
101         }
102
103         SCALE_WIDTH;
104         SCALE_HEIGHT( 420, 2 );
105     }
106 }
107
108 /*****************************************************************************
109  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
110  *****************************************************************************/
111 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
112 {
113     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
114     int         i_vertical_scaling;                 /* vertical scaling type */
115     int         i_x, i_y;                 /* horizontal and vertical indexes */
116     int         i_scale_count;                       /* scale modulo counter */
117     int         i_chroma_width;                              /* chroma width */
118     u16 *       p_pic_start;       /* beginning of the current line for copy */
119     u16 *       p_buffer_start;                   /* conversion buffer start */
120     u16 *       p_buffer;                       /* conversion buffer pointer */
121     int *       p_offset_start;                        /* offset array start */
122     int *       p_offset;                            /* offset array pointer */
123
124     /*
125      * Initialize some values  - i_pic_line_width will store the line skip
126      */
127     i_pic_line_width -= i_pic_width;
128     i_chroma_width =    i_width / 2;
129     p_buffer_start =    p_vout->yuv.p_buffer;
130     p_offset_start =    p_vout->yuv.p_offset;
131     SetOffset( i_width, i_height, i_pic_width, i_pic_height,
132                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
133
134     /*
135      * Perform conversion
136      */
137     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
138     for( i_y = 0; i_y < i_height; i_y++ )
139     {
140         /* Mark beginnning of line for possible later line copy, and initialize
141          * buffer */
142         p_pic_start =   p_pic;
143         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
144
145         for ( i_x = i_width / 8; i_x--; )
146         {
147             __asm__( MMX_INIT_16
148                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
149
150             __asm__( ".align 8"
151                      MMX_YUV_MUL
152                      MMX_YUV_ADD
153                      MMX_UNPACK_16
154                      : : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
155
156             p_y += 8;
157             p_u += 4;
158             p_v += 4;
159             p_buffer += 8;
160         }
161
162         SCALE_WIDTH;
163         SCALE_HEIGHT( 420, 2 );
164     }
165 }
166
167 /*****************************************************************************
168  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
169  *****************************************************************************/
170 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
171 {
172     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, bpp = 16" );
173 }
174
175 /*****************************************************************************
176  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
177  *****************************************************************************/
178 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
179 {
180     intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, bpp = 16" );
181 }
182