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