]> git.sesse.net Git - vlc/blobdiff - modules/control/netsync.c
vlc_plugin: fix non-LGPL plugins meta infos
[vlc] / modules / control / netsync.c
index 455be184dcbb1f71c74630c12d707a43ecba0667..1226e2cbab6ece30a61888edc8b9815bbb7b2d06 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * netsync.c: synchronisation between several network clients.
+ * netsync.c: synchronization between several network clients.
  *****************************************************************************
  * Copyright (C) 2004-2009 the VideoLAN team
  * $Id$
 #endif
 #include <assert.h>
 
+#define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_interface.h>
 #include <vlc_input.h>
 #include <vlc_playlist.h>
 
-#ifdef HAVE_UNISTD_H
-#    include <unistd.h>
-#endif
 #include <sys/types.h>
+#include <unistd.h>
 #ifdef HAVE_POLL
 #   include <poll.h>
 #endif
@@ -55,29 +54,29 @@ static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);
 
 #define NETSYNC_TEXT N_("Network master clock")
-#define NETSYNC_LONGTEXT N_("When set then " \
-  "this vlc instance shall dictate its clock for synchronisation" \
-  "over clients listening on the masters network ip address")
+#define NETSYNC_LONGTEXT N_("When set, " \
+  "this VLC instance will act as the master clock for synchronization " \
+  "for clients listening")
 
 #define MIP_TEXT N_("Master server ip address")
 #define MIP_LONGTEXT N_("The IP address of " \
-  "the network master clock to use for clock synchronisation.")
+  "the network master clock to use for clock synchronization.")
 
 #define NETSYNC_TIMEOUT_TEXT N_("UDP timeout (in ms)")
-#define NETSYNC_TIMEOUT_LONGTEXT N_("Amount of time (in ms) " \
-  "to wait before aborting network reception of data.")
+#define NETSYNC_TIMEOUT_LONGTEXT N_("Length of time (in ms) " \
+  "until aborting data reception.")
 
 vlc_module_begin()
     set_shortname(N_("Network Sync"))
-    set_description(N_("Network synchronisation"))
+    set_description(N_("Network synchronization"))
     set_category(CAT_ADVANCED)
     set_subcategory(SUBCAT_ADVANCED_MISC)
 
-    add_bool("netsync-master", false, NULL,
+    add_bool("netsync-master", false,
               NETSYNC_TEXT, NETSYNC_LONGTEXT, true)
-    add_string("netsync-master-ip", NULL, NULL, MIP_TEXT, MIP_LONGTEXT,
+    add_string("netsync-master-ip", NULL, MIP_TEXT, MIP_LONGTEXT,
                 true)
-    add_integer("netsync-timeout", 500, NULL,
+    add_integer("netsync-timeout", 500,
                  NETSYNC_TIMEOUT_TEXT, NETSYNC_TIMEOUT_LONGTEXT, true)
 
     set_capability("interface", 0)
@@ -127,7 +126,6 @@ static int Open(vlc_object_t *object)
         return VLC_EGENERIC;
     }
 
-    intf->pf_run = NULL;
     intf->p_sys = sys = malloc(sizeof(*sys));
     if (!sys) {
         net_Close(fd);
@@ -154,8 +152,13 @@ void Close(vlc_object_t *object)
     intf_thread_t *intf = (intf_thread_t*)object;
     intf_sys_t *sys = intf->p_sys;
 
-    assert(sys->input == NULL);
     var_DelCallback(sys->playlist, "input-current", PlaylistEvent, intf);
+
+    if (sys->input != NULL) {
+        vlc_cancel(sys->thread);
+        vlc_join(sys->thread, NULL);
+    }
+
     net_Close(sys->fd);
     free(sys);
 }
@@ -180,14 +183,16 @@ static void *Master(void *handle)
         struct pollfd ufd = { .fd = sys->fd, .events = POLLIN, };
         uint64_t data[2];
 
-        if (poll(&ufd, 1, -1) <= 0)
+        if (poll(&ufd, 1, -1) < 0)
             continue;
 
         /* We received something */
         struct sockaddr_storage from;
-        unsigned struct_size = sizeof(from);
-        recvfrom(sys->fd, data, sizeof(data), 0,
-                 (struct sockaddr*)&from, &struct_size);
+        socklen_t fromlen = sizeof (from);
+
+        if (recvfrom(sys->fd, data, 8, 0,
+                     (struct sockaddr *)&from, &fromlen) < 8)
+            continue;
 
         mtime_t master_system = GetPcrSystem(sys->input);
         if (master_system < 0)
@@ -197,8 +202,8 @@ static void *Master(void *handle)
         data[1] = hton64(master_system);
 
         /* Reply to the sender */
-        sendto(sys->fd, data, sizeof(data), 0,
-               (struct sockaddr *)&from, struct_size);
+        sendto(sys->fd, data, 16, 0,
+               (struct sockaddr *)&from, fromlen);
 #if 0
         /* not sure we need the client information to sync,
            since we are the master anyway */
@@ -209,6 +214,7 @@ static void *Master(void *handle)
                  : "non-IPv4", /*date*/ 0);
 #endif
     }
+    return NULL;
 }
 
 static void *Slave(void *handle)
@@ -225,21 +231,17 @@ static void *Slave(void *handle)
             goto wait;
 
         /* Send clock request to the master */
-        data[0] = hton64(system);
-
         const mtime_t send_date = mdate();
-        if (send(sys->fd, data, sizeof(data[0]), 0) <= 0)
-            goto wait;
+
+        data[0] = hton64(system);
+        send(sys->fd, data, 8, 0);
 
         /* Don't block */
-        int ret = poll(&ufd, 1, sys->timeout);
-        if (ret == 0)
+        if (poll(&ufd, 1, sys->timeout) <= 0)
             continue;
-        if (ret < 0)
-            goto wait;
 
         const mtime_t receive_date = mdate();
-        if (recv(sys->fd, data, sizeof(data), 0) <= 0)
+        if (recv(sys->fd, data, 16, 0) < 16)
             goto wait;
 
         const mtime_t master_date   = ntoh64(data[0]);
@@ -268,41 +270,32 @@ static void *Slave(void *handle)
     wait:
         msleep(INTF_IDLE_SLEEP);
     }
+    return NULL;
 }
 
-static int InputEvent(vlc_object_t *object, char const *cmd,
-                      vlc_value_t oldval, vlc_value_t newval, void *data)
+static int PlaylistEvent(vlc_object_t *object, char const *cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *data)
 {
-    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(object);
+    VLC_UNUSED(cmd); VLC_UNUSED(object);
     intf_thread_t  *intf = data;
     intf_sys_t     *sys = intf->p_sys;
+    input_thread_t *input = newval.p_address;
 
-    if (newval.i_int == INPUT_EVENT_DEAD && sys->input) {
+    if (sys->input != NULL) {
         msg_Err(intf, "InputEvent DEAD");
+        assert(oldval.p_address == sys->input);
+
         vlc_cancel(sys->thread);
         vlc_join(sys->thread, NULL);
-        vlc_object_release(sys->input);
-        sys->input = NULL;
     }
-    return VLC_SUCCESS;
-}
 
-static int PlaylistEvent(vlc_object_t *object, char const *cmd,
-                         vlc_value_t oldval, vlc_value_t newval, void *data)
-{
-    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(object);
-    intf_thread_t  *intf = data;
-    intf_sys_t     *sys = intf->p_sys;
+    sys->input = input;
 
-    input_thread_t *input = newval.p_address;
-    assert(sys->input == NULL);
-    sys->input = vlc_object_hold(input);
-    if (vlc_clone(&sys->thread, sys->is_master ? Master : Slave, intf,
-                  VLC_THREAD_PRIORITY_INPUT)) {
-        vlc_object_release(input);
-        return VLC_SUCCESS;
+    if (input != NULL) {
+        if (vlc_clone(&sys->thread, sys->is_master ? Master : Slave, intf,
+                      VLC_THREAD_PRIORITY_INPUT))
+            sys->input = NULL;
     }
-    var_AddCallback(input, "intf-event", InputEvent, intf);
     return VLC_SUCCESS;
 }