1 /*
2 * Simple xawtv deinterlacing plugin - cubic interpolation
3 *
4 * CAVEATS: Effectively halves framerate, (working on it)
5 * May cause some general slowness (uses more cpu) but the framerate is smooth
6 * on my athlon 700, running the -mjc branch of 2.4 kernel (preempt and other
7 * patches for desktop performance)
8 *
9 * BENEFITS: It's no longer interlaced ;)
10 * Looks a metric shitton better than line doubling & bilinear interpolation
11 * around text, but these nasty white specks occur on the border of pure black
12 * (0) and pure white (255). My original theory was that it had something to
13 * do with 0 messing up our multiplication, but that does not appear to be the
14 * case based on preliminary fiddling around.
15 *
16 * AUTHORS:
17 * Conrad Kreyling <conrad@conrad.nerdland.org>
18 * Patrick Barrett <yebyen@nerdland.org>
19 *
20 * This is licenced under the GNU GPL until someone tells me I'm stealing code
21 * and can't do that ;) www.gnu.org for any version of the license.
22 *
23 * Based on xawtv-3.66/libng/plugins/flt-nop.c (also GPL)
24 * Cubic deinterlacing algorithm adapted from mplayer's libpostproc
25 */
26
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <pthread.h>
33
34 #include "grab-ng.h"
35
36 /*static int isOdd; // Global variable so we can tell if a frame uses even or
37 //odd scanlines, not implemented properly yet */
38
39 static void inline
deinterlace(struct ng_video_buf * frame)40 deinterlace (struct ng_video_buf *frame)
41 {
42 unsigned int x, y, bytes = frame->fmt.bytesperline;
43
44 /*
45 * if(isOdd){
46 * isOdd=0;
47 * y=3;
48 * }
49 * else
50 * {
51 * isOdd=1;
52 * y=4;
53 * } //Set y based on scanline evenness/oddness, not implemented yet
54 */
55
56 /* for (x=0; x < strlen(frame->data); x++){
57 switch (frame->data[x])
58 {
59 case 0:
60 frame->data[x]++;
61 break;
62 case 255:
63 frame->data[x]--;
64 break;
65 }
66 }*/ // This doesn't work to fix the problem with the specks
67
68 for (y = 3; y < frame->fmt.height - 3; y += 2)
69 {
70 for (x = 0; x < bytes; x++)
71 {
72 frame->data[(y * bytes + x)] =
73 ((-frame->data[((y - 3) * bytes + x)]) +
74 (9 * frame->data[((y - 1) * bytes + x)]) +
75 (9 * frame->data[((y + 1) * bytes + x)]) +
76 (-frame->data[((y + 3) * bytes + x)])) >> 4;
77 } // Basic algorithm borrowed from mplayer's libpostproc
78 } // Angry math
79 }
80
81
82 static void *
init(struct ng_video_fmt * out)83 init (struct ng_video_fmt *out)
84 {
85 /* we will be using this variable soon enough */
86 static int isOdd = 0;
87 return &isOdd;
88 }
89
90 static struct ng_video_buf *
frame(void * handle,struct ng_video_buf * frame)91 frame (void *handle, struct ng_video_buf *frame)
92 {
93 deinterlace (frame);
94 return frame;
95 }
96
97 static void
fini(void * handle)98 fini (void *handle)
99 {
100 /* nothing to clean up */
101 }
102
103 /* ------------------------------------------------------------------- */
104
105 static struct ng_filter filter = {
106 .name ="cubic interpolation",
107 .fmts =
108 (1 << VIDEO_GRAY) |
109 (1 << VIDEO_RGB15_NATIVE) |
110 (1 << VIDEO_RGB16_NATIVE) |
111 (1 << VIDEO_BGR24) |
112 (1 << VIDEO_RGB24) |
113 (1 << VIDEO_BGR32) |
114 (1 << VIDEO_RGB32) |
115 (1 << VIDEO_YUYV) |
116 (1 << VIDEO_UYVY),
117 .init = init,
118 .frame = frame,
119 .fini = fini,
120 };
121
122 extern void ng_plugin_init (void);
123 void
ng_plugin_init(void)124 ng_plugin_init (void)
125 {
126 ng_filter_register (NG_PLUGIN_MAGIC,__FILE__,&filter);
127 }
128