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