UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
rtp.h File Reference
#include "config_win32.h"
#include "config_unix.h"
#include <cstddef>
#include <cstdint>
#include "tv.h"
#include "video_codec.h"
Include dependency graph for rtp.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  rtcp_app
 
struct  rtcp_rr
 
struct  rtcp_rx
 
struct  rtcp_sdes_item
 
struct  rtcp_sr
 
struct  rtp_event
 

Macros

#define RTP_MAX_MTU   9000
 
#define RTP_MAX_PACKET_LEN   (RTP_MAX_MTU+RTP_PACKET_HEADER_SIZE+MAX_PADDING)
 
#define RTP_PACKET_HEADER_SIZE   ((int) (offsetof(rtp_packet, extn_type) - offsetof(rtp_packet, csrc) + sizeof ((rtp_packet *) 0)->extn_type))
 
#define RTP_VERSION   2
 

Typedefs

typedef rtcp_app *(* rtcp_app_callback) (struct rtp *session, uint32_t rtp_ts, int max_size)
 
typedef void(* rtp_callback) (struct rtp *session, rtp_event *e)
 
typedef struct rtp * rtp_t
 

Enumerations

enum  { IPV4_HDR_LEN = 20 , IPV6_HDR_LEN = 40 , UDP_HDR_LEN = 8 , RTP_HDR_LEN = 12 }
 
enum  rtcp_sdes_type {
  RTCP_SDES_END = 0 , RTCP_SDES_CNAME = 1 , RTCP_SDES_NAME = 2 , RTCP_SDES_EMAIL = 3 ,
  RTCP_SDES_PHONE = 4 , RTCP_SDES_LOC = 5 , RTCP_SDES_TOOL = 6 , RTCP_SDES_NOTE = 7 ,
  RTCP_SDES_PRIV = 8
}
 
enum  rtp_event_type {
  RX_RTP , RX_RTP_IOV , RX_SR , RX_RR ,
  RX_TFRC_RX , RX_SDES , RX_BYE , SOURCE_CREATED ,
  SOURCE_DELETED , RX_RR_EMPTY , RX_RTCP_START , RX_RTCP_FINISH ,
  RR_TIMEOUT , RX_APP , PEEK_RTP
}
 
enum  rtp_option {
  RTP_OPT_PROMISC = 1 , RTP_OPT_WEAK_VALIDATION = 2 , RTP_OPT_FILTER_MY_PACKETS = 3 , RTP_OPT_REUSE_PACKET_BUFS = 4 ,
  RTP_OPT_PEEK = 5 , RTP_OPT_RECORD_SOURCE = 6 , RTP_OPT_SEND_BACK = 7
}
 

Functions

struct __attribute__ ((packed))
 
