doorbell

view doorbelld/src/main.c @ 2:d3f2a2b19504

doorbell server under construction
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 13 Mar 2016 07:56:03 +0200
parents
children 08ea0abdbb8a
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <signal.h>
6 #include <pthread.h>
7 #include <wcam.h>
8 #include "srv.h"
10 void *frame_proc(void *arg);
11 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz);
12 void sighandler(int s);
14 int fd;
15 int width = 640;
16 int height = 480;
17 int framerate = 30;
18 unsigned char *frame;
19 int done;
20 int frame_available;
21 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
22 pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
24 int main(int argc, char **argv)
25 {
26 char *devfile = "/dev/video0";
27 pthread_t thread;
29 if(argv[1]) {
30 devfile = argv[1];
31 }
33 signal(SIGINT, sighandler);
34 signal(SIGQUIT, sighandler);
35 signal(SIGSEGV, sighandler);
37 if(srv_init(2828) == -1) {
38 return 1;
39 }
41 if(!(frame = malloc(width * height * 4))) {
42 perror("failed to allocate frame");
43 return 1;
44 }
46 if((fd = wcam_open(devfile, width, height, framerate)) == -1) {
47 fprintf(stderr, "failed to open video device: %s\n", devfile);
48 return 1;
49 }
50 wcam_start(fd);
52 if(pthread_create(&thread, 0, frame_proc, 0) == -1) {
53 fprintf(stderr, "failed to create frame processing thread\n");
54 return 1;
55 }
57 while(!done) {
58 int i, res;
59 int *sock = srv_sockets();
60 int num_sockets = srv_num_sockets();
61 int maxfd = srv_max_socket();
62 fd_set rdset;
64 if(fd > maxfd) maxfd = fd;
66 FD_ZERO(&rdset);
67 FD_SET(fd, &rdset);
69 for(i=0; i<num_sockets; i++) {
70 FD_SET(sock[i], &rdset);
71 }
73 while((res = select(maxfd + 1, &rdset, 0, 0, 0)) == -1 && errno == EINTR);
74 if(res == -1) {
75 fprintf(stderr, "unexpected failure while waiting for I/O\n");
76 break;
77 }
79 if(FD_ISSET(fd, &rdset)) {
80 wcam_wait(fd);
81 pthread_mutex_lock(&mutex);
82 frame_available = 1;
83 pthread_mutex_unlock(&mutex);
84 pthread_cond_signal(&condvar);
85 }
87 for(i=0; i<num_sockets; i++) {
88 if(FD_ISSET(sock[i], &rdset)) {
89 srv_handle(sock[i]);
90 }
91 }
92 }
94 frame_available = 1;
95 pthread_cond_signal(&condvar);
96 pthread_join(thread, 0);
97 free(frame);
98 wcam_stop(fd);
99 wcam_close(fd);
100 return 0;
101 }
103 void *frame_proc(void *arg)
104 {
105 for(;;) {
106 pthread_mutex_lock(&mutex);
107 while(!frame_available) {
108 pthread_cond_wait(&condvar, &mutex);
109 }
110 frame_available = 0;
111 pthread_mutex_unlock(&mutex);
113 if(done) break;
115 wcam_read_frame_rgb(fd, frame);
116 save_image("output.ppm", frame, width, height);
117 }
118 return 0;
119 }
121 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz)
122 {
123 int i, num_pixels = xsz * ysz;
124 FILE *fp = fopen(fname, "wb");
125 if(!fp) return -1;
127 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
128 for(i=0; i<num_pixels; i++) {
129 fputc(*pixels++, fp);
130 fputc(*pixels++, fp);
131 fputc(*pixels++, fp);
132 ++pixels;
133 }
134 fclose(fp);
135 return 0;
136 }
138 void sighandler(int s)
139 {
140 done = 1;
141 }