rev |
line source |
nuclear@2
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <stdlib.h>
|
nuclear@2
|
3 #include <string.h>
|
nuclear@2
|
4 #include <errno.h>
|
nuclear@2
|
5 #include <signal.h>
|
nuclear@2
|
6 #include <pthread.h>
|
nuclear@2
|
7 #include <wcam.h>
|
nuclear@2
|
8 #include "srv.h"
|
nuclear@2
|
9
|
nuclear@2
|
10 void *frame_proc(void *arg);
|
nuclear@2
|
11 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz);
|
nuclear@2
|
12 void sighandler(int s);
|
nuclear@4
|
13 int parse_args(int argc, char **argv);
|
nuclear@2
|
14
|
nuclear@4
|
15 const char *devfile = "/dev/video0";
|
nuclear@4
|
16 int fd = -1;
|
nuclear@4
|
17 int port = 2828;
|
nuclear@2
|
18 int width = 640;
|
nuclear@2
|
19 int height = 480;
|
nuclear@2
|
20 int framerate = 30;
|
nuclear@2
|
21 unsigned char *frame;
|
nuclear@2
|
22 int done;
|
nuclear@2
|
23 int frame_available;
|
nuclear@2
|
24 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
nuclear@2
|
25 pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
|
nuclear@2
|
26
|
nuclear@2
|
27 int main(int argc, char **argv)
|
nuclear@2
|
28 {
|
nuclear@2
|
29 pthread_t thread;
|
nuclear@2
|
30
|
nuclear@4
|
31 if(parse_args(argc, argv) == -1) {
|
nuclear@4
|
32 return 1;
|
nuclear@2
|
33 }
|
nuclear@2
|
34
|
nuclear@2
|
35 signal(SIGINT, sighandler);
|
nuclear@2
|
36 signal(SIGQUIT, sighandler);
|
nuclear@2
|
37 signal(SIGSEGV, sighandler);
|
nuclear@2
|
38
|
nuclear@4
|
39 if(srv_init(port) == -1) {
|
nuclear@2
|
40 return 1;
|
nuclear@2
|
41 }
|
nuclear@2
|
42
|
nuclear@2
|
43 if(!(frame = malloc(width * height * 4))) {
|
nuclear@2
|
44 perror("failed to allocate frame");
|
nuclear@2
|
45 return 1;
|
nuclear@2
|
46 }
|
nuclear@4
|
47 if(devfile) {
|
nuclear@4
|
48 if((fd = wcam_open(devfile, width, height, framerate)) == -1) {
|
nuclear@4
|
49 fprintf(stderr, "failed to open video device: %s\n", devfile);
|
nuclear@4
|
50 return 1;
|
nuclear@4
|
51 }
|
nuclear@4
|
52 wcam_start(fd);
|
nuclear@4
|
53 } else {
|
nuclear@4
|
54 int i, j;
|
nuclear@4
|
55 unsigned char *pptr = frame;
|
nuclear@4
|
56 for(i=0; i<height; i++) {
|
nuclear@4
|
57 for(j=0; j<width; j++) {
|
nuclear@4
|
58 int p = (i ^ j) & 0xff;
|
nuclear@4
|
59 pptr[0] = p;
|
nuclear@4
|
60 pptr[1] = p << 1;
|
nuclear@4
|
61 pptr[2] = p << 2;
|
nuclear@4
|
62 pptr[3] = 255;
|
nuclear@4
|
63 pptr += 4;
|
nuclear@4
|
64 }
|
nuclear@4
|
65 }
|
nuclear@4
|
66 printf("serving test pattern\n");
|
nuclear@2
|
67 }
|
nuclear@2
|
68
|
nuclear@2
|
69 if(pthread_create(&thread, 0, frame_proc, 0) == -1) {
|
nuclear@2
|
70 fprintf(stderr, "failed to create frame processing thread\n");
|
nuclear@2
|
71 return 1;
|
nuclear@2
|
72 }
|
nuclear@2
|
73
|
nuclear@2
|
74 while(!done) {
|
nuclear@2
|
75 int i, res;
|
nuclear@2
|
76 int *sock = srv_sockets();
|
nuclear@2
|
77 int num_sockets = srv_num_sockets();
|
nuclear@2
|
78 int maxfd = srv_max_socket();
|
nuclear@2
|
79 fd_set rdset;
|
nuclear@2
|
80
|
nuclear@4
|
81 FD_ZERO(&rdset);
|
nuclear@2
|
82
|
nuclear@4
|
83 if(fd != -1) {
|
nuclear@4
|
84 if(fd > maxfd) maxfd = fd;
|
nuclear@4
|
85 FD_SET(fd, &rdset);
|
nuclear@4
|
86 printf("select on socket: %d (video)\n", fd);
|
nuclear@4
|
87 }
|
nuclear@2
|
88
|
nuclear@2
|
89 for(i=0; i<num_sockets; i++) {
|
nuclear@2
|
90 FD_SET(sock[i], &rdset);
|
nuclear@4
|
91 printf("select on socket: %d\n", sock[i]);
|
nuclear@2
|
92 }
|
nuclear@2
|
93
|
nuclear@4
|
94 while((res = select(maxfd + 1, &rdset, 0, 0, 0)) == -1 &&
|
nuclear@4
|
95 errno == EINTR && !done);
|
nuclear@4
|
96 if(done) break;
|
nuclear@2
|
97 if(res == -1) {
|
nuclear@2
|
98 fprintf(stderr, "unexpected failure while waiting for I/O\n");
|
nuclear@2
|
99 break;
|
nuclear@2
|
100 }
|
nuclear@4
|
101 printf("res: %d\n", res);
|
nuclear@2
|
102
|
nuclear@4
|
103 if(fd != -1 && FD_ISSET(fd, &rdset)) {
|
nuclear@2
|
104 wcam_wait(fd);
|
nuclear@2
|
105 pthread_mutex_lock(&mutex);
|
nuclear@2
|
106 frame_available = 1;
|
nuclear@2
|
107 pthread_mutex_unlock(&mutex);
|
nuclear@2
|
108 pthread_cond_signal(&condvar);
|
nuclear@2
|
109 }
|
nuclear@2
|
110
|
nuclear@2
|
111 for(i=0; i<num_sockets; i++) {
|
nuclear@2
|
112 if(FD_ISSET(sock[i], &rdset)) {
|
nuclear@2
|
113 srv_handle(sock[i]);
|
nuclear@5
|
114 if(fd == -1) {
|
nuclear@5
|
115 pthread_mutex_lock(&mutex);
|
nuclear@5
|
116 frame_available = 1;
|
nuclear@5
|
117 pthread_mutex_unlock(&mutex);
|
nuclear@5
|
118 pthread_cond_signal(&condvar);
|
nuclear@5
|
119 }
|
nuclear@2
|
120 }
|
nuclear@2
|
121 }
|
nuclear@2
|
122 }
|
nuclear@2
|
123
|
nuclear@2
|
124 frame_available = 1;
|
nuclear@2
|
125 pthread_cond_signal(&condvar);
|
nuclear@2
|
126 pthread_join(thread, 0);
|
nuclear@2
|
127 free(frame);
|
nuclear@4
|
128 if(fd != -1) {
|
nuclear@4
|
129 wcam_stop(fd);
|
nuclear@4
|
130 wcam_close(fd);
|
nuclear@4
|
131 }
|
nuclear@2
|
132 return 0;
|
nuclear@2
|
133 }
|
nuclear@2
|
134
|
nuclear@2
|
135 void *frame_proc(void *arg)
|
nuclear@2
|
136 {
|
nuclear@2
|
137 for(;;) {
|
nuclear@2
|
138 pthread_mutex_lock(&mutex);
|
nuclear@2
|
139 while(!frame_available) {
|
nuclear@2
|
140 pthread_cond_wait(&condvar, &mutex);
|
nuclear@2
|
141 }
|
nuclear@2
|
142 frame_available = 0;
|
nuclear@2
|
143 pthread_mutex_unlock(&mutex);
|
nuclear@2
|
144
|
nuclear@2
|
145 if(done) break;
|
nuclear@2
|
146
|
nuclear@4
|
147 if(fd != -1) {
|
nuclear@4
|
148 wcam_read_frame_rgb(fd, frame);
|
nuclear@5
|
149 /*save_image("output.ppm", frame, width, height);*/
|
nuclear@4
|
150 }
|
nuclear@5
|
151 srv_send_frame(frame, width, height);
|
nuclear@2
|
152 }
|
nuclear@2
|
153 return 0;
|
nuclear@2
|
154 }
|
nuclear@2
|
155
|
nuclear@2
|
156 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz)
|
nuclear@2
|
157 {
|
nuclear@2
|
158 int i, num_pixels = xsz * ysz;
|
nuclear@2
|
159 FILE *fp = fopen(fname, "wb");
|
nuclear@2
|
160 if(!fp) return -1;
|
nuclear@2
|
161
|
nuclear@2
|
162 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
|
nuclear@2
|
163 for(i=0; i<num_pixels; i++) {
|
nuclear@2
|
164 fputc(*pixels++, fp);
|
nuclear@2
|
165 fputc(*pixels++, fp);
|
nuclear@2
|
166 fputc(*pixels++, fp);
|
nuclear@2
|
167 ++pixels;
|
nuclear@2
|
168 }
|
nuclear@2
|
169 fclose(fp);
|
nuclear@2
|
170 return 0;
|
nuclear@2
|
171 }
|
nuclear@2
|
172
|
nuclear@2
|
173 void sighandler(int s)
|
nuclear@2
|
174 {
|
nuclear@2
|
175 done = 1;
|
nuclear@2
|
176 }
|
nuclear@4
|
177
|
nuclear@4
|
178 void print_usage(const char *argv0)
|
nuclear@4
|
179 {
|
nuclear@4
|
180 printf("Usage: %s [options]\n", argv0);
|
nuclear@4
|
181 printf("options:\n");
|
nuclear@4
|
182 printf(" -s,-size <WxH>\n");
|
nuclear@4
|
183 printf(" -f,-fps <framerate>\n");
|
nuclear@4
|
184 printf(" -d,-device <devfile>\n");
|
nuclear@4
|
185 printf(" -p,-port <port>\n");
|
nuclear@4
|
186 printf(" -novideo\n");
|
nuclear@4
|
187 printf(" -h,-help\n");
|
nuclear@4
|
188 }
|
nuclear@4
|
189
|
nuclear@4
|
190 int parse_args(int argc, char **argv)
|
nuclear@4
|
191 {
|
nuclear@4
|
192 int i;
|
nuclear@4
|
193
|
nuclear@4
|
194 for(i=1; i<argc; i++) {
|
nuclear@4
|
195 if(argv[i][0] == '-') {
|
nuclear@4
|
196 if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "-size") == 0) {
|
nuclear@4
|
197 if(sscanf(argv[++i], "%dx%d", &width, &height) != 2) {
|
nuclear@4
|
198 fprintf(stderr, "invalid size specified: %s\n", argv[i - 1]);
|
nuclear@4
|
199 return -1;
|
nuclear@4
|
200 }
|
nuclear@4
|
201 } else if(strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "-fps") == 0) {
|
nuclear@4
|
202 framerate = atoi(argv[++i]);
|
nuclear@4
|
203 if(framerate <= 0) {
|
nuclear@4
|
204 fprintf(stderr, "invalid framerate specified: %s\n", argv[i - 1]);
|
nuclear@4
|
205 return -1;
|
nuclear@4
|
206 }
|
nuclear@4
|
207 } else if(strcmp(argv[i], "-novideo") == 0) {
|
nuclear@4
|
208 devfile = 0;
|
nuclear@4
|
209 } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-device") == 0) {
|
nuclear@4
|
210 devfile = argv[++i];
|
nuclear@4
|
211 } else if(strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-port") == 0) {
|
nuclear@4
|
212 port = atoi(argv[++i]);
|
nuclear@4
|
213 if(port <= 0 || port >= 65535) {
|
nuclear@4
|
214 fprintf(stderr, "invalid port specified: %s\n", argv[i - 1]);
|
nuclear@4
|
215 return -1;
|
nuclear@4
|
216 }
|
nuclear@4
|
217 } else {
|
nuclear@4
|
218 int help = strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0;
|
nuclear@4
|
219 if(!help) fprintf(stderr, "unrecognized option: %s\n", argv[i]);
|
nuclear@4
|
220 print_usage(argv[0]);
|
nuclear@4
|
221 exit(help ? 0 : 1);
|
nuclear@4
|
222 }
|
nuclear@4
|
223 } else {
|
nuclear@4
|
224 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
|
nuclear@4
|
225 print_usage(argv[0]);
|
nuclear@4
|
226 return -1;
|
nuclear@4
|
227 }
|
nuclear@4
|
228 }
|
nuclear@4
|
229 return 0;
|
nuclear@4
|
230 }
|