bool rtcp_recv_r (struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
 
bool rtp_add_csrc (struct rtp *session, uint32_t csrc)
 
void rtp_async_start (struct rtp *session, int nr_packets)
 
void rtp_async_wait (struct rtp *session)
 
int rtp_compute_fract_lost (struct rtp *session, uint32_t ssrc)
 
bool rtp_del_csrc (struct rtp *session, uint32_t csrc)
 
void rtp_done (struct rtp *session)
 
void rtp_flush_recv_buf (struct rtp *session)
 
uint64_t rtp_get_bytes_sent (struct rtp *session)
 
bool rtp_get_option (struct rtp *session, rtp_option optname, int *optval)
 
int rtp_get_recv_buf (struct rtp *session)
 
const rtcp_rr * rtp_get_rr (struct rtp *session, uint32_t reporter, uint32_t reportee)
 
const char * rtp_get_sdes (struct rtp *session, uint32_t ssrc, rtcp_sdes_type type)
 
const rtcp_sr * rtp_get_sr (struct rtp *session, uint32_t ssrc)
 
struct socket_udp_local * rtp_get_udp_local_socket (struct rtp *session)
 
int rtp_get_udp_rx_port (struct rtp *session)
 
uint8_t * rtp_get_userdata (struct rtp *session)
 
bool rtp_has_receiver (struct rtp *session)
 
rtp_t rtp_init (const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, int tfrc_on, rtp_callback callback, uint8_t *userdata, int force_ip_version, bool multithreaded)
 
rtp_t rtp_init_if (const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, int tfrc_on, rtp_callback callback, uint8_t *userdata, int force_ip_version, bool multithreaded)
 
rtp_t rtp_init_with_udp_socket (struct socket_udp_local *l, struct sockaddr *sa, socklen_t len, rtp_callback callback)
 
bool rtp_is_ipv6 (struct rtp *session)
 
uint32_t rtp_my_ssrc (struct rtp *session)
 
bool rtp_recv (struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts) __attribute__((deprecated))
 
int rtp_recv_poll_r (struct rtp **sessions, struct timeval *timeout, uint32_t curr_rtp_ts)
 
bool rtp_recv_r (struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
 Receive RTP packets and dispatch them.
 
void rtp_send_bye (struct rtp *session)
 
void rtp_send_ctrl (struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback, time_ns_t curr_time)
 
int rtp_send_data (struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, const uint32_t *csrc, char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type)
 
int rtp_send_data_hdr (struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, const uint32_t *csrc, char *phdr, int phdr_len, char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type)
 
int rtp_send_raw_rtp_data (struct rtp *session, char *buffer, int buffer_len)
 
bool rtp_set_encryption_key (struct rtp *session, const char *passphrase)
 
bool rtp_set_my_ssrc (struct rtp *session, uint32_t ssrc)
 
bool rtp_set_option (struct rtp *session, rtp_option optname, int optval)
 
bool rtp_set_recv_buf (struct rtp *session, int bufsize)
 
void rtp_set_recv_iov (struct rtp *session, struct msghdr *m)
 
bool rtp_set_sdes (struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length)
 
bool rtp_set_send_buf (struct rtp *session, int bufsize)
 
void rtp_update (struct rtp *session, time_ns_t curr_time)
 

Variables

 rtp_packet
 

Macro Definition Documentation

◆ RTP_MAX_MTU

#define RTP_MAX_MTU   9000

Definition at line 60 of file rtp.h.

Referenced by adjust_params(), and tx_init().

◆ RTP_MAX_PACKET_LEN

◆ RTP_PACKET_HEADER_SIZE

#define RTP_PACKET_HEADER_SIZE   ((int) (offsetof(rtp_packet, extn_type) - offsetof(rtp_packet, csrc) + sizeof ((rtp_packet *) 0)->extn_type))

Definition at line 128 of file rtp.h.

Referenced by rtp_recv_data(), rtp_send_data_hdr(), and udp_reader().

◆ RTP_VERSION

#define RTP_VERSION   2

Definition at line 59 of file rtp.h.

Referenced by format_rtcp_app().

Typedef Documentation

◆ rtcp_app_callback

typedef rtcp_app *(* rtcp_app_callback) (struct rtp *session, uint32_t rtp_ts, int max_size)

Definition at line 205 of file rtp.h.

◆ rtp_callback

typedef void(* rtp_callback) (struct rtp *session, rtp_event *e)

Definition at line 204 of file rtp.h.

◆ rtp_t

typedef struct rtp* rtp_t

Definition at line 81 of file rtp.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
IPV4_HDR_LEN 
IPV6_HDR_LEN 
UDP_HDR_LEN 
RTP_HDR_LEN 

Definition at line 63 of file rtp.h.

63 {
64 IPV4_HDR_LEN = 20,
65 IPV6_HDR_LEN = 40,
66 UDP_HDR_LEN = 8,
67 RTP_HDR_LEN = 12,
68
69};
@ IPV6_HDR_LEN
Definition rtp.h:65
@ IPV4_HDR_LEN
Definition rtp.h:64
@ RTP_HDR_LEN
Definition rtp.h:67
@ UDP_HDR_LEN
Definition rtp.h:66

◆ rtcp_sdes_type

Enumerator
RTCP_SDES_END 
RTCP_SDES_CNAME 
RTCP_SDES_NAME 
RTCP_SDES_EMAIL 
RTCP_SDES_PHONE 
RTCP_SDES_LOC 
RTCP_SDES_TOOL 
RTCP_SDES_NOTE 
RTCP_SDES_PRIV 

Definition at line 208 of file rtp.h.

208 {
209 RTCP_SDES_END = 0,
210 RTCP_SDES_CNAME = 1,
211 RTCP_SDES_NAME = 2,
212 RTCP_SDES_EMAIL = 3,
213 RTCP_SDES_PHONE = 4,
214 RTCP_SDES_LOC = 5,
215 RTCP_SDES_TOOL = 6,
216 RTCP_SDES_NOTE = 7,
rtcp_sdes_type
Definition rtp.h:208
@ RTCP_SDES_NOTE
Definition rtp.h:216
@ RTCP_SDES_CNAME
Definition rtp.h:210
@ RTCP_SDES_PHONE
Definition rtp.h:213
@ RTCP_SDES_TOOL
Definition rtp.h:215
@ RTCP_SDES_LOC
Definition rtp.h:214
@ RTCP_SDES_EMAIL
Definition rtp.h:212
@ RTCP_SDES_END
Definition rtp.h:209
@ RTCP_SDES_NAME
Definition rtp.h:211
@ RTCP_SDES_PRIV
Definition rtp.h:217

◆ rtp_event_type

Enumerator
RX_RTP 
RX_RTP_IOV 
RX_SR 
RX_RR 
RX_TFRC_RX 
RX_SDES 
RX_BYE 
SOURCE_CREATED 
SOURCE_DELETED 
RX_RR_EMPTY 
RX_RTCP_START 
RX_RTCP_FINISH 
RR_TIMEOUT 
RX_APP 
PEEK_RTP 

Definition at line 179 of file rtp.h.

179 {
180 RX_RTP,
182 RX_SR,
183 RX_RR,
184 RX_TFRC_RX, /* received TFRC extended report */
185 RX_SDES,
186 RX_BYE, /* Source is leaving the session, database entry is still valid */
188 SOURCE_DELETED, /* Source has been removed from the database */
189 RX_RR_EMPTY, /* We've received an empty reception report block */
190 RX_RTCP_START, /* Processing a compound RTCP packet about to start. The SSRC is not valid in this event. */
191 RX_RTCP_FINISH, /* Processing a compound RTCP packet finished. The SSRC is not valid in this event. */
193 RX_APP,
rtp_event_type
Definition rtp.h:179
@ RX_RTP_IOV
Definition rtp.h:181
@ RX_RTP
Definition rtp.h:180
@ RR_TIMEOUT
Definition rtp.h:192
@ RX_SDES
Definition rtp.h:185
@ RX_APP
Definition rtp.h:193
@ PEEK_RTP
Definition rtp.h:194
@ RX_RTCP_START
Definition rtp.h:190
@ RX_TFRC_RX
Definition rtp.h:184
@ RX_SR
Definition rtp.h:182
@ SOURCE_CREATED
Definition rtp.h:187
@ RX_RTCP_FINISH
Definition rtp.h:191
@ SOURCE_DELETED
Definition rtp.h:188
@ RX_RR_EMPTY
Definition rtp.h:189
@ RX_BYE
Definition rtp.h:186
@ RX_RR
Definition rtp.h:183

◆ rtp_option

enum rtp_option
Enumerator
RTP_OPT_PROMISC 
RTP_OPT_WEAK_VALIDATION 
RTP_OPT_FILTER_MY_PACKETS 
RTP_OPT_REUSE_PACKET_BUFS 
RTP_OPT_PEEK 
RTP_OPT_RECORD_SOURCE 
RTP_OPT_SEND_BACK 

Definition at line 227 of file rtp.h.

227 {
228 RTP_OPT_PROMISC = 1,
231 RTP_OPT_REUSE_PACKET_BUFS = 4, /* Each data packet is written into the same buffer, */
232 /* rather than malloc()ing a new buffer each time. */
233 RTP_OPT_PEEK = 5,
234 RTP_OPT_RECORD_SOURCE = 6, /* Record network source (sockaddr_storage) at the */
235 /* end of the packet */
236 RTP_OPT_SEND_BACK = 7, // Send to a receiver that is sending to us. Sets also
237 // RTP_POT_RECORD_SOURCE
238} rtp_option;
rtp_option
Definition rtp.h:227
@ RTP_OPT_PEEK
Definition rtp.h:233
@ RTP_OPT_REUSE_PACKET_BUFS
Definition rtp.h:231
@ RTP_OPT_FILTER_MY_PACKETS
Definition rtp.h:230
@ RTP_OPT_PROMISC
Definition rtp.h:228
@ RTP_OPT_WEAK_VALIDATION
Definition rtp.h:229
@ RTP_OPT_SEND_BACK
Definition rtp.h:236
@ RTP_OPT_RECORD_SOURCE
Definition rtp.h:234

Function Documentation

◆ __attribute__()

struct __attribute__ ( (packed) )

Definition at line 81 of file rtp.h.

88 {
89 /* The following are pointers to the data in the packet as */
90 /* it came off the wire. The packet it read in such that the */
91 /* header maps onto the latter part of this struct, and the */
92 /* fields in this first part of the struct point into it. The */
93 /* entire packet can be freed by freeing this struct, without */
94 /* having to free the csrc, data and extn blocks separately. */
95 /* WARNING: Don't change the size of the first portion of the */
96 /* struct without changing RTP_PACKET_HEADER_SIZE to match. */
97 uint32_t *csrc;
98 char *data;
99 int data_len;
100 unsigned char *extn;
101 uint16_t extn_len; /* Size of the extension in 32 bit words minus one */
102 uint16_t extn_type; /* Extension type field in the RTP packet header */
103 /* The following map directly onto the RTP packet header... */
104#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
105 unsigned short v:2; /* packet type */
106 unsigned short p:1; /* padding flag */
107 unsigned short x:1; /* header extension flag */
108 unsigned short cc:4; /* CSRC count */
109 unsigned short m:1; /* marker bit */
110 unsigned short pt:7; /* payload type */
111#else
112 unsigned short cc:4; /* CSRC count */
113 unsigned short x:1; /* header extension flag */
114 unsigned short p:1; /* padding flag */
115 unsigned short v:2; /* packet type */
116 unsigned short pt:7; /* payload type */
117 unsigned short m:1; /* marker bit */
118#endif
119 uint16_t seq; /* sequence number */
120 uint32_t ts; /* timestamp */
121 uint32_t ssrc; /* synchronization source */
122 /* The csrc list, header extension and data follow, but can't */
123 /* be represented in the struct. */
124 uint32_t send_ts;
125 uint32_t rtt;
126} rtp_packet;
rtp_packet
Definition rtp.h:126
uint32_t ts
Definition tfrc.c:101
uint32_t seq
Definition tfrc.c:100

References __attribute__::data, seq, and ts.

Referenced by avg_lines(), compute_loss_event(), qfDES(), read_adobe_app14(), read_sos(), and rtp_send_data_hdr().

◆ rtcp_recv_r()

bool rtcp_recv_r ( struct rtp * session,
struct timeval * timeout,
uint32_t curr_rtp_ts )

Similar to rtp_recv_r(), expect that it only receives data from RTCP socket. This should be used when the socket acts as a sender only, therefore rtp_recv_r() is not called. Running rtp_recv_r() instead would cause leaks in this context (because RTP packets are usually pushed into PBUF which is not processed by sender and thus it will grow indefinitely).

Definition at line 2398 of file rtp.c.

2399{
2400 UNUSED(curr_rtp_ts);
2401 struct udp_fd_r fd;
2402
2403 check_database(session);
2404 udp_fd_zero_r(&fd);
2405 udp_fd_set_r(session->rtcp_socket, &fd);
2406 if (udp_select_r(timeout, &fd) > 0) {
2407 if (udp_fd_isset_r(session->rtcp_socket, &fd)) {
2408 uint8_t buffer[RTP_MAX_PACKET_LEN];
2409 int buflen;
2410 session->rtcp_dest_len = sizeof(session->rtcp_dest);
2411 buflen =
2412 udp_recvfrom(session->rtcp_socket, (char *)buffer,
2414 (struct sockaddr *) &session->rtcp_dest, &session->rtcp_dest_len);
2415 rtp_process_ctrl(session, buffer, buflen);
2416 }
2417 check_database(session);
2418 return true;
2419 }
2420 check_database(session);
2421 return false;
2422}
#define UNUSED(x)
int udp_recvfrom(socket_udp *s, char *buffer, int buflen, struct sockaddr *src_addr, socklen_t *addrlen)
Definition net_udp.c:1245
int udp_select_r(struct timeval *timeout, struct udp_fd_r *fd_struct)
Definition net_udp.c:1355
void udp_fd_zero_r(struct udp_fd_r *fd_struct)
Definition net_udp.c:961
void udp_fd_set_r(socket_udp *s, struct udp_fd_r *fd_struct)
Definition net_udp.c:1312
int udp_fd_isset_r(socket_udp *s, struct udp_fd_r *fd_struct)
Definition net_udp.c:1336
static void rtp_process_ctrl(struct rtp *session, uint8_t *buffer, int buflen)
Definition rtp.c:2127
static void check_database(struct rtp *session)
Definition rtp.c:540
#define RTP_MAX_PACKET_LEN
Definition rtp.h:61
socklen_t rtcp_dest_len
Definition rtp.c:278
struct sockaddr_storage rtcp_dest
Definition rtp.c:277
socket_udp * rtcp_socket
Definition rtp.c:276

References check_database(), rtp::rtcp_dest, rtp::rtcp_dest_len, rtp::rtcp_socket, RTP_MAX_PACKET_LEN, rtp_process_ctrl(), udp_fd_isset_r(), udp_fd_set_r(), udp_fd_zero_r(), udp_recvfrom(), udp_select_r(), and UNUSED.

Referenced by audio_sender_thread(), and ultragrid_rtp_video_rxtx::send_frame_async().

Here is the call graph for this function:

◆ rtp_add_csrc()

bool rtp_add_csrc ( struct rtp * session,
uint32_t csrc )

rtp_add_csrc: @session: the session pointer (returned by rtp_init()) @csrc: Constributing SSRC identifier

Adds @csrc to list of contributing sources used in SDES items. Used by mixers and transcoders.

Return value: true.

Definition at line 2478 of file rtp.c.

2479{
2480 /* Mark csrc as something for which we should advertise RTCP SDES items, */
2481 /* in addition to our own SDES. */
2482 source *s;
2483
2484 check_database(session);
2485 s = get_source(session, csrc);
2486 if (s == NULL) {
2487 s = create_source(session, csrc, FALSE);
2488 debug_msg("Created source 0x%08x as CSRC\n", csrc);
2489 }
2490 check_source(s);
2491 if (!s->should_advertise_sdes) {
2493 session->csrc_count++;
2494 debug_msg("Added CSRC 0x%08" PRIx32 " as CSRC %d\n", csrc,
2495 session->csrc_count);
2496 }
2497 return true;
2498}
#define TRUE
#define FALSE
#define debug_msg(...)
#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, "[pid/%d +%d %s] ", getpid(), LINE,...
Definition debug.h:92
static source * create_source(struct rtp *session, uint32_t ssrc, int probation)
Definition rtp.c:660
static void check_source(source *s)
Definition rtp.c:530
static source * get_source(struct rtp *session, uint32_t ssrc)
Definition rtp.c:596
Definition rtp.c:206
int should_advertise_sdes
Definition rtp.c:222
int csrc_count
Definition rtp.c:289

References check_database(), check_source(), create_source(), rtp::csrc_count, debug_msg, FALSE, get_source(), _source::should_advertise_sdes, and TRUE.

Here is the call graph for this function:

◆ rtp_async_start()

void rtp_async_start ( struct rtp * session,
int nr_packets )

Definition at line 4027 of file rtp.c.

4028{
4029 udp_async_start(session->rtp_socket, nr_packets);
4030}
void udp_async_start(socket_udp *s, int nr_packets)
Definition net_udp.c:1530
socket_udp * rtp_socket
Definition rtp.c:275

References rtp::rtp_socket, and udp_async_start().

Referenced by tx_send_base().

Here is the call graph for this function:

◆ rtp_async_wait()

void rtp_async_wait ( struct rtp * session)

Definition at line 4032 of file rtp.c.

4033{
4034 udp_async_wait(session->rtp_socket);
4035}
void udp_async_wait(socket_udp *s)
Definition net_udp.c:1557

References rtp::rtp_socket, and udp_async_wait().

Referenced by tx_send_base().

Here is the call graph for this function:

◆ rtp_compute_fract_lost()

int rtp_compute_fract_lost ( struct rtp * session,
uint32_t ssrc )

Definition at line 3974 of file rtp.c.

3975{
3976 int h;
3977 source *s;
3978
3979 for (h = 0; h < RTP_DB_SIZE; h++) {
3980 for (s = session->db[h]; s != NULL; s = s->next) {
3981 check_source(s);
3982 if (s->ssrc == ssrc) {
3983 /* Much of this is taken from A.3 of draft-ietf-avt-rtp-new-01.txt */
3984 int extended_max = s->cycles + s->max_seq;
3985 int expected = extended_max - s->base_seq + 1;
3986 //int lost = expected - s->received;
3987 int expected_interval =
3988 expected - s->expected_prior;
3989 int received_interval =
3990 s->received - s->received_prior;
3991 int lost_interval =
3992 expected_interval - received_interval;
3993 int fraction;
3994 //uint32_t lsr;
3995 //uint32_t dlsr;
3996
3997 //printf("lost_interval %d\n", lost_interval);
3998 s->expected_prior = expected;
3999 s->received_prior = s->received;
4000 if (expected_interval == 0
4001 || lost_interval <= 0) {
4002 fraction = 0;
4003 } else {
4004 fraction =
4005 (lost_interval << 8) /
4006 expected_interval;
4007 }
4008
4009 return fraction;
4010 }
4011 }
4012 }
4013 return 0;
4014}
#define RTP_DB_SIZE
Definition rtp.c:247
uint16_t max_seq
Definition rtp.c:226
int received_prior
Definition rtp.c:230
int expected_prior
Definition rtp.c:231
uint32_t base_seq
Definition rtp.c:225
int received
Definition rtp.c:229
uint32_t ssrc
Definition rtp.c:209
uint32_t cycles
Definition rtp.c:228
struct _source * next
Definition rtp.c:207
source * db[RTP_DB_SIZE]
Definition rtp.c:282

References _source::base_seq, check_source(), _source::cycles, rtp::db, _source::expected_prior, _source::max_seq, _source::next, _source::received, _source::received_prior, RTP_DB_SIZE, and _source::ssrc.

Here is the call graph for this function:

◆ rtp_del_csrc()

bool rtp_del_csrc ( struct rtp * session,
uint32_t csrc )

rtp_del_csrc: @session: the session pointer (returned by rtp_init()) @csrc: Constributing SSRC identifier

Removes @csrc from list of contributing sources used in SDES items. Used by mixers and transcoders.

Return values
trueon success, false if @csrc is not a valid source.

Definition at line 2510 of file rtp.c.

2511{
2512 source *s;
2513
2514 check_database(session);
2515 s = get_source(session, csrc);
2516 if (s == NULL) {
2517 debug_msg("Invalid source 0x%08x\n", csrc);
2518 return false;
2519 }
2520 check_source(s);
2522 session->csrc_count--;
2523 if (session->last_advertised_csrc >= session->csrc_count) {
2524 session->last_advertised_csrc = 0;
2525 }
2526 return true;
2527}
int last_advertised_csrc
Definition rtp.c:281

References check_database(), check_source(), rtp::csrc_count, debug_msg, FALSE, get_source(), rtp::last_advertised_csrc, and _source::should_advertise_sdes.

Here is the call graph for this function:

◆ rtp_done()

void rtp_done ( struct rtp * session)

rtp_done: @session: the RTP session to finish

Free the state associated with the given RTP session. This function does not send any packets (e.g. an RTCP BYE) - an application which wishes to exit in a clean manner should call rtp_send_bye() first.

Definition at line 3676 of file rtp.c.

3677{
3678 int i;
3679 source *s, *n;
3680
3681 check_database(session);
3682 /* In delete_source, check database gets called and this assumes */
3683 /* first added and last removed is us. */
3684 for (i = 0; i < RTP_DB_SIZE; i++) {
3685 s = session->db[i];
3686 while (s != NULL) {
3687 n = s->next;
3688 if (s->ssrc != session->my_ssrc) {
3689 delete_source(session, session->db[i]->ssrc);
3690 }
3691 s = n;
3692 }
3693 }
3694
3695 delete_source(session, session->my_ssrc);
3696
3697 /*
3698 * Introduce a memory leak until we add algorithm-specific
3699 * cleanup functions.
3700 if (session->encryption_key != NULL) {
3701 free(session->encryption_key);
3702 }
3703 */
3704
3705 udp_exit(session->rtp_socket);
3706 udp_exit(session->rtcp_socket);
3707 free(session->opt);
3708 free(session);
3709}
void udp_exit(socket_udp *s)
Definition net_udp.c:974
static void delete_source(struct rtp *session, uint32_t ssrc)
Definition rtp.c:673
uint32_t my_ssrc
Definition rtp.c:280
options * opt
Definition rtp.c:284

References check_database(), rtp::db, delete_source(), rtp::my_ssrc, _source::next, rtp::opt, rtp::rtcp_socket, RTP_DB_SIZE, rtp::rtp_socket, _source::ssrc, and udp_exit().

Referenced by am_participant::~am_participant(), audio_done(), audio_receiver_process_message(), audio_sender_process_message(), rtp_video_rxtx::destroy_rtp_device(), and vidcap_rtsp_done().

Here is the call graph for this function:

◆ rtp_flush_recv_buf()

void rtp_flush_recv_buf ( struct rtp * session)

rtp_flush_recv_buf: Flushes receiver buffer contents. @session: The RTP Session.

Definition at line 3964 of file rtp.c.

3965{
3967}
void udp_flush_recv_buf(socket_udp *s)
Definition net_udp.c:1500

References rtp::rtp_socket, and udp_flush_recv_buf().

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ rtp_get_bytes_sent()

uint64_t rtp_get_bytes_sent ( struct rtp * session)

Definition at line 3969 of file rtp.c.

3970{
3971 return session->rtp_bytes_sent;
3972}
uint64_t rtp_bytes_sent
Definition rtp.c:309

References rtp::rtp_bytes_sent.

◆ rtp_get_option()

bool rtp_get_option ( struct rtp * session,
rtp_option optname,
int * optval )

rtp_get_option: @session: The RTP session. @optname: The option name, see rtp_option. @optval: The return value.

Retrieves the value of a session option. See rtp_option for documentation on the options and their legal values.

Returns
true and the value of the option in optval on success, else false.

Definition at line 1352 of file rtp.c.

1353{
1354 switch (optname) {
1356 *optval = session->opt->wait_for_rtcp;
1357 break;
1358 case RTP_OPT_PROMISC:
1359 *optval = session->opt->promiscuous_mode;
1360 break;
1362 *optval = session->opt->filter_my_packets;
1363 break;
1365 *optval = session->opt->reuse_bufs;
1366 break;
1367 default:
1368 *optval = 0;
1369 debug_msg
1370 ("Ignoring unknown option (%d) in call to rtp_get_option().\n",
1371 optname);
1372 return false;
1373 }
1374 return true;
1375}
int reuse_bufs
Definition rtp.c:257
int wait_for_rtcp
Definition rtp.c:255
int promiscuous_mode
Definition rtp.c:254
int filter_my_packets
Definition rtp.c:256

References debug_msg, options::filter_my_packets, rtp::opt, options::promiscuous_mode, options::reuse_bufs, RTP_OPT_FILTER_MY_PACKETS, RTP_OPT_PROMISC, RTP_OPT_REUSE_PACKET_BUFS, RTP_OPT_WEAK_VALIDATION, and options::wait_for_rtcp.

◆ rtp_get_recv_buf()

int rtp_get_recv_buf ( struct rtp * session)

Definition at line 3944 of file rtp.c.

3945{
3946 return udp_get_recv_buf(session->rtp_socket);
3947}
int udp_get_recv_buf(socket_udp *s)
Definition net_udp.c:1445

References rtp::rtp_socket, and udp_get_recv_buf().

Referenced by ultragrid_rtp_video_rxtx::receiver_loop().

Here is the call graph for this function:

◆ rtp_get_rr()

const rtcp_rr * rtp_get_rr ( struct rtp * session,
uint32_t reporter,
uint32_t reportee )

rtp_get_rr: @session: the session pointer (returned by rtp_init()) @reporter: participant originating receiver report @reportee: participant included in receiver report

Retrieve the latest receiver report on @reportee made by @reporter. Provides an indication of other receivers reception service.

Return value: A pointer to a rtcp_rr structure on success, NULL otherwise. The pointer must not be freed.

Definition at line 2707 of file rtp.c.

2709{
2710 check_database(session);
2711 return get_rr(session, reporter, reportee);
2712}
static const rtcp_rr * get_rr(struct rtp *session, uint32_t reporter_ssrc, uint32_t reportee_ssrc)
Definition rtp.c:512

References check_database(), and get_rr().

Referenced by process_rr().

Here is the call graph for this function:

◆ rtp_get_sdes()

const char * rtp_get_sdes ( struct rtp * session,
uint32_t ssrc,
rtcp_sdes_type type )

rtp_get_sdes: @session: the session pointer (returned by rtp_init()) @ssrc: the SSRC identifier of a participant @type: the SDES information to retrieve

Recovers session description (SDES) information on participant identified with @ssrc. The SDES information associated with a source is updated when receiver reports are received. There are several different types of SDES information, e.g. username, location, phone, email. These are enumerated by rtcp_sdes_type.

Return value: pointer to string containing SDES description if received, NULL otherwise.

Definition at line 2631 of file rtp.c.

2633{
2634 source *s;
2635
2636 check_database(session);
2637
2638 s = get_source(session, ssrc);
2639 if (s == NULL) {
2640 debug_msg("Invalid source 0x%08x\n", ssrc);
2641 return NULL;
2642 }
2643 check_source(s);
2644
2645 switch (type) {
2646 case RTCP_SDES_CNAME:
2647 return s->sdes_cname;
2648 case RTCP_SDES_NAME:
2649 return s->sdes_name;
2650 case RTCP_SDES_EMAIL:
2651 return s->sdes_email;
2652 case RTCP_SDES_PHONE:
2653 return s->sdes_phone;
2654 case RTCP_SDES_LOC:
2655 return s->sdes_loc;
2656 case RTCP_SDES_TOOL:
2657 return s->sdes_tool;
2658 case RTCP_SDES_NOTE:
2659 return s->sdes_note;
2660 case RTCP_SDES_PRIV:
2661 return s->sdes_priv;
2662 default:
2663 /* This includes RTCP_SDES_PRIV and RTCP_SDES_END */
2664 debug_msg("Unknown SDES item (type=%d)\n", type);
2665 }
2666 return NULL;
2667}
Option::OptType type
Definition settings.cpp:194
char * sdes_loc
Definition rtp.c:214
char * sdes_cname
Definition rtp.c:210
char * sdes_tool
Definition rtp.c:215
char * sdes_priv
Definition rtp.c:217
char * sdes_note
Definition rtp.c:216
char * sdes_name
Definition rtp.c:211
char * sdes_email
Definition rtp.c:212
char * sdes_phone
Definition rtp.c:213

References check_database(), check_source(), debug_msg, get_source(), RTCP_SDES_CNAME, RTCP_SDES_EMAIL, RTCP_SDES_LOC, RTCP_SDES_NAME, RTCP_SDES_NOTE, RTCP_SDES_PHONE, RTCP_SDES_PRIV, RTCP_SDES_TOOL, _source::sdes_cname, _source::sdes_email, _source::sdes_loc, _source::sdes_name, _source::sdes_note, _source::sdes_phone, _source::sdes_priv, _source::sdes_tool, and type.

Referenced by format_rtcp_sdes().

Here is the call graph for this function:

◆ rtp_get_sr()

const rtcp_sr * rtp_get_sr ( struct rtp * session,
uint32_t ssrc )

rtp_get_sr: @session: the session pointer (returned by rtp_init()) @ssrc: identifier of source

Retrieve the latest sender report made by sender with @ssrc identifier.

Return value: A pointer to an rtcp_sr structure on success, NULL otherwise. The pointer must not be freed.

Definition at line 2679 of file rtp.c.

2680{
2681 /* Return the last SR received from this ssrc. The */
2682 /* caller MUST NOT free the memory returned to it. */
2683 source *s;
2684
2685 check_database(session);
2686
2687 s = get_source(session, ssrc);
2688 if (s == NULL) {
2689 return NULL;
2690 }
2691 check_source(s);
2692 return s->sr;
2693}
rtcp_sr *_Atomic sr
Definition rtp.c:218

References check_database(), check_source(), get_source(), and _source::sr.

Here is the call graph for this function:

◆ rtp_get_udp_local_socket()

struct socket_udp_local * rtp_get_udp_local_socket ( struct rtp * session)

Definition at line 4037 of file rtp.c.

4038{
4039 return udp_get_local(session->rtp_socket);
4040}
struct socket_udp_local * udp_get_local(socket_udp *s)
Definition net_udp.c:1751

References rtp::rtp_socket, and udp_get_local().

Referenced by audio_play_mixer_ctl().

Here is the call graph for this function:

◆ rtp_get_udp_rx_port()

int rtp_get_udp_rx_port ( struct rtp * session)

Definition at line 4042 of file rtp.c.

4043{
4044 return udp_get_udp_rx_port(session->rtp_socket);
4045}
int udp_get_udp_rx_port(socket_udp *s)
Definition net_udp.c:1756

References rtp::rtp_socket, and udp_get_udp_rx_port().

Referenced by set_audio_spec_to_vrxtx(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_get_userdata()

uint8_t * rtp_get_userdata ( struct rtp * session)

rtp_get_userdata: @session: The RTP session.

This function returns the userdata pointer that was passed to the rtp_init() or rtp_init_if() function when creating this session.

Returns: pointer to userdata.

Definition at line 1386 of file rtp.c.

1387{
1388 check_database(session);
1389 return session->userdata;
1390}
uint8_t * userdata
Definition rtp.c:285

References check_database(), and rtp::userdata.

Referenced by rtp_recv_callback().

Here is the call graph for this function:

◆ rtp_has_receiver()

bool rtp_has_receiver ( struct rtp * session)

Definition at line 4016 of file rtp.c.

4017{
4018 return !session->opt->send_back ||
4020}
bool udp_is_server_mode_blackhole(socket_udp *s)
Definition net_udp.c:911
int send_back
Definition rtp.c:259

References rtp::opt, rtp::rtp_socket, options::send_back, and udp_is_server_mode_blackhole().

Referenced by audio_tx_send(), rtp_process_data(), and tx_send_base().

Here is the call graph for this function:

◆ rtp_init()

rtp_t rtp_init ( const char * addr,
uint16_t rx_port,
uint16_t tx_port,
int ttl,
double rtcp_bw,
int tfrc_on,
rtp_callback callback,
uint8_t * userdata,
int force_ip_version,
bool multithreaded )

rtp_init: @addr: IP destination of this session (unicast or multicast), as an ASCII string. May be a host name, which will be looked up, or may be an IPv4 dotted quad or IPv6 literal adddress. @rx_port: The port to which to bind the UDP socket @tx_port: The port to which to send UDP packets @ttl: The TTL for both multicast and unicast (-1 for default) @rtcp_bw: The total bandwidth (in units of bytes per second) that is allocated to RTCP. @callback: See section on rtp_callback. @userdata: Opaque data associated with the session. See rtp_get_userdata().

Returns: An opaque session identifier to be used in future calls to the RTP library functions, or NULL on failure.

Definition at line 999 of file rtp.c.

1004{
1005 return rtp_init_if(addr, NULL, rx_port, tx_port, ttl, rtcp_bw, tfrc_on,
1006 callback, userdata, force_ip_version, multithreaded);
1007}
struct rtp * rtp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, int tfrc_on, rtp_callback callback, uint8_t *userdata, int force_ip_version, bool multithreaded)
Definition rtp.c:1034
Option::Callback::fcn_type callback
Definition settings.cpp:251

References callback, rtp::rtcp_bw, rtp_init_if(), rtp::tfrc_on, and rtp::userdata.

Here is the call graph for this function:

◆ rtp_init_if()

rtp_t rtp_init_if ( const char * addr,
const char * iface,
uint16_t rx_port,
uint16_t tx_port,
int ttl,
double rtcp_bw,
int tfrc_on,
rtp_callback callback,
uint8_t * userdata,
int force_ip_version,
bool multithreaded )

rtp_init_if: @addr: IP destination of this session (unicast or multicast), as an ASCII string. May be a host name, which will be looked up, or may be an IPv4 dotted quad or IPv6 literal adddress. @iface: If the destination of the session is multicast, the optional interface to bind to. May be NULL, in which case the default multicast interface as determined by the system will be used. @rx_port: The port to which to bind the UDP socket @tx_port: The port to which to send UDP packets @ttl: The TTL for both multicast and unicast (-1 for default) @rtcp_bw: The total bandwidth (in units of ___) that is allocated to RTCP. @callback: See section on rtp_callback. @userdata: Opaque data associated with the session. See rtp_get_userdata(). @force_ip_version if IPv4 or IPv4 is requested, pass 4 or 6 respectively, otherwise 0 @multithreaded if set to true uses separate thread to receive data (performance optimization)

Creates and initializes an RTP session.

Returns: An opaque session identifier to be used in future calls to the RTP library functions, or NULL on failure.

Definition at line 1034 of file rtp.c.

1039{
1040 struct rtp *session;
1041 int i, j;
1042 char *cname;
1043 char *hname;
1044
1045#ifdef _WIN32
1046 if (multithreaded) {
1047 log_msg(LOG_LEVEL_WARNING, "Multithreaded RTP is not recommended for MSW due to internal locking within Winsock implementation.\n");
1048 }
1049#endif
1050
1051 if (force_ip_version != 0 && force_ip_version != 4 && force_ip_version != 6) {
1052 log_msg(LOG_LEVEL_ERROR, "IP version must be either 4 or 6 (or 0)\n");
1053 return NULL;
1054 }
1055 if (ttl < -1 || ttl > 255) {
1056 log_msg(LOG_LEVEL_ERROR, "ttl must be in range [0..255] or -1, %d given\n", ttl);
1057 return NULL;
1058 }
1059 if (rx_port % 2) {
1060 log_msg(LOG_LEVEL_WARNING, "RTP: rx_port should be even, using %d.\n", rx_port);
1061 }
1062 if (tx_port % 2) {
1063 log_msg(LOG_LEVEL_WARNING, "RTP: tx_port should be even, using %d.\n", tx_port);
1064 }
1065
1066 session = (struct rtp *)malloc(sizeof(struct rtp));
1067 memset(session, 0, sizeof(struct rtp));
1068
1069 session->magic = 0xfeedface;
1070 session->opt = (options *) malloc(sizeof(options));
1071 session->userdata = userdata;
1072 session->mt_recv = multithreaded;
1073 session->send_rtcp_to_origin =
1074 (tx_port == 0 && is_host_loopback(addr)) ||
1075 strcmp(addr, IN6_BLACKHOLE_SERVER_MODE_STR) == 0;
1076
1077 if (rx_port == 0) {
1078 const unsigned random_off = (ug_rand() % (IPPORT_MAX - IPPORT_DYNAMIC + 1)) & ~1U;
1079 for (unsigned i = 0; i <= (IPPORT_MAX - IPPORT_DYNAMIC) - 1; i += 2) {
1080 int port = IPPORT_DYNAMIC + ((random_off + i) % (IPPORT_MAX - IPPORT_DYNAMIC + 1));
1081 // this stuff is not atomic. but... it cannot be done in this way, either
1082 int ret = udp_port_pair_is_free(force_ip_version, port);
1083 if (ret == 0) {
1084 rx_port = port;
1085 break;
1086 }
1087 }
1088 if (rx_port == 0) {
1089 log_msg(LOG_LEVEL_ERROR, "Unable to find empty RTP port pair!\n");
1090 } else {
1091 verbose_msg("Found empty UDP port pair %d/%d\n", rx_port, rx_port + 1);
1092 }
1093 } else {
1094 MSG(VERBOSE, "Bound to ports %d/%d\n", rx_port, rx_port + 1);
1095 }
1096 if (tx_port == 0) {
1097 tx_port = rx_port;
1098 }
1099 session->rtp_socket = udp_init_if(addr, iface, rx_port, tx_port, ttl, force_ip_version, multithreaded);
1100
1101 session->rtcp_socket =
1102 udp_init_if(addr, iface, (uint16_t) (rx_port + (rx_port ? 1 : 0)),
1103 (uint16_t) (tx_port + (tx_port ? 1 : 0)), ttl, force_ip_version, false);
1104
1105 init_opt(session);
1106
1107 if (session->rtp_socket == NULL || session->rtcp_socket == NULL) {
1108 printf("Unable to open network\n");
1109 free(session);
1110 return NULL;
1111 }
1112
1113 hname = udp_host_addr(session->rtp_socket);
1114 free(hname);
1115
1116 session->my_ssrc = ug_rand();
1117 session->callback = callback;
1118 session->invalid_rtp_count = 0;
1119 session->invalid_rtcp_count = 0;
1120 session->bye_count = 0;
1121 session->csrc_count = 0;
1122 session->ssrc_count = 0;
1123 session->ssrc_count_prev = 0;
1124 session->sender_count = 0;
1125 session->initial_rtcp = TRUE;
1126 session->sending_bye = FALSE;
1127 session->avg_rtcp_size = -1; /* Sentinal value: reception of first packet starts initial value... */
1128 session->we_sent = FALSE;
1129 session->rtcp_bw = rtcp_bw;
1130 session->sdes_count_pri = 0;
1131 session->sdes_count_sec = 0;
1132 session->sdes_count_ter = 0;
1133 session->rtp_seq = (uint16_t) ug_rand();
1134 session->rtp_pcount = 0;
1135 session->mhdr = NULL;
1136 session->tfrc_on = tfrc_on;
1137 session->rtp_bcount = 0;
1138 session->rtp_bytes_sent = 0;
1139 session->last_update =
1140 session->last_rtcp_send_time =
1142 session->encryption_enabled = 0;
1143 session->encryption_algorithm = NULL;
1144
1145 /* Calculate when we're supposed to send our first RTCP packet... */
1146 session->next_rtcp_send_time += rtcp_interval(session) * NS_IN_SEC;
1147
1148 /* Initialise the source database... */
1149 for (i = 0; i < RTP_DB_SIZE; i++) {
1150 session->db[i] = NULL;
1151 }
1152 session->last_advertised_csrc = 0;
1153
1154 /* Initialize sentinels in rr table */
1155 for (i = 0; i < RTP_DB_SIZE; i++) {
1156 for (j = 0; j < RTP_DB_SIZE; j++) {
1157 session->rr[i][j].next = &session->rr[i][j];
1158 session->rr[i][j].prev = &session->rr[i][j];
1159 }
1160 }
1161
1162 /* Create a database entry for ourselves... */
1163 create_source(session, session->my_ssrc, FALSE);
1164 cname = get_cname(session->rtp_socket);
1165 rtp_set_sdes(session, session->my_ssrc, RTCP_SDES_CNAME, cname,
1166 strlen(cname));
1167 free(cname); /* cname is copied by rtp_set_sdes()... */
1168
1169 log_msg(LOG_LEVEL_DEBUG, "Created new RTP session with SSRC 0x%08x.\n",
1170 session->my_ssrc);
1171
1172 return session;
1173}
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
#define verbose_msg(...)
Definition debug.h:90
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
bool is_host_loopback(const char *hostname)
Definition net.c:174
#define IN6_BLACKHOLE_SERVER_MODE_STR
Definition net.h:52
char * udp_host_addr(socket_udp *s)
Definition net_udp.c:1367
int udp_port_pair_is_free(int force_ip_version, int even_port)
Definition net_udp.c:1608
socket_udp * udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, int force_ip_version, bool multithreaded)
Definition net_udp.c:789
static double rtcp_interval(struct rtp *session)
Definition rtp.c:832
static char * get_cname(socket_udp *s)
Definition rtp.c:907
#define IPPORT_DYNAMIC
Definition rtp.c:102
bool rtp_set_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length)
Definition rtp.c:2546
#define IPPORT_MAX
Definition rtp.c:103
static void init_opt(struct rtp *session)
Definition rtp.c:966
struct _rtcp_rr_wrapper * next
Definition rtp.c:193
struct _rtcp_rr_wrapper * prev
Definition rtp.c:194
Definition rtp.c:253
Definition rtp.c:274
int ssrc_count
Definition rtp.c:290
int tfrc_on
Definition rtp.c:310
int sender_count
Definition rtp.c:292
int sdes_count_sec
Definition rtp.c:304
bool mt_recv
Definition rtp.c:334
int invalid_rtp_count
Definition rtp.c:286
int initial_rtcp
Definition rtp.c:293
int sdes_count_pri
Definition rtp.c:303
rtcp_rr_wrapper rr[RTP_DB_SIZE][RTP_DB_SIZE]
Definition rtp.c:283
double rtcp_bw
Definition rtp.c:297
char * encryption_algorithm
Definition rtp.c:317
time_ns_t last_update
Definition rtp.c:298
bool send_rtcp_to_origin
Definition rtp.c:279
int sdes_count_ter
Definition rtp.c:305
int encryption_enabled
Definition rtp.c:318
time_ns_t last_rtcp_send_time
Definition rtp.c:300
uint32_t magic
Definition rtp.c:335
uint16_t rtp_seq
Definition rtp.c:306
int ssrc_count_prev
Definition rtp.c:291
uint32_t rtp_pcount
Definition rtp.c:307
rtp_callback callback
Definition rtp.c:332
int we_sent
Definition rtp.c:296
int invalid_rtcp_count
Definition rtp.c:287
int bye_count
Definition rtp.c:288
struct msghdr * mhdr
Definition rtp.c:333
int sending_bye
Definition rtp.c:294
time_ns_t next_rtcp_send_time
Definition rtp.c:301
double avg_rtcp_size
Definition rtp.c:295
uint32_t rtp_bcount
Definition rtp.c:308
#define NS_IN_SEC
Definition tv.h:92
static time_ns_t get_time_in_ns()
Definition tv.h:101
uint32_t ug_rand(void)
Definition random.c:88

References rtp::avg_rtcp_size, rtp::bye_count, callback, rtp::callback, create_source(), rtp::csrc_count, rtp::db, rtp::encryption_algorithm, rtp::encryption_enabled, FALSE, get_cname(), get_time_in_ns(), IN6_BLACKHOLE_SERVER_MODE_STR, init_opt(), rtp::initial_rtcp, rtp::invalid_rtcp_count, rtp::invalid_rtp_count, IPPORT_DYNAMIC, IPPORT_MAX, is_host_loopback(), rtp::last_advertised_csrc, rtp::last_rtcp_send_time, rtp::last_update, LOG_LEVEL_DEBUG, LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, log_msg(), rtp::magic, rtp::mhdr, MSG, rtp::mt_recv, rtp::my_ssrc, _rtcp_rr_wrapper::next, rtp::next_rtcp_send_time, NS_IN_SEC, rtp::opt, _rtcp_rr_wrapper::prev, rtp::rr, rtp::rtcp_bw, rtcp_interval(), RTCP_SDES_CNAME, rtp::rtcp_socket, rtp::rtp_bcount, rtp::rtp_bytes_sent, RTP_DB_SIZE, rtp::rtp_pcount, rtp::rtp_seq, rtp_set_sdes(), rtp::rtp_socket, rtp::sdes_count_pri, rtp::sdes_count_sec, rtp::sdes_count_ter, rtp::send_rtcp_to_origin, rtp::sender_count, rtp::sending_bye, rtp::ssrc_count, rtp::ssrc_count_prev, rtp::tfrc_on, TRUE, udp_host_addr(), udp_init_if(), udp_port_pair_is_free(), ug_rand(), rtp::userdata, verbose_msg, and rtp::we_sent.

Referenced by initialize_audio_network(), rtp_video_rxtx::initialize_network(), rtp_init(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_init_with_udp_socket()

rtp_t rtp_init_with_udp_socket ( struct socket_udp_local * l,
struct sockaddr * sa,
socklen_t len,
rtp_callback callback )

Definition at line 1175 of file rtp.c.

1176{
1177 struct rtp *session;
1178 int i, j;
1179 char *cname;
1180 char *hname;
1181 int ttl = 127; /* FIXME */
1182 int tfrc_on = FALSE; /* FIXME */
1183
1184 session = (struct rtp *)malloc(sizeof(struct rtp));
1185 memset(session, 0, sizeof(struct rtp));
1186
1187 session->magic = 0xfeedface;
1188 session->opt = (options *) malloc(sizeof(options));
1189 // socket is not designated to receiving
1190 session->userdata = 0;
1191 session->mt_recv = false;
1192 session->send_rtcp_to_origin = true;
1193
1194 session->rtp_socket = udp_init_with_local(l, sa, len);
1195 session->rtcp_socket = udp_init_if("localhost", NULL, 0, 0, ttl, 6, false);
1196
1197 init_opt(session);
1198
1199 if (session->rtp_socket == NULL || session->rtcp_socket == NULL) {
1200 printf("Unable to open network\n");
1201 free(session);
1202 return NULL;
1203 }
1204
1205 hname = udp_host_addr(session->rtp_socket);
1206 free(hname);
1207
1208 session->my_ssrc = ug_rand();
1209 session->callback = callback;
1210 session->invalid_rtp_count = 0;
1211 session->invalid_rtcp_count = 0;
1212 session->bye_count = 0;
1213 session->csrc_count = 0;
1214 session->ssrc_count = 0;
1215 session->ssrc_count_prev = 0;
1216 session->sender_count = 0;
1217 session->initial_rtcp = TRUE;
1218 session->sending_bye = FALSE;
1219 session->avg_rtcp_size = -1; /* Sentinal value: reception of first packet starts initial value... */
1220 session->we_sent = FALSE;
1221 session->rtcp_bw = 5 * 1024 * 1024; /* FIXME */
1222 session->sdes_count_pri = 0;
1223 session->sdes_count_sec = 0;
1224 session->sdes_count_ter = 0;
1225 session->rtp_seq = (uint16_t) ug_rand();
1226 session->rtp_pcount = 0;
1227 session->mhdr = NULL;
1228 session->tfrc_on = tfrc_on;
1229 session->rtp_bcount = 0;
1230 session->rtp_bytes_sent = 0;
1231 session->last_update =
1232 session->last_rtcp_send_time =
1234 session->encryption_enabled = 0;
1235 session->encryption_algorithm = NULL;
1236
1237 /* Calculate when we're supposed to send our first RTCP packet... */
1238 session->next_rtcp_send_time += NS_IN_SEC * rtcp_interval(session);
1239
1240 /* Initialise the source database... */
1241 for (i = 0; i < RTP_DB_SIZE; i++) {
1242 session->db[i] = NULL;
1243 }
1244 session->last_advertised_csrc = 0;
1245
1246 /* Initialize sentinels in rr table */
1247 for (i = 0; i < RTP_DB_SIZE; i++) {
1248 for (j = 0; j < RTP_DB_SIZE; j++) {
1249 session->rr[i][j].next = &session->rr[i][j];
1250 session->rr[i][j].prev = &session->rr[i][j];
1251 }
1252 }
1253
1254 /* Create a database entry for ourselves... */
1255 create_source(session, session->my_ssrc, FALSE);
1256 cname = get_cname(session->rtp_socket);
1257 rtp_set_sdes(session, session->my_ssrc, RTCP_SDES_CNAME, cname,
1258 strlen(cname));
1259 free(cname); /* cname is copied by rtp_set_sdes()... */
1260
1261 log_msg(LOG_LEVEL_DEBUG, "Created new RTP session with SSRC 0x%08x.\n",
1262 session->my_ssrc);
1263
1264 return session;
1265}
int void size_t * len
socket_udp * udp_init_with_local(struct socket_udp_local *l, struct sockaddr *sa, socklen_t len)
Definition net_udp.c:927

References rtp::avg_rtcp_size, rtp::bye_count, callback, rtp::callback, create_source(), rtp::csrc_count, rtp::db, rtp::encryption_algorithm, rtp::encryption_enabled, FALSE, get_cname(), get_time_in_ns(), init_opt(), rtp::initial_rtcp, rtp::invalid_rtcp_count, rtp::invalid_rtp_count, rtp::last_advertised_csrc, rtp::last_rtcp_send_time, rtp::last_update, len, LOG_LEVEL_DEBUG, log_msg(), rtp::magic, rtp::mhdr, rtp::mt_recv, rtp::my_ssrc, _rtcp_rr_wrapper::next, rtp::next_rtcp_send_time, NS_IN_SEC, rtp::opt, _rtcp_rr_wrapper::prev, rtp::rr, rtp::rtcp_bw, rtcp_interval(), RTCP_SDES_CNAME, rtp::rtcp_socket, rtp::rtp_bcount, rtp::rtp_bytes_sent, RTP_DB_SIZE, rtp::rtp_pcount, rtp::rtp_seq, rtp_set_sdes(), rtp::rtp_socket, rtp::sdes_count_pri, rtp::sdes_count_sec, rtp::sdes_count_ter, rtp::send_rtcp_to_origin, rtp::sender_count, rtp::sending_bye, rtp::ssrc_count, rtp::ssrc_count_prev, rtp::tfrc_on, TRUE, udp_host_addr(), udp_init_if(), udp_init_with_local(), ug_rand(), rtp::userdata, and rtp::we_sent.

Referenced by am_participant::am_participant().

Here is the call graph for this function:

◆ rtp_is_ipv6()

bool rtp_is_ipv6 ( struct rtp * session)

Definition at line 4022 of file rtp.c.

4023{
4024 return udp_is_ipv6(session->rtp_socket);
4025}
bool udp_is_ipv6(socket_udp *s)
Definition net_udp.c:1598

References rtp::rtp_socket, and udp_is_ipv6().

Referenced by audio_tx_send_chan(), h264_sdp_video_rxtx::sdp_add_video(), set_audio_spec_to_vrxtx(), tx_send_base(), and tx_send_jpeg().

Here is the call graph for this function:

◆ rtp_my_ssrc()

uint32_t rtp_my_ssrc ( struct rtp * session)

rtp_my_ssrc: @session: The RTP Session.

Returns: The SSRC we are currently using in this session. Note that our SSRC can change at any time (due to collisions) so applications must not store the value returned, but rather should call this function each time they need it.

Definition at line 1401 of file rtp.c.

1402{
1403 check_database(session);
1404 return session->my_ssrc;
1405}

References check_database(), and rtp::my_ssrc.

Referenced by audio_sender_process_message(), filter_event(), format_rtcp_sr(), ultragrid_rtp_video_rxtx::get_ssrc(), initialize_audio_network(), rtp_video_rxtx::initialize_network(), process_rr(), rtp_video_rxtx::process_sender_message(), report_stats(), rtp_process_ctrl(), rtp_update(), send_rtcp(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_recv()

bool rtp_recv ( struct rtp * session,
struct timeval * timeout,
uint32_t curr_rtp_ts )

rtp_recv: @session: the session pointer (returned by rtp_init()) @timeout: the amount of time that rtcp_recv() is allowed to block @curr_rtp_ts: the current time expressed in units of the media timestamp.

Receive RTP packets and dispatch them.

Return values
trueif data received, false if the timeout occurred.
Deprecated
Use thread-safe rtp_recv_r() instead.

Definition at line 2297 of file rtp.c.

2298{
2299 check_database(session);
2300 udp_fd_zero();
2301 udp_fd_set(session->rtp_socket);
2302 udp_fd_set(session->rtcp_socket);
2303 if (udp_select(timeout) > 0) {
2304 if (udp_fd_isset(session->rtp_socket)) {
2305 rtp_recv_data(session, curr_rtp_ts);
2306 }
2307 if (udp_fd_isset(session->rtcp_socket)) {
2308 uint8_t buffer[RTP_MAX_PACKET_LEN];
2309 int buflen;
2310 buflen =
2311 udp_recv(session->rtcp_socket, (char *)buffer,
2313 rtp_process_ctrl(session, buffer, buflen);
2314 }
2315 check_database(session);
2316 return true;
2317 }
2318 check_database(session);
2319 return false;
2320}
int udp_recv(socket_udp *s, char *buffer, int buflen)
Definition net_udp.c:1236
void udp_fd_set(socket_udp *s)
Definition net_udp.c:1304
int udp_fd_isset(socket_udp *s)
Definition net_udp.c:1331
void udp_fd_zero(void)
Definition net_udp.c:955
int udp_select(struct timeval *timeout)
Definition net_udp.c:1350
static int rtp_recv_data(struct rtp *session, uint32_t curr_rtp_ts)
Definition rtp.c:1523

References check_database(), rtp::rtcp_socket, RTP_MAX_PACKET_LEN, rtp_process_ctrl(), rtp_recv_data(), rtp::rtp_socket, udp_fd_isset(), udp_fd_set(), udp_fd_zero(), udp_recv(), and udp_select().

Here is the call graph for this function:

◆ rtp_recv_poll_r()

int rtp_recv_poll_r ( struct rtp ** sessions,
struct timeval * timeout,
uint32_t curr_rtp_ts )

rtp_recv_poll_r: The meaning is as above with except that this function polls for first nonempty stream and returns data.

Parameters
sessionsnull-terminated list of rtp sessions.
timeouttimeout
cur_rtp_tslist null-terminated of timestamps for each session
Returns
received bytes

Definition at line 2434 of file rtp.c.

2435{
2436 struct rtp **current;
2437 struct udp_fd_r fd;
2438
2439 udp_fd_zero_r(&fd);
2440
2441 for(current = sessions; *current != NULL; ++current) {
2442 check_database(*current);
2443 udp_fd_set_r((*current)->rtp_socket, &fd);
2444 udp_fd_set_r((*current)->rtcp_socket, &fd);
2445 }
2446 if (udp_select_r(timeout, &fd) > 0) {
2447 int received_bytes = 0;
2448 for(current = sessions; *current != NULL; ++current) {
2449 if (udp_fd_isset_r((*current)->rtp_socket, &fd)) {
2450 received_bytes = rtp_recv_data(*current, curr_rtp_ts);
2451 }
2452 if (udp_fd_isset_r((*current)->rtcp_socket, &fd)) {
2453 uint8_t buffer[RTP_MAX_PACKET_LEN];
2454 int buflen;
2455 buflen =
2456 udp_recv((*current)->rtcp_socket, (char *)buffer,
2458 rtp_process_ctrl(*current, buffer, buflen);
2459 }
2460 check_database(*current);
2461 }
2462 return received_bytes;
2463 }
2464 //check_database(session);
2465 return 0;
2466}

References check_database(), RTP_MAX_PACKET_LEN, rtp_process_ctrl(), rtp_recv_data(), udp_fd_isset_r(), udp_fd_set_r(), udp_fd_zero_r(), udp_recv(), and udp_select_r().

Here is the call graph for this function:

◆ rtp_recv_r()

bool rtp_recv_r ( struct rtp * session,
struct timeval * timeout,
uint32_t curr_rtp_ts )

Receive RTP packets and dispatch them.

Reentrant variant of rtp_recv()

Currently, this function is the only one of rtp_recv family eligible for multithreaded receiving.

Parameters
sessionthe session pointer (returned by rtp_init())
timeoutthe amount of time that rtcp_recv() is allowed to block
curr_rtp_tsthe current time expressed in units of the media timestamp.
Return values
trueif data received
falseif the timeout occurred

Definition at line 2338 of file rtp.c.

2339{
2340 struct udp_fd_r fd;
2341
2342 check_database(session);
2343 if (session->mt_recv) {
2344 bool ret = false;
2345 if (udp_not_empty(session->rtp_socket, timeout)) {
2346 rtp_recv_data(session, curr_rtp_ts);
2347 ret = true;
2348 }
2349 udp_fd_zero_r(&fd);
2350 udp_fd_set_r(session->rtcp_socket, &fd);
2351 struct timeval no_wait_tv = { .tv_sec = 0, .tv_usec = 0 };
2352
2353 if (udp_select_r(&no_wait_tv, &fd) > 0) {
2354 uint8_t buffer[RTP_MAX_PACKET_LEN];
2355 int buflen;
2356 session->rtcp_dest_len = sizeof(session->rtcp_dest);
2357 buflen =
2358 udp_recvfrom(session->rtcp_socket, (char *)buffer,
2360 (struct sockaddr *) &session->rtcp_dest, &session->rtcp_dest_len);
2361 rtp_process_ctrl(session, buffer, buflen);
2362 ret = true;
2363 }
2364 return ret; // NOLINTNEXTLINE(readability-else-after-return)
2365 } else {
2366 udp_fd_zero_r(&fd);
2367 udp_fd_set_r(session->rtp_socket, &fd);
2368 udp_fd_set_r(session->rtcp_socket, &fd);
2369 if (udp_select_r(timeout, &fd) > 0) {
2370 if (udp_fd_isset_r(session->rtp_socket, &fd)) {
2371 rtp_recv_data(session, curr_rtp_ts);
2372 }
2373 if (udp_fd_isset_r(session->rtcp_socket, &fd)) {
2374 uint8_t buffer[RTP_MAX_PACKET_LEN];
2375 int buflen;
2376 session->rtcp_dest_len = sizeof(session->rtcp_dest);
2377 buflen =
2378 udp_recvfrom(session->rtcp_socket, (char *)buffer,
2380 (struct sockaddr *) &session->rtcp_dest, &session->rtcp_dest_len);
2381 rtp_process_ctrl(session, buffer, buflen);
2382 }
2383 check_database(session);
2384 return true;
2385 }
2386 }
2387 check_database(session);
2388 return false;
2389}
bool udp_not_empty(socket_udp *s, struct timeval *timeout)
Checks whether there are data ready to read in socket.
Definition net_udp.c:1197

References check_database(), rtp::mt_recv, rtp::rtcp_dest, rtp::rtcp_dest_len, rtp::rtcp_socket, RTP_MAX_PACKET_LEN, rtp_process_ctrl(), rtp_recv_data(), rtp::rtp_socket, udp_fd_isset_r(), udp_fd_set_r(), udp_fd_zero_r(), udp_not_empty(), udp_recvfrom(), and udp_select_r().

Referenced by audio_receiver_thread(), ultragrid_rtp_video_rxtx::receiver_loop(), h264_rtp_video_rxtx::send_frame(), h264_sdp_video_rxtx::send_frame(), and vidcap_rtsp_thread().

Here is the call graph for this function:

◆ rtp_send_bye()

void rtp_send_bye ( struct rtp * session)

rtp_send_bye: @session: The RTP session

Sends a BYE message on the RTP session, indicating that this participant is leaving the session. The process of sending a BYE may take some time, and this function will block until it is complete. During this time, RTCP events are reported to the application via the callback function (data packets are silently discarded).

Definition at line 3598 of file rtp.c.

3599{
3600 uint8_t buffer[RTP_MAX_PACKET_LEN];
3601 int buflen;
3602 double new_interval;
3603
3604 check_database(session);
3605
3606 /* "...a participant which never sent an RTP or RTCP packet MUST NOT send */
3607 /* a BYE packet when they leave the group." (section 6.3.7 of RTP spec) */
3608 if ((session->we_sent == FALSE) && (session->initial_rtcp == TRUE)) {
3609 debug_msg("Silent BYE\n");
3610 return;
3611 }
3612
3613 /* If the session is small, send an immediate BYE. Otherwise, we delay and */
3614 /* perform BYE reconsideration as needed. */
3615 if (session->ssrc_count < 50) {
3616 rtp_send_bye_now(session);
3617 } else {
3618 time_ns_t curr_time = get_time_in_ns();
3619 session->sending_bye = TRUE;
3620 session->last_rtcp_send_time =
3621 session->next_rtcp_send_time = curr_time;
3622 session->bye_count = 1;
3623 session->initial_rtcp = TRUE;
3624 session->we_sent = FALSE;
3625 session->sender_count = 0;
3626 session->avg_rtcp_size = 70.0 + RTP_LOWER_LAYER_OVERHEAD; /* FIXME */
3627 session->next_rtcp_send_time += (rtcp_interval(session) / (session->csrc_count + 1)) * NS_IN_SEC;
3628
3629 debug_msg("Preparing to send BYE...\n");
3630 while (1) {
3631 /* Schedule us to block in udp_select() until the time we are due to send our */
3632 /* BYE packet. If we receive an RTCP packet from another participant before */
3633 /* then, we are woken up to handle it... */
3634 long long us = (session->next_rtcp_send_time - curr_time) / NS_IN_US;
3635 lldiv_t d = lldiv(us, US_IN_SEC);
3636 struct timeval timeout = { .tv_sec = d.quot, .tv_usec = d.rem };
3637 udp_fd_zero();
3638 udp_fd_set(session->rtcp_socket);
3639 if ((udp_select(&timeout) > 0)
3640 && udp_fd_isset(session->rtcp_socket)) {
3641 /* We woke up because an RTCP packet was received; process it... */
3642 buflen =
3643 udp_recv(session->rtcp_socket,
3644 (char *)buffer,
3646 rtp_process_ctrl(session, buffer, buflen);
3647 }
3648 /* Is it time to send our BYE? */
3649 time_ns_t curr_time = get_time_in_ns();
3650 new_interval =
3651 rtcp_interval(session) / (session->csrc_count + 1);
3652 time_ns_t new_send_time = session->last_rtcp_send_time + new_interval * NS_IN_SEC;
3653 if (curr_time > new_send_time) {
3654 debug_msg("Sent BYE...\n");
3655 rtp_send_bye_now(session);
3656 break;
3657 }
3658 /* No, we reconsider... */
3659 session->next_rtcp_send_time = new_send_time;
3660 debug_msg("Reconsidered sending BYE... delay = %f\n",
3661 (session->next_rtcp_send_time - curr_time) / (double) NS_IN_SEC);
3662 /* ...and perform housekeeping in the usual manner */
3663 rtp_update(session, curr_time);
3664 }
3665 }
3666}
#define RTP_LOWER_LAYER_OVERHEAD
Definition rtp.c:136
void rtp_update(struct rtp *session, time_ns_t curr_time)
Definition rtp.c:3456
static void rtp_send_bye_now(struct rtp *session)
Definition rtp.c:3525
long long time_ns_t
Definition tv.h:81
#define US_IN_SEC
Definition tv.h:89
#define NS_IN_US
Definition tv.h:94

References rtp::avg_rtcp_size, rtp::bye_count, check_database(), rtp::csrc_count, debug_msg, FALSE, get_time_in_ns(), rtp::initial_rtcp, rtp::last_rtcp_send_time, rtp::next_rtcp_send_time, NS_IN_SEC, NS_IN_US, rtcp_interval(), rtp::rtcp_socket, RTP_LOWER_LAYER_OVERHEAD, RTP_MAX_PACKET_LEN, rtp_process_ctrl(), rtp_send_bye_now(), rtp_update(), rtp::sender_count, rtp::sending_bye, rtp::ssrc_count, TRUE, udp_fd_isset(), udp_fd_set(), udp_fd_zero(), udp_recv(), udp_select(), US_IN_SEC, and rtp::we_sent.

Here is the call graph for this function:

◆ rtp_send_ctrl()

void rtp_send_ctrl ( struct rtp * session,
uint32_t rtp_ts,
rtcp_app_callback appcallback,
time_ns_t curr_time )

rtp_send_ctrl: @session: the session pointer (returned by rtp_init()) @rtp_ts: the current time expressed in units of the media timestamp. @appcallback: a callback to create an APP RTCP packet, if needed.

Checks RTCP timer and sends RTCP data when nececessary. The interval between RTCP packets is randomized over an interval that depends on the session bandwidth, the number of participants, and whether the local participant is a sender. This function should be called at least once per second, and can be safely called more frequently.

Definition at line 3409 of file rtp.c.

3411{
3412 /* Send an RTCP packet, if one is due... */
3413
3414 check_database(session);
3415 if (curr_time > session->next_rtcp_send_time) {
3416 /* The RTCP transmission timer has expired. The following */
3417 /* implements draft-ietf-avt-rtp-new-02.txt section 6.3.6 */
3418 int h;
3419 source *s;
3420 double new_interval =
3421 rtcp_interval(session) / (session->csrc_count + 1);
3422 time_ns_t new_send_time = session->last_rtcp_send_time + new_interval * NS_IN_SEC;
3423 if (curr_time > new_send_time) {
3424 send_rtcp(session, rtp_ts, appcallback);
3425 session->initial_rtcp = FALSE;
3426 session->last_rtcp_send_time = curr_time;
3427 session->next_rtcp_send_time = curr_time + (rtcp_interval(session) / (session->csrc_count +
3428 1)) * NS_IN_SEC;
3429 /* We're starting a new RTCP reporting interval, zero out */
3430 /* the per-interval statistics. */
3431 session->sender_count = 0;
3432 for (h = 0; h < RTP_DB_SIZE; h++) {
3433 for (s = session->db[h]; s != NULL; s = s->next) {
3434 check_source(s);
3435 s->sender = FALSE;
3436 }
3437 }
3438 } else {
3439 session->next_rtcp_send_time = new_send_time;
3440 }
3441 session->ssrc_count_prev = session->ssrc_count;
3442 }
3443 check_database(session);
3444}
static void send_rtcp(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback)
Definition rtp.c:3284
int sender
Definition rtp.c:223

References check_database(), check_source(), rtp::csrc_count, rtp::db, FALSE, rtp::initial_rtcp, rtp::last_rtcp_send_time, _source::next, rtp::next_rtcp_send_time, NS_IN_SEC, rtcp_interval(), RTP_DB_SIZE, send_rtcp(), _source::sender, rtp::sender_count, rtp::ssrc_count, and rtp::ssrc_count_prev.

Referenced by audio_receiver_thread(), audio_sender_thread(), audio_tx_send_standard(), ultragrid_rtp_video_rxtx::receiver_loop(), h264_rtp_video_rxtx::send_frame(), h264_sdp_video_rxtx::send_frame(), and ultragrid_rtp_video_rxtx::send_frame_async().

Here is the call graph for this function:

◆ rtp_send_data()

int rtp_send_data ( struct rtp * session,
uint32_t rtp_ts,
char pt,
int m,
int cc,
const uint32_t * csrc,
char * data,
int data_len,
char * extn,
uint16_t extn_len,
uint16_t extn_type )

rtp_send_data: @session: the session pointer (returned by rtp_init()) @rtp_ts: The timestamp reflects the sampling instant of the first octet of the RTP data to be sent. The timestamp is expressed in media units. @pt: The payload type identifying the format of the data. @m: Marker bit, interpretation defined by media profile of payload. @cc: Number of contributing sources (excluding local participant) @csrc: Array of SSRC identifiers for contributing sources. @data: The RTP data to be sent. @data_len: The size @data in bytes. @extn: Extension data (if present). @extn_len: size of @extn in bytes. @extn_type: extension type indicator.

Send an RTP packet. Most media applications will only set the @session, @rtp_ts, @pt, @m, @data, @data_len arguments.

Mixers and translators typically set additional contributing sources arguments (@cc, @csrc).

Extensions fields (@extn, @extn_len, @extn_type) are for including application specific information. When the widest amount of inter-operability is required these fields should be avoided as some applications discard packets with extensions they do not recognize.

Return value: Number of bytes transmitted.

Definition at line 2742 of file rtp.c.

2746{
2747 return rtp_send_data_hdr(session, rtp_ts, pt, m, cc, csrc, NULL, 0,
2748 data, data_len, extn, extn_len, extn_type);
2749}
int rtp_send_data_hdr(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, const uint32_t *csrc, char *phdr, int phdr_len, char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type)
Definition rtp.c:2752

References rtp_send_data_hdr().

Referenced by audio_tx_send_standard(), and tx_send_h264().

Here is the call graph for this function:

◆ rtp_send_data_hdr()

int rtp_send_data_hdr ( struct rtp * session,
uint32_t rtp_ts,
char pt,
int m,
int cc,
const uint32_t * csrc,
char * phdr,
int phdr_len,
char * data,
int data_len,
char * extn,
uint16_t extn_len,
uint16_t extn_type )

Definition at line 2752 of file rtp.c.

2758{
2759 int vlen, buffer_len, i, rc, pad, pad_len __attribute__((unused));
2760 uint8_t *buffer = NULL;
2761 rtp_packet *packet = NULL;
2762 uint8_t initVec[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
2763#ifdef _WIN32
2764 WSABUF *send_vector = NULL;
2765#else
2766 struct iovec send_vector[3];
2767#endif
2768 int send_vector_len;
2769
2770 void *d; // to be freed after packet is sent
2771
2772 check_database(session);
2773
2774 assert((data == NULL && data_len == 0)
2775 || (data != NULL && data_len > 0));
2776
2777 vlen = 12;
2778 if (session->tfrc_on) {
2779 vlen += 4;
2780 if (session->new_rtt)
2781 vlen += 4;
2782 }
2783 buffer_len = vlen + (4 * cc);
2784
2785 if (extn != NULL) {
2786 buffer_len += (extn_len + 1) * 4;
2787 }
2788
2789 /* Do we need to pad this packet to a multiple of 64 bits? */
2790 /* This is only needed if encryption is enabled, since DES */
2791 /* only works on multiples of 64 bits. We just calculate */
2792 /* the amount of padding to add here, so we can reserve */
2793 /* space - the actual padding is added later. */
2794#ifdef NDEF
2795 /* FIXME: This is broken, due to scatter send [csp] *//* FIXME */
2796 if ((session->encryption_enabled) &&
2797 ((buffer_len % session->encryption_pad_length) != 0)) {
2798 pad = TRUE;
2799 pad_len =
2800 session->encryption_pad_length -
2801 (buffer_len % session->encryption_pad_length);
2802 buffer_len += pad_len;
2803 assert((buffer_len % session->encryption_pad_length) == 0);
2804 } else {
2805 pad = FALSE;
2806 pad_len = 0;
2807 }
2808#endif
2809 pad = FALSE; /* FIXME */
2810 pad_len = 0;
2811
2812 /* Allocate memory for the packet... */
2813 assert(buffer_len < RTP_MAX_PACKET_LEN);
2814 /* we dont always need 20 (12|16) but this seems to work. LG */
2815#ifdef _WIN32
2816 d = (uint8_t *) malloc(3 * sizeof(WSABUF) + 20 + RTP_PACKET_HEADER_SIZE);
2817 send_vector = d;
2818 buffer = (uint8_t *) d + 3 * sizeof(WSABUF);
2819#else
2820 d = buffer = (uint8_t *) malloc(20 + RTP_PACKET_HEADER_SIZE);
2821#endif
2822 packet = (rtp_packet *)(void *) buffer;
2823
2824#ifdef _WIN32
2825 send_vector[0].buf = (char *) (buffer + RTP_PACKET_HEADER_SIZE);
2826 send_vector[0].len = buffer_len;
2827#else
2828 send_vector[0].iov_base = buffer + RTP_PACKET_HEADER_SIZE;
2829 send_vector[0].iov_len = buffer_len;
2830#endif
2831 send_vector_len = 1;
2832
2833 /* These are internal pointers into the buffer... */
2834#ifdef NDEF
2835 packet->csrc = (uint32_t *) (buffer + RTP_PACKET_HEADER_SIZE + vlen);
2836 packet->extn =
2837 (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + vlen + (4 * cc));
2838 packet->data =
2839 (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + vlen + (4 * cc));
2840 if (extn != NULL) {
2841 packet->data += (extn_len + 1) * 4;
2842 }
2843#endif
2844 /* ...and the actual packet header... */
2845 packet->v = 2;
2846 packet->p = pad;
2847 packet->x = (extn != NULL);
2848 packet->cc = cc;
2849 packet->m = m;
2850 packet->pt = pt;
2851 packet->seq = htons(session->rtp_seq++);
2852 packet->ts = htonl(rtp_ts);
2853 packet->ssrc = htonl(session->my_ssrc);
2854
2855 /* ... do tfrc stuff... */
2856 if (session->tfrc_on) {
2857 packet->send_ts = htonl(get_local_mediatime());
2858 if (session->new_rtt) {
2859 packet->rtt = htonl(session->cmp_rtt);
2860 /* hopefully this will set the 7th bit */
2861 packet->pt = packet->pt | 64;
2862 } else
2863 packet->pt = packet->pt & 63; /* this should clear the 7th bit */
2864 }
2865
2866 /* ...now the CSRC list... */
2867 for (i = 0; i < cc; i++) {
2868 packet->csrc[i] = htonl(csrc[i]);
2869 }
2870 /* ...a header extension? */
2871 if (extn != NULL) {
2872 /* We don't use the packet->extn_type field here, that's for receive only... */
2873 uint16_t *base = (uint16_t *)(void *) packet->extn;
2874 base[0] = htons(extn_type);
2875 base[1] = htons(extn_len);
2876 memcpy(packet->extn + 4, extn, extn_len * 4);
2877 }
2878 /* ...the payload header... */
2879 if (phdr != NULL) {
2880#ifdef _WIN32
2881 send_vector[send_vector_len].buf = phdr;
2882 send_vector[send_vector_len].len = phdr_len;
2883#else
2884 send_vector[send_vector_len].iov_base = phdr;
2885 send_vector[send_vector_len].iov_len = phdr_len;
2886#endif
2887 send_vector_len++;
2888 }
2889 /* ...and the media data... */
2890 if (data_len > 0) {
2891#ifdef _WIN32
2892 send_vector[send_vector_len].buf = (void *) data;
2893 send_vector[send_vector_len].len = data_len;
2894#else
2895 send_vector[send_vector_len].iov_base = (void *) data;
2896 send_vector[send_vector_len].iov_len = data_len;
2897#endif
2898 send_vector_len++;
2899 }
2900#ifdef NDEF /* FIXME */
2901 /* ...and any padding... */
2902 if (pad) {
2903 for (i = 0; i < pad_len; i++) {
2904 buffer[buffer_len + RTP_PACKET_HEADER_SIZE - pad_len +
2905 i] = 0;
2906 }
2907 buffer[buffer_len + RTP_PACKET_HEADER_SIZE - 1] = (char)pad_len;
2908 }
2909#endif
2910
2911 /* Finally, encrypt if desired... */
2912 if (session->encryption_enabled) {
2913 assert((buffer_len % session->encryption_pad_length) == 0);
2914 (session->encrypt_func) (session,
2915 buffer + RTP_PACKET_HEADER_SIZE,
2916 buffer_len, initVec);
2917 }
2918
2919 rc = udp_sendv(session->rtp_socket, send_vector, send_vector_len, d);
2920 if (rc == -1) {
2921 log_msg(LOG_LEVEL_WARNING, "sending RTP packet: %s", ug_strerror(errno));
2922 }
2923
2924 /* Update the RTCP statistics... */
2925 session->we_sent = TRUE;
2926 session->rtp_pcount += 1;
2927 session->rtp_bcount += buffer_len;
2928 session->rtp_bytes_sent += buffer_len + data_len;
2930
2931 check_database(session);
2932 return rc;
2933}
const char * ug_strerror(int errnum)
Definition misc.cpp:203
int udp_sendv(socket_udp *s, struct iovec *vector, int count, void *d)
Definition net_udp.c:1067
struct __attribute__((packed))
Definition rtp.h:88
#define RTP_PACKET_HEADER_SIZE
Definition rtp.h:128
rtp_encrypt_func encrypt_func
Definition rtp.c:319
time_ns_t last_rtp_send_time
Definition rtp.c:299
int encryption_pad_length
Definition rtp.c:321
uint16_t new_rtt
Definition rtp.c:313
uint32_t cmp_rtt
Definition rtp.c:312
uint32_t get_local_mediatime(void)
Definition tv.c:65

References __attribute__(), check_database(), rtp::cmp_rtt, rtp::encrypt_func, rtp::encryption_enabled, rtp::encryption_pad_length, FALSE, get_local_mediatime(), get_time_in_ns(), rtp::last_rtp_send_time, LOG_LEVEL_WARNING, log_msg(), rtp::my_ssrc, rtp::new_rtt, rtp::rtp_bcount, rtp::rtp_bytes_sent, RTP_MAX_PACKET_LEN, rtp_packet, RTP_PACKET_HEADER_SIZE, rtp::rtp_pcount, rtp::rtp_seq, rtp::rtp_socket, rtp::tfrc_on, TRUE, udp_sendv(), ug_strerror(), and rtp::we_sent.

Referenced by audio_tx_send_chan(), rtp_send_data(), tx_send_base(), tx_send_h264(), and tx_send_jpeg().

Here is the call graph for this function:

◆ rtp_send_raw_rtp_data()

int rtp_send_raw_rtp_data ( struct rtp * session,
char * buffer,
int buffer_len )

Definition at line 1518 of file rtp.c.

1519{
1520 return udp_send(session->rtp_socket, buffer, buffer_len);
1521}
int udp_send(socket_udp *s, char *buffer, int buflen)
Definition net_udp.c:1028

References rtp::rtp_socket, and udp_send().

Here is the call graph for this function:

◆ rtp_set_encryption_key()

bool rtp_set_encryption_key ( struct rtp * session,
const char * passphrase )

rtp_set_encryption_key: @session: The RTP session. @passphrase: The user-provided "pass phrase" to map to an encryption key.

Converts the user supplied key into a form suitable for use with RTP and install it as the active key. Passing in NULL as the passphrase disables encryption. The passphrase is converted into a DES key as specified in RFC1890, that is:

  • convert to canonical form
  • derive an MD5 hash of the canonical form
  • take the first 56 bits of the MD5 hash
  • add parity bits to form a 64 bit key

Note that versions of rat prior to 4.1.2 do not convert the passphrase to canonical form before taking the MD5 hash, and so will not be compatible for keys which are non-invarient under this step.

Determine from the user's encryption key which encryption mechanism we're using. Per the RTP RFC, if the key is of the form

 string/key

then "string" is the name of the encryption algorithm, and "key" is the key to be used. If no / is present, then the algorithm is assumed to be (the appropriate variant of) DES.

Definition at line 3742 of file rtp.c.

3743{
3744 char *canonical_passphrase;
3745 u_char hash[16];
3746 MD5CTX context;
3747 char *slash;
3748
3749 check_database(session);
3750 if (session->encryption_algorithm != NULL) {
3751 free(session->encryption_algorithm);
3752 session->encryption_algorithm = NULL;
3753 }
3754
3755 if (passphrase == NULL) {
3756 /* A NULL passphrase means disable encryption... */
3757 session->encryption_enabled = 0;
3758 check_database(session);
3759 return true;
3760 }
3761
3762 debug_msg("Enabling RTP/RTCP encryption\n");
3763 session->encryption_enabled = 1;
3764
3765 /*
3766 * Determine which algorithm we're using.
3767 */
3768
3769 slash = strchr(passphrase, '/');
3770 if (slash == 0) {
3771 session->encryption_algorithm = strdup("DES");
3772 } else {
3773 int l = slash - passphrase;
3774 session->encryption_algorithm = malloc(l + 1);
3775 strncpy(session->encryption_algorithm, passphrase, l);
3776 session->encryption_algorithm[l] = '\0';
3777 passphrase = slash + 1;
3778 }
3779
3780 debug_msg("Initializing encryption, algorithm is '%s'\n",
3781 session->encryption_algorithm);
3782
3783 /* Step 1: convert to canonical form, comprising the following steps: */
3784 /* a) convert the input string to the ISO 10646 character set, using */
3785 /* the UTF-8 encoding as specified in Annex P to ISO/IEC */
3786 /* 10646-1:1993 (ASCII characters require no mapping, but ISO */
3787 /* 8859-1 characters do); */
3788 /* b) remove leading and trailing white space characters; */
3789 /* c) replace one or more contiguous white space characters by a */
3790 /* single space (ASCII or UTF-8 0x20); */
3791 /* d) convert all letters to lower case and replace sequences of */
3792 /* characters and non-spacing accents with a single character, */
3793 /* where possible. */
3794 canonical_passphrase = strdup(passphrase); /* FIXME */
3795
3796 /* Step 2: derive an MD5 hash */
3797 MD5Init(&context);
3798 MD5Update(&context, (u_char *) canonical_passphrase,
3799 strlen(canonical_passphrase));
3800 MD5Final((u_char *) hash, &context);
3801 free(canonical_passphrase);
3802
3803 /* Initialize the encryption algorithm we've received */
3804
3805 if (strcmp(session->encryption_algorithm, "DES") == 0) {
3806 return des_initialize(session, hash, sizeof(hash)); // NOLINTNEXTLINE(readability-else-after-return)
3807 } else if (strcmp(session->encryption_algorithm, "Rijndael") == 0) {
3808 return rijndael_initialize(session, hash, sizeof(hash)); // NOLINTNEXTLINE(readability-else-after-return)
3809 } else {
3810 debug_msg("Encryption algorithm \"%s\" not found\n",
3811 session->encryption_algorithm);
3812 return false;
3813 }
3814}
void MD5Update(MD5CTX *context, const unsigned char *input, unsigned int inputLen)
Definition md5.c:249
void MD5Final(unsigned char digest[16], MD5CTX *context)
Definition md5.c:295
void MD5Init(MD5CTX *context)
Definition md5.c:229
static bool des_initialize(struct rtp *session, const u_char *hash, int hash_len)
Definition rtp.c:3816
static bool rijndael_initialize(struct rtp *session, const u_char *hash, int hash_len)
Definition rtp.c:3871
Definition md5.h:34

References check_database(), debug_msg, des_initialize(), rtp::encryption_algorithm, rtp::encryption_enabled, MD5Final(), MD5Init(), MD5Update(), and rijndael_initialize().

Here is the call graph for this function:

◆ rtp_set_my_ssrc()

bool rtp_set_my_ssrc ( struct rtp * session,
uint32_t ssrc )

rtp_set_my_ssrc: @session: the RTP session @ssrc: the SSRC to be used by the RTP session

This function coerces the local SSRC identifer to be ssrc. For this function to succeed it must be called immediately after rtp_init or rtp_init_if. The intended purpose of this function is to co-ordinate SSRC's between layered sessions, it should not be used otherwise.

Definition at line 1278 of file rtp.c.

1279{
1280 source *s;
1281 uint32_t h;
1282
1283 if (session->ssrc_count != 1 && session->sender_count != 0) {
1284 return false;
1285 }
1286 /* Remove existing source */
1287 h = ssrc_hash(session->my_ssrc);
1288 s = session->db[h];
1289 session->db[h] = NULL;
1290 /* Fill in new ssrc */
1291 session->my_ssrc = ssrc;
1292 s->ssrc = ssrc;
1293 h = ssrc_hash(ssrc);
1294 /* Put source back */
1295 session->db[h] = s;
1296 return true;
1297}
static int ssrc_hash(uint32_t ssrc)
Definition rtp.c:371

References rtp::db, rtp::my_ssrc, rtp::sender_count, _source::ssrc, rtp::ssrc_count, and ssrc_hash().

Here is the call graph for this function:

◆ rtp_set_option()

bool rtp_set_option ( struct rtp * session,
rtp_option optname,
int optval )

rtp_set_option: @session: The RTP session. @optname: The option name, see rtp_option. @optval: The value to set.

Sets the value of a session option. See rtp_option for documentation on the options and their legal values.

Definition at line 1308 of file rtp.c.

1309{
1310 switch (optname) {
1312 session->opt->wait_for_rtcp = optval;
1313 break;
1314 case RTP_OPT_PROMISC:
1315 session->opt->promiscuous_mode = optval;
1316 break;
1318 session->opt->filter_my_packets = optval;
1319 break;
1321 session->opt->reuse_bufs = optval;
1322 break;
1324 session->opt->record_source = optval;
1325 break;
1326 case RTP_OPT_SEND_BACK:
1327 session->opt->send_back = optval;
1328 if (optval) {
1329 session->opt->record_source = TRUE;
1330 }
1331 break;
1332 default:
1333 debug_msg
1334 ("Ignoring unknown option (%d) in call to rtp_set_option().\n",
1335 optname);
1336 return false;
1337 }
1338 return true;
1339}
int record_source
Definition rtp.c:258

References debug_msg, options::filter_my_packets, rtp::opt, options::promiscuous_mode, options::record_source, options::reuse_bufs, RTP_OPT_FILTER_MY_PACKETS, RTP_OPT_PROMISC, RTP_OPT_RECORD_SOURCE, RTP_OPT_REUSE_PACKET_BUFS, RTP_OPT_SEND_BACK, RTP_OPT_WEAK_VALIDATION, options::send_back, TRUE, and options::wait_for_rtcp.

Referenced by init_opt(), initialize_audio_network(), rtp_video_rxtx::initialize_network(), and vidcap_rtsp_init().

◆ rtp_set_recv_buf()

bool rtp_set_recv_buf ( struct rtp * session,
int bufsize )

Sets receiver buffer size

Parameters
sessionthe RTP Session
bufsizerequested recv network buffer size

Definition at line 3938 of file rtp.c.

3939{
3940 return udp_set_recv_buf(session->rtp_socket, bufsize);
3941}
bool udp_set_recv_buf(socket_udp *s, int size)
Definition net_udp.c:1486

References rtp::rtp_socket, and udp_set_recv_buf().

Referenced by audio_update_recv_buf(), initialize_audio_network(), rtp_video_rxtx::initialize_network(), ultragrid_rtp_video_rxtx::receiver_loop(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_set_recv_iov()

void rtp_set_recv_iov ( struct rtp * session,
struct msghdr * m )

Definition at line 1513 of file rtp.c.

1514{
1515 session->mhdr = m;
1516}

References rtp::mhdr.

◆ rtp_set_sdes()

bool rtp_set_sdes ( struct rtp * session,
uint32_t ssrc,
rtcp_sdes_type type,
const char * value,
int length )

rtp_set_sdes: @session: the session pointer (returned by rtp_init()) @ssrc: the SSRC identifier of a participant @type: the SDES type represented by @value @value: the SDES description @length: the length of the description

Sets session description information associated with participant @ssrc. Under normal circumstances applications always use the @ssrc of the local participant, this SDES information is transmitted in receiver reports. Setting SDES information for other participants affects the local SDES entries, but are not transmitted onto the network.

Return values
returnstrue if participant exists, false otherwise.

Definition at line 2546 of file rtp.c.

2548{
2549 source *s;
2550 char *v;
2551
2552 check_database(session);
2553
2554 s = get_source(session, ssrc);
2555 if (s == NULL) {
2556 debug_msg("Invalid source 0x%08x\n", ssrc);
2557 return false;
2558 }
2559 check_source(s);
2560
2561 v = (char *)malloc(length + 1);
2562 memset(v, '\0', length + 1);
2563 memcpy(v, value, length);
2564
2565 switch (type) {
2566 case RTCP_SDES_CNAME:
2567 if (s->sdes_cname)
2568 free(s->sdes_cname);
2569 s->sdes_cname = v;
2570 break;
2571 case RTCP_SDES_NAME:
2572 if (s->sdes_name)
2573 free(s->sdes_name);
2574 s->sdes_name = v;
2575 break;
2576 case RTCP_SDES_EMAIL:
2577 if (s->sdes_email)
2578 free(s->sdes_email);
2579 s->sdes_email = v;
2580 break;
2581 case RTCP_SDES_PHONE:
2582 if (s->sdes_phone)
2583 free(s->sdes_phone);
2584 s->sdes_phone = v;
2585 break;
2586 case RTCP_SDES_LOC:
2587 if (s->sdes_loc)
2588 free(s->sdes_loc);
2589 s->sdes_loc = v;
2590 break;
2591 case RTCP_SDES_TOOL:
2592 if (s->sdes_tool)
2593 free(s->sdes_tool);
2594 s->sdes_tool = v;
2595 break;
2596 case RTCP_SDES_NOTE:
2597 if (s->sdes_note)
2598 free(s->sdes_note);
2599 s->sdes_note = v;
2600 break;
2601 case RTCP_SDES_PRIV:
2602 if (s->sdes_priv)
2603 free(s->sdes_priv);
2604 s->sdes_priv = v;
2605 break;
2606 default:
2607 debug_msg("Unknown SDES item (type=%d, value=%s)\n", type, v);
2608 free(v);
2609 check_database(session);
2610 return false;
2611 }
2612 check_database(session);
2613 return true;
2614}

References check_database(), check_source(), debug_msg, get_source(), RTCP_SDES_CNAME, RTCP_SDES_EMAIL, RTCP_SDES_LOC, RTCP_SDES_NAME, RTCP_SDES_NOTE, RTCP_SDES_PHONE, RTCP_SDES_PRIV, RTCP_SDES_TOOL, _source::sdes_cname, _source::sdes_email, _source::sdes_loc, _source::sdes_name, _source::sdes_note, _source::sdes_phone, _source::sdes_priv, _source::sdes_tool, and type.

Referenced by initialize_audio_network(), rtp_video_rxtx::initialize_network(), process_rtcp_sdes(), rtp_init_if(), rtp_init_with_udp_socket(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_set_send_buf()

bool rtp_set_send_buf ( struct rtp * session,
int bufsize )

Sets sender buffer size

Parameters
sessionthe RTP Session
bufsizerequested send network buffer size

Definition at line 3954 of file rtp.c.

3955{
3956 return udp_set_send_buf(session->rtp_socket, bufsize);
3957}
bool udp_set_send_buf(socket_udp *s, int size)
Definition net_udp.c:1492

References rtp::rtp_socket, and udp_set_send_buf().

Referenced by rtp_video_rxtx::initialize_network(), and vidcap_rtsp_init().

Here is the call graph for this function:

◆ rtp_update()

void rtp_update ( struct rtp * session,
time_ns_t curr_time )

rtp_update: @session: the session pointer (returned by rtp_init())

Trawls through the internal data structures and performs housekeeping. This function should be called at least once per second. It uses an internal timer to limit the number of passes through the data structures to once per second, it can be safely called more frequently.

Definition at line 3456 of file rtp.c.

3457{
3458 /* Perform housekeeping on the source database... */
3459 int h;
3460 source *s, *n;
3461
3462 if (curr_time - session->last_update < 1 * NS_IN_SEC) {
3463 /* We only perform housekeeping once per second... */
3464 return;
3465 }
3466 session->last_update = curr_time;
3467
3468 /* Update we_sent (section 6.3.8 of RTP spec) */
3469 time_ns_t delay = curr_time - session->last_rtp_send_time;
3470 if (delay >= 2 * NS_IN_SEC * rtcp_interval(session)) {
3471 session->we_sent = FALSE;
3472 }
3473
3474 check_database(session);
3475
3476 for (h = 0; h < RTP_DB_SIZE; h++) {
3477 for (s = session->db[h]; s != NULL; s = n) {
3478 check_source(s);
3479 n = s->next;
3480 /* Expire sources which haven't been heard from for a int time. */
3481 /* Section 6.2.1 of the RTP specification details the timers used. */
3482
3483 /* How int since we last heard from this source? */
3484 delay = curr_time - s->last_active;
3485
3486 /* Check if we've received a BYE packet from this source. */
3487 /* If we have, and it was received more than 2 seconds ago */
3488 /* then the source is deleted. The arbitrary 2 second delay */
3489 /* is to ensure that all delayed packets are received before */
3490 /* the source is timed out. */
3491 if (s->got_bye && (delay > 2 * NS_IN_SEC)) {
3492 debug_msg
3493 ("Deleting source 0x%08" PRIx32 " due to reception of BYE %f seconds ago...\n",
3494 s->ssrc, (double) delay / NS_IN_SEC);
3495 delete_source(session, s->ssrc);
3496 }
3497
3498 /* Sources are marked as inactive if they haven't been heard */
3499 /* from for more than 2 intervals (RTP section 6.3.5) */
3500 if ((s->ssrc != rtp_my_ssrc(session))
3501 && (delay > (session->rtcp_interval * 2 * NS_IN_SEC))) {
3502 if (s->sender) {
3503 s->sender = FALSE;
3504 session->sender_count--;
3505 }
3506 }
3507
3508 /* If a source hasn't been heard from for more than 5 RTCP */
3509 /* reporting intervals, we delete it from our database... */
3510 if ((s->ssrc != rtp_my_ssrc(session))
3511 && (delay > (session->rtcp_interval * 5 * NS_IN_SEC))) {
3512 debug_msg
3513 ("Deleting source 0x%08" PRIx32 " due to timeout...\n",
3514 s->ssrc);
3515 delete_source(session, s->ssrc);
3516 }
3517 }
3518 }
3519
3520 /* Timeout those reception reports which haven't been refreshed for a int time */
3521 timeout_rr(session, curr_time);
3522 check_database(session);
3523}
uint32_t rtp_my_ssrc(struct rtp *session)
Definition rtp.c:1401
static void timeout_rr(struct rtp *session, time_ns_t curr_ts)
Definition rtp.c:474
int got_bye
Definition rtp.c:224
time_ns_t last_active
Definition rtp.c:221
double rtcp_interval
Definition rtp.c:302

References check_database(), check_source(), rtp::db, debug_msg, delete_source(), FALSE, _source::got_bye, _source::last_active, rtp::last_rtp_send_time, rtp::last_update, _source::next, NS_IN_SEC, rtcp_interval(), rtp::rtcp_interval, RTP_DB_SIZE, rtp_my_ssrc(), _source::sender, rtp::sender_count, _source::ssrc, timeout_rr(), and rtp::we_sent.

Referenced by audio_receiver_thread(), audio_sender_thread(), ultragrid_rtp_video_rxtx::receiver_loop(), rtp_send_bye(), h264_rtp_video_rxtx::send_frame(), h264_sdp_video_rxtx::send_frame(), ultragrid_rtp_video_rxtx::send_frame_async(), and vidcap_rtsp_thread().

Here is the call graph for this function:

Variable Documentation

◆ rtp_packet