[vlc-commits] rtp: remove VoD hooks
Rémi Denis-Courmont
git at videolan.org
Sat Feb 29 16:31:29 CET 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 29 14:24:33 2020 +0200| [4b5f6714a2932df9c6431168ff464a9c422ffe91] | committer: Rémi Denis-Courmont
rtp: remove VoD hooks
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4b5f6714a2932df9c6431168ff464a9c422ffe91
---
modules/stream_out/Makefile.am | 2 +-
modules/stream_out/rtp.c | 112 +--------
modules/stream_out/rtp.h | 26 +-
modules/stream_out/rtsp.c | 186 +-------------
modules/stream_out/vod.c | 548 -----------------------------------------
5 files changed, 17 insertions(+), 857 deletions(-)
diff --git a/modules/stream_out/Makefile.am b/modules/stream_out/Makefile.am
index 900dbfeabc..f2ad0db3e3 100644
--- a/modules/stream_out/Makefile.am
+++ b/modules/stream_out/Makefile.am
@@ -80,7 +80,7 @@ endif
sout_LTLIBRARIES += libstream_out_rtp_plugin.la
libstream_out_rtp_plugin_la_SOURCES = \
stream_out/rtp.c stream_out/rtp.h stream_out/rtpfmt.c \
- stream_out/rtcp.c stream_out/rtsp.c stream_out/vod.c
+ stream_out/rtcp.c stream_out/rtsp.c
libstream_out_rtp_plugin_la_CFLAGS = $(AM_CFLAGS)
libstream_out_rtp_plugin_la_LIBADD = $(SOCKET_LIBS)
if HAVE_GCRYPT
diff --git a/modules/stream_out/rtp.c b/modules/stream_out/rtp.c
index b0d640436f..5e1461e487 100644
--- a/modules/stream_out/rtp.c
+++ b/modules/stream_out/rtp.c
@@ -187,7 +187,7 @@ vlc_module_begin ()
set_shortname( N_("RTP"))
set_description( N_("RTP stream output") )
set_capability( "sout stream", 0 )
- add_shortcut( "rtp", "vod" )
+ add_shortcut( "rtp" )
set_category( CAT_SOUT )
set_subcategory( SUBCAT_SOUT_STREAM )
@@ -239,21 +239,6 @@ vlc_module_begin ()
RFC3016_LONGTEXT, false )
set_callbacks( Open, Close )
-
- add_submodule ()
- set_shortname( N_("RTSP VoD" ) )
- set_description( N_("RTSP VoD server") )
- set_category( CAT_SOUT )
- set_subcategory( SUBCAT_SOUT_VOD )
- set_capability( "vod server", 10 )
- set_callbacks( OpenVoD, CloseVoD )
- add_shortcut( "rtsp" )
- add_integer( "rtsp-timeout", 60, RTSP_TIMEOUT_TEXT,
- RTSP_TIMEOUT_LONGTEXT, true )
- add_string( "sout-rtsp-user", "",
- RTSP_USER_TEXT, RTSP_USER_LONGTEXT, true )
- add_password("sout-rtsp-pwd", "", RTSP_PASS_TEXT, RTSP_PASS_LONGTEXT)
-
vlc_module_end ()
/*****************************************************************************
@@ -287,9 +272,6 @@ 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 * );
-static vlc_tick_t rtp_init_ts( const vod_media_t *p_media,
- const char *psz_vod_session );
-
typedef struct
{
/* SDP */
@@ -325,10 +307,6 @@ typedef struct
bool rtcp_mux;
bool b_latm;
- /* VoD */
- vod_media_t *p_vod_media;
- char *psz_vod_session;
-
/* in case we do TS/PS over rtp */
sout_mux_t *p_mux;
sout_access_out_t *p_grab;
@@ -475,33 +453,7 @@ static int Open( vlc_object_t *p_this )
free (psz);
var_Create (p_this, "dccp-service", VLC_VAR_STRING);
- p_sys->p_vod_media = NULL;
- p_sys->psz_vod_session = NULL;
-
- if (! strcmp(p_stream->psz_name, "vod"))
- {
- /* The VLM stops all instances before deleting a media, so this
- * reference will remain valid during the lifetime of the rtp
- * stream output. */
- p_sys->p_vod_media = var_InheritAddress(p_stream, "vod-media");
-
- if (p_sys->p_vod_media != NULL)
- {
- p_sys->psz_vod_session = var_InheritString(p_stream, "vod-session");
- if (p_sys->psz_vod_session == NULL)
- {
- msg_Err(p_stream, "missing VoD session");
- free(p_sys);
- return VLC_EGENERIC;
- }
-
- const char *mux = vod_get_mux(p_sys->p_vod_media);
- var_SetString(p_stream, SOUT_CFG_PREFIX "mux", mux);
- }
- }
-
- if( p_sys->psz_destination == NULL && !b_rtsp
- && p_sys->p_vod_media == NULL )
+ if( p_sys->psz_destination == NULL && !b_rtsp )
{
msg_Err( p_stream, "missing destination and not in RTSP mode" );
free( p_sys );
@@ -519,12 +471,11 @@ static int Open( vlc_object_t *p_this )
/* NPT=0 time will be determined when we packetize the first packet
* (of any ES). But we want to be able to report rtptime in RTSP
- * without waiting (and already did in the VoD case). So until then,
+ * without waiting. So until then,
* we use an arbitrary reference PTS for timestamp computations, and
* then actual PTS will catch up using offsets. */
p_sys->i_npt_zero = VLC_TICK_INVALID;
- p_sys->i_pts_zero = rtp_init_ts(p_sys->p_vod_media,
- p_sys->psz_vod_session);
+ p_sys->i_pts_zero = vlc_tick_now();
p_sys->i_es = 0;
p_sys->es = NULL;
p_sys->rtsp = NULL;
@@ -553,7 +504,6 @@ static int Open( vlc_object_t *p_this )
{
msg_Err( p_stream, "unsupported muxer type for RTP (only TS/PS)" );
free( psz );
- free( p_sys->psz_vod_session );
free( p_sys->psz_destination );
free( p_sys );
return VLC_EGENERIC;
@@ -567,7 +517,6 @@ static int Open( vlc_object_t *p_this )
{
msg_Err( p_stream, "cannot create muxer" );
sout_AccessOutDelete( p_sys->p_grab );
- free( p_sys->psz_vod_session );
free( p_sys->psz_destination );
free( p_sys );
return VLC_EGENERIC;
@@ -669,7 +618,6 @@ static void Close( vlc_object_t * p_this )
unlink( p_sys->psz_sdp_file );
free( p_sys->psz_sdp_file );
}
- free( p_sys->psz_vod_session );
free( p_sys->psz_destination );
free( p_sys );
}
@@ -724,7 +672,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, const char *psz_url )
var_SetInteger( p_stream, "rtsp-port", url.i_port );
}
- p_sys->rtsp = RtspSetup( VLC_OBJECT(p_stream), NULL, url.psz_path );
+ p_sys->rtsp = RtspSetup( VLC_OBJECT(p_stream), url.psz_path );
if( p_sys->rtsp == NULL )
msg_Err( p_stream, "cannot export SDP as RTSP" );
}
@@ -975,27 +923,6 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
bool format = false;
- if (p_sys->p_vod_media != NULL)
- {
- id->rtp_fmt.ptname = NULL;
- uint32_t ssrc;
- int val = vod_init_id(p_sys->p_vod_media, p_sys->psz_vod_session,
- p_fmt ? p_fmt->i_id : 0, id, &id->rtp_fmt,
- &ssrc, &id->i_seq_sent_next);
- if (val == VLC_SUCCESS)
- {
- memcpy(id->ssrc, &ssrc, sizeof(id->ssrc));
- /* This is ugly, but id->i_seq_sent_next needs to be
- * initialized inside vod_init_id() to avoid race
- * conditions. */
- id->i_sequence = id->i_seq_sent_next;
- }
- /* vod_init_id() may fail either because the ES wasn't found in
- * the VoD media, or because the RTSP session is gone. In the
- * former case, id->rtp_fmt was left untouched. */
- format = (id->rtp_fmt.ptname != NULL);
- }
-
if (!format)
{
id->rtp_fmt.fmtp = NULL; /* don't free() garbage on error */
@@ -1222,8 +1149,6 @@ static void Del( sout_stream_t *p_stream, void *_id )
free( id->rtp_fmt.fmtp );
- if (p_sys->p_vod_media != NULL)
- vod_detach_id(p_sys->p_vod_media, p_sys->psz_vod_session, id);
if( id->rtsp_id )
RtspDelId( p_sys->rtsp, id->rtsp_id );
if( id->listen.fd != NULL )
@@ -1536,37 +1461,12 @@ uint16_t rtp_get_seq( sout_stream_id_sys_t *id )
return seq;
}
-/* Return an arbitrary initial timestamp for RTP timestamp computations.
- * RFC 3550 states that the resulting initial RTP timestamps SHOULD be
- * random (although we use the same reference for all the ES as a
- * feature). In the VoD case, this function is called independently
- * from several parts of the code, so we need to always return the same
- * value. */
-static vlc_tick_t rtp_init_ts( const vod_media_t *p_media,
- const char *psz_vod_session )
-{
- if (p_media == NULL || psz_vod_session == NULL)
- return vlc_tick_now();
-
- uint64_t i_ts_init = 0;
- /* As per RFC 2326, session identifiers are at least 8 bytes long */
- size_t session_length = strlen(psz_vod_session);
- memcpy(&i_ts_init, psz_vod_session, __MIN(session_length,
- sizeof(uint64_t)));
- i_ts_init ^= (uintptr_t)p_media;
- /* Limit the timestamp to 48 bits, this is enough and allows us
- * to stay away from overflows */
- i_ts_init &= 0xFFFFFFFFFFFF;
- return i_ts_init;
-}
-
/* Return a timestamp corresponding to packets being sent now, and that
* can be passed to rtp_compute_ts() to get rtptime values for each ES.
* Also return the NPT corresponding to this timestamp. If the stream
* output is not started, the initial timestamp that will be used with
* the first packets for NPT=0 is returned instead. */
vlc_tick_t rtp_get_ts( const sout_stream_t *p_stream, const sout_stream_id_sys_t *id,
- const vod_media_t *p_media, const char *psz_vod_session,
vlc_tick_t *p_npt )
{
if (p_npt != NULL)
@@ -1576,7 +1476,7 @@ vlc_tick_t rtp_get_ts( const sout_stream_t *p_stream, const sout_stream_id_sys_t
p_stream = id->p_stream;
if (p_stream == NULL)
- return rtp_init_ts(p_media, psz_vod_session);
+ return vlc_tick_now();
sout_stream_sys_t *p_sys = p_stream->p_sys;
vlc_tick_t i_npt_zero;
diff --git a/modules/stream_out/rtp.h b/modules/stream_out/rtp.h
index 2b1838f679..81689f604d 100644
--- a/modules/stream_out/rtp.h
+++ b/modules/stream_out/rtp.h
@@ -25,8 +25,7 @@ typedef struct rtsp_stream_t rtsp_stream_t;
typedef struct rtsp_stream_id_t rtsp_stream_id_t;
typedef struct sout_stream_id_sys_t sout_stream_id_sys_t;
-rtsp_stream_t *RtspSetup( vlc_object_t *owner, vod_media_t *media,
- const char *path );
+rtsp_stream_t *RtspSetup( vlc_object_t *owner, const char *path );
void RtspUnsetup( rtsp_stream_t *rtsp );
rtsp_stream_id_t *RtspAddId( rtsp_stream_t *rtsp, sout_stream_id_sys_t *sid,
@@ -43,15 +42,13 @@ void RtspTrackDetach( rtsp_stream_t *rtsp, const char *name,
sout_stream_id_sys_t *sout_id);
char *SDPGenerate( sout_stream_t *p_stream, const char *rtsp_url );
-char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url );
uint32_t rtp_compute_ts( unsigned i_clock_rate, vlc_tick_t i_pts );
int rtp_add_sink( sout_stream_id_sys_t *id, int fd, bool rtcp_mux, uint16_t *seq );
void rtp_del_sink( sout_stream_id_sys_t *id, int fd );
uint16_t rtp_get_seq( sout_stream_id_sys_t *id );
vlc_tick_t rtp_get_ts( const sout_stream_t *p_stream, const sout_stream_id_sys_t *id,
- const vod_media_t *p_media, const char *psz_vod_session,
- vlc_tick_t *p_npt );
+ vlc_tick_t *p_npt );
/* RTP packetization */
void rtp_packetize_common (sout_stream_id_sys_t *id, block_t *out,
@@ -92,22 +89,3 @@ int rtp_get_fmt( vlc_object_t *obj, const es_format_t *p_fmt, const char *mux,
/* Only used by rtp_packetize_rawvideo */
void rtp_get_video_geometry( sout_stream_id_sys_t *id, int *width, int *height );
uint16_t rtp_get_extended_sequence( sout_stream_id_sys_t *id );
-
-/* VoD */
-int OpenVoD ( vlc_object_t * );
-void CloseVoD( vlc_object_t * );
-
-int vod_check_range(vod_media_t *p_media, const char *psz_session,
- vlc_tick_t start, vlc_tick_t end);
-void vod_play(vod_media_t *p_media, const char *psz_session,
- vlc_tick_t *start, vlc_tick_t end);
-void vod_pause(vod_media_t *p_media, const char *psz_session, vlc_tick_t *npt);
-void vod_stop(vod_media_t *p_media, const char *psz_session);
-
-const char *vod_get_mux(const vod_media_t *p_media);
-int vod_init_id(vod_media_t *p_media, const char *psz_session, int es_id,
- sout_stream_id_sys_t *sout_id, rtp_format_t *rtp_fmt,
- uint32_t *ssrc, uint16_t *seq_init);
-void vod_detach_id(vod_media_t *p_media, const char *psz_session,
- sout_stream_id_sys_t *sout_id);
-
diff --git a/modules/stream_out/rtsp.c b/modules/stream_out/rtsp.c
index d62ccebccd..8d79803c8e 100644
--- a/modules/stream_out/rtsp.c
+++ b/modules/stream_out/rtsp.c
@@ -59,7 +59,6 @@ struct rtsp_stream_t
{
vlc_mutex_t lock;
vlc_object_t *owner;
- vod_media_t *vod_media;
httpd_host_t *host;
httpd_url_t *url;
char *psz_path;
@@ -83,8 +82,7 @@ static void RtspClientDel( rtsp_stream_t *rtsp, rtsp_session_t *session );
static void RtspTimeOut( void *data );
-rtsp_stream_t *RtspSetup( vlc_object_t *owner, vod_media_t *media,
- const char *path )
+rtsp_stream_t *RtspSetup( vlc_object_t *owner, const char *path )
{
rtsp_stream_t *rtsp = calloc( 1, sizeof( *rtsp ) );
@@ -92,7 +90,6 @@ rtsp_stream_t *RtspSetup( vlc_object_t *owner, vod_media_t *media,
return NULL;
rtsp->owner = owner;
- rtsp->vod_media = media;
vlc_mutex_init( &rtsp->lock );
rtsp->timeout = vlc_tick_from_sec(__MAX(0,var_InheritInteger(owner, "rtsp-timeout")));
@@ -325,19 +322,8 @@ static void RtspTimeOut( void *data )
vlc_mutex_lock(&rtsp->lock);
vlc_tick_t now = vlc_tick_now();
for (int i = rtsp->sessionc - 1; i >= 0; i--)
- {
if (rtsp->sessionv[i]->last_seen + rtsp->timeout < now)
- {
- if (rtsp->vod_media != NULL)
- {
- char psz_sesbuf[17];
- snprintf( psz_sesbuf, sizeof( psz_sesbuf ), "%"PRIx64,
- rtsp->sessionv[i]->id );
- vod_stop(rtsp->vod_media, psz_sesbuf);
- }
RtspClientDel(rtsp, rtsp->sessionv[i]);
- }
- }
RtspUpdateTimer(rtsp);
vlc_mutex_unlock(&rtsp->lock);
}
@@ -427,110 +413,6 @@ static int dup_socket(int oldfd)
return newfd;
}
-/* Attach a starting VoD RTP id to its RTSP track, and let it
- * initialize with the parameters of the SETUP request */
-int RtspTrackAttach( rtsp_stream_t *rtsp, const char *name,
- rtsp_stream_id_t *id, sout_stream_id_sys_t *sout_id,
- uint32_t *ssrc, uint16_t *seq_init )
-{
- int val = VLC_EGENERIC;
- rtsp_session_t *session;
-
- vlc_mutex_lock(&rtsp->lock);
- session = RtspClientGet(rtsp, name);
-
- if (session == NULL)
- goto out;
-
- rtsp_strack_t *tr = NULL;
- for (int i = 0; i < session->trackc; i++)
- {
- if (session->trackv[i].id == id)
- {
- tr = session->trackv + i;
- break;
- }
- }
-
- if (tr != NULL)
- {
- tr->sout_id = sout_id;
- tr->rtp_fd = dup_socket(tr->setup_fd);
- }
- else
- {
- /* The track was not SETUP. We still create one because we'll
- * need the sout_id if we set it up later. */
- rtsp_strack_t track = { .id = id, .sout_id = sout_id,
- .setup_fd = -1, .rtp_fd = -1 };
- vlc_rand_bytes (&track.seq_init, sizeof (track.seq_init));
- vlc_rand_bytes (&track.ssrc, sizeof (track.ssrc));
-
- TAB_APPEND(session->trackc, session->trackv, track);
- tr = session->trackv + session->trackc - 1;
- }
-
- *ssrc = ntohl(tr->ssrc);
- *seq_init = tr->seq_init;
-
- if (tr->rtp_fd != -1)
- {
- uint16_t seq;
- rtp_add_sink(tr->sout_id, tr->rtp_fd, false, &seq);
- /* To avoid race conditions, sout_id->i_seq_sent_next must
- * be set here and now. Make sure the caller did its job
- * properly when passing seq_init. */
- assert(tr->seq_init == seq);
- }
-
- val = VLC_SUCCESS;
-out:
- vlc_mutex_unlock(&rtsp->lock);
- return val;
-}
-
-
-/* Remove references to the RTP id when it is stopped */
-void RtspTrackDetach( rtsp_stream_t *rtsp, const char *name,
- sout_stream_id_sys_t *sout_id )
-{
- rtsp_session_t *session;
-
- vlc_mutex_lock(&rtsp->lock);
- session = RtspClientGet(rtsp, name);
-
- if (session == NULL)
- goto out;
-
- for (int i = 0; i < session->trackc; i++)
- {
- rtsp_strack_t *tr = session->trackv + i;
- if (tr->sout_id == sout_id)
- {
- if (tr->setup_fd == -1)
- {
- /* No (more) SETUP information: better get rid of the
- * track so that we can have new random ssrc and
- * seq_init next time. */
- TAB_ERASE(session->trackc, session->trackv, i);
- break;
- }
- /* We keep the SETUP information of the track, but stop it */
- if (tr->rtp_fd != -1)
- {
- rtp_del_sink(tr->sout_id, tr->rtp_fd);
- tr->rtp_fd = -1;
- }
- tr->sout_id = NULL;
- break;
- }
- }
-
-out:
- vlc_mutex_unlock(&rtsp->lock);
-}
-
-
/** rtsp must be locked */
static void RtspTrackClose( rtsp_strack_t *tr )
{
@@ -609,7 +491,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
const char *psz_session = NULL, *psz;
char control[sizeof("rtsp://[]:12345") + NI_MAXNUMERICHOST
+ strlen( rtsp->psz_path )];
- bool vod = rtsp->vod_media != NULL;
time_t now;
time (&now);
@@ -682,9 +563,8 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
httpd_MsgAdd( answer, "Content-Type", "%s", "application/sdp" );
httpd_MsgAdd( answer, "Content-Base", "%s", control );
- answer->p_body = (uint8_t *) ( vod ?
- SDPGenerateVoD( rtsp->vod_media, control ) :
- SDPGenerate( (sout_stream_t *)owner, control ) );
+ answer->p_body = (uint8_t *)
+ SDPGenerate( (sout_stream_t *)owner, control );
if( answer->p_body != NULL )
answer->i_body = strlen( (char *)answer->p_body );
else
@@ -887,16 +767,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
.setup_fd = fd,
.rtp_fd = -1 };
- if (vod)
- {
- vlc_rand_bytes (&track.seq_init,
- sizeof (track.seq_init));
- vlc_rand_bytes (&track.ssrc, sizeof (track.ssrc));
- ssrc = track.ssrc;
- }
- else
- ssrc = id->ssrc;
-
+ ssrc = id->ssrc;
TAB_APPEND(ses->trackc, ses->trackv, track);
}
else if (tr->setup_fd == -1)
@@ -970,15 +841,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
break;
}
- if (vod)
- {
- if (vod_check_range(rtsp->vod_media, psz_session,
- start, end) != VLC_SUCCESS)
- {
- answer->i_status = 457;
- break;
- }
- }
/* We accept start times of 0 even for broadcast streams
* that already started */
else if (start > 0 || end >= 0)
@@ -998,20 +860,8 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
RtspClientAlive(ses);
sout_stream_id_sys_t *sout_id = NULL;
- if (vod)
- {
- /* We don't keep a reference to the sout_stream_t,
- * so we check if a sout_id is available instead. */
- for (int i = 0; i < ses->trackc; i++)
- {
- sout_id = ses->trackv[i].sout_id;
- if (sout_id != NULL)
- break;
- }
- }
- vlc_tick_t ts = rtp_get_ts(vod ? NULL : (sout_stream_t *)owner,
- sout_id, rtsp->vod_media, psz_session,
- vod ? NULL : &npt);
+ vlc_tick_t ts = rtp_get_ts((sout_stream_t *)owner,
+ sout_id, &npt);
for( int i = 0; i < ses->trackc; i++ )
{
@@ -1064,12 +914,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
if (ses != NULL)
{
- if (vod)
- {
- vod_play(rtsp->vod_media, psz_session, &start, end);
- npt = start;
- }
-
double f_npt = secf_from_vlc_tick(npt);
httpd_MsgAdd( answer, "Range", "npt=%f-", f_npt );
}
@@ -1081,7 +925,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
case HTTPD_MSG_PAUSE:
{
- if (id == NULL && !vod)
+ if (id == NULL)
{
answer->i_status = 405;
httpd_MsgAdd( answer, "Allow",
@@ -1122,15 +966,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
RtspClientAlive(ses);
}
vlc_mutex_unlock( &rtsp->lock );
-
- if (ses != NULL && id == NULL)
- {
- assert(vod);
- vlc_tick_t npt = 0;
- vod_pause(rtsp->vod_media, psz_session, &npt);
- double f_npt = secf_from_vlc_tick(npt);
- httpd_MsgAdd( answer, "Range", "npt=%f-", f_npt );
- }
break;
}
@@ -1167,8 +1002,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
if( id == NULL ) /* Delete the entire session */
{
RtspClientDel( rtsp, ses );
- if (vod)
- vod_stop(rtsp->vod_media, psz_session);
RtspUpdateTimer(rtsp);
}
else /* Delete one track from the session */
@@ -1178,10 +1011,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
if( ses->trackv[i].id == id )
{
RtspTrackClose( &ses->trackv[i] );
- /* Keep VoD tracks whose instance is still
- * running */
- if (!(vod && ses->trackv[i].sout_id != NULL))
- TAB_ERASE(ses->trackc, ses->trackv, i);
+ TAB_ERASE(ses->trackc, ses->trackv, i);
}
}
RtspClientAlive(ses);
diff --git a/modules/stream_out/vod.c b/modules/stream_out/vod.c
deleted file mode 100644
index 75bfacdeb4..0000000000
--- a/modules/stream_out/vod.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*****************************************************************************
- * vod.c: rtsp VoD server module
- *****************************************************************************
- * Copyright (C) 2003-2006, 2010 VLC authors and VideoLAN
- *
- * Authors: Laurent Aimar <fenrir at via.ecp.fr>
- * Gildas Bazin <gbazin at videolan.org>
- * Pierre Ynard
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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_item.h>
-#include <vlc_sout.h>
-#include <vlc_block.h>
-
-#include <vlc_vod.h>
-#include <vlc_url.h>
-#include <vlc_network.h>
-#include <vlc_memstream.h>
-
-#include <assert.h>
-
-#include "rtp.h"
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-
-typedef struct media_es_t media_es_t;
-
-struct media_es_t
-{
- int es_id;
- rtp_format_t rtp_fmt;
- rtsp_stream_id_t *rtsp_id;
-};
-
-struct vod_media_t
-{
- /* VoD server */
- vod_t *p_vod;
-
- /* RTSP server */
- rtsp_stream_t *rtsp;
-
- /* ES list */
- int i_es;
- media_es_t **es;
- const char *psz_mux;
-
- /* Infos */
- vlc_tick_t i_length;
-};
-
-typedef struct
-{
- char *psz_rtsp_path;
-
- /* */
- vlc_thread_t thread;
- block_fifo_t *p_fifo_cmd;
-} vod_sys_t;
-
-/* rtsp delayed command (to avoid deadlock between vlm/httpd) */
-typedef enum
-{
- RTSP_CMD_TYPE_STOP,
- RTSP_CMD_TYPE_ADD,
- RTSP_CMD_TYPE_DEL,
-} rtsp_cmd_type_t;
-
-/* */
-typedef struct
-{
- int i_type;
- vod_media_t *p_media;
- char *psz_arg;
-} rtsp_cmd_t;
-
-static vod_media_t *MediaNew( vod_t *, const char *, input_item_t * );
-static void MediaDel( vod_t *, vod_media_t * );
-static void MediaAskDel ( vod_t *, vod_media_t * );
-
-static void* CommandThread( void *obj );
-static void CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *,
- const char *psz_arg );
-
-/*****************************************************************************
- * Open: Starts the RTSP server module
- *****************************************************************************/
-int OpenVoD( vlc_object_t *p_this )
-{
- vod_t *p_vod = (vod_t *)p_this;
- vod_sys_t *p_sys = NULL;
- char *psz_url;
-
- p_vod->p_sys = p_sys = malloc( sizeof( vod_sys_t ) );
- if( !p_sys ) goto error;
-
- psz_url = var_InheritString( p_vod, "rtsp-host" );
-
- if( psz_url == NULL )
- p_sys->psz_rtsp_path = strdup( "/" );
- else
- {
- vlc_url_t url;
- vlc_UrlParse( &url, psz_url );
- free( psz_url );
-
- if( url.psz_path == NULL )
- p_sys->psz_rtsp_path = strdup( "/" );
- else
- if( !( strlen( url.psz_path ) > 0
- && url.psz_path[strlen( url.psz_path ) - 1] == '/' ) )
- {
- if( asprintf( &p_sys->psz_rtsp_path, "%s/", url.psz_path ) == -1 )
- {
- p_sys->psz_rtsp_path = NULL;
- vlc_UrlClean( &url );
- goto error;
- }
- }
- else
- p_sys->psz_rtsp_path = strdup( url.psz_path );
-
- vlc_UrlClean( &url );
- }
-
- p_vod->pf_media_new = MediaNew;
- p_vod->pf_media_del = MediaAskDel;
-
- p_sys->p_fifo_cmd = block_FifoNew();
- if( vlc_clone( &p_sys->thread, CommandThread, p_vod, VLC_THREAD_PRIORITY_LOW ) )
- {
- msg_Err( p_vod, "cannot spawn rtsp vod thread" );
- block_FifoRelease( p_sys->p_fifo_cmd );
- goto error;
- }
-
- return VLC_SUCCESS;
-
-error:
- if( p_sys )
- {
- free( p_sys->psz_rtsp_path );
- free( p_sys );
- }
-
- return VLC_EGENERIC;
-}
-
-/*****************************************************************************
- * Close:
- *****************************************************************************/
-void CloseVoD( 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_cancel( p_sys->thread );
- vlc_join( p_sys->thread, NULL );
-
- while( block_FifoCount( p_sys->p_fifo_cmd ) > 0 )
- {
- rtsp_cmd_t cmd;
- block_t *p_block_cmd = block_FifoGet( p_sys->p_fifo_cmd );
- memcpy( &cmd, p_block_cmd->p_buffer, sizeof(cmd) );
- block_Release( p_block_cmd );
- if ( cmd.i_type == RTSP_CMD_TYPE_DEL )
- MediaDel(p_vod, cmd.p_media);
- free( cmd.psz_arg );
- }
- block_FifoRelease( p_sys->p_fifo_cmd );
-
- free( p_sys->psz_rtsp_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_media_t *p_media = calloc( 1, sizeof(vod_media_t) );
- if( !p_media )
- return NULL;
-
- p_media->p_vod = p_vod;
- p_media->rtsp = NULL;
- TAB_INIT( p_media->i_es, p_media->es );
- p_media->psz_mux = NULL;
- p_media->i_length = input_item_GetDuration( p_item );
-
- vlc_mutex_lock( &p_item->lock );
- msg_Dbg( p_vod, "media '%s' has %i declared ES", psz_name, p_item->i_es );
- for( int i = 0; i < p_item->i_es; i++ )
- {
- es_format_t *p_fmt = p_item->es[i];
-
- switch( p_fmt->i_codec )
- {
- case VLC_FOURCC( 'm', 'p', '2', 't' ):
- p_media->psz_mux = "ts";
- break;
- case VLC_FOURCC( 'm', 'p', '2', 'p' ):
- p_media->psz_mux = "ps";
- break;
- }
- assert(p_media->psz_mux == NULL || p_item->i_es == 1);
-
- media_es_t *p_es = calloc( 1, sizeof(media_es_t) );
- if( !p_es )
- continue;
-
- p_es->es_id = p_fmt->i_id;
- p_es->rtsp_id = NULL;
-
- if (rtp_get_fmt(VLC_OBJECT(p_vod), p_fmt, p_media->psz_mux,
- &p_es->rtp_fmt) != VLC_SUCCESS)
- {
- free(p_es);
- continue;
- }
-
- TAB_APPEND( p_media->i_es, p_media->es, p_es );
- msg_Dbg(p_vod, " - added ES %u %s (%4.4s)",
- p_es->rtp_fmt.payload_type, p_es->rtp_fmt.ptname,
- (char *)&p_fmt->i_codec);
- }
- vlc_mutex_unlock( &p_item->lock );
-
- if (p_media->i_es == 0)
- {
- msg_Err(p_vod, "no ES was added to the media, aborting");
- goto error;
- }
-
- msg_Dbg(p_vod, "adding media '%s'", psz_name);
-
- CommandPush( p_vod, RTSP_CMD_TYPE_ADD, p_media, psz_name );
- return p_media;
-
-error:
- MediaDel(p_vod, p_media);
- return NULL;
-}
-
-static void MediaSetup( vod_t *p_vod, vod_media_t *p_media,
- const char *psz_name )
-{
- vod_sys_t *p_sys = p_vod->p_sys;
- char *psz_path;
-
- if( asprintf( &psz_path, "%s%s", p_sys->psz_rtsp_path, psz_name ) < 0 )
- return;
-
- p_media->rtsp = RtspSetup(VLC_OBJECT(p_vod), p_media, psz_path);
- free( psz_path );
-
- if (p_media->rtsp == NULL)
- return;
-
- for (int i = 0; i < p_media->i_es; i++)
- {
- media_es_t *p_es = p_media->es[i];
- p_es->rtsp_id = RtspAddId(p_media->rtsp, NULL, 0,
- p_es->rtp_fmt.clock_rate, -1);
- }
-}
-
-static void MediaAskDel ( vod_t *p_vod, vod_media_t *p_media )
-{
- msg_Dbg( p_vod, "deleting media" );
- CommandPush( p_vod, RTSP_CMD_TYPE_DEL, p_media, NULL );
-}
-
-static void MediaDel( vod_t *p_vod, vod_media_t *p_media )
-{
- (void) p_vod;
-
- if (p_media->rtsp != NULL)
- {
- for (int i = 0; i < p_media->i_es; i++)
- {
- media_es_t *p_es = p_media->es[i];
- if (p_es->rtsp_id != NULL)
- RtspDelId(p_media->rtsp, p_es->rtsp_id);
- }
- RtspUnsetup(p_media->rtsp);
- }
-
- for( int i = 0; i < p_media->i_es; i++ )
- {
- free( p_media->es[i]->rtp_fmt.fmtp );
- free( p_media->es[i] );
- }
- free( p_media->es );
-
- free( p_media );
-}
-
-static void CommandPush( vod_t *p_vod, rtsp_cmd_type_t i_type,
- vod_media_t *p_media, const char *psz_arg )
-{
- rtsp_cmd_t cmd;
- block_t *p_cmd;
-
- cmd.i_type = i_type;
- cmd.p_media = p_media;
- if( psz_arg )
- cmd.psz_arg = strdup(psz_arg);
- else
- cmd.psz_arg = NULL;
-
- p_cmd = block_Alloc( sizeof(rtsp_cmd_t) );
- memcpy( p_cmd->p_buffer, &cmd, sizeof(cmd) );
-
- vod_sys_t *p_sys = p_vod->p_sys;
- block_FifoPut( p_sys->p_fifo_cmd, p_cmd );
-}
-
-static void* CommandThread( void *obj )
-{
- vod_t *p_vod = (vod_t*)obj;
- vod_sys_t *p_sys = p_vod->p_sys;
-
- for( ;; )
- {
- block_t *p_block_cmd = block_FifoGet( p_sys->p_fifo_cmd );
- rtsp_cmd_t cmd;
-
- if( !p_block_cmd )
- break;
-
- int canc = vlc_savecancel ();
- memcpy( &cmd, p_block_cmd->p_buffer, sizeof(cmd) );
- block_Release( p_block_cmd );
-
- /* */
- switch( cmd.i_type )
- {
- case RTSP_CMD_TYPE_ADD:
- MediaSetup(p_vod, cmd.p_media, cmd.psz_arg);
- break;
- case RTSP_CMD_TYPE_DEL:
- MediaDel(p_vod, cmd.p_media);
- break;
- case RTSP_CMD_TYPE_STOP:
- vod_MediaControl( p_vod, cmd.p_media, cmd.psz_arg, VOD_MEDIA_STOP );
- break;
-
- default:
- break;
- }
-
- free( cmd.psz_arg );
- vlc_restorecancel (canc);
- }
-
- return NULL;
-}
-
-/*****************************************************************************
- * SDPGenerateVoD
- * FIXME: needs to be merged more?
- *****************************************************************************/
-char *SDPGenerateVoD( const vod_media_t *p_media, const char *rtsp_url )
-{
- assert(rtsp_url != NULL);
- /* Check against URL format rtsp://[<ipv6>]:<port>/<path> */
- bool ipv6 = strlen( rtsp_url ) > 7 && rtsp_url[7] == '[';
-
- /* Dummy destination address for RTSP */
- struct sockaddr_storage dst;
- socklen_t dstlen = ipv6 ? sizeof( struct sockaddr_in6 )
- : sizeof( struct sockaddr_in );
- memset (&dst, 0, dstlen);
- dst.ss_family = ipv6 ? AF_INET6 : AF_INET;
-#ifdef HAVE_SA_LEN
- dst.ss_len = dstlen;
-#endif
-
- struct vlc_memstream sdp;
-
- if( vlc_sdp_Start( &sdp, VLC_OBJECT( p_media->p_vod ), "sout-rtp-",
- NULL, 0, (struct sockaddr *)&dst, dstlen ) )
- return NULL;
-
- if( p_media->i_length > 0 )
- {
- lldiv_t d = lldiv( MS_FROM_VLC_TICK(p_media->i_length), 1000 );
- sdp_AddAttribute( &sdp, "range"," npt=0-%lld.%03u", d.quot,
- (unsigned)d.rem );
- }
-
- sdp_AddAttribute( &sdp, "control", "%s", rtsp_url );
-
- /* No locking needed, the ES table can't be modified now */
- for( int i = 0; i < p_media->i_es; i++ )
- {
- media_es_t *p_es = p_media->es[i];
- rtp_format_t *rtp_fmt = &p_es->rtp_fmt;
- const char *mime_major; /* major MIME type */
-
- switch( rtp_fmt->cat )
- {
- case VIDEO_ES:
- mime_major = "video";
- break;
- case AUDIO_ES:
- mime_major = "audio";
- break;
- case SPU_ES:
- mime_major = "text";
- break;
- default:
- continue;
- }
-
- sdp_AddMedia( &sdp, mime_major, "RTP/AVP", 0,
- rtp_fmt->payload_type, false, 0,
- rtp_fmt->ptname, rtp_fmt->clock_rate, rtp_fmt->channels,
- rtp_fmt->fmtp );
-
- char *track_url = RtspAppendTrackPath( p_es->rtsp_id, rtsp_url );
- if( track_url != NULL )
- {
- sdp_AddAttribute( &sdp, "control", "%s", track_url );
- free( track_url );
- }
- }
-
- return vlc_memstream_close( &sdp ) ? NULL : sdp.ptr;
-}
-
-int vod_check_range(vod_media_t *p_media, const char *psz_session,
- int64_t start, int64_t end)
-{
- (void) psz_session;
-
- if (p_media->i_length > 0 && (start > p_media->i_length
- || end > p_media->i_length))
- return VLC_EGENERIC;
-
- return VLC_SUCCESS;
-}
-
-/* TODO: add support in the VLM for queueing proper PLAY requests with
- * start and end times, fetch whether the input is seekable... and then
- * clean this up */
-void vod_play(vod_media_t *p_media, const char *psz_session,
- int64_t *start, int64_t end)
-{
- if (vod_check_range(p_media, psz_session, *start, end) != VLC_SUCCESS)
- return;
-
- /* We're passing the #vod{} sout chain here */
- vod_MediaControl(p_media->p_vod, p_media, psz_session,
- VOD_MEDIA_PLAY, "vod", start);
-}
-
-void vod_pause(vod_media_t *p_media, const char *psz_session, int64_t *npt)
-{
- vod_MediaControl(p_media->p_vod, p_media, psz_session,
- VOD_MEDIA_PAUSE, npt);
-}
-
-void vod_stop(vod_media_t *p_media, const char *psz_session)
-{
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session);
-}
-
-
-const char *vod_get_mux(const vod_media_t *p_media)
-{
- return p_media->psz_mux;
-}
-
-
-/* Match an RTP id to a VoD media ES and RTSP track to initialize it
- * with the data that was already set up */
-int vod_init_id(vod_media_t *p_media, const char *psz_session, int es_id,
- sout_stream_id_sys_t *sout_id, rtp_format_t *rtp_fmt,
- uint32_t *ssrc, uint16_t *seq_init)
-{
- media_es_t *p_es;
-
- if (p_media->psz_mux != NULL)
- {
- assert(p_media->i_es == 1);
- p_es = p_media->es[0];
- }
- else
- {
- p_es = NULL;
- /* No locking needed, the ES table can't be modified now */
- for (int i = 0; i < p_media->i_es; i++)
- {
- if (p_media->es[i]->es_id == es_id)
- {
- p_es = p_media->es[i];
- break;
- }
- }
- if (p_es == NULL)
- return VLC_EGENERIC;
- }
-
- memcpy(rtp_fmt, &p_es->rtp_fmt, sizeof(*rtp_fmt));
- if (p_es->rtp_fmt.fmtp != NULL)
- rtp_fmt->fmtp = strdup(p_es->rtp_fmt.fmtp);
-
- return RtspTrackAttach(p_media->rtsp, psz_session, p_es->rtsp_id,
- sout_id, ssrc, seq_init);
-}
-
-/* Remove references to the RTP id from its RTSP track */
-void vod_detach_id(vod_media_t *p_media, const char *psz_session,
- sout_stream_id_sys_t *sout_id)
-{
- RtspTrackDetach(p_media->rtsp, psz_session, sout_id);
-}
-
More information about the vlc-commits
mailing list