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 }