doorbell

annotate doorbelld/src/main.c @ 5:f21ae31ef0e7

craptacular
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 15 Mar 2016 08:35:21 +0200
parents 08ea0abdbb8a
children dc4018af3a40
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@4 13 int parse_args(int argc, char **argv);
nuclear@2 14
nuclear@4 15 const char *devfile = "/dev/video0";
nuclear@4 16 int fd = -1;
nuclear@4 17 int port = 2828;
nuclear@2 18 int width = 640;
nuclear@2 19 int height = 480;
nuclear@2 20 int framerate = 30;
nuclear@2 21 unsigned char *frame;
nuclear@2 22 int done;
nuclear@2 23 int frame_available;
nuclear@2 24 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
nuclear@2 25 pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
nuclear@2 26
nuclear@2 27 int main(int argc, char **argv)
nuclear@2 28 {
nuclear@2 29 pthread_t thread;
nuclear@2 30
nuclear@4 31 if(parse_args(argc, argv) == -1) {
nuclear@4 32 return 1;
nuclear@2 33 }
nuclear@2 34
nuclear@2 35 signal(SIGINT, sighandler);
nuclear@2 36 signal(SIGQUIT, sighandler);
nuclear@2 37 signal(SIGSEGV, sighandler);
nuclear@2 38
nuclear@4 39 if(srv_init(port) == -1) {
nuclear@2 40 return 1;
nuclear@2 41 }
nuclear@2 42
nuclear@2 43 if(!(frame = malloc(width * height * 4))) {
nuclear@2 44 perror("failed to allocate frame");
nuclear@2 45 return 1;
nuclear@2 46 }
nuclear@4 47 if(devfile) {
nuclear@4 48 if((fd = wcam_open(devfile, width, height, framerate)) == -1) {
nuclear@4 49 fprintf(stderr, "failed to open video device: %s\n", devfile);
nuclear@4 50 return 1;
nuclear@4 51 }
nuclear@4 52 wcam_start(fd);
nuclear@4 53 } else {
nuclear@4 54 int i, j;
nuclear@4 55 unsigned char *pptr = frame;
nuclear@4 56 for(i=0; i<height; i++) {
nuclear@4 57 for(j=0; j<width; j++) {
nuclear@4 58 int p = (i ^ j) & 0xff;
nuclear@4 59 pptr[0] = p;
nuclear@4 60 pptr[1] = p << 1;
nuclear@4 61 pptr[2] = p << 2;
nuclear@4 62 pptr[3] = 255;
nuclear@4 63 pptr += 4;
nuclear@4 64 }
nuclear@4 65 }
nuclear@4 66 printf("serving test pattern\n");
nuclear@2 67 }
nuclear@2 68
nuclear@2 69 if(pthread_create(&thread, 0, frame_proc, 0) == -1) {
nuclear@2 70 fprintf(stderr, "failed to create frame processing thread\n");
nuclear@2 71 return 1;
nuclear@2 72 }
nuclear@2 73
nuclear@2 74 while(!done) {
nuclear@2 75 int i, res;
nuclear@2 76 int *sock = srv_sockets();
nuclear@2 77 int num_sockets = srv_num_sockets();
nuclear@2 78 int maxfd = srv_max_socket();
nuclear@2 79 fd_set rdset;
nuclear@2 80
nuclear@4 81 FD_ZERO(&rdset);
nuclear@2 82
nuclear@4 83 if(fd != -1) {
nuclear@4 84 if(fd > maxfd) maxfd = fd;
nuclear@4 85 FD_SET(fd, &rdset);
nuclear@4 86 printf("select on socket: %d (video)\n", fd);
nuclear@4 87 }
nuclear@2 88
nuclear@2 89 for(i=0; i<num_sockets; i++) {
nuclear@2 90 FD_SET(sock[i], &rdset);
nuclear@4 91 printf("select on socket: %d\n", sock[i]);
nuclear@2 92 }
nuclear@2 93
nuclear@4 94 while((res = select(maxfd + 1, &rdset, 0, 0, 0)) == -1 &&
nuclear@4 95 errno == EINTR && !done);
nuclear@4 96 if(done) break;
nuclear@2 97 if(res == -1) {
nuclear@2 98 fprintf(stderr, "unexpected failure while waiting for I/O\n");
nuclear@2 99 break;
nuclear@2 100 }
nuclear@4 101 printf("res: %d\n", res);
nuclear@2 102
nuclear@4 103 if(fd != -1 && FD_ISSET(fd, &rdset)) {
nuclear@2 104 wcam_wait(fd);
nuclear@2 105 pthread_mutex_lock(&mutex);
nuclear@2 106 frame_available = 1;
nuclear@2 107 pthread_mutex_unlock(&mutex);
nuclear@2 108 pthread_cond_signal(&condvar);
nuclear@2 109 }
nuclear@2 110
nuclear@2 111 for(i=0; i<num_sockets; i++) {
nuclear@2 112 if(FD_ISSET(sock[i], &rdset)) {
nuclear@2 113 srv_handle(sock[i]);
nuclear@5 114 if(fd == -1) {
nuclear@5 115 pthread_mutex_lock(&mutex);
nuclear@5 116 frame_available = 1;
nuclear@5 117 pthread_mutex_unlock(&mutex);
nuclear@5 118 pthread_cond_signal(&condvar);
nuclear@5 119 }
nuclear@2 120 }
nuclear@2 121 }
nuclear@2 122 }
nuclear@2 123
nuclear@2 124 frame_available = 1;
nuclear@2 125 pthread_cond_signal(&condvar);
nuclear@2 126 pthread_join(thread, 0);
nuclear@2 127 free(frame);
nuclear@4 128 if(fd != -1) {
nuclear@4 129 wcam_stop(fd);
nuclear@4 130 wcam_close(fd);
nuclear@4 131 }
nuclear@2 132 return 0;
nuclear@2 133 }
nuclear@2 134
nuclear@2 135 void *frame_proc(void *arg)
nuclear@2 136 {
nuclear@2 137 for(;;) {
nuclear@2 138 pthread_mutex_lock(&mutex);
nuclear@2 139 while(!frame_available) {
nuclear@2 140 pthread_cond_wait(&condvar, &mutex);
nuclear@2 141 }
nuclear@2 142 frame_available = 0;
nuclear@2 143 pthread_mutex_unlock(&mutex);
nuclear@2 144
nuclear@2 145 if(done) break;
nuclear@2 146
nuclear@4 147 if(fd != -1) {
nuclear@4 148 wcam_read_frame_rgb(fd, frame);
nuclear@5 149 /*save_image("output.ppm", frame, width, height);*/
nuclear@4 150 }
nuclear@5 151 srv_send_frame(frame, width, height);
nuclear@2 152 }
nuclear@2 153 return 0;
nuclear@2 154 }
nuclear@2 155
nuclear@2 156 int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz)
nuclear@2 157 {
nuclear@2 158 int i, num_pixels = xsz * ysz;
nuclear@2 159 FILE *fp = fopen(fname, "wb");
nuclear@2 160 if(!fp) return -1;
nuclear@2 161
nuclear@2 162 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
nuclear@2 163 for(i=0; i<num_pixels; i++) {
nuclear@2 164 fputc(*pixels++, fp);
nuclear@2 165 fputc(*pixels++, fp);
nuclear@2 166 fputc(*pixels++, fp);
nuclear@2 167 ++pixels;
nuclear@2 168 }
nuclear@2 169 fclose(fp);
nuclear@2 170 return 0;
nuclear@2 171 }
nuclear@2 172
nuclear@2 173 void sighandler(int s)
nuclear@2 174 {
nuclear@2 175 done = 1;
nuclear@2 176 }
nuclear@4 177
nuclear@4 178 void print_usage(const char *argv0)
nuclear@4 179 {
nuclear@4 180 printf("Usage: %s [options]\n", argv0);
nuclear@4 181 printf("options:\n");
nuclear@4 182 printf(" -s,-size <WxH>\n");
nuclear@4 183 printf(" -f,-fps <framerate>\n");
nuclear@4 184 printf(" -d,-device <devfile>\n");
nuclear@4 185 printf(" -p,-port <port>\n");
nuclear@4 186 printf(" -novideo\n");
nuclear@4 187 printf(" -h,-help\n");
nuclear@4 188 }
nuclear@4 189
nuclear@4 190 int parse_args(int argc, char **argv)
nuclear@4 191 {
nuclear@4 192 int i;
nuclear@4 193
nuclear@4 194 for(i=1; i<argc; i++) {
nuclear@4 195 if(argv[i][0] == '-') {
nuclear@4 196 if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "-size") == 0) {
nuclear@4 197 if(sscanf(argv[++i], "%dx%d", &width, &height) != 2) {
nuclear@4 198 fprintf(stderr, "invalid size specified: %s\n", argv[i - 1]);
nuclear@4 199 return -1;
nuclear@4 200 }
nuclear@4 201 } else if(strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "-fps") == 0) {
nuclear@4 202 framerate = atoi(argv[++i]);
nuclear@4 203 if(framerate <= 0) {
nuclear@4 204 fprintf(stderr, "invalid framerate specified: %s\n", argv[i - 1]);
nuclear@4 205 return -1;
nuclear@4 206 }
nuclear@4 207 } else if(strcmp(argv[i], "-novideo") == 0) {
nuclear@4 208 devfile = 0;
nuclear@4 209 } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-device") == 0) {
nuclear@4 210 devfile = argv[++i];
nuclear@4 211 } else if(strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-port") == 0) {
nuclear@4 212 port = atoi(argv[++i]);
nuclear@4 213 if(port <= 0 || port >= 65535) {
nuclear@4 214 fprintf(stderr, "invalid port specified: %s\n", argv[i - 1]);
nuclear@4 215 return -1;
nuclear@4 216 }
nuclear@4 217 } else {
nuclear@4 218 int help = strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0;
nuclear@4 219 if(!help) fprintf(stderr, "unrecognized option: %s\n", argv[i]);
nuclear@4 220 print_usage(argv[0]);
nuclear@4 221 exit(help ? 0 : 1);
nuclear@4 222 }
nuclear@4 223 } else {
nuclear@4 224 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
nuclear@4 225 print_usage(argv[0]);
nuclear@4 226 return -1;
nuclear@4 227 }
nuclear@4 228 }
nuclear@4 229 return 0;
nuclear@4 230 }