doorbell

annotate 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
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 }