1 /*****************************************************************************
2 * algo_basic.c : Basic algorithms for the VLC deinterlacer
3 *****************************************************************************
4 * Copyright (C) 2000-2011 VLC authors and VideoLAN
7 * Author: Sam Hocevar <sam@zoy.org>
8 * Damien Lucas <nitrox@videolan.org> (Bob, Blend)
9 * Laurent Aimar <fenrir@videolan.org> (Bob, Blend)
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_picture.h>
35 #include <vlc_filter.h>
38 #include "deinterlace.h" /* definition of p_sys, needed for Merge() */
40 #include "algo_basic.h"
42 /*****************************************************************************
43 * RenderDiscard: only keep TOP or BOTTOM field, discard the other.
44 *****************************************************************************/
46 int RenderDiscard( filter_t
*p_filter
, picture_t
*p_outpic
, picture_t
*p_pic
)
51 /* Copy image and skip lines */
52 for( i_plane
= 0 ; i_plane
< p_pic
->i_planes
; i_plane
++ )
54 uint8_t *p_in
, *p_out_end
, *p_out
;
56 p_in
= p_pic
->p
[i_plane
].p_pixels
;
58 p_out
= p_outpic
->p
[i_plane
].p_pixels
;
59 p_out_end
= p_out
+ p_outpic
->p
[i_plane
].i_pitch
60 * p_outpic
->p
[i_plane
].i_visible_lines
;
62 for( ; p_out
< p_out_end
; )
64 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
66 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
67 p_in
+= 2 * p_pic
->p
[i_plane
].i_pitch
;
73 /*****************************************************************************
74 * RenderBob: renders a BOB picture - simple copy
75 *****************************************************************************/
77 int RenderBob( filter_t
*p_filter
, picture_t
*p_outpic
, picture_t
*p_pic
,
78 int order
, int i_field
)
84 /* Copy image and skip lines */
85 for( i_plane
= 0 ; i_plane
< p_pic
->i_planes
; i_plane
++ )
87 uint8_t *p_in
, *p_out_end
, *p_out
;
89 p_in
= p_pic
->p
[i_plane
].p_pixels
;
90 p_out
= p_outpic
->p
[i_plane
].p_pixels
;
91 p_out_end
= p_out
+ p_outpic
->p
[i_plane
].i_pitch
92 * p_outpic
->p
[i_plane
].i_visible_lines
;
94 /* For BOTTOM field we need to add the first line */
97 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
98 p_in
+= p_pic
->p
[i_plane
].i_pitch
;
99 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
102 p_out_end
-= 2 * p_outpic
->p
[i_plane
].i_pitch
;
104 for( ; p_out
< p_out_end
; )
106 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
108 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
110 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
112 p_in
+= 2 * p_pic
->p
[i_plane
].i_pitch
;
113 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
116 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
118 /* For TOP field we need to add the last line */
121 p_in
+= p_pic
->p
[i_plane
].i_pitch
;
122 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
123 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
129 /*****************************************************************************
130 * RenderLinear: BOB with linear interpolation
131 *****************************************************************************/
133 int RenderLinear( filter_t
*p_filter
,
134 picture_t
*p_outpic
, picture_t
*p_pic
, int order
, int i_field
)
136 VLC_UNUSED(p_filter
);
140 /* Copy image and skip lines */
141 for( i_plane
= 0 ; i_plane
< p_pic
->i_planes
; i_plane
++ )
143 uint8_t *p_in
, *p_out_end
, *p_out
;
145 p_in
= p_pic
->p
[i_plane
].p_pixels
;
146 p_out
= p_outpic
->p
[i_plane
].p_pixels
;
147 p_out_end
= p_out
+ p_outpic
->p
[i_plane
].i_pitch
148 * p_outpic
->p
[i_plane
].i_visible_lines
;
150 /* For BOTTOM field we need to add the first line */
153 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
154 p_in
+= p_pic
->p
[i_plane
].i_pitch
;
155 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
158 p_out_end
-= 2 * p_outpic
->p
[i_plane
].i_pitch
;
160 for( ; p_out
< p_out_end
; )
162 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
164 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
166 Merge( p_out
, p_in
, p_in
+ 2 * p_pic
->p
[i_plane
].i_pitch
,
167 p_pic
->p
[i_plane
].i_pitch
);
169 p_in
+= 2 * p_pic
->p
[i_plane
].i_pitch
;
170 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
173 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
175 /* For TOP field we need to add the last line */
178 p_in
+= p_pic
->p
[i_plane
].i_pitch
;
179 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
180 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
187 /*****************************************************************************
188 * RenderMean: Half-resolution blender
189 *****************************************************************************/
191 int RenderMean( filter_t
*p_filter
, picture_t
*p_outpic
, picture_t
*p_pic
)
193 VLC_UNUSED(p_filter
);
196 /* Copy image and skip lines */
197 for( i_plane
= 0 ; i_plane
< p_pic
->i_planes
; i_plane
++ )
199 uint8_t *p_in
, *p_out_end
, *p_out
;
201 p_in
= p_pic
->p
[i_plane
].p_pixels
;
203 p_out
= p_outpic
->p
[i_plane
].p_pixels
;
204 p_out_end
= p_out
+ p_outpic
->p
[i_plane
].i_pitch
205 * p_outpic
->p
[i_plane
].i_visible_lines
;
207 /* All lines: mean value */
208 for( ; p_out
< p_out_end
; )
210 Merge( p_out
, p_in
, p_in
+ p_pic
->p
[i_plane
].i_pitch
,
211 p_pic
->p
[i_plane
].i_pitch
);
213 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
214 p_in
+= 2 * p_pic
->p
[i_plane
].i_pitch
;
221 /*****************************************************************************
222 * RenderBlend: Full-resolution blender
223 *****************************************************************************/
225 int RenderBlend( filter_t
*p_filter
, picture_t
*p_outpic
, picture_t
*p_pic
)
227 VLC_UNUSED(p_filter
);
230 /* Copy image and skip lines */
231 for( i_plane
= 0 ; i_plane
< p_pic
->i_planes
; i_plane
++ )
233 uint8_t *p_in
, *p_out_end
, *p_out
;
235 p_in
= p_pic
->p
[i_plane
].p_pixels
;
237 p_out
= p_outpic
->p
[i_plane
].p_pixels
;
238 p_out_end
= p_out
+ p_outpic
->p
[i_plane
].i_pitch
239 * p_outpic
->p
[i_plane
].i_visible_lines
;
241 /* First line: simple copy */
242 memcpy( p_out
, p_in
, p_pic
->p
[i_plane
].i_pitch
);
243 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
245 /* Remaining lines: mean value */
246 for( ; p_out
< p_out_end
; )
248 Merge( p_out
, p_in
, p_in
+ p_pic
->p
[i_plane
].i_pitch
,
249 p_pic
->p
[i_plane
].i_pitch
);
251 p_out
+= p_outpic
->p
[i_plane
].i_pitch
;
252 p_in
+= p_pic
->p
[i_plane
].i_pitch
;