changeset 33486:e46989c7f47e

Change -udp-slave code to temporarily fall back to normal timing after 30s network timeout. This is the second try, this time tested with -vo xv to avoid being tricked by vsync. It will also still wait 30s for a message right after startup. As a side-effect it also contains a fix against a minor issue that -udp-slave would start up playing or seeking for files with a non-zero start time.
author reimar
date Wed, 08 Jun 2011 18:58:10 +0000
parents 2f8dc5fbec77
children 45e772bf4d6a
files mplayer.c udp_sync.c
diffstat 2 files changed, 38 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mplayer.c	Wed Jun 08 18:25:17 2011 +0000
+++ b/mplayer.c	Wed Jun 08 18:58:10 2011 +0000
@@ -2263,11 +2263,11 @@
 #ifdef CONFIG_NETWORKING
     if (udp_slave) {
         int udp_master_exited = udp_slave_sync(mpctx);
-        if (udp_master_exited) {
+        if (udp_master_exited > 0) {
             mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_MasterQuit);
             exit_player(EXIT_QUIT);
-        }
-        return 0;
+        } else if (udp_master_exited == 0)
+            return 0;
     }
 #endif /* CONFIG_NETWORKING */
 
--- a/udp_sync.c	Wed Jun 08 18:25:17 2011 +0000
+++ b/udp_sync.c	Wed Jun 08 18:58:10 2011 +0000
@@ -43,6 +43,7 @@
 #include "mp_msg.h"
 #include "help_mp.h"
 #include "udp_sync.h"
+#include "osdep/timer.h"
 
 
 // config options for UDP sync
@@ -53,9 +54,6 @@
                                   // (can be a broadcast address)
 float udp_seek_threshold = 1.0;   // how far off before we seek
 
-// remember where the master is in the file
-static double udp_master_position = -1.0;
-
 // how far off is still considered equal
 #define UDP_TIMING_TOLERANCE 0.02
 
@@ -74,7 +72,7 @@
 
 // gets a datagram from the master with or without blocking.  updates
 // master_position if successful.  if the master has exited, returns 1.
-// returns -1 on error.
+// returns -1 on error or if no message received.
 // otherwise, returns 0.
 static int get_udp(int blocking, double *master_position)
 {
@@ -117,9 +115,11 @@
         *master_position = strtod(mesg, &end);
         if (*end) {
             mp_msg(MSGT_CPLAYER, MSGL_WARN, "Could not parse udp string!\n");
-            *master_position = MP_NOPTS_VALUE;
+            return -1;
         }
     }
+    if (chars_received == -1)
+        return -1;
 
     return 0;
 }
@@ -161,13 +161,29 @@
 }
 
 // this function makes sure we stay as close as possible to the master's
-// position.  returns 1 if the master tells us to exit, 0 otherwise.
+// position.  returns 1 if the master tells us to exit,
+// -1 on error and normal timing should be used again, 0 otherwise.
 int udp_slave_sync(MPContext *mpctx)
 {
+    // remember where the master is in the file
+    static double udp_master_position;
+    // whether we timed out before waiting for a master message
+    static int timed_out = -1;
+    // last time we received a valid master message
+    static unsigned last_success;
+    int master_exited;
+
+    if (timed_out < 0) {
+        // initialize
+        udp_master_position = mpctx->sh_video->pts - udp_seek_threshold / 2;
+        timed_out = 0;
+        last_success = GetTimerMS();
+    }
+
     // grab any waiting datagrams without blocking
-    int master_exited = get_udp(0, &udp_master_position);
+    master_exited = get_udp(0, &udp_master_position);
 
-    while (!master_exited) {
+    while (!master_exited || (!timed_out && master_exited < 0)) {
         double my_position = mpctx->sh_video->pts;
 
         // if we're way off, seek to catch up
@@ -193,7 +209,17 @@
         // arrived.  call get_udp again, but this time block until we receive
         // a datagram.
         master_exited = get_udp(1, &udp_master_position);
+        if (master_exited < 0)
+            timed_out = 1;
     }
 
-    return master_exited;
+    if (master_exited >= 0) {
+        last_success = GetTimerMS();
+        timed_out = 0;
+    } else {
+        master_exited = 0;
+        timed_out |= GetTimerMS() - last_success > 30000;
+    }
+
+    return timed_out ? -1 : master_exited;
 }