Mercurial > mplayer.hg
annotate udp_sync.c @ 35404:0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
try switching to non-interleaved mode.
author | reimar |
---|---|
date | Wed, 28 Nov 2012 19:13:39 +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 } |