📄 udp.c
字号:
/***************************************************************************** * udp.c ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN * $Id: udp.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * Eric Petit <titer@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <vlc/vlc.h>#include <vlc/sout.h>#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef WIN32# include <winsock2.h># include <ws2tcpip.h># ifndef IN_MULTICAST# define IN_MULTICAST(a) IN_CLASSD(a)# endif#else# include <sys/socket.h>#endif#include "network.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t * );static void Close( vlc_object_t * );#define SOUT_CFG_PREFIX "sout-udp-"#define CACHING_TEXT N_("Caching value (ms)")#define CACHING_LONGTEXT N_( \ "Allows you to modify the default caching value for UDP streams. This " \ "value should be set in millisecond units." )#define TTL_TEXT N_("Time To Live")#define TTL_LONGTEXT N_("Allows you to define the time to live of the " \ "outgoing stream.")#define GROUP_TEXT N_("Group packets")#define GROUP_LONGTEXT N_("Packets can be sent one by one at the right time " \ "or by groups. This allows you to give the number " \ "of packets that will be sent at a time. It " \ "helps reducing the scheduling load on " \ "heavily-loaded systems." )#define LATE_TEXT N_("Late delay (ms)" )#define LATE_LONGTEXT N_("Late packets are dropped. This allows you to give " \ "the time (in milliseconds) a packet is allowed to be" \ " late.")#define RAW_TEXT N_("Raw write")#define RAW_LONGTEXT N_("If you enable this option, packets will be sent " \ "directly, without trying to fill the MTU (ie, " \ "without trying to make the biggest possible packets " \ "in order to improve streaming)." )vlc_module_begin(); set_description( _("UDP stream output") ); set_shortname( N_( "UDP" ) ); set_category( CAT_SOUT ); set_subcategory( SUBCAT_SOUT_ACO ); add_integer( SOUT_CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL,TTL_TEXT, TTL_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "group", 1, NULL, GROUP_TEXT, GROUP_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "late", 0, NULL, LATE_TEXT, LATE_LONGTEXT, VLC_TRUE ); add_bool( SOUT_CFG_PREFIX "raw", 0, NULL, RAW_TEXT, RAW_LONGTEXT, VLC_TRUE ); set_capability( "sout access", 100 ); add_shortcut( "udp" ); add_shortcut( "rtp" ); // Will work only with ts muxer set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Exported prototypes *****************************************************************************/static const char *ppsz_sout_options[] = { "caching", "ttl", "group", "late", "raw", NULL};static int Write ( sout_access_out_t *, block_t * );static int WriteRaw( sout_access_out_t *, block_t * );static int Seek ( sout_access_out_t *, off_t );static void ThreadWrite( vlc_object_t * );static block_t *NewUDPPacket( sout_access_out_t *, mtime_t );typedef struct sout_access_thread_t{ VLC_COMMON_MEMBERS sout_instance_t *p_sout; block_fifo_t *p_fifo; int i_handle; int64_t i_caching; int64_t i_late; int i_group;} sout_access_thread_t;struct sout_access_out_sys_t{ int b_rtpts; // 1 if add rtp/ts header uint16_t i_sequence_number; uint32_t i_ssrc; int i_mtu; block_t *p_buffer; sout_access_thread_t *p_thread; vlc_bool_t b_mtu_warning;};#define DEFAULT_PORT 1234/***************************************************************************** * Open: open the file *****************************************************************************/static int Open( vlc_object_t *p_this ){ sout_access_out_t *p_access = (sout_access_out_t*)p_this; sout_access_out_sys_t *p_sys; char *psz_parser; char *psz_dst_addr; int i_dst_port; module_t *p_network; network_socket_t socket_desc; vlc_value_t val; sout_CfgParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg ); if( !( p_sys = malloc( sizeof( sout_access_out_sys_t ) ) ) ) { msg_Err( p_access, "not enough memory" ); return VLC_EGENERIC; } memset( p_sys, 0, sizeof(sout_access_out_sys_t) ); p_access->p_sys = p_sys; if( p_access->psz_access != NULL && !strcmp( p_access->psz_access, "rtp" ) ) { msg_Warn( p_access, "be careful that rtp output only works with ts " "payload (not an error)" ); p_sys->b_rtpts = 1; } else { p_sys->b_rtpts = 0; } psz_parser = strdup( p_access->psz_name ); psz_dst_addr = psz_parser; i_dst_port = 0; if ( *psz_parser == '[' ) { while( *psz_parser && *psz_parser != ']' ) { psz_parser++; } } while( *psz_parser && *psz_parser != ':' ) { psz_parser++; } if( *psz_parser == ':' ) { *psz_parser = '\0'; psz_parser++; i_dst_port = atoi( psz_parser ); } if( i_dst_port <= 0 ) { i_dst_port = DEFAULT_PORT; } p_sys->p_thread = vlc_object_create( p_access, sizeof( sout_access_thread_t ) ); if( !p_sys->p_thread ) { msg_Err( p_access, "out of memory" ); return VLC_EGENERIC; } p_sys->p_thread->p_sout = p_access->p_sout; p_sys->p_thread->b_die = 0; p_sys->p_thread->b_error= 0; p_sys->p_thread->p_fifo = block_FifoNew( p_access ); socket_desc.i_type = NETWORK_UDP; socket_desc.psz_server_addr = psz_dst_addr; socket_desc.i_server_port = i_dst_port; socket_desc.psz_bind_addr = ""; socket_desc.i_bind_port = 0; var_Get( p_access, SOUT_CFG_PREFIX "ttl", &val ); socket_desc.i_ttl = val.i_int; p_sys->p_thread->p_private = (void*)&socket_desc; if( !( p_network = module_Need( p_sys->p_thread, "network", NULL, 0 ) ) ) { msg_Err( p_access, "failed to open a connection (udp)" ); return VLC_EGENERIC; } module_Unneed( p_sys->p_thread, p_network ); p_sys->p_thread->i_handle = socket_desc.i_handle; var_Get( p_access, SOUT_CFG_PREFIX "caching", &val ); p_sys->p_thread->i_caching = (int64_t)val.i_int * 1000; var_Get( p_access, SOUT_CFG_PREFIX "group", &val ); p_sys->p_thread->i_group = val.i_int; var_Get( p_access, SOUT_CFG_PREFIX "late", &val ); p_sys->p_thread->i_late = (int64_t)val.i_int * 1000; p_sys->i_mtu = socket_desc.i_mtu;#ifdef WIN32 if( vlc_thread_create( p_sys->p_thread, "sout write thread", ThreadWrite, VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )#else if( vlc_thread_create( p_sys->p_thread, "sout write thread", ThreadWrite, VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -