Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
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
Show 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 );
...
@@ -166,6 +166,61 @@ static int SapSetup( sout_stream_t *p_stream );
static
int
FileSetup
(
sout_stream_t
*
p_stream
);
static
int
FileSetup
(
sout_stream_t
*
p_stream
);
static
int
HttpSetup
(
sout_stream_t
*
p_stream
,
vlc_url_t
*
);
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
struct
sout_stream_id_t
{
{
sout_stream_t
*
p_stream
;
sout_stream_t
*
p_stream
;
...
@@ -300,7 +355,6 @@ static int Open( vlc_object_t *p_this )
...
@@ -300,7 +355,6 @@ static int Open( vlc_object_t *p_this )
p_sys
->
i_payload_type
=
96
;
p_sys
->
i_payload_type
=
96
;
p_sys
->
i_es
=
0
;
p_sys
->
i_es
=
0
;
p_sys
->
es
=
NULL
;
p_sys
->
es
=
NULL
;
p_sys
->
i_rtsp
=
0
;
p_sys
->
rtsp
=
NULL
;
p_sys
->
rtsp
=
NULL
;
p_sys
->
psz_sdp
=
NULL
;
p_sys
->
psz_sdp
=
NULL
;
...
@@ -314,10 +368,6 @@ static int Open( vlc_object_t *p_this )
...
@@ -314,10 +368,6 @@ static int Open( vlc_object_t *p_this )
p_sys
->
p_httpd_host
=
NULL
;
p_sys
->
p_httpd_host
=
NULL
;
p_sys
->
p_httpd_file
=
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_sdp
);
vlc_mutex_init
(
p_stream
,
&
p_sys
->
lock_es
);
vlc_mutex_init
(
p_stream
,
&
p_sys
->
lock_es
);
...
@@ -547,7 +597,8 @@ static void Close( vlc_object_t * p_this )
...
@@ -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
);
vlc_mutex_destroy
(
&
p_sys
->
lock_sdp
);
...
@@ -597,26 +648,27 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
...
@@ -597,26 +648,27 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
if
(
p_sys
->
p_httpd_file
)
if
(
p_sys
->
p_httpd_file
)
{
{
msg_Err
(
p_stream
,
"you can use sdp=http:// only once"
);
msg_Err
(
p_stream
,
"you can use sdp=http:// only once"
);
return
;
goto
out
;
}
}
if
(
HttpSetup
(
p_stream
,
&
url
)
)
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"
)
)
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"
);
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 */
/* 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"
)
)
||
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 )
...
@@ -630,7 +682,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
if
(
p_sys
->
b_export_sdp_file
)
if
(
p_sys
->
b_export_sdp_file
)
{
{
msg_Err
(
p_stream
,
"you can use sdp=file:// only once"
);
msg_Err
(
p_stream
,
"you can use sdp=file:// only once"
);
return
;
goto
out
;
}
}
p_sys
->
b_export_sdp_file
=
VLC_TRUE
;
p_sys
->
b_export_sdp_file
=
VLC_TRUE
;
psz_url
=
&
psz_url
[
5
];
psz_url
=
&
psz_url
[
5
];
...
@@ -643,6 +695,8 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
...
@@ -643,6 +695,8 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
msg_Warn
(
p_stream
,
"unknown protocol for SDP (%s)"
,
msg_Warn
(
p_stream
,
"unknown protocol for SDP (%s)"
,
url
.
psz_protocol
);
url
.
psz_protocol
);
}
}
out:
vlc_UrlClean
(
&
url
);
vlc_UrlClean
(
&
url
);
}
}
...
@@ -662,11 +716,12 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_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= charset: (normally charset should be UTF-8, this can be used to override s= and i=)
a= x-plgroup: (missing)
a= x-plgroup: (missing)
RTP packets need to get the correct src IP address */
RTP packets need to get the correct src IP address */
/*static*/
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
/*static*/
const
char
*
psz_destination
,
vlc_bool_t
b_rtsp
)
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
rtsp_url
)
{
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
const
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
int
i_size
;
size_t
i_size
;
const
char
*
psz_destination
=
p_sys
->
psz_destination
;
char
*
psz_sdp
,
*
p
,
ipv
;
char
*
psz_sdp
,
*
p
,
ipv
;
int
i
;
int
i
;
...
@@ -702,9 +757,9 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
...
@@ -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
;
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
)
if
(
p_sys
->
p_mux
)
...
@@ -774,7 +829,7 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
...
@@ -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
,
p
+=
sprintf
(
p
,
"a=fmtp:%d %s
\r\n
"
,
id
->
i_payload_type
,
id
->
psz_fmtp
);
id
->
psz_fmtp
);
}
}
if
(
b_rtsp
)
if
(
rtsp_url
!=
NULL
)
{
{
p
+=
sprintf
(
p
,
"a=control:/trackID=%d
\r\n
"
,
i
);
p
+=
sprintf
(
p
,
"a=control:/trackID=%d
\r\n
"
,
i
);
}
}
...
@@ -1136,15 +1191,17 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -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
;
id
->
i_mtu
-=
MTU_REDUCE
;
msg_Dbg
(
p_stream
,
"maximum RTP packet size: %d bytes"
,
id
->
i_mtu
);
msg_Dbg
(
p_stream
,
"maximum RTP packet size: %d bytes"
,
id
->
i_mtu
);
if
(
p_sys
->
p_rtsp_url
)
if
(
p_sys
->
rtsp
!=
NULL
)
id
->
rtsp_id
=
RtspAddId
(
p_stream
,
id
,
id
->
i_port
,
id
->
i_port
+
1
);
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 */
/* Update p_sys context */
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
id
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
id
);
vlc_mutex_unlock
(
&
p_sys
->
lock_es
);
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
);
vlc_mutex_lock
(
&
p_sys
->
lock_sdp
);
free
(
p_sys
->
psz_sdp
);
free
(
p_sys
->
psz_sdp
);
...
@@ -1196,7 +1253,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
...
@@ -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
);
sout_MuxDeleteStream
(
p_sys
->
p_mux
,
id
->
p_input
);
}
}
if
(
id
->
rtsp_id
)
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
);
vlc_mutex_destroy
(
&
id
->
lock_sink
);
free
(
id
->
sink
);
free
(
id
->
sink
);
...
@@ -1477,6 +1534,7 @@ int rtp_add_sink( sout_stream_id_t *id, sout_access_out_t *access )
...
@@ -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
)
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
);
vlc_mutex_lock
(
&
id
->
lock_sink
);
TAB_REMOVE
(
id
->
i_sink
,
id
->
sink
,
access
);
TAB_REMOVE
(
id
->
i_sink
,
id
->
sink
,
access
);
vlc_mutex_unlock
(
&
id
->
lock_sink
);
vlc_mutex_unlock
(
&
id
->
lock_sink
);
...
...
modules/stream_out/rtp.h
View file @
35754aba
...
@@ -22,81 +22,20 @@
...
@@ -22,81 +22,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
*****************************************************************************/
/*ypedef struct rtsp_stream_t rtsp_stream_t;*/
typedef
struct
rtsp_stream_t
rtsp_stream_t
;
typedef
struct
rtsp_stream_id_t
rtsp_stream_id_t
;
typedef
struct
rtsp_stream_id_t
rtsp_stream_id_t
;
typedef
struct
rtsp_client_t
rtsp_client_t
;
int
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
);
void
RtspUnsetup
(
sout_stream_t
*
p_stream
);
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
);
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
,
char
*
SDPGenerate
(
const
sout_stream_t
*
p_stream
,
const
char
*
rtsp_url
);
const
char
*
psz_destination
,
vlc_bool_t
b_rtsp
);
int
rtp_add_sink
(
sout_stream_id_t
*
id
,
sout_access_out_t
*
access
);
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
);
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 @@
...
@@ -30,107 +30,155 @@
#include <vlc_httpd.h>
#include <vlc_httpd.h>
#include <vlc_url.h>
#include <vlc_url.h>
#include <vlc_network.h>
#include <vlc_network.h>
#include <assert.h>
#include "rtp.h"
#include "rtp.h"
/* For unicast/interleaved streaming */
typedef
struct
rtsp_session_t
rtsp_session_t
;
struct
rtsp_client_t
{
char
*
psz_session
;
int64_t
i_last
;
/* for timeout */
/* is it in "play" state */
struct
rtsp_stream_t
vlc_bool_t
b_playing
;
{
vlc_mutex_t
lock
;
sout_stream_t
*
owner
;
httpd_host_t
*
host
;
httpd_url_t
*
url
;
char
*
psz_control
;
char
*
psz_path
;
/* output (id-access) */
int
sessionc
;
int
i_id
;
rtsp_session_t
**
sessionv
;
sout_stream_id_t
**
id
;
int
i_access
;
sout_access_out_t
**
access
;
};
};
static
int
RtspCallback
(
httpd_callback_sys_t
*
p_args
,
static
int
RtspCallback
(
httpd_callback_sys_t
*
p_args
,
httpd_client_t
*
cl
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
);
httpd_message_t
*
answer
,
httpd_message_t
*
query
);
static
int
RtspCallbackId
(
httpd_callback_sys_t
*
p_args
,
static
int
RtspCallbackId
(
httpd_callback_sys_t
*
p_args
,
httpd_client_t
*
cl
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
);
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
);
int
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
);
rtsp
->
owner
=
p_stream
;
if
(
p_sys
->
p_rtsp_host
==
NULL
)
rtsp
->
sessionc
=
0
;
{
rtsp
->
sessionv
=
NULL
;
return
VLC_EGENERIC
;
vlc_mutex_init
(
p_stream
,
&
rtsp
->
lock
);
}
p_sys
->
psz_rtsp_path
=
strdup
(
url
->
psz_path
?
url
->
psz_path
:
"/"
);
msg_Dbg
(
p_stream
,
"rtsp setup: %s : %d / %s
\n
"
,
p_sys
->
psz_rtsp_control
=
malloc
(
strlen
(
url
->
psz_host
)
+
20
+
strlen
(
p_sys
->
psz_rtsp_path
)
+
1
);
url
->
psz_host
,
url
->
i_port
,
url
->
psz_path
);
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
);
p_sys
->
p_rtsp_url
=
httpd_UrlNewUnique
(
p_sys
->
p_rtsp_host
,
p_sys
->
psz_rtsp_path
,
NULL
,
NULL
,
NULL
);
rtsp
->
psz_path
=
strdup
(
url
->
psz_path
?
url
->
psz_path
:
"/"
);
if
(
p_sys
->
p_rtsp_url
==
NULL
)
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
(
rtsp
->
sessionc
>
0
)
while
(
p_sys
->
i_rtsp
>
0
)
RtspClientDel
(
rtsp
,
rtsp
->
sessionv
[
0
]
);
RtspClientDel
(
p_stream
,
p_sys
->
rtsp
[
0
]
);
if
(
rtsp
->
url
)
httpd_UrlDelete
(
rtsp
->
url
);
if
(
p_sys
->
p_rtsp_url
)
if
(
rtsp
->
host
)
httpd_
UrlDelete
(
p_sys
->
p_rtsp_url
);
httpd_
HostDelete
(
rtsp
->
host
);
if
(
p_sys
->
p_rtsp_host
)
vlc_mutex_destroy
(
&
rtsp
->
lock
);
httpd_HostDelete
(
p_sys
->
p_rtsp_host
);
}
}
struct
rtsp_stream_id_t
struct
rtsp_stream_id_t
{
{
sout_stream_t
*
sout_
stream
;
rtsp_stream_t
*
stream
;
sout_stream_id_t
*
sout_id
;
sout_stream_id_t
*
sout_id
;
httpd_url_t
*
url
;
httpd_url_t
*
url
;
const
char
*
dst
;
int
ttl
;
unsigned
loport
,
hiport
;
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
)
unsigned
loport
,
unsigned
hiport
)
{
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
char
urlbuf
[
strlen
(
rtsp
->
psz_control
)
+
1
+
10
];
char
psz_urlc
[
strlen
(
p_sys
->
psz_rtsp_control
)
+
1
+
10
];
rtsp_stream_id_t
*
id
=
malloc
(
sizeof
(
*
id
)
);
rtsp_stream_id_t
*
id
=
malloc
(
sizeof
(
*
id
)
);
httpd_url_t
*
url
;
httpd_url_t
*
url
;
if
(
id
==
NULL
)
if
(
id
==
NULL
)
return
NULL
;
return
NULL
;
id
->
s
out_stream
=
p_stream
;
id
->
s
tream
=
rtsp
;
id
->
sout_id
=
sid
;
id
->
sout_id
=
sid
;
/* 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
->
loport
=
loport
;
id
->
hiport
=
loport
;
id
->
hiport
=
hiport
;
}
sprintf
(
psz_urlc
,
"%s/trackID=%d"
,
p_sys
->
psz_rtsp_path
,
p_sys
->
i_es
);
sprintf
(
urlbuf
,
"%s/trackID=%d"
,
rtsp
->
psz_path
,
num
);
msg_Dbg
(
p_stream
,
"RTSP: adding %s
\n
"
,
psz_urlc
);
msg_Dbg
(
rtsp
->
owner
,
"RTSP: adding %s
\n
"
,
urlbuf
);
url
=
id
->
url
=
url
=
id
->
url
=
httpd_UrlNewUnique
(
rtsp
->
host
,
urlbuf
,
NULL
,
NULL
,
NULL
);
httpd_UrlNewUnique
(
p_sys
->
p_rtsp_host
,
psz_urlc
,
NULL
,
NULL
,
NULL
);
if
(
url
==
NULL
)
if
(
url
==
NULL
)
{
{
...
@@ -148,62 +196,87 @@ rtsp_stream_id_t *RtspAddId( sout_stream_t *p_stream, sout_stream_id_t *sid,
...
@@ -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
)
{
{
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
);
httpd_UrlDelete
(
id
->
url
);
free
(
id
);
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
);
s
->
stream
=
rtsp
;
rtsp
->
i_last
=
0
;
s
->
b_playing
=
VLC_FALSE
;
rtsp
->
b_playing
=
VLC_FALSE
;
s
->
i_id
=
s
->
i_access
=
0
;
rtsp
->
i_id
=
0
;
s
->
id
=
NULL
;
rtsp
->
id
=
NULL
;
s
->
access
=
NULL
;
rtsp
->
i_access
=
0
;
strcpy
(
s
->
name
,
name
);
rtsp
->
access
=
NULL
;
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
;
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
)
)
if
(
!
strcmp
(
rtsp
->
sessionv
[
i
]
->
name
,
name
)
)
{
return
rtsp
->
sessionv
[
i
];
return
p_stream
->
p_sys
->
rtsp
[
i
];
}
}
}
return
NULL
;
return
NULL
;
}
}
static
void
RtspClientDel
(
sout_stream_t
*
p_stream
,
rtsp_client_t
*
rtsp
)
/** rtsp must be locked */
static
void
RtspClientDel
(
rtsp_stream_t
*
rtsp
,
rtsp_session_t
*
session
)
{
{
int
i
;
int
i
;
TAB_REMOVE
(
p_stream
->
p_sys
->
i_rtsp
,
p_stream
->
p_sys
->
rtsp
,
rtsp
);
TAB_REMOVE
(
rtsp
->
sessionc
,
rtsp
->
sessionv
,
session
);
for
(
i
=
0
;
i
<
rtsp
->
i_access
;
i
++
)
for
(
i
=
0
;
i
<
session
->
i_access
;
i
++
)
{
{
sout_AccessOutDelete
(
rtsp
->
access
[
i
]
);
rtp_del_sink
(
session
->
id
[
i
],
session
->
access
[
i
]
);
sout_AccessOutDelete
(
session
->
access
[
i
]
);
}
}
if
(
rtsp
->
id
)
free
(
rtsp
->
id
);
if
(
rtsp
->
access
)
free
(
rtsp
->
access
);
free
(
rtsp
->
psz_session
);
free
(
session
->
id
);
free
(
rtsp
);
free
(
session
->
access
);
free
(
session
);
}
}
...
@@ -212,11 +285,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
...
@@ -212,11 +285,8 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
httpd_client_t
*
cl
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
)
httpd_message_t
*
answer
,
httpd_message_t
*
query
)
{
{
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_args
;
rtsp_stream_t
*
rtsp
=
(
rtsp_stream_t
*
)
p_args
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
const
char
*
psz_session
=
NULL
,
*
psz_cseq
;
char
*
psz_destination
=
p_sys
->
psz_destination
;
const
char
*
psz_session
=
NULL
;
const
char
*
psz_cseq
=
NULL
;
if
(
answer
==
NULL
||
query
==
NULL
)
if
(
answer
==
NULL
||
query
==
NULL
)
{
{
...
@@ -241,11 +311,11 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
...
@@ -241,11 +311,11 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
{
{
case
HTTPD_MSG_DESCRIBE
:
case
HTTPD_MSG_DESCRIBE
:
{
{
char
*
psz_sdp
=
SDPGenerate
(
p_stream
,
psz_destination
,
VLC_TRUE
);
char
*
psz_sdp
=
SDPGenerate
(
rtsp
->
owner
,
rtsp
->
psz_control
);
answer
->
i_status
=
200
;
answer
->
i_status
=
200
;
httpd_MsgAdd
(
answer
,
"Content-Type"
,
"%s"
,
"application/sdp"
);
httpd_MsgAdd
(
answer
,
"Content-Type"
,
"%s"
,
"application/sdp"
);
httpd_MsgAdd
(
answer
,
"Content-Base"
,
"%s"
,
p_sys
->
psz_rtsp
_control
);
httpd_MsgAdd
(
answer
,
"Content-Base"
,
"%s"
,
rtsp
->
psz
_control
);
answer
->
p_body
=
(
uint8_t
*
)
psz_sdp
;
answer
->
p_body
=
(
uint8_t
*
)
psz_sdp
;
answer
->
i_body
=
strlen
(
psz_sdp
);
answer
->
i_body
=
strlen
(
psz_sdp
);
break
;
break
;
...
@@ -257,34 +327,22 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
...
@@ -257,34 +327,22 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
case
HTTPD_MSG_PLAY
:
case
HTTPD_MSG_PLAY
:
{
{
rtsp_
client_t
*
rtsp
;
rtsp_
session_t
*
ses
;
answer
->
i_status
=
200
;
answer
->
i_status
=
200
;
psz_session
=
httpd_MsgGet
(
query
,
"Session"
);
psz_session
=
httpd_MsgGet
(
query
,
"Session"
);
rtsp
=
RtspClientGet
(
p_stream
,
psz_session
);
if
(
rtsp
&&
!
rtsp
->
b_playing
)
{
int
i_id
;
/* FIXME */
rtsp
->
b_playing
=
VLC_TRUE
;
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
vlc_mutex_lock
(
&
rtsp
->
lock
);
for
(
i_id
=
0
;
i_id
<
rtsp
->
i_id
;
i_id
++
)
ses
=
RtspClientGet
(
rtsp
,
psz_session
);
if
(
(
ses
!=
NULL
)
&&
!
ses
->
b_playing
)
{
{
sout_stream_id_t
*
id
=
rtsp
->
id
[
i_id
];
/* FIXME */
int
i
;
ses
->
b_playing
=
VLC_TRUE
;
for
(
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
{
if
(
id
==
p_sys
->
es
[
i
]
)
break
;
}
if
(
i
>=
p_sys
->
i_es
)
continue
;
rtp_add_sink
(
id
,
rtsp
->
access
[
i_id
]
);
for
(
int
i_id
=
0
;
i_id
<
ses
->
i_id
;
i_id
++
)
}
rtp_add_sink
(
ses
->
id
[
i_id
],
ses
->
access
[
i_id
]
);
vlc_mutex_unlock
(
&
p_sys
->
lock_es
);
}
}
vlc_mutex_unlock
(
&
rtsp
->
lock
);
break
;
break
;
}
}
...
@@ -295,36 +353,18 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
...
@@ -295,36 +353,18 @@ static int RtspCallback( httpd_callback_sys_t *p_args,
case
HTTPD_MSG_TEARDOWN
:
case
HTTPD_MSG_TEARDOWN
:
{
{
rtsp_
client_t
*
rtsp
;
rtsp_
session_t
*
ses
;
/* for now only multicast so easy again */
/* for now only multicast so easy again */
answer
->
i_status
=
200
;
answer
->
i_status
=
200
;
psz_session
=
httpd_MsgGet
(
query
,
"Session"
);
psz_session
=
httpd_MsgGet
(
query
,
"Session"
);
rtsp
=
RtspClientGet
(
p_stream
,
psz_session
);
if
(
rtsp
)
{
int
i_id
;
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
for
(
i_id
=
0
;
i_id
<
rtsp
->
i_id
;
i_id
++
)
{
sout_stream_id_t
*
id
=
rtsp
->
id
[
i_id
];
int
i
;
for
(
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
vlc_mutex_lock
(
&
rtsp
->
lock
);
{
ses
=
RtspClientGet
(
rtsp
,
psz_session
);
if
(
id
==
p_sys
->
es
[
i
]
)
if
(
ses
!=
NULL
)
break
;
RtspClientDel
(
rtsp
,
ses
);
}
vlc_mutex_unlock
(
&
rtsp
->
lock
);
if
(
i
>=
p_sys
->
i_es
)
continue
;
rtp_del_sink
(
id
,
rtsp
->
access
[
i_id
]
);
}
vlc_mutex_unlock
(
&
p_sys
->
lock_es
);
RtspClientDel
(
p_stream
,
rtsp
);
}
break
;
break
;
}
}
...
@@ -376,10 +416,9 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -376,10 +416,9 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
httpd_client_t
*
cl
,
httpd_client_t
*
cl
,
httpd_message_t
*
answer
,
httpd_message_t
*
query
)
httpd_message_t
*
answer
,
httpd_message_t
*
query
)
{
{
rtsp_stream_id_t
*
id
=
(
rtsp_stream_id_t
*
)
p_args
;
rtsp_stream_id_t
*
id
=
(
rtsp_stream_id_t
*
)
p_args
;
sout_stream_t
*
p_stream
=
id
->
s
out_stream
;
sout_stream_t
*
p_stream
=
id
->
s
tream
->
owner
;
sout_stream_id_t
*
sid
=
id
->
sout_id
;
sout_stream_id_t
*
sid
=
id
->
sout_id
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
char
psz_session_init
[
21
];
char
psz_session_init
[
21
];
const
char
*
psz_session
;
const
char
*
psz_session
;
const
char
*
psz_cseq
;
const
char
*
psz_cseq
;
...
@@ -483,7 +522,8 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -483,7 +522,8 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
if
(
b_multicast
)
if
(
b_multicast
)
{
{
if
(
p_sys
->
psz_destination
==
NULL
)
const
char
*
dst
=
id
->
dst
;
if
(
dst
==
NULL
)
continue
;
continue
;
answer
->
i_status
=
200
;
answer
->
i_status
=
200
;
...
@@ -491,36 +531,15 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -491,36 +531,15 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
httpd_MsgAdd
(
answer
,
"Transport"
,
httpd_MsgAdd
(
answer
,
"Transport"
,
"RTP/AVP/UDP;destination=%s;port=%u-%u;"
"RTP/AVP/UDP;destination=%s;port=%u-%u;"
"ttl=%d;mode=play"
,
"ttl=%d;mode=play"
,
p_sys
->
psz_destination
,
id
->
loport
,
dst
,
id
->
loport
,
id
->
hiport
,
id
->
hiport
,
(
id
->
ttl
>
0
)
?
id
->
ttl
:
1
);
(
p_sys
->
i_ttl
>
0
)
?
p_sys
->
i_ttl
:
1
);
}
}
else
else
{
{
char
ip
[
NI_MAXNUMERICHOST
],
psz_access
[
22
],
char
ip
[
NI_MAXNUMERICHOST
],
url
[
NI_MAXNUMERICHOST
+
8
];
url
[
NI_MAXNUMERICHOST
+
8
]
;
static
const
char
access
[]
=
"udp{raw,rtcp}"
;
sout_access_out_t
*
p_access
;
sout_access_out_t
*
p_access
;
rtsp_client_t
*
rtsp
=
NULL
;
rtsp_session_t
*
ses
=
NULL
;
if
(
(
hiport
-
loport
)
!=
(
id
->
hiport
-
id
->
loport
)
)
continue
;
if
(
psz_session
==
NULL
)
{
psz_session
=
psz_session_init
;
rtsp
=
RtspClientNew
(
p_stream
,
psz_session
);
}
else
{
/* FIXME: we probably need to remove an access out,
* if there is already one for the same ID */
rtsp
=
RtspClientGet
(
p_stream
,
psz_session
);
if
(
rtsp
==
NULL
)
{
answer
->
i_status
=
454
;
continue
;
}
}
if
(
httpd_ClientIP
(
cl
,
ip
)
==
NULL
)
if
(
httpd_ClientIP
(
cl
,
ip
)
==
NULL
)
{
{
...
@@ -528,29 +547,45 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -528,29 +547,45 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
continue
;
continue
;
}
}
if
(
p_sys
->
i_ttl
>
0
)
snprintf
(
psz_access
,
sizeof
(
psz_access
),
"udp{raw,rtcp,ttl=%d}"
,
p_sys
->
i_ttl
);
else
strcpy
(
psz_access
,
"udp{raw,rtcp}"
);
snprintf
(
url
,
sizeof
(
url
),
snprintf
(
url
,
sizeof
(
url
),
(
strchr
(
ip
,
':'
)
!=
NULL
)
?
"[%s]:%d"
:
"%s:%d"
,
(
strchr
(
ip
,
':'
)
!=
NULL
)
?
"[%s]:%d"
:
"%s:%d"
,
ip
,
loport
);
ip
,
loport
);
p_access
=
sout_AccessOutNew
(
p_stream
->
p_sout
,
p_access
=
sout_AccessOutNew
(
p_stream
->
p_sout
,
access
,
psz_access
,
url
);
url
);
if
(
p_access
==
NULL
)
if
(
p_access
==
NULL
)
{
{
msg_Err
(
p_stream
,
msg_Err
(
p_stream
,
"cannot create access output for %s://%s"
,
"cannot create access output for %s://%s"
,
psz_
access
,
url
);
access
,
url
);
answer
->
i_status
=
500
;
answer
->
i_status
=
500
;
break
;
continue
;
}
vlc_mutex_lock
(
&
id
->
stream
->
lock
);
if
(
psz_session
==
NULL
)
{
psz_session
=
psz_session_init
;
ses
=
RtspClientNew
(
id
->
stream
,
psz_session
);
}
else
{
/* FIXME: we probably need to remove an access out,
* if there is already one for the same ID */
ses
=
RtspClientGet
(
id
->
stream
,
psz_session
);
if
(
ses
==
NULL
)
{
answer
->
i_status
=
454
;
vlc_mutex_unlock
(
&
id
->
stream
->
lock
);
continue
;
}
}
}
TAB_APPEND
(
rtsp
->
i_id
,
rtsp
->
id
,
sid
);
assert
(
ses
->
i_id
==
ses
->
i_access
);
TAB_APPEND
(
rtsp
->
i_access
,
rtsp
->
access
,
p_access
);
TAB_APPEND
(
ses
->
i_id
,
ses
->
id
,
sid
);
TAB_APPEND
(
ses
->
i_access
,
ses
->
access
,
p_access
);
assert
(
ses
->
i_id
==
ses
->
i_access
);
vlc_mutex_unlock
(
&
id
->
stream
->
lock
);
char
*
src
=
var_GetNonEmptyString
(
p_access
,
"src-addr"
);
char
*
src
=
var_GetNonEmptyString
(
p_access
,
"src-addr"
);
int
sport
=
var_GetInteger
(
p_access
,
"src-port"
);
int
sport
=
var_GetInteger
(
p_access
,
"src-port"
);
...
@@ -568,7 +603,7 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -568,7 +603,7 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
"RTP/AVP/UDP;unicast;source=%s;"
"RTP/AVP/UDP;unicast;source=%s;"
"client_port=%u-%u;server_port=%u-%u;"
"client_port=%u-%u;server_port=%u-%u;"
"mode=play"
,
"mode=play"
,
src
,
loport
,
hiport
,
sport
,
sport
+
1
);
src
,
loport
,
loport
+
1
,
sport
,
sport
+
1
);
}
}
else
else
{
{
...
@@ -576,7 +611,7 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
...
@@ -576,7 +611,7 @@ static int RtspCallbackId( httpd_callback_sys_t *p_args,
"RTP/AVP/UDP;unicast;"
"RTP/AVP/UDP;unicast;"
"client_port=%u-%u;server_port=%u-%u;"
"client_port=%u-%u;server_port=%u-%u;"
"mode=play"
,
"mode=play"
,
loport
,
hiport
,
sport
,
sport
+
1
);
loport
,
loport
+
1
,
sport
,
sport
+
1
);
}
}
answer
->
i_status
=
200
;
answer
->
i_status
=
200
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment