📄 rtp.c
字号:
/***************************************************************************** * rtp.c: rtp stream output module ***************************************************************************** * Copyright (C) 2003-2004 VideoLAN * $Id: rtp.c 11047 2005-05-17 13:37:48Z fkuehne $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * 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 <errno.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/sout.h>#include "vlc_httpd.h"#include "network.h"/***************************************************************************** * Module descriptor *****************************************************************************/#define DST_TEXT N_("Destination")#define DST_LONGTEXT N_( \ "Allows you to specify the output URL used for the streaming output." )#define SDP_TEXT N_("SDP")#define SDP_LONGTEXT N_( \ "Allows you to specify the SDP used for the streaming output. " \ "You must use an url: http://location to access the SDP via HTTP, " \ "rtsp://location for RTSP access, and sap:// for the SDP to be " \ "announced via SAP." )#define MUX_TEXT N_("Muxer")#define MUX_LONGTEXT N_( \ "Allows you to specify the muxer used for the streaming output." )#define NAME_TEXT N_("Session name")#define NAME_LONGTEXT N_( \ "Allows you to specify the session name used for the streaming output." )#define DESC_TEXT N_("Session description")#define DESC_LONGTEXT N_( \ "Allows you to give a broader description of the stream." )#define URL_TEXT N_("Session URL")#define URL_LONGTEXT N_( \ "Allows you to specify a URL with additional information on the stream." )#define EMAIL_TEXT N_("Session email")#define EMAIL_LONGTEXT N_( \ "Allows you to specify contact e-mail address for this session." )#define PORT_TEXT N_("Port")#define PORT_LONGTEXT N_( \ "Allows you to specify the base port used for the RTP streaming." )#define PORT_AUDIO_TEXT N_("Audio port")#define PORT_AUDIO_LONGTEXT N_( \ "Allows you to specify the default audio port used for the RTP streaming." )#define PORT_VIDEO_TEXT N_("Video port")#define PORT_VIDEO_LONGTEXT N_( \ "Allows you to specify the default video port used for the RTP streaming." )#define TTL_TEXT N_("Time To Live")#define TTL_LONGTEXT N_( \ "Allows you to specify the time to live for the output stream." )static int Open ( vlc_object_t * );static void Close( vlc_object_t * );#define SOUT_CFG_PREFIX "sout-rtp-"vlc_module_begin(); set_shortname( _("RTP")); set_description( _("RTP stream output") ); set_capability( "sout stream", 0 ); add_shortcut( "rtp" ); set_category( CAT_SOUT ); set_subcategory( SUBCAT_SOUT_STREAM ); add_string( SOUT_CFG_PREFIX "dst", "", NULL, DST_TEXT, DST_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "sdp", "", NULL, SDP_TEXT, SDP_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "mux", "", NULL, MUX_TEXT, MUX_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "name", "NONE", NULL, NAME_TEXT, NAME_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "description", "", NULL, DESC_TEXT, DESC_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "url", "", NULL, URL_TEXT, URL_LONGTEXT, VLC_TRUE ); add_string( SOUT_CFG_PREFIX "email", "", NULL, EMAIL_TEXT, EMAIL_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "port-audio", 1234, NULL, PORT_AUDIO_TEXT, PORT_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "port-video", 1236, NULL, PORT_VIDEO_TEXT, PORT_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "port", 1238, NULL, PORT_TEXT, PORT_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL, TTL_TEXT, TTL_LONGTEXT, VLC_TRUE ); set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Exported prototypes *****************************************************************************/static const char *ppsz_sout_options[] = { "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux", "description", "url","email", NULL};static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );static int Del ( sout_stream_t *, sout_stream_id_t * );static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );/* For unicast/interleaved streaming */typedef struct{ char *psz_session; int64_t i_last; /* for timeout */ /* is it in "play" state */ vlc_bool_t b_playing; /* output (id-access) */ int i_id; sout_stream_id_t **id; int i_access; sout_access_out_t **access;} rtsp_client_t;struct sout_stream_sys_t{ /* sdp */ int64_t i_sdp_id; int i_sdp_version; char *psz_sdp; vlc_mutex_t lock_sdp; char *psz_session_name; char *psz_session_description; char *psz_session_url; char *psz_session_email; /* */ vlc_bool_t b_export_sdp_file; char *psz_sdp_file; /* sap */ vlc_bool_t b_export_sap; session_descriptor_t *p_session; httpd_host_t *p_httpd_host; httpd_file_t *p_httpd_file; httpd_host_t *p_rtsp_host; httpd_url_t *p_rtsp_url; char *psz_rtsp_control; char *psz_rtsp_path; /* */ char *psz_destination; int i_port; int i_port_audio; int i_port_video; int i_ttl; /* when need to use a private one or when using muxer */ int i_payload_type; /* in case we do TS/PS over rtp */ sout_mux_t *p_mux; sout_access_out_t *p_access; int i_mtu; sout_access_out_t *p_grab; uint16_t i_sequence; uint32_t i_timestamp_start; uint8_t ssrc[4]; block_t *packet; /* */ vlc_mutex_t lock_es; int i_es; sout_stream_id_t **es; /* */ int i_rtsp; rtsp_client_t **rtsp;};typedef int (*pf_rtp_packetizer_t)( sout_stream_t *, sout_stream_id_t *, block_t * );struct sout_stream_id_t{ sout_stream_t *p_stream; /* rtp field */ uint8_t i_payload_type; uint16_t i_sequence; uint32_t i_timestamp_start; uint8_t ssrc[4]; /* for sdp */ int i_clock_rate; char *psz_rtpmap; char *psz_fmtp; char *psz_destination; int i_port; int i_cat; /* Packetizer specific fields */ pf_rtp_packetizer_t pf_packetize; int i_mtu; /* for sending the packets */ sout_access_out_t *p_access; vlc_mutex_t lock_rtsp; int i_rtsp_access; sout_access_out_t **rtsp_access; /* */ sout_input_t *p_input; /* RTSP url control */ httpd_url_t *p_rtsp_url;};static int AccessOutGrabberWrite( sout_access_out_t *, block_t * );static void SDPHandleUrl( sout_stream_t *, char * );static int SapSetup( sout_stream_t *p_stream );static int FileSetup( sout_stream_t *p_stream );static int HttpSetup( sout_stream_t *p_stream, vlc_url_t * );static int RtspSetup( sout_stream_t *p_stream, vlc_url_t * );static int RtspCallback( httpd_callback_sys_t *, httpd_client_t *, httpd_message_t *, httpd_message_t * );static int RtspCallbackId( httpd_callback_sys_t *, httpd_client_t *, httpd_message_t *, httpd_message_t * );static rtsp_client_t *RtspClientNew( sout_stream_t *, char *psz_session );static rtsp_client_t *RtspClientGet( sout_stream_t *, char *psz_session );static void RtspClientDel( sout_stream_t *, rtsp_client_t * );/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_instance_t *p_sout = p_stream->p_sout; sout_stream_sys_t *p_sys; vlc_value_t val; sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); p_sys = malloc( sizeof( sout_stream_sys_t ) ); p_sys->psz_destination = var_GetString( p_stream, SOUT_CFG_PREFIX "dst" ); if( *p_sys->psz_destination == '\0' ) { free( p_sys->psz_destination ); p_sys->psz_destination = NULL; } p_sys->psz_session_name = var_GetString( p_stream, SOUT_CFG_PREFIX "name" ); p_sys->psz_session_description = var_GetString( p_stream, SOUT_CFG_PREFIX "description" ); p_sys->psz_session_url = var_GetString( p_stream, SOUT_CFG_PREFIX "url" ); p_sys->psz_session_email = var_GetString( p_stream, SOUT_CFG_PREFIX "email" ); p_sys->i_port = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port" ); p_sys->i_port_audio = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-audio" ); p_sys->i_port_video = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-video" ); p_sys->psz_sdp_file = NULL; if( p_sys->i_port_audio == p_sys->i_port_video ) { msg_Err( p_stream, "audio and video port cannot be the same" ); p_sys->i_port_audio = 0; p_sys->i_port_video = 0; } if( !p_sys->psz_session_name ) { if( p_sys->psz_destination ) p_sys->psz_session_name = strdup( p_sys->psz_destination ); else p_sys->psz_session_name = strdup( "NONE" ); } if( !p_sys->psz_destination || *p_sys->psz_destination == '\0' ) { sout_cfg_t *p_cfg; vlc_bool_t b_ok = VLC_FALSE; for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next ) { if( !strcmp( p_cfg->psz_name, "sdp" ) ) { if( p_cfg->psz_value && !strncasecmp( p_cfg->psz_value, "rtsp", 4 ) ) { b_ok = VLC_TRUE; break; } } } if( !b_ok ) { vlc_value_t val2; var_Get( p_stream, SOUT_CFG_PREFIX "sdp", &val2 ); if( !strncasecmp( val2.psz_string, "rtsp", 4 ) ) b_ok = VLC_TRUE; free( val2.psz_string ); } if( !b_ok ) { msg_Err( p_stream, "missing destination and not in rtsp mode" ); free( p_sys ); return VLC_EGENERIC; } p_sys->psz_destination = NULL; } else if( p_sys->i_port <= 0 ) { msg_Err( p_stream, "invalid port" ); free( p_sys ); return VLC_EGENERIC; } var_Get( p_stream, SOUT_CFG_PREFIX "ttl", &val ); p_sys->i_ttl = val.i_int; p_sys->i_payload_type = 96; p_sys->i_es = 0; p_sys->es = NULL; p_sys->i_rtsp = 0; p_sys->rtsp = NULL; p_sys->psz_sdp = NULL; p_sys->i_sdp_id = mdate(); p_sys->i_sdp_version = 1; p_sys->psz_sdp = NULL; p_sys->b_export_sap = VLC_FALSE; p_sys->b_export_sdp_file = VLC_FALSE; p_sys->p_session = NULL; p_sys->p_httpd_host = NULL; p_sys->p_httpd_file = NULL; p_sys->p_rtsp_host = NULL; p_sys->p_rtsp_url = NULL; p_sys->psz_rtsp_control = NULL; p_sys->psz_rtsp_path = NULL; vlc_mutex_init( p_stream, &p_sys->lock_sdp ); vlc_mutex_init( p_stream, &p_sys->lock_es ); p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; var_Get( p_stream, SOUT_CFG_PREFIX "mux", &val ); if( *val.psz_string ) { sout_access_out_t *p_grab; char *psz_rtpmap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -