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@2
|
13
|
nuclear@2
|
14 int fd;
|
nuclear@2
|
15 int width = 640;
|
nuclear@2
|
16 int height = 480;
|
nuclear@2
|
17 int framerate = 30;
|
nuclear@2
|
18 unsigned char *frame;
|
nuclear@2
|
19 int done;
|
nuclear@2
|
20 int frame_available;
|
nuclear@2
|
21 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
nuclear@2
|
22 pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
|
nuclear@2
|
23
|
nuclear@2
|
24 int main(int argc, char **argv)
|
nuclear@2
|
25 {
|
nuclear@2
|
26 char *devfile = "/dev/video0";
|
nuclear@2
|
27 pthread_t thread;
|
nuclear@2
|
28
|
nuclear@2
|
29 if(argv[1]) {
|
nuclear@2
|
30 devfile = argv[1];
|
nuclear@2
|
31 }
|
nuclear@2
|
32
|
nuclear@2
|
33 signal(SIGINT, sighandler);
|
nuclear@2
|
34 signal(SIGQUIT, sighandler);
|
nuclear@2
|
35 signal(SIGSEGV, sighandler);
|
nuclear@2
|
36
|
nuclear@2
|
37 if(srv_init(2828) == -1) {
|
nuclear@2
|
38 return 1;
|
nuclear@2
|
39 }
|
nuclear@2
|
40
|
nuclear@2
|
41 if(!(frame = malloc(width * height * 4))) {
|
nuclear@2
|
42 perror("failed to allocate frame");
|
nuclear@2
|
43 return 1;
|
nuclear@2
|
44 }
|
nuclear@2
|
45
|
nuclear@2
|
46 if((fd = wcam_open(devfile, width, height, framerate)) == -1) {
|
nuclear@2
|
47 fprintf(stderr, "failed to open video device: %s\n", devfile);
|
nuclear@2
|
48 return 1;
|
nuclear@2
|
49 }
|
nuclear@2
|
50 wcam_start(fd);
|
nuclear@2
|
51
|
nuclear@2
|
52 if(pthread_create(&thread, 0, frame_proc, 0) == -1) {
|
nuclear@2
|
53 fprintf(stderr, "failed to create frame processing thread\n");
|
nuclear@2
|
54 return 1;
|
nuclear@2
|
55 }
|
nuclear@2
|
56
|
nuclear@2
|
57 while(!done) {
|
nuclear@2
|
58 int i, res;
|
nuclear@2
|
59 int *sock = srv_sockets();
|
nuclear@2
|
60 int num_sockets = srv_num_sockets();
|
nuclear@2
|
61 int maxfd = srv_max_socket();
|
nuclear@2
|
62 fd_set rdset;
|
nuclear@2
|
63
|
nuclear@2
|
64 if(fd > maxfd) maxfd = fd;
|
nuclear@2
|
65
|
nuclear@2
|
66 FD_ZERO(&rdset);
|
nuclear@2
|
67 FD_SET(fd, &rdset);
|
nuclear@2
|
68
|
nuclear@2
|
69 for(i=0; i<num_sockets; i++) {
|
nuclear@2
|
70 FD_SET(sock[i], &rdset);
|
nuclear@2
|
71 }
|
nuclear@2
|
72
|
nuclear@2
|
73 while((res = select(maxfd + 1, &rdset, 0, 0, 0)) == -1 && errno == EINTR);
|
nuclear@2
|
74 if(res == -1) {
|
nuclear@2
|
75 fprintf(stderr, "unexpected failure while waiting for I/O\n");
|
nuclear@2
|
76 break;
|
nuclear@2
|
77 }
|
nuclear@2
|
78
|
nuclear@2
|
79 if(FD_ISSET(fd, &rdset)) {
|
nuclear@2
|
80 wcam_wait(fd);
|
nuclear@2
|
81 pthread_mutex_lock(&mutex);
|
nuclear@2
|
82 frame_available = 1;
|
nuclear@2
|
83 pthread_mutex_unlock(&mutex);
|
nuclear@2
|
84 pthread_cond_signal(&condvar);
|
nuclear@2
|
85 }
|
nuclear@2
|
86
|
nuclear@2
|
87 for(i=0; i<num_sockets; i++) {
|
nuclear@2
|
88 if(FD_ISSET(sock[i], &rdset)) {
|
nuclear@2
|
89 srv_handle(sock[i]);
|
nuclear@2
|
90 }
|
nuclear@2
|
91 }
|
nuclear@2
|
92 }
|
nuclear@2
|
93
|
nuclear@2
|
94 frame_available = 1;
|
nuclear@2
|
95 pthread_cond_signal(&condvar);
|
nuclear@2
|
96 pthread_join(thread, 0);
|
nuclear@2
|
97 free(frame);
|
nuclear@2
|
98 wcam_stop(fd);
|
nuclear@2
|
99 wcam_close(fd);
|
nuclear@2
|
100 return 0;
|
nuclear@2
|
101 }
|
nuclear@2
|
102
|
nuclear@2
|
103 void *frame_proc(void *arg)
|
nuclear@2
|
104 {
|
nuclear@2
|
105 for(;;) {
|
nuclear@2
|
106 pthread_mutex_lock(&mutex);
|
nuclear@2
|
107 while(!frame_available) {
|
nuclear@2
|
108 pthread_cond_wait(&condvar, &mutex);
|
nuclear@2
|
109 }
|
nuclear@2
|
110 frame_available = 0;
|
nuclear@2
|
111 pthread_mutex_unlock(&mutex);
|
nuclear@2
|
112
|
nuclear@2
|
113 if(done) break;
|
nuclear@2
|
114
|
nuclear@2
|
115 wcam_read_frame_rgb(fd, frame);
|
nuclear@2
|
116 save_image("output.ppm", frame, width, height);
|
nuclear@2
|
117 }
|
nuclear@2
|
118 return 0;
|
nuclear@2
|
119 }
|
nuclear@2
|
120
|
nuclear@2
|
121 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz)
|
nuclear@2
|
122 {
|
nuclear@2
|
123 int i, num_pixels = xsz * ysz;
|
nuclear@2
|
124 FILE *fp = fopen(fname, "wb");
|
nuclear@2
|
125 if(!fp) return -1;
|
nuclear@2
|
126
|
nuclear@2
|
127 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
|
nuclear@2
|
128 for(i=0; i<num_pixels; i++) {
|
nuclear@2
|
129 fputc(*pixels++, fp);
|
nuclear@2
|
130 fputc(*pixels++, fp);
|
nuclear@2
|
131 fputc(*pixels++, fp);
|
nuclear@2
|
132 ++pixels;
|
nuclear@2
|
133 }
|
nuclear@2
|
134 fclose(fp);
|
nuclear@2
|
135 return 0;
|
nuclear@2
|
136 }
|
nuclear@2
|
137
|
nuclear@2
|
138 void sighandler(int s)
|
nuclear@2
|
139 {
|
nuclear@2
|
140 done = 1;
|
nuclear@2
|
141 }
|