]> git.sesse.net Git - vlc/blob - plugins/chroma/i420_rgb.c
279b72e05299a91456a802fc9cd97952b5685fc8
[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.2 2002/01/12 01:25:57 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_RGB32 );
155                     break;
156
157                 default:
158                     return -1;
159             }
160             break;
161
162         default:
163             return -1;
164     }
165     
166     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
167     if( p_vout->chroma.p_sys == NULL )
168     {
169         return -1;
170     }
171
172     switch( p_vout->output.i_chroma )
173     {
174 #if defined (MODULE_NAME_IS_chroma_i420_rgb)
175         case FOURCC_BI_RGB:
176             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH );
177             break;
178 #endif
179
180         case FOURCC_RV15:
181         case FOURCC_RV16:
182             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 2 );
183             break;
184
185         case FOURCC_BI_BITFIELDS:
186             p_vout->chroma.p_sys->p_buffer = malloc( VOUT_MAX_WIDTH * 4 );
187             break;
188
189         default:
190             p_vout->chroma.p_sys->p_buffer = NULL;
191             break;
192     }
193
194     if( p_vout->chroma.p_sys->p_buffer == NULL )
195     {
196         free( p_vout->chroma.p_sys );
197         return -1;
198     }
199
200     p_vout->chroma.p_sys->p_offset = malloc( p_vout->output.i_width
201                                               * sizeof( int ) );
202     if( p_vout->chroma.p_sys->p_offset == NULL )
203     {
204         free( p_vout->chroma.p_sys->p_buffer );
205         free( p_vout->chroma.p_sys );
206         return -1;
207     }
208
209     return 0; 
210 }
211
212 /*****************************************************************************
213  * chroma_End: free the chroma function
214  *****************************************************************************
215  * This function frees the previously allocated chroma function
216  *****************************************************************************/
217 static void chroma_End( vout_thread_t *p_vout )
218 {
219     free( p_vout->chroma.p_sys->p_offset );
220     free( p_vout->chroma.p_sys->p_buffer );
221     free( p_vout->chroma.p_sys );
222 }
223