]> git.sesse.net Git - vlc/blob - plugins/chroma/i420_rgb.c
* ./BUGS: added a list of known bugs. Please add your findings!
[vlc] / plugins / chroma / i420_rgb.c
1 /*****************************************************************************
2  * i420_rgb.c : YUV to bitmap RGB conversion module for vlc
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: i420_rgb.c,v 1.1 2002/01/04 14:01:34 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
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
17  * GNU General Public License for more details.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <math.h>                                            /* exp(), pow() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdlib.h>                                      /* malloc(), free() */
31
32 #include <videolan/vlc.h>
33
34 #include "video.h"
35 #include "video_output.h"
36
37 #include "i420_rgb.h"
38
39 /*****************************************************************************
40  * Local and extern prototypes.
41  *****************************************************************************/
42 static void chroma_getfunctions ( function_list_t * p_function_list );
43
44 static int  chroma_Probe        ( probedata_t *p_data );
45 static int  chroma_Init         ( vout_thread_t *p_vout );
46 static void chroma_End          ( vout_thread_t *p_vout );
47
48 /*****************************************************************************
49  * Build configuration tree.
50  *****************************************************************************/
51 MODULE_CONFIG_START
52 MODULE_CONFIG_STOP
53
54 MODULE_INIT_START
55 #if defined (MODULE_NAME_IS_chroma_i420_rgb)
56     SET_DESCRIPTION( "I420/IYUV/YV12 to RGB 8/15/16/24/32 conversions" )
57     ADD_CAPABILITY( CHROMA, 80 )
58 #elif defined (MODULE_NAME_IS_chroma_i420_rgb_mmx)
59     SET_DESCRIPTION( "MMX I420/IYUV/YV12 to RGB 15/16/24/32 conversions" )
60     ADD_CAPABILITY( CHROMA, 100 )
61     ADD_REQUIREMENT( MMX )
62 #endif
63 MODULE_INIT_STOP
64
65 MODULE_ACTIVATE_START
66     chroma_getfunctions( &p_module->p_functions->chroma );
67 MODULE_ACTIVATE_STOP
68
69 MODULE_DEACTIVATE_START
70 MODULE_DEACTIVATE_STOP
71
72 /*****************************************************************************
73  * Functions exported as capabilities. They are declared as static so that
74  * we don't pollute the namespace too much.
75  *****************************************************************************/
76 static void chroma_getfunctions( function_list_t * p_function_list )
77 {
78     p_function_list->pf_probe = chroma_Probe;
79     p_function_list->functions.chroma.pf_init = chroma_Init;
80     p_function_list->functions.chroma.pf_end  = chroma_End;
81 }
82
83 /*****************************************************************************
84  * chroma_Probe: return a score
85  *****************************************************************************
86  * This function checks that we can handle the required data
87  *****************************************************************************/
88 static int chroma_Probe( probedata_t *p_data )
89 {
90     if( p_data->chroma.p_render->i_width & 1
91          || p_data->chroma.p_render->i_height & 1 )
92     {
93         return 0;
94     }
95
96     switch( p_data->chroma.p_render->i_chroma )
97     {
98         case FOURCC_YV12:
99         case FOURCC_I420:
100         case FOURCC_IYUV:
101             switch( p_data->chroma.p_output->i_chroma )
102             {
103 #if defined (MODULE_NAME_IS_chroma_i420_rgb)
104                 case FOURCC_BI_RGB:
105                     break;
106 #endif
107                 case FOURCC_RV15:
108                 case FOURCC_RV16:
109                 case FOURCC_BI_BITFIELDS:
110                     break;
111
112                 default:
113                     return 0;
114             }
115             break;
116
117         default:
118             return 0;
119     }
120
121     return 100;
122 }
123
124 /*****************************************************************************
125  * chroma_Init: allocate a chroma function
126  *****************************************************************************
127  * This function allocates and initializes a chroma function
128  *****************************************************************************/
129 static int chroma_Init( vout_thread_t *p_vout )
130 {
131     if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 )
132     {
133         return -1;
134     }
135
136     switch( p_vout->render.i_chroma )
137     {
138         case FOURCC_YV12:
139         case FOURCC_I420:
140         case FOURCC_IYUV:
141             switch( p_vout->output.i_chroma )
142             {
143 #if defined (MODULE_NAME_IS_chroma_i420_rgb)
144                 case FOURCC_BI_RGB:
145                     p_vout->chroma.pf_convert = _M( I420_RGB8 );
146                     break;
147 #endif
148                 case FOURCC_RV15:
149                 case FOURCC_RV16:
150                     p_vout->chroma.pf_convert = _M( I420_RGB16 );
151                     break;
152
153                 case FOURCC_BI_BITFIELDS:
154                     //p_vout->chroma.pf_convert = _M( I420_RGB24 );
155                     p_vout->chroma.pf_convert = _M( I420_RGB32 );
156                     break;
157
158                 default:
159                     return -1;
160             }
161             break;
162
163         default:
164             return -1;
165     }
166     
167     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
168     if( p_vout->chroma.p_sys == NULL )
169     {
170         return -1;
171     }
172
173     switch( p_vout->output.i_chroma )
174     {
175 #if defined (MODULE_NAME_IS_chroma_i420_rgb)
176         case FOURCC_BI_RGB:
177             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH );
178             break;
179 #endif
180
181         case FOURCC_RV15:
182         case FOURCC_RV16:
183             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 2 );
184             break;
185
186         case FOURCC_BI_BITFIELDS:
187             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 4 );
188             break;
189
190         default:
191             p_vout->chroma.p_sys->p_buffer = NULL;
192             break;
193     }
194
195     if( p_vout->chroma.p_sys->p_buffer == NULL )
196     {
197         free( p_vout->chroma.p_sys );
198         return -1;
199     }
200
201     p_vout->chroma.p_sys->p_offset = malloc( p_vout->output.i_width
202                                               * sizeof( int ) );
203     if( p_vout->chroma.p_sys->p_offset == NULL )
204     {
205         free( p_vout->chroma.p_sys->p_buffer );
206         free( p_vout->chroma.p_sys );
207         return -1;
208     }
209
210     return 0; 
211 }
212
213 /*****************************************************************************
214  * chroma_End: free the chroma function
215  *****************************************************************************
216  * This function frees the previously allocated chroma function
217  *****************************************************************************/
218 static void chroma_End( vout_thread_t *p_vout )
219 {
220     free( p_vout->chroma.p_sys->p_offset );
221     free( p_vout->chroma.p_sys->p_buffer );
222     free( p_vout->chroma.p_sys );
223 }
224