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

📄 rtsp.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * rtsp.c: rtsp VoD server module ***************************************************************************** * Copyright (C) 2003-2006 the VideoLAN team * $Id: 561e110cae0a647b6a087abcd47642e3bfef78f6 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Gildas Bazin <gbazin@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., 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_input.h>#include <vlc_sout.h>#include <vlc_block.h>#include "vlc_httpd.h"#include "vlc_vod.h"#include "vlc_url.h"#include <vlc_network.h>#include <vlc_charset.h>#include <vlc_strings.h>#include <errno.h>#ifndef WIN32# include <locale.h>#endif#ifdef HAVE_XLOCALE_H# include <xlocale.h>#endif/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );#define HOST_TEXT N_( "RTSP host address" )#define HOST_LONGTEXT N_( \    "This defines the address, port and path the RTSP VOD server will listen " \    "on.\nSyntax is address:port/path. The default is to listen on all "\    "interfaces (address 0.0.0.0), on port 554, with no path.\nTo listen " \    "only on the local interface, use \"localhost\" as address." )#define THROTLE_TEXT N_( "Maximum number of connections" )#define THROTLE_LONGTEXT N_( "This limits the maximum number of clients " \    "that can connect to the RTSP VOD. 0 means no limit."  )#define RAWMUX_TEXT N_( "MUX for RAW RTSP transport" )#define SESSION_TIMEOUT_TEXT N_( "Sets the timeout option in the RTSP " \    "session string" )#define SESSION_TIMEOUT_LONGTEXT N_( "Defines what timeout option to add " \    "to the RTSP session ID string. Setting it to a negative number removes " \    "the timeout option entirely. This is needed by some IPTV STBs (such as " \    "those made by HansunTech) which get confused by it. The default is 5." )vlc_module_begin();    set_shortname( N_("RTSP VoD" ) );    set_description( N_("RTSP VoD server") );    set_category( CAT_SOUT );    set_subcategory( SUBCAT_SOUT_VOD );    set_capability( "vod server", 1 );    set_callbacks( Open, Close );    add_shortcut( "rtsp" );    add_string ( "rtsp-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, true );    add_string( "rtsp-raw-mux", "ts", NULL, RAWMUX_TEXT,                RAWMUX_TEXT, true );    add_integer( "rtsp-throttle-users", 0, NULL, THROTLE_TEXT,                                           THROTLE_LONGTEXT, true );    add_integer( "rtsp-session-timeout", 5, NULL, SESSION_TIMEOUT_TEXT,                 SESSION_TIMEOUT_LONGTEXT, true );vlc_module_end();/***************************************************************************** * Exported prototypes *****************************************************************************/typedef struct media_es_t media_es_t;typedef struct{    media_es_t *p_media_es;    char *psz_ip;    int i_port;} rtsp_client_es_t;typedef struct{    char *psz_session;    int64_t i_last; /* for timeout */    bool b_playing; /* is it in "play" state */    bool b_paused; /* is it in "pause" state */    int i_es;    rtsp_client_es_t **es;} rtsp_client_t;struct media_es_t{    /* VoD server */    vod_t *p_vod;    /* RTSP server */    httpd_url_t *p_rtsp_url;    vod_media_t *p_media;    es_format_t fmt;    int         i_port;    uint8_t     i_payload_type;    char        *psz_rtpmap;    char        *psz_fmtp;};struct vod_media_t{    int id;    /* VoD server */    vod_t *p_vod;    /* RTSP server */    httpd_url_t  *p_rtsp_url;    char         *psz_rtsp_control_v4;    char         *psz_rtsp_control_v6;    char         *psz_rtsp_path;    int  i_port;    int  i_port_audio;    int  i_port_video;    int  i_ttl;    int  i_payload_type;    int64_t i_sdp_id;    int     i_sdp_version;    bool b_multicast;    vlc_mutex_t lock;    /* ES list */    int        i_es;    media_es_t **es;    char       *psz_mux;    bool  b_raw;    /* RTSP client */    int           i_rtsp;    rtsp_client_t **rtsp;    /* Infos */    char *psz_session_name;    char *psz_session_description;    char *psz_session_url;    char *psz_session_email;    mtime_t i_length;};struct vod_sys_t{    /* RTSP server */    httpd_host_t *p_rtsp_host;    char *psz_path;    int i_port;    int i_throttle_users;    int i_connections;    char *psz_raw_mux;    int i_session_timeout;    /* List of media */    vlc_mutex_t lock_media;    int i_media_id;    int i_media;    vod_media_t **media;    /* */    block_fifo_t *p_fifo_cmd;};/* rtsp delayed command (to avoid deadlock between vlm/httpd) */typedef enum{    RTSP_CMD_TYPE_NONE,  /* Exit requested */    RTSP_CMD_TYPE_PLAY,    RTSP_CMD_TYPE_PAUSE,    RTSP_CMD_TYPE_STOP,    RTSP_CMD_TYPE_SEEK,    RTSP_CMD_TYPE_REWIND,    RTSP_CMD_TYPE_FORWARD,} rtsp_cmd_type_t;static vod_media_t *MediaNew( vod_t *, const char *, input_item_t * );static void         MediaDel( vod_t *, vod_media_t * );static int          MediaAddES( vod_t *, vod_media_t *, es_format_t * );static void         MediaDelES( vod_t *, vod_media_t *, es_format_t * );static void* CommandThread( vlc_object_t *p_this );static void  CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *, const char *psz_session,                          double f_arg, const char *psz_arg );static rtsp_client_t *RtspClientNew( vod_media_t *, char * );static rtsp_client_t *RtspClientGet( vod_media_t *, const char * );static void           RtspClientDel( vod_media_t *, rtsp_client_t * );static int RtspCallback( httpd_callback_sys_t *, httpd_client_t *,                         httpd_message_t *, const httpd_message_t * );static int RtspCallbackES( httpd_callback_sys_t *, httpd_client_t *,                           httpd_message_t *, const httpd_message_t * );static char *SDPGenerate( const vod_media_t *, httpd_client_t *cl );static void sprintf_hexa( char *s, uint8_t *p_data, int i_data ){    static const char hex[16] = "0123456789abcdef";    int i;    for( i = 0; i < i_data; i++ )    {        s[2*i+0] = hex[(p_data[i]>>4)&0xf];        s[2*i+1] = hex[(p_data[i]   )&0xf];    }    s[2*i_data] = '\0';}/***************************************************************************** * Open: Starts the RTSP server module *****************************************************************************/static int Open( vlc_object_t *p_this ){    vod_t *p_vod = (vod_t *)p_this;    vod_sys_t *p_sys = 0;    char *psz_url = 0;    vlc_url_t url;    psz_url = config_GetPsz( p_vod, "rtsp-host" );    vlc_UrlParse( &url, psz_url, 0 );    free( psz_url );    if( url.i_port <= 0 ) url.i_port = 554;    p_vod->p_sys = p_sys = malloc( sizeof( vod_sys_t ) );    if( !p_sys ) goto error;    p_sys->p_rtsp_host = 0;    p_sys->i_session_timeout = var_CreateGetInteger( p_this, "rtsp-session-timeout" );    p_sys->i_throttle_users = var_CreateGetInteger( p_this, "rtsp-throttle-users" );    msg_Dbg( p_this, "allowing up to %d connections", p_sys->i_throttle_users );    p_sys->i_connections = 0;    p_sys->psz_raw_mux = var_CreateGetString( p_this, "rtsp-raw-mux" );    p_sys->p_rtsp_host =        httpd_HostNew( VLC_OBJECT(p_vod), url.psz_host, url.i_port );    if( !p_sys->p_rtsp_host )    {        msg_Err( p_vod, "cannot create RTSP server (%s:%i)",                 url.psz_host, url.i_port );        goto error;    }    p_sys->psz_path = strdup( url.psz_path ? url.psz_path : "/" );    p_sys->i_port = url.i_port;    vlc_UrlClean( &url );    vlc_mutex_init( &p_sys->lock_media );    TAB_INIT( p_sys->i_media, p_sys->media );    p_sys->i_media_id = 0;    p_vod->pf_media_new = MediaNew;    p_vod->pf_media_del = MediaDel;    p_vod->pf_media_add_es = MediaAddES;    p_vod->pf_media_del_es = MediaDelES;    p_sys->p_fifo_cmd = block_FifoNew();    if( vlc_thread_create( p_vod, "rtsp vod thread", CommandThread,                           VLC_THREAD_PRIORITY_LOW, false ) )    {        msg_Err( p_vod, "cannot spawn rtsp vod thread" );        block_FifoRelease( p_sys->p_fifo_cmd );        free( p_sys->psz_path );        goto error;    }    return VLC_SUCCESS;error:    if( p_sys )    {        if( p_sys->p_rtsp_host ) httpd_HostDelete( p_sys->p_rtsp_host );        free( p_sys->psz_raw_mux );        free( p_sys );    }    vlc_UrlClean( &url );    return VLC_EGENERIC;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){    vod_t *p_vod = (vod_t *)p_this;    vod_sys_t *p_sys = p_vod->p_sys;    /* Stop command thread */    vlc_object_kill( p_vod );    CommandPush( p_vod, RTSP_CMD_TYPE_NONE, NULL, NULL, 0.0, NULL );    vlc_thread_join( p_vod );    block_FifoRelease( p_sys->p_fifo_cmd );    httpd_HostDelete( p_sys->p_rtsp_host );    var_Destroy( p_this, "rtsp-session-timeout" );    var_Destroy( p_this, "rtsp-throttle-users" );    var_Destroy( p_this, "rtsp-raw-mux" );    /* Check VLM is not buggy */    if( p_sys->i_media > 0 )        msg_Err( p_vod, "rtsp vod leaking %d medias", p_sys->i_media );    TAB_CLEAN( p_sys->i_media, p_sys->media );    vlc_mutex_destroy( &p_sys->lock_media );    free( p_sys->psz_path );    free( p_sys->psz_raw_mux );    free( p_sys );}/***************************************************************************** * Media handling *****************************************************************************/static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name,                              input_item_t *p_item ){    vod_sys_t *p_sys = p_vod->p_sys;    vod_media_t *p_media = malloc( sizeof(vod_media_t) );    int i;    if( !p_media )        return NULL;    memset( p_media, 0, sizeof(vod_media_t) );    p_media->id = p_sys->i_media_id++;    TAB_INIT( p_media->i_es, p_media->es );    p_media->psz_mux = 0;    TAB_INIT( p_media->i_rtsp, p_media->rtsp );    p_media->b_raw = false;    if( asprintf( &p_media->psz_rtsp_path, "%s%s",                  p_sys->psz_path, psz_name ) <0 )        return NULL;    p_media->p_rtsp_url =        httpd_UrlNewUnique( p_sys->p_rtsp_host, p_media->psz_rtsp_path, NULL,                            NULL, NULL );    if( !p_media->p_rtsp_url )    {        msg_Err( p_vod, "cannot create RTSP url (%s)", p_media->psz_rtsp_path);        free( p_media->psz_rtsp_path );        free( p_media );        return NULL;    }    msg_Dbg( p_vod, "created RTSP url: %s", p_media->psz_rtsp_path );    if( asprintf( &p_media->psz_rtsp_control_v4,               "a=control:rtsp://%%s:%d%s/trackID=%%d\r\n",               p_sys->i_port, p_media->psz_rtsp_path ) < 0 )    {        httpd_UrlDelete( p_media->p_rtsp_url );        free( p_media->psz_rtsp_path );        free( p_media );        return NULL;    }    if( asprintf( &p_media->psz_rtsp_control_v6,               "a=control:rtsp://[%%s]:%d%s/trackID=%%d\r\n",              p_sys->i_port, p_media->psz_rtsp_path ) < 0 )    {

⌨️ 快捷键说明

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