Implement frame streaming-> and event streaming<- over UDP

This commit is contained in:
jndean
2022-12-14 15:07:22 +00:00
parent f791d97a1e
commit 7c5d55edb4
7 changed files with 177 additions and 67 deletions

View File

@@ -20,6 +20,7 @@
//
#include <stdlib.h>
#include <stdio.h>
#include "d_event.h"
#define MAXEVENTS 64

View File

@@ -100,4 +100,7 @@ void I_GetWindowPosition(int *x, int *y, int w, int h);
// Joystic/gamepad hysteresis
extern unsigned int joywait;
// JOSEF
void I_GetEvent(void);
#endif

View File

@@ -6,6 +6,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <time.h>
#include "d_event.h"
@@ -17,9 +18,10 @@ static int sockfd;
static struct sockaddr_in servaddr;
static unsigned int serveraddr_len;
void connect_to_server() {
void connect_to_server(void) {
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
@@ -32,20 +34,16 @@ void connect_to_server() {
HelloMsg msg;
msg.type = MSGT_HELLO;
sendto(
sockfd,
(const char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &servaddr, sizeof(servaddr)
);
sendto(sockfd,
(const char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &servaddr, sizeof(servaddr));
LargestMsgType rcv[1];
recvfrom(
sockfd,
(char *)(rcv), sizeof(rcv),
MSG_WAITALL,
(struct sockaddr *) &servaddr, &serveraddr_len
);
recvfrom(sockfd,
(char *)(rcv), sizeof(rcv),
MSG_WAITALL,
(struct sockaddr *) &servaddr, &serveraddr_len);
if (rcv->type == MSGT_HELLO) {
printf("Server says hello\n");
} else {
@@ -56,7 +54,9 @@ void connect_to_server() {
}
void send_events() {
void send_events(void) {
I_GetEvent();
EventMsg msg;
msg.type = MSGT_EVENT;
msg.count = 0;
@@ -68,7 +68,7 @@ void send_events() {
((event_t*) msg.events)[msg.count] = *ev;
} else if (msg.count == 255) {
printf("\nmsg.count was about to overflow! Too many events?\n");
exit(1);
exit(EXIT_FAILURE);
} else {
printf("WARNING: exceeding %d events per frame, dropping some key presses\n",
STREAMEVENTSPERMESSAGE);
@@ -78,28 +78,53 @@ void send_events() {
// Send the packet
if (msg.count > 0) {
sendto(
sockfd,
(const char *)(&msg), sizeof(msg),
0,
(const struct sockaddr *) &servaddr, sizeof(servaddr)
);
sendto(sockfd,
(const char *)(&msg), sizeof(msg),
0,
(const struct sockaddr *) &servaddr, sizeof(servaddr));
}
}
void recv_loop() {
void ping(void) {
const int frequency = 64;
static int call_count = 0;
call_count = (call_count + 1) % frequency;
if (call_count) return;
PingMsg msg;
msg.type = MSGT_PING;
gettimeofday(&msg.sent_time, NULL);
sendto(sockfd,
(const char *)(&msg), sizeof(msg),
0,
(const struct sockaddr *) &servaddr, sizeof(servaddr)
);
}
void flush_incoming(void) {
while (1) {
LargestMsgType rcv[1];
ssize_t n = recvfrom(sockfd,
(char *)rcv, sizeof(rcv),
MSG_DONTWAIT,
NULL, NULL);
if (n == -1) return;
}
}
void recv_loop(void) {
unsigned char last_scanline = 0;
while (1) {
LargestMsgType rcv[1];
ssize_t n = recvfrom(
sockfd,
(char *)rcv, sizeof(rcv),
MSG_DONTWAIT,
(struct sockaddr *) &servaddr, &serveraddr_len
);
ssize_t n = recvfrom(sockfd,
(char *)rcv, sizeof(rcv),
MSG_DONTWAIT,
(struct sockaddr *) &servaddr, &serveraddr_len);
if (n == -1) {
struct timespec ts;
@@ -107,26 +132,43 @@ void recv_loop() {
ts.tv_nsec = 1000;
if(nanosleep(&ts, &ts)) {
printf("Nanosleep failed\n");
exit(1);
exit(EXIT_FAILURE);
}
continue;
}
switch (rcv->type) {
case MSGT_SCANLINE:;
case MSGT_SCANLINE: {
ScanlineMsg *msg = (ScanlineMsg*) rcv;
memcpy(&I_VideoBuffer[msg->idx*STREAMWIDTH], msg->data, STREAMSCANSIZE);
if (msg->idx > 190) {
printf(">%d ", msg->idx);
}
if (msg->idx < last_scanline) {
if (msg->idx < last_scanline - 100) {
send_events();
ping();
I_FinishUpdate();
/*static int tmp_count = 0;
if (tmp_count++ == 128) {
printf("----FLUSH!----\n");
tmp_count = 0;
flush_incoming();
}*/
}
last_scanline = msg->idx;
break;
}
case MSGT_PING: {
PingMsg *msg = (PingMsg*) rcv;
struct timeval T;
gettimeofday(&T, NULL);
double delta = (T.tv_usec - msg->sent_time.tv_usec) / 1000.;
delta += (T.tv_sec - msg->sent_time.tv_sec) * 1000.;
printf("PING: %.1lf\n", delta);
break;
}
default:
perror("Received unknown msg type\n");
printf("Received unknown msg type %d\n", (int)rcv->type);
exit(EXIT_FAILURE);
}
}

View File

@@ -1,14 +1,16 @@
#ifndef __COMMON_STREAMING__
#define __COMMON_STREAMING__
#include <sys/time.h>
#define STREAMPORT (6666)
#define STREAMWIDTH (320)
#define STREAMLINESPERMESSAGE (1)
#define STREAMEVENTSPERMESSAGE (5)
#define STREAMSCANSIZE (STREAMLINESPERMESSAGE * STREAMWIDTH)
typedef struct {
unsigned char type;
} HelloMsg;
@@ -25,11 +27,18 @@ typedef struct {
unsigned char events[20 * STREAMEVENTSPERMESSAGE];
} EventMsg;
typedef struct {
unsigned char type;
struct timeval sent_time;
} PingMsg;
typedef ScanlineMsg LargestMsgType;
#define MSGT_HELLO (0)
#define MSGT_SCANLINE (1)
#define MSGT_EVENT (2)
#define MSGT_PING (3)
#endif // __COMMON_STREAMING__

View File

@@ -790,15 +790,8 @@ void I_FinishUpdate (void)
}
// JOSEF: Streaming
const int stride = 1;
static int offset = 0;
for (int i = offset; i < SCREENHEIGHT; i += STREAMLINESPERMESSAGE * stride) {
if (i > 190) {
printf(">%d ", i);
}
send_scanline(I_VideoBuffer, i);
}
offset = (offset + 1) % stride;
stream_send_receive(I_VideoBuffer);
if (palette_to_set)
{

View File

@@ -7,6 +7,8 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include "d_event.h"
#include "i_video.h"
#include "streaming.h"
@@ -16,13 +18,13 @@ static unsigned int clientaddr_len;
// Driver code
void wait_for_client_connect() {
void wait_for_client_connect(void) {
LargestMsgType rcv[1];
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
@@ -43,12 +45,10 @@ void wait_for_client_connect() {
}
clientaddr_len = sizeof(cliaddr);
recvfrom(
sockfd,
(char *)(rcv), sizeof(rcv),
MSG_WAITALL,
(struct sockaddr *) &cliaddr, &clientaddr_len
);
recvfrom(sockfd,
(char *)(rcv), sizeof(rcv),
MSG_WAITALL,
(struct sockaddr *) &cliaddr, &clientaddr_len);
if (rcv->type != MSGT_HELLO) {
perror("Client said something other than hello?");
exit(EXIT_FAILURE);
@@ -57,12 +57,10 @@ void wait_for_client_connect() {
HelloMsg msg;
msg.type = MSGT_HELLO;
sendto(
sockfd,
(char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &cliaddr, clientaddr_len
);
sendto(sockfd,
(char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &cliaddr, clientaddr_len);
return;
}
@@ -73,15 +71,78 @@ void send_scanline(unsigned char *data, unsigned char linenum) {
msg.type = MSGT_SCANLINE;
msg.idx = linenum;
memcpy(msg.data, &data[linenum * STREAMWIDTH], STREAMSCANSIZE);
ssize_t sent = sendto(
sockfd,
(char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &cliaddr, clientaddr_len
);
ssize_t sent = sendto(sockfd,
(char *)(&msg), sizeof(msg),
MSG_CONFIRM,
(const struct sockaddr *) &cliaddr, clientaddr_len);
if (sent == -1) {
perror("Failed to send scanline");
exit(EXIT_FAILURE);
}
return;
}
void recv_events(void) {
while (1) {
LargestMsgType rcv[1];
ssize_t n = recvfrom(sockfd,
(char *)rcv, sizeof(rcv),
MSG_DONTWAIT,
(struct sockaddr *) &cliaddr, &clientaddr_len);
if (n == -1) break;
if (rcv->type != MSGT_EVENT) {
printf("Expected to receive MSGT_EVENT(%d), but got %d\n", MSGT_EVENT, rcv->type);
exit(EXIT_FAILURE);
}
EventMsg *msg = (EventMsg*) rcv;
for (int i = 0; i < msg->count; ++i) {
D_PostEvent(&((event_t*)msg->events)[i]);
}
}
}
void stream_send_receive(unsigned char *data) {
const int stride = 1; // Controls interlacing, 1 = no-interlacing
static int offset = 0;
for (int i = offset; i < SCREENHEIGHT; i += STREAMLINESPERMESSAGE * stride) {
send_scanline(data, i);
}
offset = (offset + 1) % stride;
while (1) {
LargestMsgType rcv[1];
ssize_t n = recvfrom(sockfd,
(char *)rcv, sizeof(rcv),
MSG_DONTWAIT,
(struct sockaddr *) &cliaddr, &clientaddr_len);
if (n == -1) break;
switch(rcv->type) {
case MSGT_EVENT: {
EventMsg *msg = (EventMsg*) rcv;
for (int i = 0; i < msg->count; ++i) {
D_PostEvent(&((event_t*)msg->events)[i]);
}
break;
}
case MSGT_PING: {
PingMsg *msg = (PingMsg*) rcv;
sendto(sockfd,
(char *)(msg), sizeof(*msg),
MSG_CONFIRM,
(const struct sockaddr *) &cliaddr, clientaddr_len);
break;
}
default:
printf("Unexpected message type %d\n", (int) rcv->type);
exit(EXIT_FAILURE);
}
}
}

View File

@@ -4,6 +4,7 @@
#include "../common/streaming.h"
void wait_for_client_connect();
void stream_send_receive(unsigned char *data);
void send_scanline(unsigned char *data, unsigned char linenum);