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
31067bdd
Commit
31067bdd
authored
Sep 08, 2007
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bring back the lightweight RTCP sender
parent
c9d3f473
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
190 additions
and
1 deletion
+190
-1
modules/stream_out/Modules.am
modules/stream_out/Modules.am
+1
-1
modules/stream_out/rtcp.c
modules/stream_out/rtcp.c
+183
-0
modules/stream_out/rtp.h
modules/stream_out/rtp.h
+6
-0
No files found.
modules/stream_out/Modules.am
View file @
31067bdd
...
...
@@ -6,7 +6,7 @@ SOURCES_stream_out_duplicate = duplicate.c
SOURCES_stream_out_es = es.c
SOURCES_stream_out_display = display.c
SOURCES_stream_out_gather = gather.c
SOURCES_stream_out_rtp = rtp.
c rtp.h
rtsp.c
SOURCES_stream_out_rtp = rtp.
h rtp.c rtcp.c
rtsp.c
SOURCES_stream_out_switcher = switcher.c
SOURCES_stream_out_bridge = bridge.c
SOURCES_stream_out_mosaic_bridge = mosaic_bridge.c
...
...
modules/stream_out/rtcp.c
0 → 100644
View file @
31067bdd
/*****************************************************************************
* rtcp.c: RTCP stream output support
*****************************************************************************
* Copyright © 2007 Rémi Denis-Courmont
* $Id$
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc_block.h>
#include <vlc_network.h>
#include <vlc_url.h>
#include <vlc_sout.h>
#include "rtp.h"
/*
* NOTE on RTCP implementation:
* - there is a single sender (us), no conferencing here! => n = sender = 1,
* - as such we need not bother to include Receiver Reports,
* - in unicast case, there is a single receiver => members = 1 + 1 = 2,
* and obviously n > 25% of members,
* - in multicast case, we do not want to maintain the number of receivers
* and we assume it is big (i.e. than 3) because that's what broadcasting is
* all about,
* - it is assumed we_sent = true (could be wrong), since we are THE sender,
* - we always send SR + SDES, while running,
* - FIXME: we do not implement separate rate limiting for SDES,
* - we do not implement any profile-specific extensions for the time being.
*/
struct
rtcp_sender_t
{
size_t
length
;
/* RTCP packet length */
uint8_t
payload
[
28
+
8
+
(
2
*
257
)];
int
handle
;
/* RTCP socket handler */
uint32_t
packets
;
/* RTP packets sent */
uint32_t
bytes
;
/* RTP bytes sent */
unsigned
counter
;
/* RTP packets sent since last RTCP packet */
};
rtcp_sender_t
*
OpenRTCP
(
vlc_object_t
*
obj
,
int
rtp_fd
,
int
proto
,
uint16_t
dport
)
{
rtcp_sender_t
*
rtcp
;
uint8_t
*
ptr
;
char
src
[
NI_MAXNUMERICHOST
],
dst
[
NI_MAXNUMERICHOST
];
int
sport
;
int
fd
;
if
(
net_GetSockAddress
(
rtp_fd
,
src
,
&
sport
)
||
net_GetPeerAddress
(
rtp_fd
,
dst
,
NULL
))
return
NULL
;
sport
++
;
fd
=
net_OpenDgram
(
obj
,
src
,
sport
,
dst
,
dport
,
AF_UNSPEC
,
proto
);
if
(
fd
==
-
1
)
return
NULL
;
rtcp
=
malloc
(
sizeof
(
*
rtcp
));
if
(
rtcp
==
NULL
)
{
net_Close
(
fd
);
return
NULL
;
}
rtcp
->
handle
=
fd
;
rtcp
->
bytes
=
rtcp
->
packets
=
rtcp
->
counter
=
0
;
ptr
=
(
uint8_t
*
)
strchr
(
src
,
'%'
);
if
(
ptr
!=
NULL
)
*
ptr
=
'\0'
;
/* remove scope ID frop IPv6 addresses */
ptr
=
rtcp
->
payload
;
/* Sender report */
ptr
[
0
]
=
2
<<
6
;
/* V = 2, P = RC = 0 */
ptr
[
1
]
=
200
;
/* payload type: Sender Report */
SetWBE
(
ptr
+
2
,
6
);
/* length = 6 (7 double words) */
memset
(
ptr
+
4
,
0
,
4
);
/* SSRC unknown yet */
SetQWBE
(
ptr
+
8
,
NTPtime64
());
memset
(
ptr
+
16
,
0
,
12
);
/* timestamp and counters */
ptr
+=
28
;
/* Source description */
uint8_t
*
sdes
=
ptr
;
ptr
[
0
]
=
(
2
<<
6
)
|
1
;
/* V = 2, P = 0, SC = 1 */
ptr
[
1
]
=
202
;
/* payload type: Source Description */
uint8_t
*
lenptr
=
ptr
+
2
;
memset
(
ptr
+
4
,
0
,
4
);
/* SSRC unknown yet */
ptr
+=
8
;
ptr
[
0
]
=
1
;
/* CNAME - mandatory */
assert
(
NI_MAXNUMERICHOST
<=
256
);
ptr
[
1
]
=
strlen
(
src
);
memcpy
(
ptr
+
2
,
src
,
ptr
[
1
]);
ptr
+=
ptr
[
1
]
+
2
;
static
const
char
tool
[]
=
PACKAGE_STRING
;
ptr
[
0
]
=
6
;
/* TOOL */
ptr
[
1
]
=
(
sizeof
(
tool
)
>
256
)
?
255
:
(
sizeof
(
tool
)
-
1
);
memcpy
(
ptr
+
2
,
tool
,
ptr
[
1
]);
ptr
+=
ptr
[
1
]
+
2
;
while
((
ptr
-
sdes
)
&
3
)
/* 32-bits padding */
*
ptr
++
=
0
;
SetWBE
(
lenptr
,
ptr
-
sdes
);
rtcp
->
length
=
ptr
-
rtcp
->
payload
;
return
VLC_SUCCESS
;
}
void
CloseRTCP
(
rtcp_sender_t
*
rtcp
)
{
if
(
rtcp
==
NULL
)
return
;
uint8_t
*
ptr
=
rtcp
->
payload
;
/* Bye */
ptr
[
0
]
=
(
2
<<
6
)
|
1
;
/* V = 2, P = 0, SC = 1 */
ptr
[
1
]
=
203
;
/* payload type: Bye */
SetWBE
(
ptr
+
2
,
1
);
/* SSRC is already there :) */
/* We are THE sender, so we are more important than anybody else, so
* we can afford not to check bandwidth constraints here. */
send
(
rtcp
->
handle
,
rtcp
->
payload
,
8
,
0
);
net_Close
(
rtcp
->
handle
);
}
void
SendRTCP
(
rtcp_sender_t
*
restrict
rtcp
,
const
block_t
*
rtp
)
{
if
((
rtcp
==
NULL
)
/* RTCP sender off */
||
(
rtp
->
i_buffer
<
12
))
/* too short RTP packet */
return
;
/* Updates statistics */
rtcp
->
packets
++
;
rtcp
->
bytes
+=
rtp
->
i_buffer
;
rtcp
->
counter
+=
rtp
->
i_buffer
;
/* 1.25% rate limit */
if
((
rtcp
->
counter
/
80
)
<
rtcp
->
length
)
return
;
uint8_t
*
ptr
=
rtcp
->
payload
;
uint32_t
last
=
GetDWBE
(
ptr
+
8
);
// last RTCP SR send time
uint64_t
now64
=
NTPtime64
();
if
((
now64
>>
32
)
<
(
last
+
5
))
return
;
// no more than one SR every 5 seconds
memcpy
(
ptr
+
4
,
rtp
->
p_buffer
+
8
,
4
);
/* SR SSRC */
SetQWBE
(
ptr
+
8
,
now64
);
memcpy
(
ptr
+
16
,
rtp
->
p_buffer
+
4
,
4
);
/* RTP timestamp */
SetDWBE
(
ptr
+
20
,
rtcp
->
packets
);
SetDWBE
(
ptr
+
24
,
rtcp
->
bytes
);
memcpy
(
ptr
+
28
+
4
,
rtp
->
p_buffer
+
8
,
4
);
/* SDES SSRC */
if
(
send
(
rtcp
->
handle
,
ptr
,
rtcp
->
length
,
0
)
==
(
ssize_t
)
rtcp
->
length
)
rtcp
->
counter
=
0
;
}
modules/stream_out/rtp.h
View file @
31067bdd
...
...
@@ -39,3 +39,9 @@ char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url );
int
rtp_add_sink
(
sout_stream_id_t
*
id
,
int
fd
);
void
rtp_del_sink
(
sout_stream_id_t
*
id
,
int
fd
);
/* RTCP */
typedef
struct
rtcp_sender_t
rtcp_sender_t
;
rtcp_sender_t
*
OpenRTCP
(
vlc_object_t
*
obj
,
int
rtp_fd
,
int
proto
,
uint16_t
dport
);
void
CloseRTCP
(
rtcp_sender_t
*
rtcp
);
void
SendRTCP
(
rtcp_sender_t
*
restrict
rtcp
,
const
block_t
*
rtp
);
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