Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
b3790080
Commit
b3790080
authored
Sep 19, 2007
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Partial support for RTP over connection-oriented media
parent
d6de4f03
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
43 deletions
+124
-43
modules/stream_out/rtp.c
modules/stream_out/rtp.c
+124
-43
No files found.
modules/stream_out/rtp.c
View file @
b3790080
...
@@ -44,6 +44,15 @@
...
@@ -44,6 +44,15 @@
# include <fcntl.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/stat.h>
#endif
#endif
#ifdef HAVE_LINUX_DCCP_H
# include <linux/dccp.h>
#endif
#ifndef IPPROTO_DCCP
# define IPPROTO_DCCP 33
#endif
#ifndef IPPROTO_UDPLITE
# define IPPROTO_UDPLITE 136
#endif
#include <errno.h>
#include <errno.h>
...
@@ -283,6 +292,7 @@ struct sout_stream_id_t
...
@@ -283,6 +292,7 @@ struct sout_stream_id_t
int
sinkc
;
int
sinkc
;
rtp_sink_t
*
sinkv
;
rtp_sink_t
*
sinkv
;
rtsp_stream_id_t
*
rtsp_id
;
rtsp_stream_id_t
*
rtsp_id
;
int
*
listen_fd
;
block_fifo_t
*
p_fifo
;
block_fifo_t
*
p_fifo
;
int64_t
i_caching
;
int64_t
i_caching
;
...
@@ -347,22 +357,20 @@ static int Open( vlc_object_t *p_this )
...
@@ -347,22 +357,20 @@ static int Open( vlc_object_t *p_this )
/* Transport protocol */
/* Transport protocol */
p_sys
->
proto
=
IPPROTO_UDP
;
p_sys
->
proto
=
IPPROTO_UDP
;
#if 0
if
(
var_GetBool
(
p_stream
,
SOUT_CFG_PREFIX
"dccp"
)
)
if
(
var_GetBool
(
p_stream
,
SOUT_CFG_PREFIX
"dccp"
)
)
{
{
p_sys->sotype = SOCK_DCCP;
p_sys
->
proto
=
IPPROTO_DCCP
;
p_sys->proto = 33 /*IPPROTO_DCCP*/;
}
}
#if 0
else
else
if( var_GetBool( p_stream, SOUT_CFG_PREFIX "tcp" ) )
if( var_GetBool( p_stream, SOUT_CFG_PREFIX "tcp" ) )
{
{
p_sys->sotype = SOCK_STREAM;
p_sys->proto = IPPROTO_TCP;
p_sys->proto = IPPROTO_TCP;
}
}
else
else
#endif
#endif
if
(
var_GetBool
(
p_stream
,
SOUT_CFG_PREFIX
"udplite"
)
)
if
(
var_GetBool
(
p_stream
,
SOUT_CFG_PREFIX
"udplite"
)
)
p_sys
->
proto
=
136
/*IPPROTO_UDPLITE*/
;
p_sys
->
proto
=
IPPROTO_UDPLITE
;
if
(
(
p_sys
->
psz_destination
==
NULL
)
&&
!
b_rtsp
)
if
(
(
p_sys
->
psz_destination
==
NULL
)
&&
!
b_rtsp
)
{
{
...
@@ -656,8 +664,12 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
...
@@ -656,8 +664,12 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
/* Oh boy, this is really ugly! (+ race condition on lock_es) */
/* Oh boy, this is really ugly! (+ race condition on lock_es) */
dstlen
=
sizeof
(
dst
);
dstlen
=
sizeof
(
dst
);
getpeername
(
p_sys
->
es
[
0
]
->
sinkv
[
0
].
rtp_fd
,
(
struct
sockaddr
*
)
&
dst
,
if
(
p_sys
->
es
[
0
]
->
listen_fd
!=
NULL
)
&
dstlen
);
getsockname
(
p_sys
->
es
[
0
]
->
listen_fd
[
0
],
(
struct
sockaddr
*
)
&
dst
,
&
dstlen
);
else
getpeername
(
p_sys
->
es
[
0
]
->
sinkv
[
0
].
rtp_fd
,
(
struct
sockaddr
*
)
&
dst
,
&
dstlen
);
}
}
else
else
{
{
...
@@ -687,23 +699,47 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
...
@@ -687,23 +699,47 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
{
{
sout_stream_id_t
*
id
=
p_sys
->
es
[
i
];
sout_stream_id_t
*
id
=
p_sys
->
es
[
i
];
const
char
*
mime_major
;
/* major MIME type */
const
char
*
mime_major
;
/* major MIME type */
const
char
*
proto
=
"RTP/AVP"
;
/* protocol */
const
char
*
scode
;
/* DCCP service code */
switch
(
id
->
i_cat
)
switch
(
id
->
i_cat
)
{
{
case
VIDEO_ES
:
case
VIDEO_ES
:
mime_major
=
"video"
;
mime_major
=
"video"
;
scode
=
"SC:RTPV"
;
break
;
break
;
case
AUDIO_ES
:
case
AUDIO_ES
:
mime_major
=
"audio"
;
mime_major
=
"audio"
;
scode
=
"SC:RTPA"
;
break
;
break
;
case
SPU_ES
:
case
SPU_ES
:
mime_major
=
"text"
;
mime_major
=
"text"
;
scode
=
"SC:RTPT"
;
break
;
break
;
default:
default:
mime_major
=
"application"
;
scode
=
"SC:RTPO"
;
break
;
}
if
(
rtsp_url
==
NULL
)
{
switch
(
p_sys
->
proto
)
{
case
IPPROTO_UDP
:
break
;
case
IPPROTO_TCP
:
proto
=
"TCP/RTP/AVP"
;
break
;
case
IPPROTO_DCCP
:
proto
=
"DCCP/RTP/AVP"
;
break
;
case
IPPROTO_UDPLITE
:
continue
;
continue
;
}
}
}
sdp_AddMedia
(
&
psz_sdp
,
mime_major
,
"RTP/AVP"
,
inclport
*
id
->
i_port
,
sdp_AddMedia
(
&
psz_sdp
,
mime_major
,
proto
,
inclport
*
id
->
i_port
,
id
->
i_payload_type
,
VLC_FALSE
,
id
->
i_bitrate
,
id
->
i_payload_type
,
VLC_FALSE
,
id
->
i_bitrate
,
id
->
psz_rtpmap
,
id
->
psz_fmtp
);
id
->
psz_rtpmap
,
id
->
psz_fmtp
);
...
@@ -715,6 +751,13 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
...
@@ -715,6 +751,13 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
addslash
?
"%s/trackID=%u"
:
"%strackID=%u"
,
addslash
?
"%s/trackID=%u"
:
"%strackID=%u"
,
rtsp_url
,
i
);
rtsp_url
,
i
);
}
}
else
{
if
(
id
->
listen_fd
!=
NULL
)
sdp_AddAttribute
(
&
psz_sdp
,
"setup"
,
"passive"
);
if
(
p_sys
->
proto
==
IPPROTO_DCCP
)
sdp_AddAttribute
(
&
psz_sdp
,
"dccp-service-code"
,
scode
);
}
}
}
return
psz_sdp
;
return
psz_sdp
;
...
@@ -763,6 +806,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -763,6 +806,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id
=
vlc_object_create
(
p_stream
,
sizeof
(
sout_stream_id_t
)
);
id
=
vlc_object_create
(
p_stream
,
sizeof
(
sout_stream_id_t
)
);
if
(
id
==
NULL
)
if
(
id
==
NULL
)
return
NULL
;
return
NULL
;
vlc_object_attach
(
id
,
p_stream
);
/* Choose the port */
/* Choose the port */
i_port
=
0
;
i_port
=
0
;
...
@@ -829,35 +873,40 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -829,35 +873,40 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
id
->
sinkc
=
0
;
id
->
sinkc
=
0
;
id
->
sinkv
=
NULL
;
id
->
sinkv
=
NULL
;
id
->
rtsp_id
=
NULL
;
id
->
rtsp_id
=
NULL
;
id
->
p_fifo
=
NULL
;
id
->
listen_fd
=
NULL
;
id
->
i_caching
=
id
->
i_caching
=
(
int64_t
)
1000
*
var_GetInteger
(
p_stream
,
SOUT_CFG_PREFIX
"caching"
);
(
int64_t
)
1000
*
var_GetInteger
(
p_stream
,
SOUT_CFG_PREFIX
"caching"
);
id
->
p_fifo
=
block_FifoNew
(
p_stream
);
if
(
vlc_thread_create
(
id
,
"RTP send thread"
,
ThreadSend
,
if
(
p_sys
->
psz_destination
!=
NULL
)
VLC_THREAD_PRIORITY_HIGHEST
,
VLC_FALSE
)
)
switch
(
p_sys
->
proto
)
{
{
vlc_mutex_destroy
(
&
id
->
lock_sink
);
case
IPPROTO_TCP
:
vlc_object_destroy
(
id
);
case
IPPROTO_DCCP
:
return
NULL
;
id
->
listen_fd
=
net_Listen
(
VLC_OBJECT
(
p_stream
),
p_sys
->
psz_destination
,
i_port
,
p_sys
->
proto
);
if
(
id
->
listen_fd
==
NULL
)
{
msg_Err
(
p_stream
,
"passive COMEDIA RTP socket failed"
);
goto
error
;
}
}
break
;
if
(
p_sys
->
psz_destination
!=
NULL
)
default:
{
{
int
ttl
=
(
p_sys
->
i_ttl
>
0
)
?
p_sys
->
i_ttl
:
-
1
;
int
ttl
=
(
p_sys
->
i_ttl
>
0
)
?
p_sys
->
i_ttl
:
-
1
;
int
fd
=
net_ConnectDgram
(
p_stream
,
p_sys
->
psz_destination
,
int
fd
=
net_ConnectDgram
(
p_stream
,
p_sys
->
psz_destination
,
i_port
,
ttl
,
p_sys
->
proto
);
i_port
,
ttl
,
p_sys
->
proto
);
if
(
fd
==
-
1
)
if
(
fd
==
-
1
)
{
{
msg_Err
(
p_stream
,
"cannot create RTP socket"
);
msg_Err
(
p_stream
,
"cannot create RTP socket"
);
vlc_thread_join
(
id
);
goto
error
;
vlc_mutex_destroy
(
&
id
->
lock_sink
);
vlc_object_destroy
(
id
);
return
NULL
;
}
}
rtp_add_sink
(
id
,
fd
);
rtp_add_sink
(
id
,
fd
);
}
}
}
if
(
p_fmt
==
NULL
)
if
(
p_fmt
==
NULL
)
{
{
...
@@ -1069,12 +1118,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -1069,12 +1118,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
default:
default:
msg_Err
(
p_stream
,
"cannot add this stream (unsupported "
msg_Err
(
p_stream
,
"cannot add this stream (unsupported "
"codec:%4.4s)"
,
(
char
*
)
&
p_fmt
->
i_codec
);
"codec:%4.4s)"
,
(
char
*
)
&
p_fmt
->
i_codec
);
if
(
id
->
sinkc
>
0
)
goto
error
;
rtp_del_sink
(
id
,
id
->
sinkv
[
0
].
rtp_fd
);
vlc_thread_join
(
id
);
vlc_mutex_destroy
(
&
id
->
lock_sink
);
vlc_object_destroy
(
id
);
return
NULL
;
}
}
if
(
cscov
!=
-
1
)
if
(
cscov
!=
-
1
)
...
@@ -1090,6 +1134,11 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -1090,6 +1134,11 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
p_sys
->
psz_destination
,
p_sys
->
psz_destination
,
p_sys
->
i_ttl
,
id
->
i_port
,
id
->
i_port
+
1
);
p_sys
->
i_ttl
,
id
->
i_port
,
id
->
i_port
+
1
);
id
->
p_fifo
=
block_FifoNew
(
p_stream
);
if
(
vlc_thread_create
(
id
,
"RTP send thread"
,
ThreadSend
,
VLC_THREAD_PRIORITY_HIGHEST
,
VLC_FALSE
)
)
goto
error
;
/* 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
);
...
@@ -1110,16 +1159,24 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
...
@@ -1110,16 +1159,24 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
if
(
p_sys
->
b_export_sap
)
SapSetup
(
p_stream
);
if
(
p_sys
->
b_export_sap
)
SapSetup
(
p_stream
);
if
(
p_sys
->
b_export_sdp_file
)
FileSetup
(
p_stream
);
if
(
p_sys
->
b_export_sdp_file
)
FileSetup
(
p_stream
);
vlc_object_attach
(
id
,
p_stream
);
return
id
;
return
id
;
error:
Del
(
p_stream
,
id
);
return
NULL
;
}
}
static
int
Del
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
static
int
Del
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
{
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
if
(
id
->
p_fifo
!=
NULL
)
{
vlc_object_kill
(
id
);
vlc_object_kill
(
id
);
block_FifoWake
(
id
->
p_fifo
);
block_FifoWake
(
id
->
p_fifo
);
vlc_thread_join
(
id
);
block_FifoRelease
(
id
->
p_fifo
);
}
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
vlc_mutex_lock
(
&
p_sys
->
lock_es
);
TAB_REMOVE
(
p_sys
->
i_es
,
p_sys
->
es
,
id
);
TAB_REMOVE
(
p_sys
->
i_es
,
p_sys
->
es
,
id
);
...
@@ -1141,10 +1198,10 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
...
@@ -1141,10 +1198,10 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
RtspDelId
(
p_sys
->
rtsp
,
id
->
rtsp_id
);
RtspDelId
(
p_sys
->
rtsp
,
id
->
rtsp_id
);
if
(
id
->
sinkc
>
0
)
if
(
id
->
sinkc
>
0
)
rtp_del_sink
(
id
,
id
->
sinkv
[
0
].
rtp_fd
);
/* sink for explicit dst= */
rtp_del_sink
(
id
,
id
->
sinkv
[
0
].
rtp_fd
);
/* sink for explicit dst= */
if
(
id
->
listen_fd
!=
NULL
)
net_ListenClose
(
id
->
listen_fd
);
vlc_thread_join
(
id
);
vlc_mutex_destroy
(
&
id
->
lock_sink
);
vlc_mutex_destroy
(
&
id
->
lock_sink
);
block_FifoRelease
(
id
->
p_fifo
);
/* Update SDP (sap/file) */
/* Update SDP (sap/file) */
if
(
p_sys
->
b_export_sap
&&
!
p_sys
->
p_mux
)
SapSetup
(
p_stream
);
if
(
p_sys
->
b_export_sap
&&
!
p_sys
->
p_mux
)
SapSetup
(
p_stream
);
...
@@ -1311,6 +1368,11 @@ static void ThreadSend( vlc_object_t *p_this )
...
@@ -1311,6 +1368,11 @@ static void ThreadSend( vlc_object_t *p_this )
mwait
(
i_date
);
mwait
(
i_date
);
vlc_mutex_lock
(
&
id
->
lock_sink
);
vlc_mutex_lock
(
&
id
->
lock_sink
);
#if 0
unsigned deadc = 0; /* How many dead sockets? */
int deadv[id->sinkc]; /* Dead sockets list */
#endif
for
(
int
i
=
0
;
i
<
id
->
sinkc
;
i
++
)
for
(
int
i
=
0
;
i
<
id
->
sinkc
;
i
++
)
{
{
SendRTCP
(
id
->
sinkv
[
i
].
rtcp
,
out
);
SendRTCP
(
id
->
sinkv
[
i
].
rtcp
,
out
);
...
@@ -1324,7 +1386,8 @@ static void ThreadSend( vlc_object_t *p_this )
...
@@ -1324,7 +1386,8 @@ static void ThreadSend( vlc_object_t *p_this )
/* splice failed */
/* splice failed */
splice
(
fd
[
2
],
NULL
,
fd
[
4
],
NULL
,
len
,
0
);
splice
(
fd
[
2
],
NULL
,
fd
[
4
],
NULL
,
len
,
0
);
#endif
#endif
send
(
id
->
sinkv
[
i
].
rtp_fd
,
out
->
p_buffer
,
len
,
0
);
if
(
send
(
id
->
sinkv
[
i
].
rtp_fd
,
out
->
p_buffer
,
len
,
0
)
<
0
)
/*deadv[deadc++] = id->sinkv[i].rtp_fd*/
;
}
}
vlc_mutex_unlock
(
&
id
->
lock_sink
);
vlc_mutex_unlock
(
&
id
->
lock_sink
);
...
@@ -1332,6 +1395,24 @@ static void ThreadSend( vlc_object_t *p_this )
...
@@ -1332,6 +1395,24 @@ static void ThreadSend( vlc_object_t *p_this )
#ifdef HAVE_TEE
#ifdef HAVE_TEE
splice
(
fd
[
0
],
NULL
,
fd
[
4
],
NULL
,
len
,
0
);
splice
(
fd
[
0
],
NULL
,
fd
[
4
],
NULL
,
len
,
0
);
#endif
#endif
#if 0
for( unsigned i = 0; i < deadc; i++ )
{
msg_Dbg( id, "removing socket %d", deadv[i] );
rtp_del_sink( id, deadv[i] );
}
#endif
/* Hopefully we won't overflow the SO_MAXCONN accept queue */
while
(
id
->
listen_fd
!=
NULL
)
{
int
fd
=
net_Accept
(
id
,
id
->
listen_fd
,
0
);
if
(
fd
==
-
1
)
break
;
msg_Dbg
(
id
,
"adding socket %d"
,
fd
);
rtp_add_sink
(
id
,
fd
);
}
}
}
#ifdef HAVE_TEE
#ifdef HAVE_TEE
...
...
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