2 * filter_deinterlace.c -- deinterlace filter
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "filter_deinterlace.h"
23 #include <framework/mlt_frame.h>
28 /** Deinterlace class.
33 struct mlt_filter_s parent
;
37 /* Linear Blend filter - C version contributed by Rogerio Brito.
38 This algorithm has the same interface as the other functions.
40 The destination "screen" (pdst) is constructed from the source
41 screen (psrc[0]) line by line.
43 The i-th line of the destination screen is the average of 3 lines
44 from the source screen: the (i-1)-th, i-th and (i+1)-th lines, with
45 the i-th line having weight 2 in the computation.
48 * each line on pdst doesn't depend on previous lines;
49 * due to the way the algorithm is defined, the first & last lines of the
50 screen aren't deinterlaced.
53 static void deinterlace_yuv( uint8_t *pdst
, uint8_t *psrc
, int width
, int height
)
56 register uint8_t *l0
, *l1
, *l2
, *l3
;
58 l0
= pdst
; /* target line */
59 l1
= psrc
; /* 1st source line */
60 l2
= l1
+ width
; /* 2nd source line = line that follows l1 */
61 l3
= l2
+ width
; /* 3rd source line = line that follows l2 */
63 /* Copy the first line */
64 memcpy(l0
, l1
, width
);
67 for (y
= 1; y
< height
-1; ++y
)
69 /* computes avg of: l1 + 2*l2 + l3 */
70 for (x
= 0; x
< width
; ++x
)
71 l0
[x
] = (l1
[x
] + (l2
[x
]<<1) + l3
[x
]) >> 2;
73 /* updates the line pointers */
74 l1
= l2
; l2
= l3
; l3
+= width
;
78 /* Copy the last line */
79 memcpy(l0
, l1
, width
);
85 static int filter_get_image( mlt_frame
this, uint8_t **image
, mlt_image_format
*format
, int *width
, int *height
, int writable
)
87 mlt_frame_get_image( this, image
, format
, width
, height
, 1 );
88 deinterlace_yuv( *image
, *image
, *width
* 2, *height
);
92 /** Deinterlace filter processing - this should be lazy evaluation here...
95 static mlt_frame
deinterlace_process( mlt_filter
this, mlt_frame frame
)
97 mlt_frame_push_get_image( frame
, filter_get_image
);
101 /** Constructor for the filter.
104 mlt_filter
filter_deinterlace_init( void *arg
)
106 filter_deinterlace
*this = calloc( sizeof( filter_deinterlace
), 1 );
109 mlt_filter filter
= &this->parent
;
110 mlt_filter_init( filter
, this );
111 filter
->process
= deinterlace_process
;
112 return &this->parent
;