Mercurial > mplayer.hg
annotate udp_sync.c @ 36679:36cbede21428
Fix bug with unicode font loading for font.desc files.
Unicode glyphs might not get loaded even if they are requested and
available.
Fix it by checking the font encoding rather than the subtitle encoding
when loading the font.
author | ib |
---|---|
date | Sat, 01 Feb 2014 16:57:50 +0000 |
parents | 2228001384a5 |
children |
rev | line source |
---|---|
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
1 /* |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
2 * Network playback synchronization |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
3 * Copyright (C) 2009 Google Inc. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
4 * |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
5 * This file is part of MPlayer. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
6 * |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
10 * (at your option) any later version. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
11 * |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
15 * GNU General Public License for more details. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
16 * |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
17 * You should have received a copy of the GNU General Public License along |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
20 */ |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
21 |
35906 | 22 #define _BSD_SOURCE |
23 | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
24 #include "config.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
25 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
26 #if !HAVE_WINSOCK2_H |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
27 #include <errno.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
28 #include <sys/types.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
29 #include <sys/socket.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
30 #include <netinet/in.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
31 #include <stdlib.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
32 #include <sys/ioctl.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
33 #include <fcntl.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
34 #include <string.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
35 #include <strings.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
36 #include <netdb.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
37 #include <signal.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
38 #else |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
39 #include <winsock2.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
40 #include <ws2tcpip.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
41 #endif /* HAVE_WINSOCK2_H */ |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
42 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
43 #include "mplayer.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
44 #include "mp_core.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
45 #include "mp_msg.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
46 #include "help_mp.h" |
31985 | 47 #include "udp_sync.h" |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
48 #include "osdep/timer.h" |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
49 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
50 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
51 // config options for UDP sync |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
52 int udp_master = 0; |
31985 | 53 int udp_slave = 0; |
54 int udp_port = 23867; | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
55 const char *udp_ip = "127.0.0.1"; // where the master sends datagrams |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
56 // (can be a broadcast address) |
31985 | 57 float udp_seek_threshold = 1.0; // how far off before we seek |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
58 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
59 // how far off is still considered equal |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
60 #define UDP_TIMING_TOLERANCE 0.02 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
61 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
62 static void startup(void) |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
63 { |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
64 #if HAVE_WINSOCK2_H |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
65 static int wsa_started; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
66 if (!wsa_started) { |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
67 WSADATA wd; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
68 WSAStartup(0x0202, &wd); |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
69 wsa_started = 1; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
70 } |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
71 #endif |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
72 } |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
73 |
32001 | 74 static void set_blocking(int fd, int blocking) |
75 { | |
76 long sock_flags; | |
77 #if HAVE_WINSOCK2_H | |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
78 sock_flags = !blocking; |
32001 | 79 ioctlsocket(fd, FIONBIO, &sock_flags); |
80 #else | |
81 sock_flags = fcntl(fd, F_GETFL, 0); | |
82 sock_flags = blocking ? sock_flags & ~O_NONBLOCK : sock_flags | O_NONBLOCK; | |
83 fcntl(fd, F_SETFL, sock_flags); | |
84 #endif /* HAVE_WINSOCK2_H */ | |
85 } | |
86 | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
87 // gets a datagram from the master with or without blocking. updates |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
88 // master_position if successful. if the master has exited, returns 1. |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
89 // returns -1 on error or if no message received. |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
90 // otherwise, returns 0. |
33153 | 91 static int get_udp(int blocking, double *master_position) |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
92 { |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
93 char mesg[100]; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
94 |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
95 int chars_received = -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
96 int n; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
97 |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
98 static int sockfd = -1; |
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
99 if (sockfd == -1) { |
33922 | 100 #if HAVE_WINSOCK2_H |
101 DWORD tv = 30000; | |
102 #else | |
32002
86d37b0e4dbc
Use initializer to avoid leaving struct timeval half-uninitialized.
reimar
parents:
32001
diff
changeset
|
103 struct timeval tv = { .tv_sec = 30 }; |
33922 | 104 #endif |
31990
4111548d28f9
Use initializer instead of memset, the memset in addition never
reimar
parents:
31985
diff
changeset
|
105 struct sockaddr_in servaddr = { 0 }; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
106 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
107 startup(); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
108 sockfd = socket(AF_INET, SOCK_DGRAM, 0); |
32007 | 109 if (sockfd == -1) |
110 return -1; | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
111 |
31985 | 112 servaddr.sin_family = AF_INET; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
113 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); |
31985 | 114 servaddr.sin_port = htons(udp_port); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
115 bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
116 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
117 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
118 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
119 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
120 |
32001 | 121 set_blocking(sockfd, blocking); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
122 |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
123 while (-1 != (n = recvfrom(sockfd, mesg, sizeof(mesg)-1, 0, |
32010
120953a1fc50
Use NULL for recvfrom return arguments we don't care about (source address).
reimar
parents:
32009
diff
changeset
|
124 NULL, NULL))) { |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
125 char *end; |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
126 // flush out any further messages so we don't get behind |
32001 | 127 if (chars_received == -1) |
128 set_blocking(sockfd, 0); | |
129 | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
130 chars_received = n; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
131 mesg[chars_received] = 0; |
31991 | 132 if (strcmp(mesg, "bye") == 0) |
31985 | 133 return 1; |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
134 *master_position = strtod(mesg, &end); |
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
135 if (*end) { |
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
136 mp_msg(MSGT_CPLAYER, MSGL_WARN, "Could not parse udp string!\n"); |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
137 return -1; |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
138 } |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
139 } |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
140 if (chars_received == -1) |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
141 return -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
142 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
143 return 0; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
144 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
145 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
146 void send_udp(const char *send_to_ip, int port, char *mesg) |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
147 { |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
148 static int sockfd = -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
149 static struct sockaddr_in socketinfo; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
150 |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
151 if (sockfd == -1) { |
32003
30a84c65efa4
Mark a constant as such and move it into the block where it is used.
reimar
parents:
32002
diff
changeset
|
152 static const int one = 1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
153 int ip_valid = 0; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
154 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
155 startup(); |
31985 | 156 sockfd = socket(AF_INET, SOCK_DGRAM, 0); |
32007 | 157 if (sockfd == -1) |
158 exit_player(EXIT_ERROR); | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
159 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
160 // Enable broadcast |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
161 setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
162 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
163 #if HAVE_WINSOCK2_H |
32006
3133252ce3fa
Actually set the destination address in the sockaddr_in struct for Windows as well...
reimar
parents:
32003
diff
changeset
|
164 socketinfo.sin_addr.s_addr = inet_addr(send_to_ip); |
3133252ce3fa
Actually set the destination address in the sockaddr_in struct for Windows as well...
reimar
parents:
32003
diff
changeset
|
165 ip_valid = socketinfo.sin_addr.s_addr != INADDR_NONE; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
166 #else |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
167 ip_valid = inet_aton(send_to_ip, &socketinfo.sin_addr); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
168 #endif |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
169 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
170 if (!ip_valid) { |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
171 mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_InvalidIP); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
172 exit_player(EXIT_ERROR); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
173 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
174 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
175 socketinfo.sin_family = AF_INET; |
31985 | 176 socketinfo.sin_port = htons(port); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
177 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
178 |
31985 | 179 sendto(sockfd, mesg, strlen(mesg), 0, (struct sockaddr *) &socketinfo, |
180 sizeof(socketinfo)); | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
181 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
182 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
183 // this function makes sure we stay as close as possible to the master's |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
184 // position. returns 1 if the master tells us to exit, |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
185 // -1 on error and normal timing should be used again, 0 otherwise. |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
186 int udp_slave_sync(MPContext *mpctx) |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
187 { |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
188 // remember where the master is in the file |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
189 static double udp_master_position; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
190 // whether we timed out before waiting for a master message |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
191 static int timed_out = -1; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
192 // last time we received a valid master message |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
193 static unsigned last_success; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
194 int master_exited; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
195 |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
196 if (timed_out < 0) { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
197 // initialize |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
198 udp_master_position = mpctx->sh_video->pts - udp_seek_threshold / 2; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
199 timed_out = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
200 last_success = GetTimerMS(); |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
201 } |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
202 |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
203 // grab any waiting datagrams without blocking |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
204 master_exited = get_udp(0, &udp_master_position); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
205 |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
206 while (!master_exited || (!timed_out && master_exited < 0)) { |
33153 | 207 double my_position = mpctx->sh_video->pts; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
208 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
209 // if we're way off, seek to catch up |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
210 if (FFABS(my_position - udp_master_position) > udp_seek_threshold) { |
31985 | 211 abs_seek_pos = SEEK_ABSOLUTE; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
212 rel_seek_secs = udp_master_position; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
213 break; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
214 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
215 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
216 // normally we expect that the master will have just played the |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
217 // frame we're ready to play. break out and play it, and we'll be |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
218 // right in sync. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
219 // or, the master might be up to a few seconds ahead of us, in |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
220 // which case we also want to play the current frame immediately, |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
221 // without waiting. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
222 // UDP_TIMING_TOLERANCE is a small value that lets us consider |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
223 // the master equal to us even if it's very slightly ahead. |
31991 | 224 if (udp_master_position + UDP_TIMING_TOLERANCE > my_position) |
31992 | 225 break; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
226 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
227 // the remaining case is that we're slightly ahead of the master. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
228 // usually, it just means we called get_udp() before the datagram |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
229 // arrived. call get_udp again, but this time block until we receive |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
230 // a datagram. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
231 master_exited = get_udp(1, &udp_master_position); |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
232 if (master_exited < 0) |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
233 timed_out = 1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
234 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
235 |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
236 if (master_exited >= 0) { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
237 last_success = GetTimerMS(); |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
238 timed_out = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
239 } else { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
240 master_exited = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
241 timed_out |= GetTimerMS() - last_success > 30000; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
242 } |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
243 |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
244 return timed_out ? -1 : master_exited; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
245 } |