Mercurial > vloopback
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); |
