]> git.sesse.net Git - vlc/blob - plugins/chroma/yv12_rgb8.c
dad8c1a3c10284316eced5bb4474032dff86b070
[vlc] / plugins / chroma / yv12_rgb8.c
1 /*****************************************************************************
2  * yv12_rgb8.c : YUV to paletted RGB8 conversion module for vlc
3  *****************************************************************************
4  * Copyright (C) 2000 VideoLAN
5  * $Id: yv12_rgb8.c,v 1.1 2001/12/16 16:18:36 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 #define MODULE_NAME yv12_rgb8.c
25 #include "modules_inner.h"
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <math.h>                                            /* exp(), pow() */
33 #include <errno.h>                                                 /* ENOMEM */
34 #include <string.h>                                            /* strerror() */
35 #include <stdlib.h>                                      /* malloc(), free() */
36
37 #include "config.h"
38 #include "common.h"                                     /* boolean_t, byte_t */
39 #include "threads.h"
40 #include "mtime.h"
41
42 #include "video.h"
43 #include "video_output.h"
44
45 #include "chroma_common.h"
46 #include "transforms.h"
47
48 #include "modules.h"
49 #include "modules_export.h"
50
51 /*****************************************************************************
52  * chroma_sys_t: chroma method descriptor
53  *****************************************************************************
54  * This structure is part of the chroma transformation descriptor, it
55  * describes the yuv2rgb8 specific properties.
56  *****************************************************************************/
57 typedef struct chroma_sys_s
58 {
59     u8 *p_tables;
60     u8 *p_buffer;
61     u8 *p_offset;
62 } chroma_sys_t;
63
64 /*****************************************************************************
65  * Local and extern prototypes.
66  *****************************************************************************/
67 static void chroma_getfunctions ( function_list_t * p_function_list );
68
69 static int  chroma_Probe        ( probedata_t *p_data );
70 static int  chroma_Init         ( vout_thread_t *p_vout, probedata_t *p_data );
71 static int  chroma_End          ( vout_thread_t *p_vout );
72
73 static void ConvertY4Gray8      ( vout_thread_t *, picture_t *, picture_t * );
74 static void ConvertYUV420RGB8   ( vout_thread_t *, picture_t *, picture_t * );
75
76 /*****************************************************************************
77  * Build configuration tree.
78  *****************************************************************************/
79 MODULE_CONFIG_START
80 ADD_WINDOW( "Configuration for YV12 to RGB8 module" )
81     ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
82 MODULE_CONFIG_STOP
83
84 MODULE_INIT_START
85     p_module->i_capabilities = MODULE_CAPABILITY_NULL
86                                 | MODULE_CAPABILITY_CHROMA;
87     p_module->psz_longname = "YV12 to paletted RGB8 conversion module";
88 MODULE_INIT_STOP
89
90 MODULE_ACTIVATE_START
91     _M( chroma_getfunctions )( &p_module->p_functions->chroma );
92 MODULE_ACTIVATE_STOP
93
94 MODULE_DEACTIVATE_START
95 MODULE_DEACTIVATE_STOP
96
97 /*****************************************************************************
98  * Local prototypes.
99  *****************************************************************************/
100 /*****************************************************************************
101  * Functions exported as capabilities. They are declared as static so that
102  * we don't pollute the namespace too much.
103  *****************************************************************************/
104 void _M( chroma_getfunctions )( function_list_t * p_function_list )
105 {
106     p_function_list->pf_probe = chroma_Probe;
107     p_function_list->functions.chroma.pf_init = chroma_Init;
108     p_function_list->functions.chroma.pf_end  = chroma_End;
109 }
110
111 /*****************************************************************************
112  * chroma_Probe: return a score
113  *****************************************************************************
114  * This function checks that we can handle the required data
115  *****************************************************************************/
116 static int chroma_Probe( probedata_t *p_data )
117 {
118     if( p_data->chroma.source.i_chroma != YUV_420_PICTURE
119          || p_data->chroma.dest.i_chroma != RGB_8BPP_PICTURE )
120     {
121         return 0;
122     }
123
124     return( 100 );
125 }
126
127 /*****************************************************************************
128  * chroma_Init: allocate a chroma function
129  *****************************************************************************
130  * This function allocates and initializes a chroma function
131  *****************************************************************************/
132 static int chroma_Init( vout_thread_t *p_vout, probedata_t *p_data )
133 {
134     if( p_data->chroma.source.i_chroma != YUV_420_PICTURE
135          || p_data->chroma.dest.i_chroma != RGB_8BPP_PICTURE )
136     {
137         return 0;
138     }
139
140     p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
141     if( p_vout->chroma.p_sys == NULL )
142     {
143         return 0;
144     }
145
146     p_vout->chroma.p_sys->p_tables = malloc( sizeof( u8 ) *
147                 (p_vout->b_grayscale ? GRAY_TABLE_SIZE : PALETTE_TABLE_SIZE) );
148     if( p_vout->chroma.p_sys->p_tables == NULL )
149     {
150         free( p_vout->chroma.p_sys );
151         return 0;
152     }
153
154     p_vout->chroma.p_sys->p_buffer = malloc( sizeof( u8 ) * VOUT_MAX_WIDTH );
155     if( p_vout->chroma.p_sys->p_buffer == NULL )
156     {
157         free( p_vout->chroma.p_sys->p_tables );
158         free( p_vout->chroma.p_sys );
159         return 0;
160     }
161
162     p_vout->chroma.p_sys->p_offset = malloc( sizeof( int ) *
163                                            2 * p_data->chroma.dest.i_width );
164     if( p_vout->chroma.p_sys->p_buffer == NULL )
165     {
166         free( p_vout->chroma.p_sys->p_offset );
167         free( p_vout->chroma.p_sys->p_tables );
168         free( p_vout->chroma.p_sys );
169         return 0;
170     }
171
172     //SetYUV( p_vout );
173
174     return 0; 
175 }
176
177 /*****************************************************************************
178  * chroma_End: free the chroma function
179  *****************************************************************************
180  * This function frees the previously allocated chroma function
181  *****************************************************************************/
182 static int chroma_End( vout_thread_t *p_vout )
183 {
184     return 0; 
185 }
186
187 /* Following functions are local */
188
189 #if 0
190 /*****************************************************************************
191  * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
192  *****************************************************************************/
193 static void ConvertY4Gray8( vout_thread_t *p_vout, picture_t *p_source,
194                                                    picture_t *p_dest )
195 {
196     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
197     int         i_vertical_scaling;                 /* vertical scaling type */
198     int         i_x, i_y;                 /* horizontal and vertical indexes */
199     int         i_scale_count;                       /* scale modulo counter */
200     int         i_chroma_width;                    /* chroma width, not used */
201     u8 *        p_gray;                             /* base conversion table */
202     u8 *        p_pic_start;       /* beginning of the current line for copy */
203     u8 *        p_buffer_start;                   /* conversion buffer start */
204     u8 *        p_buffer;                       /* conversion buffer pointer */
205     int *       p_offset_start;                        /* offset array start */
206     int *       p_offset;                            /* offset array pointer */
207
208     /*
209      * Initialize some values  - i_pic_line_width will store the line skip
210      */
211 //    i_pic_line_width -= i_pic_width;
212     p_gray =            p_vout->chroma.p_sys->p_gray8;
213     p_buffer_start =    p_vout->chroma.p_sys->p_buffer;
214     p_offset_start =    p_vout->chroma.p_sys->p_offset;
215     _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
216                &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
217
218     /*
219      * Perform conversion
220      */
221     i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
222     for( i_y = 0; i_y < i_height; i_y++ )
223     {
224         /* Mark beginnning of line for possible later line copy, and initialize
225          * buffer */
226         p_pic_start =   p_pic;
227         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;
228
229         /* Do YUV conversion to buffer - YUV picture is always formed of 16
230          * pixels wide blocks */
231         for( i_x = i_width / 16; i_x--;  )
232         {
233             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
234             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
235             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
236             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
237             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
238             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
239             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
240             *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
241         }
242
243         /* Do horizontal and vertical scaling */
244         SCALE_WIDTH;
245         SCALE_HEIGHT(400, 1);
246     }
247 }
248 #endif
249
250 /*****************************************************************************
251  * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
252  *****************************************************************************/
253 static void ConvertYUV420RGB8( vout_thread_t *p_vout, picture_t *p_source,
254                                                       picture_t *p_dest )
255 {
256     printf( "Colorspace transformation, YV12 to RGB8\n");
257 #if 0
258     boolean_t   b_horizontal_scaling;             /* horizontal scaling type */
259     int         i_vertical_scaling;                 /* vertical scaling type */
260     int         i_x, i_y;                 /* horizontal and vertical indexes */
261     int         i_scale_count;                       /* scale modulo counter */
262     int         i_real_y;                                           /* y % 4 */
263     u8 *        p_lookup;                                    /* lookup table */
264     int         i_chroma_width;                              /* chroma width */
265     u8 *        p_offset_start;                        /* offset array start */
266     u8 *        p_offset;                            /* offset array pointer */
267
268     int i_pic_line_width = p_source->i_width; /* XXX not sure */
269     int i_width = p_source->i_width;
270     int i_height = p_source->i_height;
271     int i_pic_width = p_dest->i_width;
272     int i_pic_height = p_dest->i_height;
273     u8* p_y = p_source->planes[ Y_PLANE ].p_data;
274     u8* p_u = p_source->planes[ U_PLANE ].p_data;
275     u8* p_v = p_source->planes[ V_PLANE ].p_data;
276     u8* p_pic = p_dest->planes[ RGB_PLANE ].p_data;
277
278     /* 
279      * The dithering matrices
280      */
281     static int dither10[4] = {  0x0,  0x8,  0x2,  0xa };
282     static int dither11[4] = {  0xc,  0x4,  0xe,  0x6 };
283     static int dither12[4] = {  0x3,  0xb,  0x1,  0x9 };
284     static int dither13[4] = {  0xf,  0x7,  0xd,  0x5 };
285
286     static int dither20[4] = {  0x0, 0x10,  0x4, 0x14 };
287     static int dither21[4] = { 0x18,  0x8, 0x1c,  0xc };
288     static int dither22[4] = {  0x6, 0x16,  0x2, 0x12 };
289     static int dither23[4] = { 0x1e,  0xe, 0x1a,  0xa };
290
291     /*
292      * Initialize some values  - i_pic_line_width will store the line skip
293      */
294     i_pic_line_width -= p_dest->i_width; /*i_pic_width*/
295     i_chroma_width =    p_source->i_width / 2;
296     p_offset_start =    p_vout->chroma.p_sys->p_offset;
297     p_lookup =          p_vout->chroma.p_sys->p_tables;
298     _M( SetOffset )( p_source->i_width, p_source->i_height,
299                      p_dest->i_width, p_dest->i_height,
300                      &b_horizontal_scaling, &i_vertical_scaling,
301                      p_offset_start, 1 );
302
303     /*
304      * Perform conversion
305      */
306     i_scale_count = ( i_vertical_scaling == 1 ) ? p_dest->i_height : p_source->i_height;
307     i_real_y = 0;
308     for( i_y = 0; i_y < p_source->i_height; i_y++ )
309     {
310         /* Do horizontal and vertical scaling */
311         SCALE_WIDTH_DITHER( 420 );
312         SCALE_HEIGHT_DITHER( 420 );
313     }
314 #endif
315 }
316