Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Steve Lhomme
VLC
Commits
35754aba
Commit
35754aba
authored
Aug 24, 2007
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Isolate RTSP from the rest of RTP
parent
a556cc82
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
306 additions
and
274 deletions
+306
-274
modules/stream_out/rtp.c
modules/stream_out/rtp.c
+84
-26
modules/stream_out/rtp.h
modules/stream_out/rtp.h
+8
-69
modules/stream_out/rtsp.c
modules/stream_out/rtsp.c
+214
-179
No files found.
modules/stream_out/rtp.c
View file @
35754aba
...
...
@@ -166,6 +166,61 @@ 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
*
);
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
;
rtsp_stream_t
*
rtsp
;
/* */
char
*
psz_destination
;
int
i_port
;
int
i_port_audio
;
int
i_port_video
;
int
i_ttl
;
vlc_bool_t
b_latm
;
/* 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
;
};
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
;
...
...
@@ -300,8 +355,7 @@ static int Open( vlc_object_t *p_this )
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
->
rtsp
=
NULL
;
p_sys
->
psz_sdp
=
NULL
;
p_sys
->
i_sdp_id
=
mdate
();
...
...
@@ -314,10 +368,6 @@ static int Open( vlc_object_t *p_this )
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
);
...
...
@@ -547,7 +597,8 @@ static void Close( vlc_object_t * p_this )
}
}
RtspUnsetup
(
p_stream
);
if
(
p_sys
->
rtsp
!=
NULL
)
RtspUnsetup
(
p_sys
->
rtsp
);
vlc_mutex_destroy
(
&
p_sys
->
lock_sdp
);
...
...
@@ -597,26 +648,27 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
if
(
p_sys
->
p_httpd_file
)
{
msg_Err
(
p_stream
,
"you can use sdp=http:// only once"
);
return
;
goto
out
;
}
if
(
HttpSetup
(
p_stream
,
&
url
)
)
{
msg_Err
(
p_stream
,
"cannot export
sdp
as
http
"
);
msg_Err
(
p_stream
,
"cannot export
SDP
as
HTTP
"
);
}
}
else
if
(
url
.
psz_protocol
&&
!
strcasecmp
(
url
.
psz_protocol
,
"rtsp"
)
)
{
if
(
p_sys
->
p_
rtsp
_url
)
if
(
p_sys
->
rtsp
!=
NULL
)
{
msg_Err
(
p_stream
,
"you can use sdp=rtsp:// only once"
);
return
;
goto
out
;
}
/* FIXME test if destination is multicast or no destination at all FIXME */
if
(
RtspSetup
(
p_stream
,
&
url
)
)
p_sys
->
rtsp
=
RtspSetup
(
p_stream
,
&
url
);
if
(
p_sys
->
rtsp
==
NULL
)
{
msg_Err
(
p_stream
,
"cannot export
sdp
as
rtsp
"
);
msg_Err
(
p_stream
,
"cannot export
SDP
as
RTSP
"
);
}
}
else
if
(
(
url
.
psz_protocol
&&
!
strcasecmp
(
url
.
psz_protocol
,
"sap"
)
)
||
...
...
@@ -630,7 +682,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
if
(
p_sys
->
b_export_sdp_file
)
{
msg_Err
(
p_stream
,
"you can use sdp=file:// only once"
);
return
;
goto
out
;
}
p_sys
->
b_export_sdp_file
=
VLC_TRUE
;
psz_url
=
&
psz_url
[
5
];
...
...
@@ -643,6 +695,8 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
msg_Warn
(
p_stream
,
"unknown protocol for SDP (%s)"
,
url
.
psz_protocol
);
}
out:
vlc_UrlClean
(
&
url
);
}
...
...
@@ -662,11 +716,12 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
a= charset: (normally charset should be UTF-8, this can be used to override s= and i=)
a= x-plgroup: (missing)
RTP packets need to get the correct src IP address */
/*static*/
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
psz_destination
,
vlc_bool_t
b_rtsp
)
/*static*/
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
rtsp_url
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
int
i_size
;
const
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
size_t
i_size
;
const
char
*
psz_destination
=
p_sys
->
psz_destination
;
char
*
psz_sdp
,
*
p
,
ipv
;
int
i
;
...
...
@@ -702,9 +757,9 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
{
i_size
+=
strlen
(
"a=fmtp:* *
\r\n
"
)
+
strlen
(
id
->
psz_fmtp
)
+
10
;
}
if
(
b_
rtsp
)
if
(
rtsp
_url
!=
NULL
)
{
i_size
+=
strlen
(
"a=control:*/trackID=*
\r\n
"
)
+
strlen
(
p_sys
->
psz_rtsp_contro
l
)
+
10
;
i_size
+=
strlen
(
"a=control:*/trackID=*
\r\n
"
)
+
strlen
(
rtsp_ur
l
)
+
10
;
}
}
if
(
p_sys
->
p_mux
)
...
...
@@ -774,7 +829,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
p
+=
sprintf
(
p
,
"a=fmtp:%d %s
\r\n
"
,
id
->
i_payload_type
,
id
->
psz_fmtp
);
}
if
(
b_
rtsp
)
if
(
rtsp
_url
!=
NULL
)
{
p
+=
sprintf
(
p
,
"a=control:/trackID=%d
\r\n
"
,
i
);
}
...
...
@@ -782,7 +837,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
if
(
p_sys
->
p_mux
)
{
p
+=
sprintf
(
p
,
"m=video %d RTP/AVP %d
\r\n
"
,
p_sys
->
i_port
,
p_sys
->
i_payload_type
);
p_sys
->
i_port
,
p_sys
->
i_payload_type
);
}
return
psz_sdp
;
...
...
@@ -1136,15 +1191,17 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id
->
i_mtu
-=
MTU_REDUCE
;
msg_Dbg
(
p_stream
,
"maximum RTP packet size: %d bytes"
,
id
->
i_mtu
);
if
(
p_sys
->
p_rtsp_url
)
id
->
rtsp_id
=
RtspAddId
(
p_stream
,
id
,
id
->
i_port
,
id
->
i_port
+
1
);
if
(
p_sys
->
rtsp
!=
NULL
)
id
->
rtsp_id
=
RtspAddId
(
p_sys
->
rtsp
,
id
,
p_sys
->
i_es
,
p_sys
->
psz_destination
,
p_sys
->
i_ttl
,
id
->
i_port
,
id
->
i_port
+
1
);
/* Update p_sys context */
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
id
);
vlc_mutex_unlock
(
&
p_sys
->
lock_es
);
psz_sdp
=
SDPGenerate
(
p_stream
,
p_sys
->
psz_destination
,
VLC_FALSE
);
psz_sdp
=
SDPGenerate
(
p_stream
,
NULL
);
vlc_mutex_lock
(
&
p_sys
->
lock_sdp
);
free
(
p_sys
->
psz_sdp
);
...
...
@@ -1196,7 +1253,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
sout_MuxDeleteStream
(
p_sys
->
p_mux
,
id
->
p_input
);
}
if
(
id
->
rtsp_id
)
RtspDelId
(
p_s
tream
,
id
->
rtsp_id
);
RtspDelId
(
p_s
ys
->
rtsp
,
id
->
rtsp_id
);
vlc_mutex_destroy
(
&
id
->
lock_sink
);
free
(
id
->
sink
);
...
...
@@ -1477,6 +1534,7 @@ int rtp_add_sink( sout_stream_id_t *id, sout_access_out_t *access )
void
rtp_del_sink
(
sout_stream_id_t
*
id
,
sout_access_out_t
*
access
)
{
/* NOTE: must be safe to use if access is not a sink to id */
vlc_mutex_lock
(
&
id
->
lock_sink
);
TAB_REMOVE
(
id
->
i_sink
,
id
->
sink
,
access
);
vlc_mutex_unlock
(
&
id
->
lock_sink
);
...
...
modules/stream_out/rtp.h
View file @
35754aba
...
...
@@ -22,81 +22,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*
ypedef struct rtsp_stream_t rtsp_stream_t;
*/
t
ypedef
struct
rtsp_stream_t
rtsp_stream_t
;
typedef
struct
rtsp_stream_id_t
rtsp_stream_id_t
;
typedef
struct
rtsp_client_t
rtsp_client_t
;
in
t
RtspSetup
(
sout_stream_t
*
p_stream
,
const
vlc_url_t
*
url
);
void
RtspUnsetup
(
sout
_stream_t
*
p_stream
);
rtsp_stream_
t
*
RtspSetup
(
sout_stream_t
*
p_stream
,
const
vlc_url_t
*
url
);
void
RtspUnsetup
(
rtsp
_stream_t
*
rtsp
);
rtsp_stream_id_t
*
RtspAddId
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
sid
,
rtsp_stream_id_t
*
RtspAddId
(
rtsp_stream_t
*
rtsp
,
sout_stream_id_t
*
sid
,
unsigned
i
,
const
char
*
dst
,
int
ttl
,
unsigned
loport
,
unsigned
hiport
);
void
RtspDelId
(
sout
_stream_t
*
p_stream
,
rtsp_stream_id_t
*
);
void
RtspDelId
(
rtsp
_stream_t
*
rtsp
,
rtsp_stream_id_t
*
);
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
psz_destination
,
vlc_bool_t
b_rtsp
);
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
rtsp_url
);
int
rtp_add_sink
(
sout_stream_id_t
*
id
,
sout_access_out_t
*
access
);
void
rtp_del_sink
(
sout_stream_id_t
*
id
,
sout_access_out_t
*
access
);
typedef
int
(
*
pf_rtp_packetizer_t
)(
sout_stream_t
*
,
sout_stream_id_t
*
,
block_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
;
vlc_bool_t
b_latm
;
/* 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
;
};
modules/stream_out/rtsp.c
View file @
35754aba
...
...
@@ -30,107 +30,155 @@
#include <vlc_httpd.h>
#include <vlc_url.h>
#include <vlc_network.h>
#include <assert.h>
#include "rtp.h"
/* For unicast/interleaved streaming */
struct
rtsp_client_t
{
char
*
psz_session
;
int64_t
i_last
;
/* for timeout */
/* is it in "play" state */
vlc_bool_t
b_playing
;
typedef
struct
rtsp_session_t
rtsp_session_t
;
/* output (id-access) */
int
i_id
;
sout_stream_id_t
**
id
;
int
i_access
;
sout_access_out_t
**
access
;
struct
rtsp_stream_t
{
vlc_mutex_t
lock
;
sout_stream_t
*
owner
;
httpd_host_t
*
host
;
httpd_url_t
*
url
;
char
*
psz_control
;
char
*
psz_path
;
int
sessionc
;
rtsp_session_t
**
sessionv
;
};
static
int
RtspCallback
(
httpd_callback_sys_t
*
p_args
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
);
static
int
RtspCallbackId
(
httpd_callback_sys_t
*
p_args
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
);
static
void
RtspClientDel
(
sout
_stream_t
*
p_stream
,
rtsp_client_t
*
rtsp
);
static
void
RtspClientDel
(
rtsp
_stream_t
*
rtsp
,
rtsp_session_t
*
session
);
in
t
RtspSetup
(
sout_stream_t
*
p_stream
,
const
vlc_url_t
*
url
)
rtsp_stream_
t
*
RtspSetup
(
sout_stream_t
*
p_stream
,
const
vlc_url_t
*
url
)
{
sout
_stream_
sys_t
*
p_sys
=
p_stream
->
p_sys
;
rtsp
_stream_
t
*
rtsp
=
malloc
(
sizeof
(
*
rtsp
)
)
;
msg_Dbg
(
p_stream
,
"rtsp setup: %s : %d / %s
\n
"
,
url
->
psz_host
,
url
->
i_port
,
url
->
psz_path
);
if
(
rtsp
==
NULL
)
return
NULL
;
p_sys
->
p_rtsp_host
=
httpd_HostNew
(
VLC_OBJECT
(
p_stream
),
url
->
psz_host
,
url
->
i_port
>
0
?
url
->
i_port
:
554
);
if
(
p_sys
->
p_rtsp_host
==
NULL
)
{
return
VLC_EGENERIC
;
}
rtsp
->
owner
=
p_stream
;
rtsp
->
sessionc
=
0
;
rtsp
->
sessionv
=
NULL
;
vlc_mutex_init
(
p_stream
,
&
rtsp
->
lock
);
p_sys
->
psz_rtsp_path
=
strdup
(
url
->
psz_path
?
url
->
psz_path
:
"/"
);
p_sys
->
psz_rtsp_control
=
malloc
(
strlen
(
url
->
psz_host
)
+
20
+
strlen
(
p_sys
->
psz_rtsp_path
)
+
1
);
sprintf
(
p_sys
->
psz_rtsp_control
,
"rtsp://%s:%d%s"
,
url
->
psz_host
,
url
->
i_port
>
0
?
url
->
i_port
:
554
,
p_sys
->
psz_rtsp_path
);
msg_Dbg
(
p_stream
,
"rtsp setup: %s : %d / %s
\n
"
,
url
->
psz_host
,
url
->
i_port
,
url
->
psz_path
);
p_sys
->
p_rtsp_url
=
httpd_UrlNewUnique
(
p_sys
->
p_rtsp_host
,
p_sys
->
psz_rtsp_path
,
NULL
,
NULL
,
NULL
);
if
(
p_sys
->
p_rtsp_url
==
NULL
)
rtsp
->
psz_path
=
strdup
(
url
->
psz_path
?
url
->
psz_path
:
"/"
);
if
(
rtsp
->
psz_path
==
NULL
)
goto
error
;
if
(
asprintf
(
&
rtsp
->
psz_control
,
"rtsp://%s:%d%s"
,
url
->
psz_host
,
url
->
i_port
>
0
?
url
->
i_port
:
554
,
rtsp
->
psz_path
)
==
-
1
)
{
return
VLC_EGENERIC
;
rtsp
->
psz_control
=
NULL
;
goto
error
;
}
httpd_UrlCatch
(
p_sys
->
p_rtsp_url
,
HTTPD_MSG_DESCRIBE
,
RtspCallback
,
(
void
*
)
p_stream
);
httpd_UrlCatch
(
p_sys
->
p_rtsp_url
,
HTTPD_MSG_SETUP
,
RtspCallback
,
(
void
*
)
p_stream
);
httpd_UrlCatch
(
p_sys
->
p_rtsp_url
,
HTTPD_MSG_PLAY
,
RtspCallback
,
(
void
*
)
p_stream
);
httpd_UrlCatch
(
p_sys
->
p_rtsp_url
,
HTTPD_MSG_PAUSE
,
RtspCallback
,
(
void
*
)
p_stream
);
httpd_UrlCatch
(
p_sys
->
p_rtsp_url
,
HTTPD_MSG_TEARDOWN
,
RtspCallback
,
(
void
*
)
p_stream
);
return
VLC_SUCCESS
;
rtsp
->
host
=
httpd_HostNew
(
VLC_OBJECT
(
p_stream
),
url
->
psz_host
,
url
->
i_port
>
0
?
url
->
i_port
:
554
);
if
(
rtsp
->
host
==
NULL
)
goto
error
;
rtsp
->
url
=
httpd_UrlNewUnique
(
rtsp
->
host
,
rtsp
->
psz_path
,
NULL
,
NULL
,
NULL
);
if
(
rtsp
->
url
==
NULL
)
goto
error
;
httpd_UrlCatch
(
rtsp
->
url
,
HTTPD_MSG_DESCRIBE
,
RtspCallback
,
(
void
*
)
rtsp
);
httpd_UrlCatch
(
rtsp
->
url
,
HTTPD_MSG_SETUP
,
RtspCallback
,
(
void
*
)
rtsp
);
httpd_UrlCatch
(
rtsp
->
url
,
HTTPD_MSG_PLAY
,
RtspCallback
,
(
void
*
)
rtsp
);
httpd_UrlCatch
(
rtsp
->
url
,
HTTPD_MSG_PAUSE
,
RtspCallback
,
(
void
*
)
rtsp
);
httpd_UrlCatch
(
rtsp
->
url
,
HTTPD_MSG_TEARDOWN
,
RtspCallback
,
(
void
*
)
rtsp
);
return
rtsp
;
error:
RtspUnsetup
(
rtsp
);
return
NULL
;
}
void
RtspUnsetup
(
sout
_stream_t
*
p_stream
)
void
RtspUnsetup
(
rtsp
_stream_t
*
rtsp
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
while
(
p_sys
->
i_rtsp
>
0
)
RtspClientDel
(
p_stream
,
p_sys
->
rtsp
[
0
]
);
while
(
rtsp
->
sessionc
>
0
)
RtspClientDel
(
rtsp
,
rtsp
->
sessionv
[
0
]
);
if
(
rtsp
->
url
)
httpd_UrlDelete
(
rtsp
->
url
);
if
(
p_sys
->
p_rtsp_url
)
httpd_
Url
Delete
(
p_sys
->
p_rtsp_url
);
if
(
rtsp
->
host
)
httpd_
Host
Delete
(
rtsp
->
host
);
if
(
p_sys
->
p_rtsp_host
)
httpd_HostDelete
(
p_sys
->
p_rtsp_host
);
vlc_mutex_destroy
(
&
rtsp
->
lock
);
}
struct
rtsp_stream_id_t
{
sout
_stream_t
*
sout_
stream
;
rtsp
_stream_t
*
stream
;
sout_stream_id_t
*
sout_id
;
httpd_url_t
*
url
;
const
char
*
dst
;
int
ttl
;
unsigned
loport
,
hiport
;
};
rtsp_stream_id_t
*
RtspAddId
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
sid
,
/* For unicast streaming */
struct
rtsp_session_t
{
rtsp_stream_t
*
stream
;
/* 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
;
char
name
[
0
];
};
rtsp_stream_id_t
*
RtspAddId
(
rtsp_stream_t
*
rtsp
,
sout_stream_id_t
*
sid
,
unsigned
num
,
/* Multicast stuff - TODO: cleanup */
const
char
*
dst
,
int
ttl
,
unsigned
loport
,
unsigned
hiport
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
char
psz_urlc
[
strlen
(
p_sys
->
psz_rtsp_control
)
+
1
+
10
];
char
urlbuf
[
strlen
(
rtsp
->
psz_control
)
+
1
+
10
];
rtsp_stream_id_t
*
id
=
malloc
(
sizeof
(
*
id
)
);
httpd_url_t
*
url
;
if
(
id
==
NULL
)
return
NULL
;
id
->
sout_
stream
=
p_stream
;
id
->
stream
=
rtsp
;
id
->
sout_id
=
sid
;
id
->
loport
=
loport
;
id
->
hiport
=
loport
;
/* TODO: can we assume that this need not be strdup'd? */
id
->
dst
=
dst
;
if
(
id
->
dst
!=
NULL
)
{
id
->
ttl
=
ttl
;
id
->
loport
=
loport
;
id
->
hiport
=
hiport
;
}
sprintf
(
psz_urlc
,
"%s/trackID=%d"
,
p_sys
->
psz_rtsp_path
,
p_sys
->
i_es
);
msg_Dbg
(
p_stream
,
"RTSP: adding %s
\n
"
,
psz_urlc
);
url
=
id
->
url
=
httpd_UrlNewUnique
(
p_sys
->
p_rtsp_host
,
psz_urlc
,
NULL
,
NULL
,
NULL
);
sprintf
(
urlbuf
,
"%s/trackID=%d"
,
rtsp
->
psz_path
,
num
);
msg_Dbg
(
rtsp
->
owner
,
"RTSP: adding %s
\n
"
,
urlbuf
);
url
=
id
->
url
=
httpd_UrlNewUnique
(
rtsp
->
host
,
urlbuf
,
NULL
,
NULL
,
NULL
);
if
(
url
==
NULL
)
{
...
...
@@ -148,62 +196,87 @@ rtsp_stream_id_t *RtspAddId( sout_stream_t *p_stream, sout_stream_id_t *sid,
}
void
RtspDelId
(
sout
_stream_t
*
p_stream
,
rtsp_stream_id_t
*
id
)
void
RtspDelId
(
rtsp
_stream_t
*
rtsp
,
rtsp_stream_id_t
*
id
)
{
httpd_UrlDelete
(
id
->
url
);
free
(
id
);
vlc_mutex_lock
(
&
rtsp
->
lock
);
for
(
int
i
=
0
;
i
<
rtsp
->
sessionc
;
i
++
)
{
rtsp_session_t
*
ses
=
rtsp
->
sessionv
[
i
];
for
(
int
j
=
0
;
j
<
ses
->
i_id
;
j
++
)
{
if
(
ses
->
id
[
j
]
==
id
->
sout_id
)
{
REMOVE_ELEM
(
ses
->
id
,
ses
->
i_id
,
j
);
assert
(
ses
->
access
[
j
]
!=
NULL
);
sout_AccessOutDelete
(
ses
->
access
[
j
]
);
REMOVE_ELEM
(
ses
->
access
,
ses
->
i_access
,
j
);
/* FIXME: are we supposed to notify the client? */
}
}
}
vlc_mutex_unlock
(
&
rtsp
->
lock
);
httpd_UrlDelete
(
id
->
url
);
free
(
id
);
}
static
rtsp_client_t
*
RtspClientNew
(
sout_stream_t
*
p_stream
,
const
char
*
psz_session
)
/** rtsp must be locked */
static
rtsp_session_t
*
RtspClientNew
(
rtsp_stream_t
*
rtsp
,
const
char
*
name
)
{
rtsp_
client_t
*
rtsp
=
malloc
(
sizeof
(
rtsp_client_t
)
);
rtsp_
session_t
*
s
=
malloc
(
sizeof
(
*
s
)
+
strlen
(
name
)
+
1
);
rtsp
->
psz_session
=
strdup
(
psz_session
);
rtsp
->
i_last
=
0
;
rtsp
->
b_playing
=
VLC_FALSE
;
rtsp
->
i_id
=
0
;
rtsp
->
id
=
NULL
;
rtsp
->
i_access
=
0
;
rtsp
->
access
=
NULL
;
s
->
stream
=
rtsp
;
s
->
b_playing
=
VLC_FALSE
;
s
->
i_id
=
s
->
i_access
=
0
;
s
->
id
=
NULL
;
s
->
access
=
NULL
;
strcpy
(
s
->
name
,
name
);
TAB_APPEND
(
p_stream
->
p_sys
->
i_rtsp
,
p_stream
->
p_sys
->
rtsp
,
rtsp
);
TAB_APPEND
(
rtsp
->
sessionc
,
rtsp
->
sessionv
,
s
);
return
rtsp
;
return
s
;
}
static
rtsp_client_t
*
RtspClientGet
(
sout_stream_t
*
p_stream
,
const
char
*
psz_session
)
/** rtsp must be locked */
static
rtsp_session_t
*
RtspClientGet
(
rtsp_stream_t
*
rtsp
,
const
char
*
name
)
{
int
i
;
if
(
!
psz_session
)
return
NULL
;
if
(
name
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
p_stream
->
p_sys
->
i_rtsp
;
i
++
)
/* FIXME: use a hash/dictionary */
for
(
i
=
0
;
i
<
rtsp
->
sessionc
;
i
++
)
{
if
(
!
strcmp
(
p_stream
->
p_sys
->
rtsp
[
i
]
->
psz_session
,
psz_session
)
)
{
return
p_stream
->
p_sys
->
rtsp
[
i
];
}
if
(
!
strcmp
(
rtsp
->
sessionv
[
i
]
->
name
,
name
)
)
return
rtsp
->
sessionv
[
i
];
}
return
NULL
;
}
static
void
RtspClientDel
(
sout_stream_t
*
p_stream
,
rtsp_client_t
*
rtsp
)
/** rtsp must be locked */
static