doorbell
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/doorbelld/src/main.c Sun Mar 13 07:56:03 2016 +0200 1.3 @@ -0,0 +1,141 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <errno.h> 1.8 +#include <signal.h> 1.9 +#include <pthread.h> 1.10 +#include <wcam.h> 1.11 +#include "srv.h" 1.12 + 1.13 +void *frame_proc(void *arg); 1.14 +int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz); 1.15 +void sighandler(int s); 1.16 + 1.17 +int fd; 1.18 +int width = 640; 1.19 +int height = 480; 1.20 +int framerate = 30; 1.21 +unsigned char *frame; 1.22 +int done; 1.23 +int frame_available; 1.24 +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 1.25 +pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; 1.26 + 1.27 +int main(int argc, char **argv) 1.28 +{ 1.29 + char *devfile = "/dev/video0"; 1.30 + pthread_t thread; 1.31 + 1.32 + if(argv[1]) { 1.33 + devfile = argv[1]; 1.34 + } 1.35 + 1.36 + signal(SIGINT, sighandler); 1.37 + signal(SIGQUIT, sighandler); 1.38 + signal(SIGSEGV, sighandler); 1.39 + 1.40 + if(srv_init(2828) == -1) { 1.41 + return 1; 1.42 + } 1.43 + 1.44 + if(!(frame = malloc(width * height * 4))) { 1.45 + perror("failed to allocate frame"); 1.46 + return 1; 1.47 + } 1.48 + 1.49 + if((fd = wcam_open(devfile, width, height, framerate)) == -1) { 1.50 + fprintf(stderr, "failed to open video device: %s\n", devfile); 1.51 + return 1; 1.52 + } 1.53 + wcam_start(fd); 1.54 + 1.55 + if(pthread_create(&thread, 0, frame_proc, 0) == -1) { 1.56 + fprintf(stderr, "failed to create frame processing thread\n"); 1.57 + return 1; 1.58 + } 1.59 + 1.60 + while(!done) { 1.61 + int i, res; 1.62 + int *sock = srv_sockets(); 1.63 + int num_sockets = srv_num_sockets(); 1.64 + int maxfd = srv_max_socket(); 1.65 + fd_set rdset; 1.66 + 1.67 + if(fd > maxfd) maxfd = fd; 1.68 + 1.69 + FD_ZERO(&rdset); 1.70 + FD_SET(fd, &rdset); 1.71 + 1.72 + for(i=0; i<num_sockets; i++) { 1.73 + FD_SET(sock[i], &rdset); 1.74 + } 1.75 + 1.76 + while((res = select(maxfd + 1, &rdset, 0, 0, 0)) == -1 && errno == EINTR); 1.77 + if(res == -1) { 1.78 + fprintf(stderr, "unexpected failure while waiting for I/O\n"); 1.79 + break; 1.80 + } 1.81 + 1.82 + if(FD_ISSET(fd, &rdset)) { 1.83 + wcam_wait(fd); 1.84 + pthread_mutex_lock(&mutex); 1.85 + frame_available = 1; 1.86 + pthread_mutex_unlock(&mutex); 1.87 + pthread_cond_signal(&condvar); 1.88 + } 1.89 + 1.90 + for(i=0; i<num_sockets; i++) { 1.91 + if(FD_ISSET(sock[i], &rdset)) { 1.92 + srv_handle(sock[i]); 1.93 + } 1.94 + } 1.95 + } 1.96 + 1.97 + frame_available = 1; 1.98 + pthread_cond_signal(&condvar); 1.99 + pthread_join(thread, 0); 1.100 + free(frame); 1.101 + wcam_stop(fd); 1.102 + wcam_close(fd); 1.103 + return 0; 1.104 +} 1.105 + 1.106 +void *frame_proc(void *arg) 1.107 +{ 1.108 + for(;;) { 1.109 + pthread_mutex_lock(&mutex); 1.110 + while(!frame_available) { 1.111 + pthread_cond_wait(&condvar, &mutex); 1.112 + } 1.113 + frame_available = 0; 1.114 + pthread_mutex_unlock(&mutex); 1.115 + 1.116 + if(done) break; 1.117 + 1.118 + wcam_read_frame_rgb(fd, frame); 1.119 + save_image("output.ppm", frame, width, height); 1.120 + } 1.121 + return 0; 1.122 +} 1.123 + 1.124 +int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz) 1.125 +{ 1.126 + int i, num_pixels = xsz * ysz; 1.127 + FILE *fp = fopen(fname, "wb"); 1.128 + if(!fp) return -1; 1.129 + 1.130 + fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz); 1.131 + for(i=0; i<num_pixels; i++) { 1.132 + fputc(*pixels++, fp); 1.133 + fputc(*pixels++, fp); 1.134 + fputc(*pixels++, fp); 1.135 + ++pixels; 1.136 + } 1.137 + fclose(fp); 1.138 + return 0; 1.139 +} 1.140 + 1.141 +void sighandler(int s) 1.142 +{ 1.143 + done = 1; 1.144 +}