Mercurial > mplayer.hg
annotate udp_sync.c @ 34634:0ef7177a063b
Fix linking after FFmpeg merge.
Protocols that are available only when librtmp is present
are no longer disabled in the code, so we have to remove
them in our configure.
author | iive |
---|---|
date | Tue, 14 Feb 2012 16:50:42 +0000 |
parents | 25de7f7ee57c |
children | 2228001384a5 |
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 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
22 #include "config.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
23 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
24 #if !HAVE_WINSOCK2_H |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
25 #include <errno.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
26 #include <sys/types.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
27 #include <sys/socket.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
28 #include <netinet/in.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
29 #include <stdlib.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
30 #include <sys/ioctl.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
31 #include <fcntl.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
32 #include <string.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
33 #include <strings.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
34 #include <netdb.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
35 #include <signal.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
36 #else |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
37 #include <winsock2.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
38 #include <ws2tcpip.h> |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
39 #endif /* HAVE_WINSOCK2_H */ |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
40 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
41 #include "mplayer.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
42 #include "mp_core.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
43 #include "mp_msg.h" |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
44 #include "help_mp.h" |
31985 | 45 #include "udp_sync.h" |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
46 #include "osdep/timer.h" |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
47 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
48 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
49 // config options for UDP sync |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
50 int udp_master = 0; |
31985 | 51 int udp_slave = 0; |
52 int udp_port = 23867; | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
53 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
|
54 // (can be a broadcast address) |
31985 | 55 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
|
56 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
57 // how far off is still considered equal |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
58 #define UDP_TIMING_TOLERANCE 0.02 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
59 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
60 static void startup(void) |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
61 { |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
62 #if HAVE_WINSOCK2_H |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
63 static int wsa_started; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
64 if (!wsa_started) { |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
65 WSADATA wd; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
66 WSAStartup(0x0202, &wd); |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
67 wsa_started = 1; |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
68 } |
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
69 #endif |
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 |
32001 | 72 static void set_blocking(int fd, int blocking) |
73 { | |
74 long sock_flags; | |
75 #if HAVE_WINSOCK2_H | |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
76 sock_flags = !blocking; |
32001 | 77 ioctlsocket(fd, FIONBIO, &sock_flags); |
78 #else | |
79 sock_flags = fcntl(fd, F_GETFL, 0); | |
80 sock_flags = blocking ? sock_flags & ~O_NONBLOCK : sock_flags | O_NONBLOCK; | |
81 fcntl(fd, F_SETFL, sock_flags); | |
82 #endif /* HAVE_WINSOCK2_H */ | |
83 } | |
84 | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
85 // gets a datagram from the master with or without blocking. updates |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
86 // 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
|
87 // returns -1 on error or if no message received. |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
88 // otherwise, returns 0. |
33153 | 89 static int get_udp(int blocking, double *master_position) |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
90 { |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
91 char mesg[100]; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
92 |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
93 int chars_received = -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
94 int n; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
95 |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
96 static int sockfd = -1; |
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
97 if (sockfd == -1) { |
33922 | 98 #if HAVE_WINSOCK2_H |
99 DWORD tv = 30000; | |
100 #else | |
32002
86d37b0e4dbc
Use initializer to avoid leaving struct timeval half-uninitialized.
reimar
parents:
32001
diff
changeset
|
101 struct timeval tv = { .tv_sec = 30 }; |
33922 | 102 #endif |
31990
4111548d28f9
Use initializer instead of memset, the memset in addition never
reimar
parents:
31985
diff
changeset
|
103 struct sockaddr_in servaddr = { 0 }; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
104 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
105 startup(); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
106 sockfd = socket(AF_INET, SOCK_DGRAM, 0); |
32007 | 107 if (sockfd == -1) |
108 return -1; | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
109 |
31985 | 110 servaddr.sin_family = AF_INET; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
111 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); |
31985 | 112 servaddr.sin_port = htons(udp_port); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
113 bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
114 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
115 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); |
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 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
118 |
32001 | 119 set_blocking(sockfd, blocking); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
120 |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
121 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
|
122 NULL, NULL))) { |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
123 char *end; |
31998
28fb4ef194f9
Avoid duplicating the recvfrom/"bye"-handling code.
reimar
parents:
31996
diff
changeset
|
124 // flush out any further messages so we don't get behind |
32001 | 125 if (chars_received == -1) |
126 set_blocking(sockfd, 0); | |
127 | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
128 chars_received = n; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
129 mesg[chars_received] = 0; |
31991 | 130 if (strcmp(mesg, "bye") == 0) |
31985 | 131 return 1; |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
132 *master_position = strtod(mesg, &end); |
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
133 if (*end) { |
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
134 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
|
135 return -1; |
33156
9ac31195a5e0
Use strtod instead of sscanf, it is both much faster and allows for
reimar
parents:
33155
diff
changeset
|
136 } |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
137 } |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
138 if (chars_received == -1) |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
139 return -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
140 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
141 return 0; |
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 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
144 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
|
145 { |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
146 static int sockfd = -1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
147 static struct sockaddr_in socketinfo; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
148 |
32008
221819bef85e
Use sockfd value to detect if we initialized already instead of a
reimar
parents:
32007
diff
changeset
|
149 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
|
150 static const int one = 1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
151 int ip_valid = 0; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
152 |
33921
6c1d39323b6e
Fix udp-slave on Windows: Make sure WSAStartup is called
reimar
parents:
33486
diff
changeset
|
153 startup(); |
31985 | 154 sockfd = socket(AF_INET, SOCK_DGRAM, 0); |
32007 | 155 if (sockfd == -1) |
156 exit_player(EXIT_ERROR); | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
157 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
158 // Enable broadcast |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
159 setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
160 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
161 #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
|
162 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
|
163 ip_valid = socketinfo.sin_addr.s_addr != INADDR_NONE; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
164 #else |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
165 ip_valid = inet_aton(send_to_ip, &socketinfo.sin_addr); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
166 #endif |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
167 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
168 if (!ip_valid) { |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
169 mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_InvalidIP); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
170 exit_player(EXIT_ERROR); |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
171 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
172 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
173 socketinfo.sin_family = AF_INET; |
31985 | 174 socketinfo.sin_port = htons(port); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
175 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
176 |
31985 | 177 sendto(sockfd, mesg, strlen(mesg), 0, (struct sockaddr *) &socketinfo, |
178 sizeof(socketinfo)); | |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
179 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
180 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
181 // 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
|
182 // 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
|
183 // -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
|
184 int udp_slave_sync(MPContext *mpctx) |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
185 { |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
186 // remember where the master is in the file |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
187 static double udp_master_position; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
188 // 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
|
189 static int timed_out = -1; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
190 // last time we received a valid master message |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
191 static unsigned last_success; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
192 int master_exited; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
193 |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
194 if (timed_out < 0) { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
195 // initialize |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
196 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
|
197 timed_out = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
198 last_success = GetTimerMS(); |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
199 } |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
200 |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
201 // grab any waiting datagrams without blocking |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
202 master_exited = get_udp(0, &udp_master_position); |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
203 |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
204 while (!master_exited || (!timed_out && master_exited < 0)) { |
33153 | 205 double my_position = mpctx->sh_video->pts; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
206 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
207 // if we're way off, seek to catch up |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
208 if (FFABS(my_position - udp_master_position) > udp_seek_threshold) { |
31985 | 209 abs_seek_pos = SEEK_ABSOLUTE; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
210 rel_seek_secs = udp_master_position; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
211 break; |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
212 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
213 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
214 // normally we expect that the master will have just played the |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
215 // 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
|
216 // right in sync. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
217 // 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
|
218 // which case we also want to play the current frame immediately, |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
219 // without waiting. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
220 // UDP_TIMING_TOLERANCE is a small value that lets us consider |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
221 // the master equal to us even if it's very slightly ahead. |
31991 | 222 if (udp_master_position + UDP_TIMING_TOLERANCE > my_position) |
31992 | 223 break; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
224 |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
225 // 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
|
226 // usually, it just means we called get_udp() before the datagram |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
227 // 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
|
228 // a datagram. |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
229 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
|
230 if (master_exited < 0) |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
231 timed_out = 1; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
232 } |
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
233 |
33486
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
234 if (master_exited >= 0) { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
235 last_success = GetTimerMS(); |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
236 timed_out = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
237 } else { |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
238 master_exited = 0; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
239 timed_out |= GetTimerMS() - last_success > 30000; |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
240 } |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
241 |
e46989c7f47e
Change -udp-slave code to temporarily fall back to normal
reimar
parents:
33485
diff
changeset
|
242 return timed_out ? -1 : master_exited; |
31982
184969a3a437
Add synchronization of multiple MPlayer instances over UDP.
reimar
parents:
diff
changeset
|
243 } |