doorbell

diff doorbell-client/src/main.c @ 7:dc4018af3a40

video broadcast with UDP. retarded amount of data, unusable.
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 16 Mar 2016 02:50:30 +0200
parents f21ae31ef0e7
children
line diff
     1.1 --- a/doorbell-client/src/main.c	Wed Mar 16 00:00:06 2016 +0200
     1.2 +++ b/doorbell-client/src/main.c	Wed Mar 16 02:50:30 2016 +0200
     1.3 @@ -1,6 +1,7 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6  #include <string.h>
     1.7 +#include <stdint.h>
     1.8  #include <errno.h>
     1.9  #include <unistd.h>
    1.10  #include <fcntl.h>
    1.11 @@ -12,12 +13,12 @@
    1.12  #include <GL/freeglut_ext.h>
    1.13  #include <GL/glx.h>
    1.14  
    1.15 -struct video_block_header {
    1.16 -	unsigned int magic;
    1.17 +struct video_block {
    1.18  	int frame;
    1.19 -	int x, y;
    1.20 -	int width, height;
    1.21 -	int frame_width, frame_height;
    1.22 +	uint16_t x, y;
    1.23 +	uint16_t width, height;
    1.24 +	uint16_t frame_width, frame_height;
    1.25 +	uint16_t pixels[1];
    1.26  };
    1.27  
    1.28  int conn(const char *host, int port);
    1.29 @@ -25,15 +26,18 @@
    1.30  void reshape(int x, int y);
    1.31  void keyb(unsigned char key, int x, int y);
    1.32  int handle_conn(int s);
    1.33 +int handle_video(int s);
    1.34  void post_redisplay(void);
    1.35  
    1.36  int quit;
    1.37 -int srvsock;
    1.38 +int ctlsock, vidsock;
    1.39  const char *address = "localhost";
    1.40  int port = 2828;
    1.41  unsigned int tex, tex_width, tex_height;
    1.42  int redraw_pending;
    1.43  
    1.44 +#define MAX(a, b)	((a) > (b) ? (a) : (b))
    1.45 +
    1.46  int main(int argc, char **argv)
    1.47  {
    1.48  	Display *dpy;
    1.49 @@ -51,10 +55,10 @@
    1.50  	dpy = glXGetCurrentDisplay();
    1.51  	xsock = ConnectionNumber(dpy);
    1.52  
    1.53 -	if((srvsock = conn(address, port)) == -1) {
    1.54 +	if(conn(address, port) == -1) {
    1.55  		return 1;
    1.56  	}
    1.57 -	write(srvsock, "hello", 5);
    1.58 +	write(ctlsock, "hello", 5);
    1.59  
    1.60  	glGenTextures(1, &tex);
    1.61  	glBindTexture(GL_TEXTURE_2D, tex);
    1.62 @@ -62,15 +66,16 @@
    1.63  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.64  
    1.65  	for(;;) {
    1.66 -		int res;
    1.67 -		int maxfd = srvsock > xsock ? srvsock : xsock;
    1.68 +		int res, maxfd;
    1.69  		struct timeval tv0 = {0, 0};
    1.70  		fd_set rdset;
    1.71  
    1.72  		FD_ZERO(&rdset);
    1.73  		FD_SET(xsock, &rdset);
    1.74 -		FD_SET(srvsock, &rdset);
    1.75 +		FD_SET(ctlsock, &rdset);
    1.76 +		FD_SET(vidsock, &rdset);
    1.77  
    1.78 +		maxfd = MAX(MAX(xsock, ctlsock), vidsock);
    1.79  		while((res = select(maxfd + 1, &rdset, 0, 0, redraw_pending ? &tv0 : 0) == -1) && errno == EINTR);
    1.80  		if(res == -1) break;
    1.81  
    1.82 @@ -80,25 +85,29 @@
    1.83  				break;
    1.84  			}
    1.85  		}
    1.86 -		if(FD_ISSET(srvsock, &rdset)) {
    1.87 -			if(handle_conn(srvsock) == -1) {
    1.88 +		if(FD_ISSET(ctlsock, &rdset)) {
    1.89 +			if(handle_conn(ctlsock) == -1) {
    1.90 +				break;
    1.91 +			}
    1.92 +		}
    1.93 +		if(FD_ISSET(vidsock, &rdset)) {
    1.94 +			if(handle_video(vidsock) == -1) {
    1.95  				break;
    1.96  			}
    1.97  		}
    1.98  	}
    1.99  
   1.100 -	close(srvsock);
   1.101 +	close(ctlsock);
   1.102  	return 0;
   1.103  }
   1.104  
   1.105  
   1.106  int conn(const char *hostname, int port)
   1.107  {
   1.108 -	int s;
   1.109  	struct sockaddr_in addr;
   1.110  	struct hostent *host;
   1.111  
   1.112 -	if((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
   1.113 +	if((ctlsock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
   1.114  		fprintf(stderr, "failed to create socket\n");
   1.115  		return -1;
   1.116  	}
   1.117 @@ -114,13 +123,28 @@
   1.118  	addr.sin_addr = *(struct in_addr*)host->h_addr;
   1.119  
   1.120  	printf("connecting to %s (%s), port %d\n", hostname, inet_ntoa(addr.sin_addr), port);
   1.121 -	if(connect(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
   1.122 +	if(connect(ctlsock, (struct sockaddr*)&addr, sizeof addr) == -1) {
   1.123  		fprintf(stderr, "failed to connect\n");
   1.124  		return -1;
   1.125  	}
   1.126 +	fcntl(ctlsock, F_SETFL, fcntl(ctlsock, F_GETFL) | O_NONBLOCK);
   1.127  
   1.128 -	fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
   1.129 -	return s;
   1.130 +	/* prepare the video socket */
   1.131 +	if((vidsock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
   1.132 +		fprintf(stderr, "failed to create video socket\n");
   1.133 +		return 1;
   1.134 +	}
   1.135 +
   1.136 +	memset(&addr, 0, sizeof addr);
   1.137 +	addr.sin_family = AF_INET;
   1.138 +	addr.sin_port = htons(port + 1);
   1.139 +	addr.sin_addr.s_addr = htonl(INADDR_ANY);
   1.140 +	if(bind(vidsock, (struct sockaddr*)&addr, sizeof addr) == -1) {
   1.141 +		fprintf(stderr, "failed to bind video socket to port %d\n", port + 1);
   1.142 +		return 1;
   1.143 +	}
   1.144 +
   1.145 +	return 0;
   1.146  }
   1.147  
   1.148  void display(void)
   1.149 @@ -139,10 +163,10 @@
   1.150  	glEnable(GL_TEXTURE_2D);
   1.151  
   1.152  	glBegin(GL_QUADS);
   1.153 -	glTexCoord2f(0, 0); glVertex2f(-1, -1);
   1.154 -	glTexCoord2f(1, 0); glVertex2f(1, -1);
   1.155 -	glTexCoord2f(1, 1); glVertex2f(1, 1);
   1.156 -	glTexCoord2f(0, 1); glVertex2f(-1, 1);
   1.157 +	glTexCoord2f(0, 1); glVertex2f(-1, -1);
   1.158 +	glTexCoord2f(1, 1); glVertex2f(1, -1);
   1.159 +	glTexCoord2f(1, 0); glVertex2f(1, 1);
   1.160 +	glTexCoord2f(0, 0); glVertex2f(-1, 1);
   1.161  	glEnd();
   1.162  
   1.163  	glDisable(GL_TEXTURE_2D);
   1.164 @@ -169,41 +193,44 @@
   1.165  
   1.166  int handle_conn(int s)
   1.167  {
   1.168 +	fprintf(stderr, "whaaaa!\n");
   1.169 +	return -1;
   1.170 +}
   1.171 +
   1.172 +int handle_video(int s)
   1.173 +{
   1.174  	static int cur_frame;
   1.175 -	struct video_block_header hdr;
   1.176 -	int size;
   1.177 -	unsigned char *pixels;
   1.178 +	static char buffer[2048];
   1.179 +	struct video_block *vblock;
   1.180 +	struct sockaddr_in addr;
   1.181 +	socklen_t addr_size;
   1.182  
   1.183 -	if(read(s, &hdr, sizeof hdr) != sizeof hdr) {
   1.184 -		fprintf(stderr, "failed to read video block header\n");
   1.185 -		return -1;
   1.186 -	}
   1.187 -	if(hdr.frame < cur_frame) {
   1.188 -		printf("skipping old frame %d\n", hdr.frame);
   1.189 -	}
   1.190 -	cur_frame = hdr.frame;
   1.191 -	printf("updating block %dx%d%+d%+d in frame %d\n", hdr.width, hdr.height, hdr.x, hdr.y, hdr.frame);
   1.192 -
   1.193 -	size = hdr.width * hdr.height * 2;
   1.194 -	if(!(pixels = malloc(size))) {
   1.195 -		fprintf(stderr, "failed to allocate pixel block %dx%d\n", hdr.width, hdr.height);
   1.196 -		return -1;
   1.197 -	}
   1.198 -	if(read(s, pixels, size) != size) {
   1.199 -		fprintf(stderr, "failed to read pixel block\n");
   1.200 +	addr_size = sizeof addr;
   1.201 +	if(recvfrom(vidsock, buffer, sizeof buffer, 0, (struct sockaddr*)&addr, &addr_size) == -1) {
   1.202 +		perror("failed to receive video block");
   1.203  		return -1;
   1.204  	}
   1.205  
   1.206 +	vblock = (struct video_block*)buffer;
   1.207 +
   1.208 +	if(vblock->frame < cur_frame) {
   1.209 +		printf("skipping old frame %d\n", vblock->frame);
   1.210 +		return 0;
   1.211 +	}
   1.212 +	cur_frame = vblock->frame;
   1.213 +	printf("updating block %dx%d%+d%+d in frame %d\n", vblock->width, vblock->height,
   1.214 +			vblock->x, vblock->y, vblock->frame);
   1.215 +
   1.216  	glBindTexture(GL_TEXTURE_2D, tex);
   1.217  
   1.218 -	if(tex_width < hdr.frame_width || tex_height < hdr.frame_height) {
   1.219 -		tex_width = hdr.frame_width;
   1.220 -		tex_height = hdr.frame_height;
   1.221 +	if(tex_width < vblock->frame_width || tex_height < vblock->frame_height) {
   1.222 +		tex_width = vblock->frame_width;
   1.223 +		tex_height = vblock->frame_height;
   1.224  		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0,
   1.225  				GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
   1.226  	}
   1.227 -	glTexSubImage2D(GL_TEXTURE_2D, 0, hdr.x, hdr.y, hdr.width, hdr.height,
   1.228 -			GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
   1.229 +	glTexSubImage2D(GL_TEXTURE_2D, 0, vblock->x, vblock->y, vblock->width, vblock->height,
   1.230 +			GL_RGB, GL_UNSIGNED_SHORT_5_6_5, vblock->pixels);
   1.231  
   1.232  	post_redisplay();
   1.233  	return 0;