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

📄 rtsp.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * rtsp.c: rtsp VoD server module ***************************************************************************** * Copyright (C) 2003-2006 the VideoLAN team * $Id: rtsp.c 16987 2006-10-08 12:54:12Z jpsaman $ * * 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 *****************************************************************************/#include <stdlib.h>#include <errno.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/sout.h>#include "vlc_httpd.h"#include "vlc_vod.h"#include "vlc_url.h"#include "network.h"#include "charset.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );#define HOST_TEXT N_( "RTSP host address" )/// \bug [String] extra space#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.\n To 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."  )vlc_module_begin();    set_shortname( _("RTSP VoD" ) );    set_description( _("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, VLC_TRUE );    add_integer( "rtsp-throttle-users", 0, NULL, THROTLE_TEXT,                                           THROTLE_LONGTEXT, VLC_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 */    vlc_bool_t b_playing; /* is it in "play" state */    vlc_bool_t 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{    /* 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;    vlc_bool_t b_multicast;    vlc_mutex_t lock;    /* ES list */    int        i_es;    media_es_t **es;    char       *psz_mux;    vlc_bool_t  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;    /* List of media */    int i_media;    vod_media_t **media;};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 rtsp_client_t *RtspClientNew( vod_media_t *, char * );static rtsp_client_t *RtspClientGet( vod_media_t *, char * );static void           RtspClientDel( vod_media_t *, rtsp_client_t * );static int RtspCallback( httpd_callback_sys_t *, httpd_client_t *,                         httpd_message_t *, httpd_message_t * );static int RtspCallbackES( httpd_callback_sys_t *, httpd_client_t *,                           httpd_message_t *, 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 );    if( psz_url ) 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;    var_Create( p_this, "rtsp-throttle-users", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    p_sys->i_throttle_users = var_GetInteger( p_this, "rtsp-throtle-users" );    msg_Dbg( p_this, "allowing up to %d connections", p_sys->i_throttle_users );    p_sys->i_connections = 0;    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 );    p_sys->media = NULL;    p_sys->i_media = 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;    return VLC_SUCCESS;error:    if( p_sys && p_sys->p_rtsp_host ) httpd_HostDelete( p_sys->p_rtsp_host );    if( p_sys ) 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;    httpd_HostDelete( p_sys->p_rtsp_host );    var_Destroy( p_this, "rtsp-throttle-users" );    /* TODO delete medias */    free( p_sys->psz_path );    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 )    {        msg_Err( p_vod, "not enough memory" );        return NULL;    }    memset( p_media, 0, sizeof(vod_media_t) );    p_media->es = 0;    p_media->psz_mux = 0;    p_media->rtsp = 0;    p_media->b_raw = VLC_FALSE;    asprintf( &p_media->psz_rtsp_path, "%s%s", p_sys->psz_path, psz_name );    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 );    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 );    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 );    httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP,                    RtspCallback, (void*)p_media );    httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_DESCRIBE,                    RtspCallback, (void*)p_media );    httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PLAY,                    RtspCallback, (void*)p_media );    httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PAUSE,                    RtspCallback, (void*)p_media );    httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_TEARDOWN,                    RtspCallback, (void*)p_media );    p_media->p_vod = p_vod;    TAB_APPEND( p_sys->i_media, p_sys->media, p_media );    vlc_mutex_init( p_vod, &p_media->lock );    p_media->psz_session_name = strdup("");    p_media->psz_session_description = strdup("");    p_media->psz_session_url = strdup("");    p_media->psz_session_email = strdup("");    p_media->i_port_audio = 1234;    p_media->i_port_video = 1236;    p_media->i_port       = 1238;    p_media->i_payload_type = 96;    p_media->i_sdp_id = mdate();    p_media->i_sdp_version = 1;    p_media->i_length = p_item->i_duration;    vlc_mutex_lock( &p_item->lock );    msg_Dbg( p_vod, "media has %i declared ES", p_item->i_es );    for( i = 0; i < p_item->i_es; i++ )    {        MediaAddES( p_vod, p_media, p_item->es[i] );    }    vlc_mutex_unlock( &p_item->lock );    return p_media;}static void MediaDel( vod_t *p_vod, vod_media_t *p_media ){    vod_sys_t *p_sys = p_vod->p_sys;    msg_Dbg( p_vod, "deleting media: %s", p_media->psz_rtsp_path );    while( p_media->i_rtsp > 0 ) RtspClientDel( p_media, p_media->rtsp[0] );    httpd_UrlDelete( p_media->p_rtsp_url );    if( p_media->psz_rtsp_path ) free( p_media->psz_rtsp_path );    if( p_media->psz_rtsp_control_v6 ) free( p_media->psz_rtsp_control_v6 );    if( p_media->psz_rtsp_control_v4 ) free( p_media->psz_rtsp_control_v4 );    TAB_REMOVE( p_sys->i_media, p_sys->media, p_media );    while( p_media->i_es ) MediaDelES( p_vod, p_media, &p_media->es[0]->fmt );    vlc_mutex_destroy( &p_media->lock );    free( p_media->psz_session_name );    free( p_media->psz_session_description );    free( p_media->psz_session_url );    free( p_media->psz_session_email );    free( p_media );}static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ){    media_es_t *p_es = malloc( sizeof(media_es_t) );    char *psz_urlc;    memset( p_es, 0, sizeof(media_es_t) );    p_media->psz_mux = NULL;    /* TODO: update SDP, etc... */    asprintf( &psz_urlc, "%s/trackID=%d",              p_media->psz_rtsp_path, p_media->i_es );    msg_Dbg( p_vod, "  - ES %4.4s (%s)", (char *)&p_fmt->i_codec, psz_urlc );    switch( p_fmt->i_codec )    {        case VLC_FOURCC( 's', '1', '6', 'b' ):            if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )            {                p_es->i_payload_type = 11;            }            else if( p_fmt->audio.i_channels == 2 && p_fmt->audio.i_rate == 44100 )            {                p_es->i_payload_type = 10;            }            else            {                p_es->i_payload_type = p_media->i_payload_type++;            }            p_es->psz_rtpmap = malloc( strlen( "L16/*/*" ) + 20+1 );            sprintf( p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate,                    p_fmt->audio.i_channels );            break;        case VLC_FOURCC( 'u', '8', ' ', ' ' ):            p_es->i_payload_type = p_media->i_payload_type++;            p_es->psz_rtpmap = malloc( strlen( "L8/*/*" ) + 20+1 );            sprintf( p_es->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate,                    p_fmt->audio.i_channels );            break;        case VLC_FOURCC( 'm', 'p', 'g', 'a' ):            p_es->i_payload_type = 14;            p_es->psz_rtpmap = strdup( "MPA/90000" );            break;        case VLC_FOURCC( 'm', 'p', 'g', 'v' ):            p_es->i_payload_type = 32;

⌨️ 快捷键说明

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