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