comparison udp_sync.c @ 33155:16e5b7f9ddb8

Send udp master updates also when paused and let slave use normal timing when it gets no messages. This allows the slave to continue playing normally if the master crashes or network stops working instead of hanging forever. Note that the slave might still hang for the 30 second network timeout in some cases.
author reimar
date Sat, 09 Apr 2011 14:55:22 +0000
parents 5dcbfb18ad58
children 9ac31195a5e0
comparison
equal deleted inserted replaced
33154:f6a049eff960 33155:16e5b7f9ddb8
51 int udp_port = 23867; 51 int udp_port = 23867;
52 const char *udp_ip = "127.0.0.1"; // where the master sends datagrams 52 const char *udp_ip = "127.0.0.1"; // where the master sends datagrams
53 // (can be a broadcast address) 53 // (can be a broadcast address)
54 float udp_seek_threshold = 1.0; // how far off before we seek 54 float udp_seek_threshold = 1.0; // how far off before we seek
55 55
56 // remember where the master is in the file
57 static double udp_master_position = -1.0;
58
59 // how far off is still considered equal 56 // how far off is still considered equal
60 #define UDP_TIMING_TOLERANCE 0.02 57 #define UDP_TIMING_TOLERANCE 0.02
61 58
62 static void set_blocking(int fd, int blocking) 59 static void set_blocking(int fd, int blocking)
63 { 60 {
82 79
83 int chars_received = -1; 80 int chars_received = -1;
84 int n; 81 int n;
85 82
86 static int sockfd = -1; 83 static int sockfd = -1;
84
85 *master_position = MP_NOPTS_VALUE;
86
87 if (sockfd == -1) { 87 if (sockfd == -1) {
88 struct timeval tv = { .tv_sec = 30 }; 88 struct timeval tv = { .tv_sec = 30 };
89 struct sockaddr_in servaddr = { 0 }; 89 struct sockaddr_in servaddr = { 0 };
90 90
91 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 91 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
157 157
158 // this function makes sure we stay as close as possible to the master's 158 // this function makes sure we stay as close as possible to the master's
159 // position. returns 1 if the master tells us to exit, 0 otherwise. 159 // position. returns 1 if the master tells us to exit, 0 otherwise.
160 int udp_slave_sync(MPContext *mpctx) 160 int udp_slave_sync(MPContext *mpctx)
161 { 161 {
162 double udp_master_position;
163
162 // grab any waiting datagrams without blocking 164 // grab any waiting datagrams without blocking
163 int master_exited = get_udp(0, &udp_master_position); 165 int master_exited = get_udp(0, &udp_master_position);
164 166
165 while (!master_exited) { 167 while (udp_master_position != MP_NOPTS_VALUE && !master_exited) {
166 double my_position = mpctx->sh_video->pts; 168 double my_position = mpctx->sh_video->pts;
167 169
168 // if we're way off, seek to catch up 170 // if we're way off, seek to catch up
169 if (FFABS(my_position - udp_master_position) > udp_seek_threshold) { 171 if (FFABS(my_position - udp_master_position) > udp_seek_threshold) {
170 abs_seek_pos = SEEK_ABSOLUTE; 172 abs_seek_pos = SEEK_ABSOLUTE;