Mercurial > vloopback
comparison example/invert.c @ 7:2fce9e157b8d
Added some work around to work with kernel 2.6.27-rc3, added debug param.
author | AngelCarpintero |
---|---|
date | Sun, 24 Aug 2008 02:20:51 +0000 |
parents | 5f21a4dddc0c |
children |
comparison
equal
deleted
inserted
replaced
6:d3fdefea8bce | 7:2fce9e157b8d |
---|---|
19 #include <signal.h> | 19 #include <signal.h> |
20 #include <sys/wait.h> | 20 #include <sys/wait.h> |
21 #include <linux/videodev.h> | 21 #include <linux/videodev.h> |
22 | 22 |
23 | 23 |
24 int fmt=0; | 24 int fmt = 0; |
25 int noexit = 1; | 25 int noexit = 1; |
26 int read_img=0; | 26 int read_img = 0; |
27 | 27 |
28 char *start_capture (int dev, int width, int height) | 28 char *start_capture (int dev, int width, int height) |
29 { | 29 { |
30 struct video_capability vid_caps; | 30 struct video_capability vid_caps; |
31 struct video_window vid_win; | 31 struct video_window vid_win; |
32 struct video_mbuf vid_buf; | 32 struct video_mbuf vid_buf; |
33 char *map; | 33 char *map; |
34 | 34 |
35 if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) { | 35 if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) { |
36 printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno)); | 36 printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno)); |
37 return (NULL); | 37 return (NULL); |
38 } | 38 } |
39 if (vid_caps.type & VID_TYPE_MONOCHROME) fmt=VIDEO_PALETTE_GREY; | 39 if (vid_caps.type & VID_TYPE_MONOCHROME) |
40 if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) { | 40 fmt = VIDEO_PALETTE_GREY; |
41 | |
42 if (ioctl(dev, VIDIOCGMBUF, &vid_buf) == -1) { | |
41 fprintf(stderr, "no mmap falling back on read\n"); | 43 fprintf(stderr, "no mmap falling back on read\n"); |
42 if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) { | 44 |
43 printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno)); | 45 if (ioctl(dev, VIDIOCGWIN, &vid_win) == -1) { |
44 return (NULL); | 46 printf ("ioctl VIDIOCGWIN\nError[%s]\n", strerror(errno)); |
45 } | 47 return (NULL); |
46 vid_win.width=width; | 48 } |
47 vid_win.height=height; | 49 |
48 if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) { | 50 vid_win.width = width; |
49 printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno)); | 51 vid_win.height = height; |
50 return (NULL); | 52 |
51 } | 53 if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) { |
52 read_img=1; | 54 printf ("ioctl VIDIOCSWIN\nError[%s]\n", strerror(errno)); |
53 map=malloc(width*height*3); | 55 return (NULL); |
56 } | |
57 | |
58 read_img = 1; | |
59 map = malloc(width * height * 3); | |
54 return (map); | 60 return (map); |
55 } | 61 } |
56 /* If we are going to capture greyscale we need room to blow the image up */ | 62 /* If we are going to capture greyscale we need room to blow the image up */ |
57 if (fmt==VIDEO_PALETTE_GREY) | 63 if (fmt == VIDEO_PALETTE_GREY) |
58 map=mmap(0, vid_buf.size*3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0); | 64 map = mmap(0, vid_buf.size * 3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0); |
59 else | 65 else |
60 map=mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0); | 66 map = mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0); |
61 | 67 |
62 if ((unsigned char *)-1 == (unsigned char *)map) | 68 if ((unsigned char *)-1 == (unsigned char *)map) |
63 return (NULL); | 69 return (NULL); |
70 | |
64 return map; | 71 return map; |
65 } | 72 } |
66 | 73 |
67 int start_pipe (int dev, int width, int height) | 74 int start_pipe (int dev, int width, int height) |
68 { | 75 { |
69 struct video_capability vid_caps; | 76 struct video_capability vid_caps; |
70 struct video_window vid_win; | 77 struct video_window vid_win; |
71 struct video_picture vid_pic; | 78 struct video_picture vid_pic; |
72 | 79 |
73 if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) { | 80 if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) { |
74 printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno)); | 81 printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno)); |
75 return (1); | 82 return (1); |
76 } | 83 } |
77 if (ioctl (dev, VIDIOCGPICT, &vid_pic)== -1) { | 84 |
78 printf ("ioctl VIDIOCGPICT\nError[%s]\n",strerror(errno)); | 85 if (ioctl(dev, VIDIOCGPICT, &vid_pic)== -1) { |
79 return (1); | 86 printf ("ioctl VIDIOCGPICT\nError[%s]\n", strerror(errno)); |
80 } | 87 return (1); |
81 vid_pic.palette=fmt; | 88 } |
82 if (ioctl (dev, VIDIOCSPICT, &vid_pic)== -1) { | 89 |
83 printf ("ioctl VIDIOCSPICT\nError[%s]\n",strerror(errno)); | 90 vid_pic.palette = fmt; |
84 return (1); | 91 |
85 } | 92 if (ioctl(dev, VIDIOCSPICT, &vid_pic) == -1) { |
86 if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) { | 93 printf ("ioctl VIDIOCSPICT\nError[%s]\n", strerror(errno)); |
87 printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno)); | 94 return (1); |
88 return (1); | 95 } |
89 } | 96 |
90 vid_win.width=width; | 97 if (ioctl (dev, VIDIOCGWIN, &vid_win) == -1) { |
91 vid_win.height=height; | 98 printf ("ioctl VIDIOCGWIN\nError[%s]\n", strerror(errno)); |
92 if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) { | 99 return (1); |
93 printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno)); | 100 } |
101 | |
102 vid_win.width = width; | |
103 vid_win.height = height; | |
104 | |
105 if (ioctl(dev, VIDIOCSWIN, &vid_win)== -1) { | |
106 printf ("ioctl VIDIOCSWIN\nError[%s]\n", strerror(errno)); | |
94 return (1); | 107 return (1); |
95 } | 108 } |
96 return 0; | 109 return 0; |
97 } | 110 } |
98 | 111 |
100 { | 113 { |
101 int i; | 114 int i; |
102 char *grey, *rgb; | 115 char *grey, *rgb; |
103 struct video_mmap vid_mmap; | 116 struct video_mmap vid_mmap; |
104 | 117 |
105 sigset_t set, old; | 118 sigset_t set, old; |
106 | 119 |
107 if (read_img) { | 120 if (read_img) { |
108 if (fmt==VIDEO_PALETTE_GREY) { | 121 if (fmt == VIDEO_PALETTE_GREY) { |
109 if (read(dev, map, width*height) != width*height) | 122 size_t size = width * height; |
123 if (read(dev, map, size) != size) | |
110 return NULL; | 124 return NULL; |
111 } else { | 125 } else { |
112 if (read(dev, map, width*height*3) != width*height*3) | 126 size_t size = width * height * 3; |
127 if (read(dev, map, size) != size) | |
113 return NULL; | 128 return NULL; |
114 } | 129 } |
115 } else { | 130 } else { |
116 vid_mmap.format=fmt; | 131 vid_mmap.format = fmt; |
117 vid_mmap.frame=0; | 132 vid_mmap.frame = 0; |
118 vid_mmap.width=width; | 133 vid_mmap.width = width; |
119 vid_mmap.height=height; | 134 vid_mmap.height = height; |
120 | 135 |
121 sigemptyset (&set); //BTTV hates signals during IOCTL | 136 sigemptyset (&set); //BTTV hates signals during IOCTL |
122 sigaddset (&set, SIGCHLD); //block SIGCHLD & SIGALRM | 137 sigaddset (&set, SIGCHLD); //block SIGCHLD & SIGALRM |
123 sigaddset (&set, SIGALRM); //for the time of ioctls | 138 sigaddset (&set, SIGALRM); //for the time of ioctls |
124 sigprocmask (SIG_BLOCK, &set, &old); | 139 sigprocmask (SIG_BLOCK, &set, &old); |
125 | 140 |
126 if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) { | 141 if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) { |
127 sigprocmask (SIG_UNBLOCK, &old, NULL); | 142 sigprocmask (SIG_UNBLOCK, &old, NULL); |
128 return (NULL); | 143 return (NULL); |
129 } | 144 } |
145 | |
130 if (ioctl(dev, VIDIOCSYNC, &vid_mmap) == -1) { | 146 if (ioctl(dev, VIDIOCSYNC, &vid_mmap) == -1) { |
131 sigprocmask (SIG_UNBLOCK, &old, NULL); | 147 sigprocmask (SIG_UNBLOCK, &old, NULL); |
132 return (NULL); | 148 return (NULL); |
133 } | 149 } |
134 | 150 |
135 sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking | 151 sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking |
136 } | 152 } |
137 /* Blow up a grey */ | 153 /* Blow up a grey */ |
138 if (fmt==VIDEO_PALETTE_GREY) { | 154 if (fmt == VIDEO_PALETTE_GREY) { |
139 i=width*height; | 155 i = width * height; |
140 grey=map+i-1; | 156 grey =map + i - 1; |
141 rgb=map+i*3; | 157 rgb = map + i * 3; |
142 for (; i>=0; i--, grey--) { | 158 for (; i >= 0; i--, grey--) { |
143 *(rgb--)=*grey; | 159 *(rgb--) =*grey; |
144 *(rgb--)=*grey; | 160 *(rgb--) =*grey; |
145 *(rgb--)=*grey; | 161 *(rgb--) =*grey; |
146 } | 162 } |
147 } | 163 } |
148 return map; | 164 return map; |
149 } | 165 } |
150 | 166 |
151 int put_image(int dev, char *image, int width, int height) | 167 int put_image(int dev, char *image, int width, int height) |
152 { | 168 { |
153 if (write(dev, image, width*height*3)!=width*height*3) { | 169 if (write(dev, image, width * height * 3) != width * height * 3) { |
154 printf("Error writing image to pipe!\nError[%s]\n",strerror(errno)); | 170 printf("Error writing image to pipe!\nError[%s]\n", strerror(errno)); |
155 return 0; | 171 return 0; |
156 } | 172 } |
173 | |
157 return 1; | 174 return 1; |
158 } | 175 } |
159 | 176 |
160 | 177 |
161 void sig_handler(int signo) | 178 void sig_handler(int signo) |
167 { | 184 { |
168 int i, devin, devout; | 185 int i, devin, devout; |
169 int width; | 186 int width; |
170 int height; | 187 int height; |
171 char *image_out, *image_new; | 188 char *image_out, *image_new; |
172 char palette[10]={'\0'}; | 189 char palette[10] = {'\0'}; |
173 | 190 |
174 if (argc != 5) { | 191 if (argc != 5) { |
175 printf("Usage:\n\n"); | 192 printf("Usage:\n\n"); |
176 printf("invert input output widthxheight rgb24|yuv420p\n\n"); | 193 printf("invert input output widthxheight rgb24|yuv420p\n\n"); |
177 printf("example: invert /dev/video0 /dev/video1 352x288 yuv420p\n\n"); | 194 printf("example: invert /dev/video0 /dev/video1 352x288 yuv420p\n\n"); |
178 exit(1); | 195 exit(1); |
179 } | 196 } |
180 sscanf(argv[3], "%dx%d", &width, &height); | 197 sscanf(argv[3], "%dx%d", &width, &height); |
181 sscanf(argv[4], "%s", palette); | 198 sscanf(argv[4], "%s", palette); |
182 | 199 |
183 if (!strcmp(palette,"rgb24")) fmt = VIDEO_PALETTE_RGB24; | 200 if (!strcmp(palette,"rgb24")) |
184 else if (!strcmp(palette,"yuv420p")) fmt = VIDEO_PALETTE_YUV420P; | 201 fmt = VIDEO_PALETTE_RGB24; |
202 else if (!strcmp(palette,"yuv420p")) | |
203 fmt = VIDEO_PALETTE_YUV420P; | |
185 else fmt = VIDEO_PALETTE_RGB24; | 204 else fmt = VIDEO_PALETTE_RGB24; |
186 | 205 |
187 | 206 |
188 image_out=malloc(width*height*3); | 207 image_out = malloc(width * height * 3); |
189 | 208 |
190 devin=open (argv[1], O_RDWR); | 209 devin = open (argv[1], O_RDWR); |
210 | |
191 if (devin < 0) { | 211 if (devin < 0) { |
192 printf("Failed to open input video device [%s]\nError:[%s]\n",argv[1],strerror(errno)); | 212 printf("Failed to open input video device [%s]\nError:[%s]\n", argv[1], strerror(errno)); |
193 exit(1); | 213 exit(1); |
194 } | 214 } |
195 | 215 |
196 devout=open (argv[2], O_RDWR); | 216 devout = open (argv[2], O_RDWR); |
217 | |
197 if (devout < 0) { | 218 if (devout < 0) { |
198 printf ("Failed to open output video device [%s]\nError:[%s]\n",argv[2],strerror(errno)); | 219 printf ("Failed to open output video device [%s]\nError:[%s]\n", argv[2], strerror(errno)); |
199 exit(1); | 220 exit(1); |
200 } | 221 } |
201 | 222 |
202 image_new=start_capture (devin, width, height); | 223 image_new = start_capture(devin, width, height); |
224 | |
203 if (!image_new) { | 225 if (!image_new) { |
204 printf("Capture error \n Error[%s]\n",strerror(errno)); | 226 printf("Capture error \n Error[%s]\n", strerror(errno)); |
205 exit(1); | 227 exit(1); |
206 } | 228 } |
207 | 229 |
208 start_pipe(devout, width, height); | 230 start_pipe(devout, width, height); |
209 | 231 |
210 signal(SIGTERM, sig_handler); | 232 signal(SIGTERM, sig_handler); |
211 | 233 |
212 printf("Starting video stream.\n"); | 234 printf("Starting video stream.\n"); |
213 while ( (next_capture(devin, image_new, width, height)) && (noexit) ){ | 235 |
214 for (i=width*height*3; i>=0; i--) image_out[i]=-image_new[i]; | 236 while ( (next_capture(devin, image_new, width, height)) && (noexit) ) { |
215 if (put_image(devout, image_out, width, height)==0) | 237 for (i = width * height * 3; i >= 0; i--) |
238 image_out[i] =-image_new[i]; | |
239 | |
240 if (put_image(devout, image_out, width, height) == 0) { | |
241 if ((read_img) && (image_new)) | |
242 free(image_new); | |
243 else if (fmt == VIDEO_PALETTE_GREY) | |
244 munmap(image_new, width * height * 3); | |
245 else | |
246 munmap(image_new, width * height); | |
247 free(image_out); | |
216 exit(1); | 248 exit(1); |
217 } | 249 } |
218 printf("You bought vaporware!\nError[%s]\n",strerror(errno)); | 250 } |
251 | |
252 printf("You bought vaporware!\nError[%s]\n", strerror(errno)); | |
253 | |
219 close (devin); | 254 close (devin); |
220 close (devout); | 255 close (devout); |
256 | |
257 if ((read_img) && (image_new)) | |
258 free(image_new); | |
259 else if (fmt == VIDEO_PALETTE_GREY) | |
260 munmap(image_new, width * height * 3); | |
261 else | |
262 munmap(image_new, width * height); | |
263 | |
221 free(image_out); | 264 free(image_out); |
265 | |
222 exit(0); | 266 exit(0); |
223 } | 267 } |