⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtp.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * rtp.c: rtp stream output module ***************************************************************************** * Copyright (C) 2003-2004 the VideoLAN team * Copyright © 2007-2008 Rémi Denis-Courmont * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_sout.h>#include <vlc_block.h>#include <vlc_httpd.h>#include <vlc_url.h>#include <vlc_network.h>#include <vlc_charset.h>#include <vlc_strings.h>#include <srtp.h>#include "rtp.h"#ifdef HAVE_UNISTD_H#   include <sys/types.h>#   include <unistd.h>#   include <fcntl.h>#   include <sys/stat.h>#endif#ifdef HAVE_LINUX_DCCP_H#   include <linux/dccp.h>#endif#ifndef IPPROTO_DCCP# define IPPROTO_DCCP 33#endif#ifndef IPPROTO_UDPLITE# define IPPROTO_UDPLITE 136#endif#include <errno.h>#include <assert.h>/***************************************************************************** * Module descriptor *****************************************************************************/#define DEST_TEXT N_("Destination")#define DEST_LONGTEXT N_( \    "This is the output URL that will be used." )#define SDP_TEXT N_("SDP")#define SDP_LONGTEXT N_( \    "This allows you to specify how the SDP (Session Descriptor) for this RTP "\    "session will be made available. 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 SAP_TEXT N_("SAP announcing")#define SAP_LONGTEXT N_("Announce this session with SAP.")#define MUX_TEXT N_("Muxer")#define MUX_LONGTEXT N_( \    "This allows you to specify the muxer used for the streaming output. " \    "Default is to use no muxer (standard RTP stream)." )#define NAME_TEXT N_("Session name")#define NAME_LONGTEXT N_( \    "This is the name of the session that will be announced in the SDP " \    "(Session Descriptor)." )#define DESC_TEXT N_("Session description")#define DESC_LONGTEXT N_( \    "This allows you to give a short description with details about the stream, " \    "that will be announced in the SDP (Session Descriptor)." )#define URL_TEXT N_("Session URL")#define URL_LONGTEXT N_( \    "This allows you to give an URL with more details about the stream " \    "(often the website of the streaming organization), that will " \    "be announced in the SDP (Session Descriptor)." )#define EMAIL_TEXT N_("Session email")#define EMAIL_LONGTEXT N_( \    "This allows you to give a contact mail address for the stream, that will " \    "be announced in the SDP (Session Descriptor)." )#define PHONE_TEXT N_("Session phone number")#define PHONE_LONGTEXT N_( \    "This allows you to give a contact telephone number for the stream, that will " \    "be announced in the SDP (Session Descriptor)." )#define PORT_TEXT N_("Port")#define PORT_LONGTEXT N_( \    "This allows you to specify the base port for the RTP streaming." )#define PORT_AUDIO_TEXT N_("Audio port")#define PORT_AUDIO_LONGTEXT N_( \    "This allows you to specify the default audio port for the RTP streaming." )#define PORT_VIDEO_TEXT N_("Video port")#define PORT_VIDEO_LONGTEXT N_( \    "This allows you to specify the default video port for the RTP streaming." )#define TTL_TEXT N_("Hop limit (TTL)")#define TTL_LONGTEXT N_( \    "This is the hop limit (also known as \"Time-To-Live\" or TTL) of " \    "the multicast packets sent by the stream output (0 = use operating " \    "system built-in default).")#define RTCP_MUX_TEXT N_("RTP/RTCP multiplexing")#define RTCP_MUX_LONGTEXT N_( \    "This sends and receives RTCP packet multiplexed over the same port " \    "as RTP packets." )#define PROTO_TEXT N_("Transport protocol")#define PROTO_LONGTEXT N_( \    "This selects which transport protocol to use for RTP." )#define SRTP_KEY_TEXT N_("SRTP key (hexadecimal)")#define SRTP_KEY_LONGTEXT N_( \    "RTP packets will be integrity-protected and ciphered "\    "with this Secure RTP master shared secret key.")#define SRTP_SALT_TEXT N_("SRTP salt (hexadecimal)")#define SRTP_SALT_LONGTEXT N_( \    "Secure RTP requires a (non-secret) master salt value.")static const char *const ppsz_protos[] = {    "dccp", "sctp", "tcp", "udp", "udplite",};static const char *const ppsz_protocols[] = {    "DCCP", "SCTP", "TCP", "UDP", "UDP-Lite",};#define RFC3016_TEXT N_("MP4A LATM")#define RFC3016_LONGTEXT N_( \    "This allows you to stream MPEG4 LATM audio streams (see RFC3016)." )static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );#define SOUT_CFG_PREFIX "sout-rtp-"#define MAX_EMPTY_BLOCKS 200vlc_module_begin();    set_shortname( N_("RTP"));    set_description( N_("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, DEST_TEXT,                DEST_LONGTEXT, true );        change_unsafe();    add_string( SOUT_CFG_PREFIX "sdp", "", NULL, SDP_TEXT,                SDP_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "mux", "", NULL, MUX_TEXT,                MUX_LONGTEXT, true );    add_bool( SOUT_CFG_PREFIX "sap", false, NULL, SAP_TEXT, SAP_LONGTEXT,              true );    add_string( SOUT_CFG_PREFIX "name", "", NULL, NAME_TEXT,                NAME_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "description", "", NULL, DESC_TEXT,                DESC_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "url", "", NULL, URL_TEXT,                URL_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "email", "", NULL, EMAIL_TEXT,                EMAIL_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "phone", "", NULL, PHONE_TEXT,                PHONE_LONGTEXT, true );    add_string( SOUT_CFG_PREFIX "proto", "udp", NULL, PROTO_TEXT,                PROTO_LONGTEXT, false );        change_string_list( ppsz_protos, ppsz_protocols, NULL );    add_integer( SOUT_CFG_PREFIX "port", 50004, NULL, PORT_TEXT,                 PORT_LONGTEXT, true );    add_integer( SOUT_CFG_PREFIX "port-audio", 50000, NULL, PORT_AUDIO_TEXT,                 PORT_AUDIO_LONGTEXT, true );    add_integer( SOUT_CFG_PREFIX "port-video", 50002, NULL, PORT_VIDEO_TEXT,                 PORT_VIDEO_LONGTEXT, true );    add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL, TTL_TEXT,                 TTL_LONGTEXT, true );    add_bool( SOUT_CFG_PREFIX "rtcp-mux", false, NULL,              RTCP_MUX_TEXT, RTCP_MUX_LONGTEXT, false );    add_string( SOUT_CFG_PREFIX "key", "", NULL,                SRTP_KEY_TEXT, SRTP_KEY_LONGTEXT, false );    add_string( SOUT_CFG_PREFIX "salt", "", NULL,                SRTP_SALT_TEXT, SRTP_SALT_LONGTEXT, false );    add_bool( SOUT_CFG_PREFIX "mp4a-latm", 0, NULL, RFC3016_TEXT,                 RFC3016_LONGTEXT, false );    set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Exported prototypes *****************************************************************************/static const char *const ppsz_sout_options[] = {    "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux",    "sap", "description", "url", "email", "phone",    "proto", "rtcp-mux", "key", "salt",    "mp4a-latm", 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* );static sout_stream_id_t *MuxAdd ( sout_stream_t *, es_format_t * );static int               MuxDel ( sout_stream_t *, sout_stream_id_t * );static int               MuxSend( sout_stream_t *, sout_stream_id_t *,                                  block_t* );static sout_access_out_t *GrabberCreate( sout_stream_t *p_sout );static void* ThreadSend( vlc_object_t *p_this );static void SDPHandleUrl( sout_stream_t *, const 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, const vlc_url_t * );struct sout_stream_sys_t{    /* SDP */    char    *psz_sdp;    vlc_mutex_t  lock_sdp;    /* SDP to disk */    bool b_export_sdp_file;    char *psz_sdp_file;    /* SDP via SAP */    bool b_export_sap;    session_descriptor_t *p_session;    /* SDP via HTTP */    httpd_host_t *p_httpd_host;    httpd_file_t *p_httpd_file;    /* RTSP */    rtsp_stream_t *rtsp;    /* */    char     *psz_destination;    uint8_t   proto;    uint8_t   i_ttl;    uint16_t  i_port;    uint16_t  i_port_audio;    uint16_t  i_port_video;    bool b_latm;    bool rtcp_mux;    /* 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_grab;    block_t           *packet;    /* */    vlc_mutex_t      lock_es;    int              i_es;    sout_stream_id_t **es;};typedef int (*pf_rtp_packetizer_t)( sout_stream_id_t *, block_t * );typedef struct rtp_sink_t{    int rtp_fd;    rtcp_sender_t *rtcp;} rtp_sink_t;struct sout_stream_id_t{    VLC_COMMON_MEMBERS    sout_stream_t *p_stream;    /* rtp field */    uint16_t    i_sequence;    uint8_t     i_payload_type;    uint8_t     ssrc[4];    /* for sdp */    const char  *psz_enc;    char        *psz_fmtp;    int          i_clock_rate;    int          i_port;    int          i_cat;    int          i_channels;    int          i_bitrate;    /* Packetizer specific fields */    int                 i_mtu;    srtp_session_t     *srtp;    pf_rtp_packetizer_t pf_packetize;    /* Packets sinks */    vlc_mutex_t       lock_sink;    int               sinkc;    rtp_sink_t       *sinkv;    rtsp_stream_id_t *rtsp_id;    int              *listen_fd;    block_fifo_t     *p_fifo;    int64_t           i_caching;};/***************************************************************************** * 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 = NULL;    config_chain_t      *p_cfg = NULL;    char                *psz;    bool          b_rtsp = false;    config_ChainParse( p_stream, SOUT_CFG_PREFIX,                       ppsz_sout_options, p_stream->p_cfg );    p_sys = malloc( sizeof( sout_stream_sys_t ) );    if( p_sys == NULL )        return VLC_ENOMEM;    p_sys->psz_destination = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "dst" );    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->rtcp_mux   = var_GetBool( p_stream, SOUT_CFG_PREFIX "rtcp-mux" );    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;    }    for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )    {        if( !strcmp( p_cfg->psz_name, "sdp" )         && ( p_cfg->psz_value != NULL )         && !strncasecmp( p_cfg->psz_value, "rtsp:", 5 ) )        {            b_rtsp = true;            break;        }    }    if( !b_rtsp )    {        psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "sdp" );        if( psz != NULL )        {            if( !strncasecmp( psz, "rtsp:", 5 ) )                b_rtsp = true;            free( psz );        }    }    /* Transport protocol */    p_sys->proto = IPPROTO_UDP;    psz = var_GetNonEmptyString (p_stream, SOUT_CFG_PREFIX"proto");    if ((psz == NULL) || !strcasecmp (psz, "udp"))        (void)0; /* default */    else    if (!strcasecmp (psz, "dccp"))    {        p_sys->proto = IPPROTO_DCCP;        p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */    }#if 0    else    if (!strcasecmp (psz, "sctp"))    {        p_sys->proto = IPPROTO_TCP;        p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */    }#endif#if 0    else    if (!strcasecmp (psz, "tcp"))    {        p_sys->proto = IPPROTO_TCP;        p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */    }#endif    else    if (!strcasecmp (psz, "udplite") || !strcasecmp (psz, "udp-lite"))        p_sys->proto = IPPROTO_UDPLITE;    else        msg_Warn (p_this, "unknown or unsupported transport protocol \"%s\"",                  psz);    free (psz);    var_Create (p_this, "dccp-service", VLC_VAR_STRING);    if( ( p_sys->psz_destination == NULL ) && !b_rtsp )    {        msg_Err( p_stream, "missing destination and not in RTSP mode" );        free( p_sys );        return VLC_EGENERIC;    }    p_sys->i_ttl = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ttl" );    if( p_sys->i_ttl == 0 )    {        /* Normally, we should let the default hop limit up to the core,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -