X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fnetsync.c;h=e6950464b1ce3ae4c411949e08927e862961b8cc;hb=e1e7a51039684334cde1bda68315fc21dabee705;hp=f6064fa87b27fb955ad31afe180d6ce01ab4ccbd;hpb=738e1f2690dfdc2f984c349ebb40c6074ede7c50;p=vlc diff --git a/modules/control/netsync.c b/modules/control/netsync.c index f6064fa87b..e6950464b1 100644 --- a/modules/control/netsync.c +++ b/modules/control/netsync.c @@ -18,16 +18,21 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include #ifdef HAVE_UNISTD_H # include @@ -38,15 +43,16 @@ #ifdef HAVE_SYS_TYPES_H # include #endif +#ifdef HAVE_POLL +# include +#endif -#include "network.h" +#include #define NETSYNC_PORT 9875 -/* Needed for Solaris */ -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif +/* FIXME: UGLY UGLY !! Netsync should be totally reworked */ +#include "../../src/input/input_internal.h" /***************************************************************************** * Module descriptor @@ -56,33 +62,30 @@ static void Close ( vlc_object_t * ); static mtime_t GetClockRef( intf_thread_t *, mtime_t ); -#define NETSYNC_TEXT N_( "Act as master for network synchronisation" ) -#define NETSYNC_LONGTEXT N_( "Allows you to specify if this client should " \ - "act as the master client for the network synchronisation." ) +/// \bug [String] This string is BAD. +#define NETSYNC_TEXT N_( "Act as master" ) +#define NETSYNC_LONGTEXT N_( "Should " \ + "act as the master client for the network synchronisation?" ) +/// \bug [String] This string is BAD. #define MIP_TEXT N_( "Master client ip address" ) -#define MIP_LONGTEXT N_( "Allows you to specify the ip address of " \ +#define MIP_LONGTEXT N_( "IP address of " \ "the master client used for the network synchronisation." ) -vlc_module_begin(); - set_shortname( _("Netsync")); - set_description( _("Network synchronisation") ); - set_category( CAT_INTERFACE ); - set_subcategory( SUBCAT_INTERFACE_CONTROL ); +vlc_module_begin () + set_shortname( N_("Network Sync")) + set_description( N_("Network synchronisation") ) + set_category( CAT_ADVANCED ) + set_subcategory( SUBCAT_ADVANCED_MISC ) add_bool( "netsync-master", 0, NULL, - NETSYNC_TEXT, NETSYNC_LONGTEXT, VLC_TRUE ); + NETSYNC_TEXT, NETSYNC_LONGTEXT, true ) add_string( "netsync-master-ip", NULL, NULL, MIP_TEXT, MIP_LONGTEXT, - VLC_TRUE ); + true ) - set_capability( "interface", 0 ); - set_callbacks( Activate, Close ); -vlc_module_end(); - -struct intf_sys_t -{ - input_thread_t *p_input; -}; + set_capability( "interface", 0 ) + set_callbacks( Activate, Close ) +vlc_module_end () /***************************************************************************** * Local prototypes @@ -95,18 +98,29 @@ static void Run( intf_thread_t *p_intf ); static int Activate( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*)p_this; + int fd; - msg_Info( p_intf, "Using the netsync interface module..." ); - - p_intf->p_sys = malloc( sizeof( intf_sys_t ) ); - if( !p_intf->p_sys ) + if( config_GetInt( p_intf, "netsync-master" ) <= 0 ) { - msg_Err( p_intf, "no memory" ); - return VLC_ENOMEM; + char *psz_master = config_GetPsz( p_intf, "netsync-master-ip" ); + if( psz_master == NULL ) + { + msg_Err( p_intf, "master address not specified" ); + return VLC_EGENERIC; + } + fd = net_ConnectUDP( VLC_OBJECT(p_intf), psz_master, NETSYNC_PORT, -1 ); + free( psz_master ); } + else + fd = net_ListenUDP1( VLC_OBJECT(p_intf), NULL, NETSYNC_PORT ); - p_intf->p_sys->p_input = NULL; + if( fd == -1 ) + { + msg_Err( p_intf, "Netsync socket failure" ); + return VLC_EGENERIC; + } + p_intf->p_sys = (void *)(intptr_t)fd; p_intf->pf_run = Run; return VLC_SUCCESS; } @@ -118,7 +132,7 @@ void Close( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*)p_this; - free( p_intf->p_sys ); + net_Close( (intptr_t)p_intf->p_sys ); } /***************************************************************************** @@ -128,56 +142,28 @@ static void Run( intf_thread_t *p_intf ) { #define MAX_MSG_LENGTH (2 * sizeof(int64_t)) - vlc_bool_t b_master = config_GetInt( p_intf, "netsync-master" ); - char *psz_master = NULL; + input_thread_t *p_input = NULL; char p_data[MAX_MSG_LENGTH]; int i_socket; - - if( !b_master ) - { - psz_master = config_GetPsz( p_intf, "netsync-master-ip" ); - if( psz_master == NULL ) - { - msg_Err( p_intf, "master address not specified" ); - return; - } - } - - if( b_master ) - i_socket = net_OpenUDP( p_intf, NULL, NETSYNC_PORT, NULL, 0 ); - else - i_socket = net_ConnectUDP( p_intf, psz_master, NETSYNC_PORT, 0 ); - - if( psz_master ) free( psz_master ); - - if( i_socket < 0 ) - { - msg_Err( p_intf, "failed opening UDP socket." ); - return; - } + int canc = vlc_savecancel(); /* High priority thread */ vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_INPUT ); - while( !p_intf->b_die ) + while( vlc_object_alive( p_intf ) ) { - struct timeval timeout; - fd_set fds_r; - /* Update the input */ - if( p_intf->p_sys->p_input == NULL ) - { - p_intf->p_sys->p_input = + if( p_input == NULL ) + p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE ); - } - else if( p_intf->p_sys->p_input->b_dead ) + else if( p_input->b_dead ) { - vlc_object_release( p_intf->p_sys->p_input ); - p_intf->p_sys->p_input = NULL; + vlc_object_release( p_input ); + p_input = NULL; } - if( p_intf->p_sys->p_input == NULL ) + if( p_input == NULL ) { /* Wait a bit */ msleep( INTF_IDLE_SLEEP ); @@ -189,10 +175,8 @@ static void Run( intf_thread_t *p_intf ) */ /* Initialize file descriptor set and timeout (0.5s) */ - FD_ZERO( &fds_r ); - FD_SET( i_socket, &fds_r ); - timeout.tv_sec = 0; - timeout.tv_usec = 500000; + /* FIXME: arbitrary tick */ + struct pollfd ufd = { .fd = i_socket, .events = POLLIN, }; if( b_master ) { @@ -201,7 +185,7 @@ static void Run( intf_thread_t *p_intf ) int i_struct_size, i_read, i_ret; /* Don't block */ - i_ret = select( i_socket + 1, &fds_r, 0, 0, &timeout ); + i_ret = poll( &ufd, 1, 500 ); if( i_ret == 0 ) continue; if( i_ret < 0 ) { @@ -213,7 +197,8 @@ static void Run( intf_thread_t *p_intf ) /* We received something */ i_struct_size = sizeof( from ); i_read = recvfrom( i_socket, p_data, MAX_MSG_LENGTH, 0, - (struct sockaddr*)&from, &i_struct_size ); + (struct sockaddr*)&from, + (unsigned int *)&i_struct_size ); i_clockref = ntoh64(*(int64_t *)p_data); @@ -228,8 +213,8 @@ static void Run( intf_thread_t *p_intf ) (struct sockaddr *)&from, i_struct_size ); #if 0 - msg_Dbg( p_intf, "Master clockref: "I64Fd" -> "I64Fd", from %s " - "(date: "I64Fd")", i_clockref, i_master_clockref, + msg_Dbg( p_intf, "Master clockref: %"PRId64" -> %"PRId64", from %s " + "(date: %"PRId64")", i_clockref, i_master_clockref, from.ss_family == AF_INET ? inet_ntoa(((struct sockaddr_in *)&from)->sin_addr) : "non-IPv4", i_date ); @@ -255,7 +240,7 @@ static void Run( intf_thread_t *p_intf ) } /* Don't block */ - i_ret = select(i_socket + 1, &fds_r, 0, 0, &timeout); + i_ret = poll( &ufd, 1, 500 ); if( i_ret == 0 ) continue; if( i_ret < 0 ) { @@ -281,20 +266,20 @@ static void Run( intf_thread_t *p_intf ) ((i_receive_date - i_send_date) / 2 + i_master_date); i_client_clockref = i_drift = 0; - if( p_intf->p_sys->p_input && i_master_clockref ) + if( p_input && i_master_clockref ) { i_client_clockref = GetClockRef( p_intf, i_clockref ); i_drift = i_client_clockref - i_master_clockref - i_diff_date; /* Update our clock to match the master's one */ if( i_client_clockref ) - p_intf->p_sys->p_input->i_pts_delay -= i_drift; + p_input->i_pts_delay -= i_drift; } #if 0 - msg_Dbg( p_intf, "Slave clockref: "I64Fd" -> "I64Fd" -> "I64Fd", " - "clock diff: "I64Fd" drift: "I64Fd, - i_clockref, i_master_clockref, + msg_Dbg( p_intf, "Slave clockref: %"PRId64" -> %"PRId64" -> %"PRId64", " + "clock diff: %"PRId64" drift: %"PRId64, + i_clockref, i_master_clockref, i_client_clockref, i_diff_date, i_drift ); #endif @@ -303,8 +288,8 @@ static void Run( intf_thread_t *p_intf ) } } - if( p_intf->p_sys->p_input ) vlc_object_release( p_intf->p_sys->p_input ); - net_Close( i_socket ); + if( p_input ) vlc_object_release( p_input ); + vlc_restorecancel( canc ); } static mtime_t GetClockRef( intf_thread_t *p_intf, mtime_t i_pts ) @@ -312,9 +297,9 @@ static mtime_t GetClockRef( intf_thread_t *p_intf, mtime_t i_pts ) input_thread_t *p_input = p_intf->p_sys->p_input; mtime_t i_ts; - if( !p_input || !p_input->p_es_out ) return 0; + if( !p_input || !p_input->p->p_es_out ) return 0; - if( es_out_Control( p_input->p_es_out, ES_OUT_GET_TS, i_pts, &i_ts ) == + if( es_out_Control( p_input->p->p_es_out, ES_OUT_GET_TS, i_pts, &i_ts ) == VLC_SUCCESS ) { return i_ts;