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