]> git.sesse.net Git - vlc/blob - modules/video_chroma/yuy2_i422.c
Merge branch 1.0-bugfix
[vlc] / modules / video_chroma / yuy2_i422.c
1 /*****************************************************************************
2  * yuy2_i422.c : Packed YUV 4:2:2 to Planar YUV conversion module for vlc
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea at videolan dot 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_filter.h>
35 #include <vlc_vout.h>
36
37 #define SRC_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,cyuv"
38 #define DEST_FOURCC  "I422"
39
40 /*****************************************************************************
41  * Local and extern prototypes.
42  *****************************************************************************/
43 static int  Activate ( vlc_object_t * );
44
45 static void YUY2_I422           ( filter_t *, picture_t *, picture_t * );
46 static void YVYU_I422           ( filter_t *, picture_t *, picture_t * );
47 static void UYVY_I422           ( filter_t *, picture_t *, picture_t * );
48 static void cyuv_I422           ( filter_t *, picture_t *, picture_t * );
49 static picture_t *YUY2_I422_Filter    ( filter_t *, picture_t * );
50 static picture_t *YVYU_I422_Filter    ( filter_t *, picture_t * );
51 static picture_t *UYVY_I422_Filter    ( filter_t *, picture_t * );
52 static picture_t *cyuv_I422_Filter    ( filter_t *, picture_t * );
53
54 /*****************************************************************************
55  * Module descriptor
56  *****************************************************************************/
57 vlc_module_begin ()
58     set_description( N_("Conversions from " SRC_FOURCC " to " DEST_FOURCC) )
59     set_capability( "video filter2", 80 )
60     set_callbacks( Activate, NULL )
61 vlc_module_end ()
62
63 /*****************************************************************************
64  * Activate: allocate a chroma function
65  *****************************************************************************
66  * This function allocates and initializes a chroma function
67  *****************************************************************************/
68 static int Activate( vlc_object_t *p_this )
69 {
70     filter_t *p_filter = (filter_t *)p_this;
71
72     if( p_filter->fmt_in.video.i_width & 1
73      || p_filter->fmt_in.video.i_height & 1 )
74     {
75         return -1;
76     }
77
78     if( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width
79      || p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height )
80         return -1;
81
82     switch( p_filter->fmt_out.video.i_chroma )
83     {
84         case VLC_CODEC_I422:
85             switch( p_filter->fmt_in.video.i_chroma )
86             {
87                 case VLC_CODEC_YUYV:
88                     p_filter->pf_video_filter = YUY2_I422_Filter;
89                     break;
90
91                 case VLC_CODEC_YVYU:
92                     p_filter->pf_video_filter = YVYU_I422_Filter;
93                     break;
94
95                 case VLC_CODEC_UYVY:
96                     p_filter->pf_video_filter = UYVY_I422_Filter;
97                     break;
98
99                 case VLC_CODEC_CYUV:
100                     p_filter->pf_video_filter = cyuv_I422_Filter;
101                     break;
102
103                 default:
104                     return -1;
105             }
106             break;
107
108         default:
109             return -1;
110     }
111     return 0;
112 }
113
114 /* Following functions are local */
115
116 VIDEO_FILTER_WRAPPER( YUY2_I422 )
117 VIDEO_FILTER_WRAPPER( YVYU_I422 )
118 VIDEO_FILTER_WRAPPER( UYVY_I422 )
119 VIDEO_FILTER_WRAPPER( cyuv_I422 )
120
121 /*****************************************************************************
122  * YUY2_I422: packed YUY2 4:2:2 to planar YUV 4:2:2
123  *****************************************************************************/
124 static void YUY2_I422( filter_t *p_filter, picture_t *p_source,
125                                            picture_t *p_dest )
126 {
127     uint8_t *p_line = p_source->p->p_pixels;
128
129     uint8_t *p_y = p_dest->Y_PIXELS;
130     uint8_t *p_u = p_dest->U_PIXELS;
131     uint8_t *p_v = p_dest->V_PIXELS;
132
133     int i_x, i_y;
134
135     const int i_dest_margin = p_dest->p[0].i_pitch
136                                  - p_dest->p[0].i_visible_pitch;
137     const int i_dest_margin_c = p_dest->p[1].i_pitch
138                                  - p_dest->p[1].i_visible_pitch;
139     const int i_source_margin = p_source->p->i_pitch
140                                - p_source->p->i_visible_pitch;
141
142     for( i_y = p_filter->fmt_out.video.i_height ; i_y-- ; )
143     {
144         for( i_x = p_filter->fmt_out.video.i_width / 8 ; i_x-- ; )
145         {
146 #define C_YUYV_YUV422( p_line, p_y, p_u, p_v )      \
147             *p_y++ = *p_line++; *p_u++ = *p_line++; \
148             *p_y++ = *p_line++; *p_v++ = *p_line++
149             C_YUYV_YUV422( p_line, p_y, p_u, p_v );
150             C_YUYV_YUV422( p_line, p_y, p_u, p_v );
151             C_YUYV_YUV422( p_line, p_y, p_u, p_v );
152             C_YUYV_YUV422( p_line, p_y, p_u, p_v );
153         }
154         for( i_x = ( p_filter->fmt_out.video.i_width % 8 ) / 2; i_x-- ; )
155         {
156             C_YUYV_YUV422( p_line, p_y, p_u, p_v );
157         }
158         p_line += i_source_margin;
159         p_y += i_dest_margin;
160         p_u += i_dest_margin_c;
161         p_v += i_dest_margin_c;
162     }
163 }
164
165 /*****************************************************************************
166  * YVYU_I422: packed YVYU 4:2:2 to planar YUV 4:2:2
167  *****************************************************************************/
168 static void YVYU_I422( filter_t *p_filter, picture_t *p_source,
169                                            picture_t *p_dest )
170 {
171     uint8_t *p_line = p_source->p->p_pixels;
172
173     uint8_t *p_y = p_dest->Y_PIXELS;
174     uint8_t *p_u = p_dest->U_PIXELS;
175     uint8_t *p_v = p_dest->V_PIXELS;
176
177     int i_x, i_y;
178
179     const int i_dest_margin = p_dest->p[0].i_pitch
180                                  - p_dest->p[0].i_visible_pitch;
181     const int i_dest_margin_c = p_dest->p[1].i_pitch
182                                  - p_dest->p[1].i_visible_pitch;
183     const int i_source_margin = p_source->p->i_pitch
184                                - p_source->p->i_visible_pitch;
185
186     for( i_y = p_filter->fmt_out.video.i_height ; i_y-- ; )
187     {
188         for( i_x = p_filter->fmt_out.video.i_width / 8 ; i_x-- ; )
189         {
190 #define C_YVYU_YUV422( p_line, p_y, p_u, p_v )      \
191             *p_y++ = *p_line++; *p_v++ = *p_line++; \
192             *p_y++ = *p_line++; *p_u++ = *p_line++
193             C_YVYU_YUV422( p_line, p_y, p_u, p_v );
194             C_YVYU_YUV422( p_line, p_y, p_u, p_v );
195             C_YVYU_YUV422( p_line, p_y, p_u, p_v );
196             C_YVYU_YUV422( p_line, p_y, p_u, p_v );
197         }
198         for( i_x = ( p_filter->fmt_out.video.i_width % 8 ) / 2; i_x-- ; )
199         {
200             C_YVYU_YUV422( p_line, p_y, p_u, p_v );
201         }
202         p_line += i_source_margin;
203         p_y += i_dest_margin;
204         p_u += i_dest_margin_c;
205         p_v += i_dest_margin_c;
206     }
207 }
208
209 /*****************************************************************************
210  * UYVY_I422: packed UYVY 4:2:2 to planar YUV 4:2:2
211  *****************************************************************************/
212 static void UYVY_I422( filter_t *p_filter, picture_t *p_source,
213                                            picture_t *p_dest )
214 {
215     uint8_t *p_line = p_source->p->p_pixels;
216
217     uint8_t *p_y = p_dest->Y_PIXELS;
218     uint8_t *p_u = p_dest->U_PIXELS;
219     uint8_t *p_v = p_dest->V_PIXELS;
220
221     int i_x, i_y;
222
223     const int i_dest_margin = p_dest->p[0].i_pitch
224                                  - p_dest->p[0].i_visible_pitch;
225     const int i_dest_margin_c = p_dest->p[1].i_pitch
226                                  - p_dest->p[1].i_visible_pitch;
227     const int i_source_margin = p_source->p->i_pitch
228                                - p_source->p->i_visible_pitch;
229
230     for( i_y = p_filter->fmt_out.video.i_height ; i_y-- ; )
231     {
232         for( i_x = p_filter->fmt_out.video.i_width / 8 ; i_x-- ; )
233         {
234 #define C_UYVY_YUV422( p_line, p_y, p_u, p_v )      \
235             *p_u++ = *p_line++; *p_y++ = *p_line++; \
236             *p_v++ = *p_line++; *p_y++ = *p_line++
237             C_UYVY_YUV422( p_line, p_y, p_u, p_v );
238             C_UYVY_YUV422( p_line, p_y, p_u, p_v );
239             C_UYVY_YUV422( p_line, p_y, p_u, p_v );
240             C_UYVY_YUV422( p_line, p_y, p_u, p_v );
241         }
242         for( i_x = ( p_filter->fmt_out.video.i_width % 8 ) / 2; i_x-- ; )
243         {
244             C_UYVY_YUV422( p_line, p_y, p_u, p_v );
245         }
246         p_line += i_source_margin;
247         p_y += i_dest_margin;
248         p_u += i_dest_margin_c;
249         p_v += i_dest_margin_c;
250     }
251 }
252
253 /*****************************************************************************
254  * cyuv_I422: upside-down packed UYVY 4:2:2 to planar YUV 4:2:2
255  * FIXME
256  *****************************************************************************/
257 static void cyuv_I422( filter_t *p_filter, picture_t *p_source,
258                                            picture_t *p_dest )
259 {
260     uint8_t *p_line = p_source->p->p_pixels;
261
262     uint8_t *p_y = p_dest->Y_PIXELS;
263     uint8_t *p_u = p_dest->U_PIXELS;
264     uint8_t *p_v = p_dest->V_PIXELS;
265
266     int i_x, i_y;
267
268     const int i_dest_margin = p_dest->p[0].i_pitch
269                                  - p_dest->p[0].i_visible_pitch;
270     const int i_dest_margin_c = p_dest->p[1].i_pitch
271                                  - p_dest->p[1].i_visible_pitch;
272     const int i_source_margin = p_source->p->i_pitch
273                                - p_source->p->i_visible_pitch;
274
275     for( i_y = p_filter->fmt_out.video.i_height ; i_y-- ; )
276     {
277         for( i_x = p_filter->fmt_out.video.i_width / 8 ; i_x-- ; )
278         {
279 #define C_cyuv_YUV422( p_line, p_y, p_u, p_v )      \
280             *p_y++ = *p_line++; *p_v++ = *p_line++; \
281             *p_y++ = *p_line++; *p_u++ = *p_line++
282             C_cyuv_YUV422( p_line, p_y, p_u, p_v );
283             C_cyuv_YUV422( p_line, p_y, p_u, p_v );
284             C_cyuv_YUV422( p_line, p_y, p_u, p_v );
285             C_cyuv_YUV422( p_line, p_y, p_u, p_v );
286         }
287         for( i_x = ( p_filter->fmt_out.video.i_width % 8 ) / 2; i_x-- ; )
288         {
289             C_cyuv_YUV422( p_line, p_y, p_u, p_v );
290         }
291         p_line += i_source_margin;
292         p_y += i_dest_margin;
293         p_u += i_dest_margin_c;
294         p_v += i_dest_margin_c;
295     }
296 }