]> git.sesse.net Git - vlc/blob - plugins/chroma/yv12_rgb16.c
* ./ChangeLog: imported the 0.2.92 changes, unrolled current CVS changes.
[vlc] / plugins / chroma / yv12_rgb16.c
1 /*****************************************************************************
2  * yv12_rgb16.c : YUV to paletted RGB16 conversion module for vlc
3  *****************************************************************************
4  * Copyright (C) 2000 VideoLAN
5  * $Id: yv12_rgb16.c,v 1.3 2002/01/02 14:37:42 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 "chroma_common.h"
38 #include "transforms.h"
39
40 /*****************************************************************************
41  * chroma_sys_t: chroma method descriptor
42  *****************************************************************************
43  * This structure is part of the chroma transformation descriptor, it
44  * describes the yuv2rgb16 specific properties.
45  *****************************************************************************/
46 typedef struct chroma_sys_s
47 {
48     u8 *p_tables;
49     u8 *p_buffer;
50     u8 *p_offset;
51 } chroma_sys_t;
52
53 /*****************************************************************************
54  * Local and extern prototypes.
55  *****************************************************************************/
56 static void chroma_getfunctions ( function_list_t * p_function_list );
57
58 static int  chroma_Probe        ( probedata_t *p_data );
59 static int  chroma_Init         ( vout_thread_t *p_vout );
60 static void chroma_End          ( vout_thread_t *p_vout );
61
62 static void ConvertYUV420RGB16  ( vout_thread_t *, picture_t *, picture_t * );
63
64 /*****************************************************************************
65  * Build configuration tree.
66  *****************************************************************************/
67 MODULE_CONFIG_START
68 MODULE_CONFIG_STOP
69
70 MODULE_INIT_START
71     SET_DESCRIPTION( "YV12 to RGB16 conversion module" )
72     ADD_CAPABILITY( CHROMA, 80 )
73 MODULE_INIT_STOP
74
75 MODULE_ACTIVATE_START
76     _M( chroma_getfunctions )( &p_module->p_functions->chroma );
77 MODULE_ACTIVATE_STOP
78
79 MODULE_DEACTIVATE_START
80 MODULE_DEACTIVATE_STOP
81
82 /*****************************************************************************
83  * Local prototypes.
84  *****************************************************************************/
85 /*****************************************************************************
86  * Functions exported as capabilities. They are declared as static so that
87  * we don't pollute the namespace too much.
88  *****************************************************************************/
89 void _M( chroma_getfunctions )( function_list_t * p_function_list )
90 {
91     p_function_list->pf_probe = chroma_Probe;
92     p_function_list->functions.chroma.pf_init = chroma_Init;
93     p_function_list->functions.chroma.pf_end  = chroma_End;
94 }
95
96 /*****************************************************************************
97  * chroma_Probe: return a score
98  *****************************************************************************
99  * This function checks that we can handle the required data
100  *****************************************************************************/
101 static int chroma_Probe( probedata_t *p_data )
102 {
103     switch( p_data->chroma.p_render->i_chroma )
104     {
105         case FOURCC_YV12:
106         case FOURCC_I420:
107         case FOURCC_IYUV:
108             switch( ONLY_FOURCC( p_data->chroma.p_output->i_chroma ) )
109             {
110                 case FOURCC_BI_BITFIELDS:
111                     break;
112
113                 default:
114                     return 0;
115             }
116             break;
117
118         default:
119             return 0;
120     }
121
122     return 100;
123 }
124
125 /*****************************************************************************
126  * chroma_Init: allocate a chroma function
127  *****************************************************************************
128  * This function allocates and initializes a chroma function
129  *****************************************************************************/
130 static int chroma_Init( vout_thread_t *p_vout )
131 {
132     switch( p_vout->render.i_chroma )
133     {
134         case FOURCC_YV12:
135         case FOURCC_I420:
136         case FOURCC_IYUV:
137             switch( ONLY_FOURCC( p_vout->output.i_chroma ) )
138             {
139                 case FOURCC_BI_BITFIELDS:
140                     switch( ONLY_EXTRA( p_vout->output.i_chroma ) )
141                     {
142                         case DEPTH_16BPP:
143                             p_vout->chroma.pf_convert = ConvertYUV420RGB16;
144                             break;
145
146                         default:
147                             return -1;
148                     }
149                     break;
150
151                 default:
152                     return -1;
153             }
154             break;
155
156         default:
157             return -1;
158     }
159     
160 #if 0
161     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
162     if( p_vout->chroma.p_sys == NULL )
163     {
164         return -1;
165     }
166 #endif
167
168     /* FIXME: this is really suboptimal ! */
169
170     return 0; 
171 }
172
173 /*****************************************************************************
174  * chroma_End: free the chroma function
175  *****************************************************************************
176  * This function frees the previously allocated chroma function
177  *****************************************************************************/
178 static void chroma_End( vout_thread_t *p_vout )
179 {
180 #if 0
181     free( p_vout->chroma.p_sys );
182 #endif
183
184     return; 
185 }
186
187 /* Following functions are local */
188
189 /*****************************************************************************
190  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 8 bpp
191  *****************************************************************************/
192 static void ConvertYUV420RGB16( vout_thread_t *p_vout, picture_t *p_source,
193                                                        picture_t *p_dest )
194 {
195     /**********************************************************************
196      *          XXX   XXX    FIXME      FIXME   XXX  XXX    XXX           *
197      *          XXX   XXX   XXX TODO  TODO XXX  XXX  XXX   TODO           *
198      *          XXX   XXX  XXX   XXX  XXX       XXX XXX    XXX            *
199      *          XXX FIXME  XXX FIXME  XXX       FIXME     XXX             *
200      *          XXX   XXX  XXX   XXX  XXX       XXX XXX   XXX             *
201      *          XXX   XXX  XXX   XXX  TODO XXX  XXX  XXX                  *
202      *          XXX   XXX  XXX   XXX    FIXME   XXX  XXX  XXX             *
203      **********************************************************************/
204
205     pixel_data_t *p_in, *p_in_end, *p_out, *p_out_end;
206
207     p_in = p_source->P_Y;
208     p_in_end = p_in + p_source->planes[ Y_PLANE ].i_bytes;
209
210     p_out = p_dest->P_MAIN;
211     p_out_end = p_out + p_dest->planes[ MAIN_PLANE ].i_bytes;
212
213     while( p_in < p_in_end && p_out < p_out_end )
214     {
215         int i_src = p_source->planes[ Y_PLANE ].i_line_bytes;
216         int i_dst = p_dest->planes[ MAIN_PLANE ].i_line_bytes / 2;
217
218         /* Masks: 0xf800 0x07e0 0x001f */
219 #define RED ((u16*)p_out)[--i_dst] = (u16)(p_in[--i_src]>>3) << 11;
220 #define GREEN ((u16*)p_out)[--i_dst] = (u16)(p_in[--i_src]>>2) << 5;
221 #define BLUE ((u16*)p_out)[--i_dst] = (u16)(p_in[--i_src]>>3) << 0;
222 #define WHITE ((u16*)p_out)[--i_dst] = ((u16)(p_in[i_src]>>3) << 11) | ((u16)(p_in[i_src]>>2) << 5) | ((u16)(p_in[i_src]>>3) << 0); --i_src;
223 #define BLACK ((u16*)p_out)[--i_dst] = 0; --i_src;
224         
225         while( i_src && i_dst )
226         {
227             WHITE; WHITE; WHITE; WHITE; WHITE; WHITE; WHITE; WHITE;
228             //BLACK; BLUE; GREEN; RED; GREEN; BLUE; WHITE; RED;
229         }
230
231         p_in += p_source->planes[ Y_PLANE ].i_line_bytes;
232         p_out += p_dest->planes[ MAIN_PLANE ].i_line_bytes;
233
234         if( p_in >= p_in_end || p_out >= p_out_end )
235         {
236             break;
237         }
238
239         i_src = p_source->planes[ Y_PLANE ].i_line_bytes;
240         i_dst = p_dest->planes[ MAIN_PLANE ].i_line_bytes / 2;
241
242         while( i_src && i_dst )
243         {
244             WHITE; WHITE; WHITE; WHITE; WHITE; WHITE; WHITE; WHITE;
245             //GREEN; RED; WHITE; BLUE; BLACK; RED; GREEN; BLUE;
246         }
247
248         p_in += p_source->planes[ Y_PLANE ].i_line_bytes;
249         p_out += p_dest->planes[ MAIN_PLANE ].i_line_bytes;
250     }
251
252     /**********************************************************************
253      *          XXX   XXX  XXX   XXX    FIXME   XXX  XXX    XXX           *
254      *          XXX   XXX  XXX   XXX  TODO XXX  XXX  XXX   TODO           *
255      *           XXX XXX   XXX   XXX  XXX       XXX XXX    XXX            *
256      *             TODO    XXX   XXX  XXX       FIXME     XXX             *
257      *            TODO     XXX   XXX  XXX       XXX XXX   XXX             *
258      *           XXX       TODO  XXX  TODO XXX  XXX  XXX                  *
259      *          XXX          FIXME      FIXME   XXX  XXX  XXX             *
260      **********************************************************************/
261 }
262