uvgRTP 2.1.0
An open-source library for RTP/SRTP media delivery
Loading...
Searching...
No Matches
rtcp.hh
1#pragma once
2
3#include "clock.hh"
4#include "util.hh"
5#include "frame.hh"
6
7#include <bitset>
8#include <map>
9#include <thread>
10#include <vector>
11#include <functional>
12#include <memory>
13#include <mutex>
14#include <deque>
15
16namespace uvgrtp {
17
18 class rtp;
19 class srtcp;
20 class socket;
21
22 typedef std::vector<std::pair<size_t, uint8_t*>> buf_vec; // also defined in socket.hh
23
25 enum RTCP_ROLE {
26 RECEIVER,
27 SENDER
28 };
29
30 struct sender_statistics {
31 /* sender stats */
32 uint32_t sent_pkts = 0; /* Number of sent RTP packets */
33 uint32_t sent_bytes = 0; /* Number of sent bytes excluding RTP Header */
34 bool sent_rtp_packet = false; // since last report
35 };
36
37 struct receiver_statistics {
38 /* receiver stats */
39 uint32_t received_pkts = 0; /* Number of packets received */
40 uint32_t dropped_pkts = 0; /* Number of dropped RTP packets */
41 uint32_t received_bytes = 0; /* Number of bytes received excluding RTP Header */
42 bool received_rtp_packet = false; // since last report
43
44 double jitter = 0; /* The estimation of jitter (see RFC 3550 A.8) */
45 uint32_t transit = 0; /* TODO: */
46
47
48 /* Receiver clock related stuff */
49 uint64_t initial_ntp = 0; /* Wallclock reading when the first RTP packet was received */
50 uint32_t initial_rtp = 0; /* RTP timestamp of the first RTP packet received */
51 uint32_t clock_rate = 0; /* Rate of the clock (used for jitter calculations) */
52
53 uint32_t lsr = 0; /* Middle 32 bits of the 64-bit NTP timestamp of previous SR */
54 uvgrtp::clock::hrc::hrc_t sr_ts; /* When the last SR was received (used to calculate delay) */
55
56 uint16_t max_seq = 0; /* Highest sequence number received */
57 uint32_t base_seq = 0; /* First sequence number received */
58 uint32_t bad_seq = 0; /* TODO: */
59 uint16_t cycles = 0; /* Number of sequence cycles */
60 };
61
62 struct rtcp_participant {
63 std::shared_ptr<uvgrtp::socket> socket = nullptr; /* socket associated with this participant */
64 sockaddr_in address = {}; /* address of the participant */
65 struct receiver_statistics stats; /* RTCP session statistics of the participant */
66
67 uint32_t probation = 0; /* has the participant been fully accepted to the session */
68 int role = 0; /* is the participant a sender or a receiver */
69
70 /* Save the latest RTCP packets received from this participant
71 * Users can query these packets using the SSRC of participant */
72 uvgrtp::frame::rtcp_sender_report *sr_frame = nullptr;
73 uvgrtp::frame::rtcp_receiver_report *rr_frame = nullptr;
74 uvgrtp::frame::rtcp_sdes_packet *sdes_frame = nullptr;
75 uvgrtp::frame::rtcp_app_packet *app_frame = nullptr;
76 };
77
78 struct rtcp_app_packet {
79 rtcp_app_packet(const rtcp_app_packet& orig_packet) = delete;
80 rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, const uint8_t* payload);
81 ~rtcp_app_packet();
82
83 const char* name;
84 uint8_t subtype;
85
86 uint32_t payload_len;
87 const uint8_t* payload;
88 };
90
108 class rtcp {
109 public:
111 rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_flags);
112 rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, std::shared_ptr<uvgrtp::srtcp> srtcp, int rce_flags);
113 ~rtcp();
114
115 /* start the RTCP runner thread
116 *
117 * return RTP_OK on success and RTP_MEMORY_ERROR if the allocation fails */
118 rtp_error_t start();
119
120 /* End the RTCP session and send RTCP BYE to all participants
121 *
122 * return RTP_OK on success */
123 rtp_error_t stop();
124
125 /* Generate either RTCP Sender or Receiver report and sent it to all participants
126 * Return RTP_OK on success and RTP_ERROR on error */
127 rtp_error_t generate_report();
128
129 /* Handle incoming RTCP packet (first make sure it's a valid RTCP packet)
130 * This function will call one of the above functions internally
131 *
132 * Return RTP_OK on success and RTP_ERROR on error */
133 rtp_error_t handle_incoming_packet(uint8_t *buffer, size_t size);
135
136 /* Send "frame" to all participants
137 *
138 * These routines will convert all necessary fields to network byte order
139 *
140 * Return RTP_OK on success
141 * Return RTP_INVALID_VALUE if "frame" is in some way invalid
142 * Return RTP_SEND_ERROR if sending "frame" did not succeed (see socket.hh for details) */
143
153 rtp_error_t send_sdes_packet(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items);
154
167 rtp_error_t send_app_packet(const char *name, uint8_t subtype, uint32_t payload_len, const uint8_t *payload);
168
183 rtp_error_t send_bye_packet(std::vector<uint32_t> ssrcs);
184
186 /* Return the latest RTCP packet received from participant of "ssrc"
187 * Return nullptr if we haven't received this kind of packet or if "ssrc" doesn't exist
188 *
189 * NOTE: Caller is responsible for deallocating the memory */
190 uvgrtp::frame::rtcp_sender_report *get_sender_packet(uint32_t ssrc);
191 uvgrtp::frame::rtcp_receiver_report *get_receiver_packet(uint32_t ssrc);
192 uvgrtp::frame::rtcp_sdes_packet *get_sdes_packet(uint32_t ssrc);
193 uvgrtp::frame::rtcp_app_packet *get_app_packet(uint32_t ssrc);
194
195 /* Return a reference to vector that contains the sockets of all participants */
196 std::vector<std::shared_ptr<uvgrtp::socket>>& get_sockets();
197
198 /* Somebody joined the multicast group the owner of this RTCP instance is part of
199 * Add it to RTCP participant list so we can start listening for reports
200 *
201 * "clock_rate" tells how much the RTP timestamp advances, this information is needed
202 * to calculate the interarrival jitter correctly. It has nothing do with our clock rate,
203 * (or whether we're even sending anything)
204 *
205 * Return RTP_OK on success and RTP_ERROR on error */
206 rtp_error_t add_participant(std::string src_addr, std::string dst_addr, uint16_t dst_port, uint16_t src_port, uint32_t clock_rate);
207
208 /* Functions for updating various RTP sender statistics */
209 void sender_update_stats(const uvgrtp::frame::rtp_frame *frame);
210
211 /* If we've detected that our SSRC has collided with someone else's SSRC, we need to
212 * generate new random SSRC and reinitialize our own RTCP state.
213 * RTCP object still has the participants of "last session", we can use their SSRCs
214 * to detected new collision
215 *
216 * Return RTP_OK if reinitialization succeeded
217 * Return RTP_SSRC_COLLISION if our new SSRC has collided and we need to generate new SSRC */
218 rtp_error_t reset_rtcp_state(uint32_t ssrc);
219
220 /* Update various session statistics */
221 void update_session_statistics(const uvgrtp::frame::rtp_frame *frame);
222
223 /* Getter for interval_ms_, which is calculated by set_session_bandwidth */
224 uint32_t get_rtcp_interval_ms() const;
225
226 void set_session_bandwidth(uint32_t kbps);
227
228 /* Return SSRCs of all participants */
229 std::vector<uint32_t> get_participants() const;
231
246 void set_ts_info(uint64_t clock_start, uint32_t clock_rate, uint32_t rtp_ts_start);
247
248 /* Alternate way to get RTCP packets is to install a hook for them. So instead of
249 * polling an RTCP packet, user can install a function that is called when
250 * a specific RTCP packet is received. */
251
263
274 rtp_error_t install_sender_hook(std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_handler);
275
287
298 rtp_error_t install_receiver_hook(std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_handler);
299
311
322 rtp_error_t install_sdes_hook(std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_handler);
323
335
346 rtp_error_t install_app_hook(std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_app_packet>)> app_handler);
347
349 // These have been replaced by functions with unique_ptr in them
350 rtp_error_t install_sender_hook(std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_handler);
351 rtp_error_t install_receiver_hook(std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_handler);
352 rtp_error_t install_sdes_hook(std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_handler);
353 rtp_error_t install_app_hook(std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_app_packet>)> app_handler);
355
363 rtp_error_t remove_all_hooks();
364
366 /* Update RTCP-related sender statistics */
367 rtp_error_t update_sender_stats(size_t pkt_size);
368
369 /* Update RTCP-related receiver statistics */
370 static rtp_error_t recv_packet_handler(void *arg, int rce_flags, frame::rtp_frame **out);
371
372 /* Update RTCP-related sender statistics */
373 static rtp_error_t send_packet_handler_vec(void *arg, uvgrtp::buf_vec& buffers);
374
375 // the length field is the rtcp packet size measured in 32-bit words - 1
376 size_t rtcp_length_in_bytes(uint16_t length);
377
378 void set_payload_size(size_t mtu_size);
380
381 private:
382
383 rtp_error_t set_sdes_items(const std::vector<uvgrtp::frame::rtcp_sdes_item>& items);
384
385 uint32_t size_of_ready_app_packets() const;
386
387 uint32_t size_of_compound_packet(uint16_t reports,
388 bool sr_packet, bool rr_packet, bool sdes_packet, uint32_t app_size, bool bye_packet) const;
389
390 /* read the header values from rtcp packet */
391 void read_rtcp_header(const uint8_t* buffer, size_t& read_ptr,
393 void read_reports(const uint8_t* buffer, size_t& read_ptr, size_t packet_end, uint8_t count,
394 std::vector<uvgrtp::frame::rtcp_report_block>& reports);
395
396 void read_ssrc(const uint8_t* buffer, size_t& read_ptr, uint32_t& out_ssrc);
397
398 /* Handle different kinds of incoming rtcp packets. The read header is passed to functions
399 which read rest of the frame type specific data.
400 * Return RTP_OK on success and RTP_ERROR on error */
401 rtp_error_t handle_sender_report_packet(uint8_t* buffer, size_t& read_ptr, size_t packet_end,
403 rtp_error_t handle_receiver_report_packet(uint8_t* buffer, size_t& read_ptr, size_t packet_end,
405 rtp_error_t handle_sdes_packet(uint8_t* buffer, size_t& read_ptr, size_t packet_end,
406 uvgrtp::frame::rtcp_header& header, uint32_t sender_ssrc);
407 rtp_error_t handle_bye_packet(uint8_t* buffer, size_t& read_ptr, size_t packet_end,
409 rtp_error_t handle_app_packet(uint8_t* buffer, size_t& read_ptr, size_t packet_end,
411
412 static void rtcp_runner(rtcp *rtcp, int interval);
413
414 /* when we start the RTCP instance, we don't know what the SSRC of the remote is
415 * when an RTP packet is received, we must check if we've already received a packet
416 * from this sender and if not, create new entry to receiver_stats_ map */
417 bool is_participant(uint32_t ssrc) const;
418
419 /* When we receive an RTP or RTCP packet, we need to check the source address and see if it's
420 * the same address where we've received packets before.
421 *
422 * If the address is new, it means we have detected an SSRC collision and the paket should
423 * be dropped We also need to check whether this SSRC matches with our own SSRC and if it does
424 * we need to send RTCP BYE and rejoin to the session */
425 bool collision_detected(uint32_t ssrc, const sockaddr_in& src_addr) const;
426
427 /* Move participant from initial_peers_ to participants_ */
428 rtp_error_t add_participant(uint32_t ssrc);
429
430 /* We've got a message from new source (the SSRC of the frame is not known to us)
431 * Initialize statistics for the peer and move it to participants_ */
432 rtp_error_t init_new_participant(const uvgrtp::frame::rtp_frame *frame);
433
434 /* Initialize the RTP Sequence related stuff of peer
435 * This function assumes that the peer already exists in the participants_ map */
436 rtp_error_t init_participant_seq(uint32_t ssrc, uint16_t base_seq);
437
438 /* Update the SSRC's sequence related data in participants_ map
439 *
440 * Return RTP_OK if the received packet was OK
441 * Return RTP_GENERIC_ERROR if it wasn't and
442 * packet-related statistics should not be updated */
443 rtp_error_t update_participant_seq(uint32_t ssrc, uint16_t seq);
444
445 /* Update the RTCP bandwidth variables
446 *
447 * "pkt_size" tells how much rtcp_byte_count_
448 * should be increased before calculating the new average */
449 void update_rtcp_bandwidth(size_t pkt_size);
450
451 /* Because struct statistics contains uvgRTP clock object we cannot
452 * zero it out without compiler complaining about it so all the fields
453 * must be set to zero manually */
454 void zero_stats(uvgrtp::sender_statistics *stats);
455
456 void zero_stats(uvgrtp::receiver_statistics *stats);
457
458 /* Takes ownership of the frame */
459 rtp_error_t send_rtcp_packet_to_participants(uint8_t* frame, uint32_t frame_size, bool encrypt);
460
461 void free_participant(std::unique_ptr<rtcp_participant> participant);
462
463 void cleanup_participants();
464
465 /* Secure RTCP context */
466 std::shared_ptr<uvgrtp::srtcp> srtcp_;
467
468 /* RTP context flags */
469 int rce_flags_;
470
471 /* are we a sender (and possible a receiver) or just a receiver */
472 int our_role_;
473
474 /* TODO: time_t?? */
475 // TODO: Check these, they don't seem to be used
476 size_t tp_; /* the last time an RTCP packet was transmitted */
477 size_t tc_; /* the current time */
478 size_t tn_; /* the next scheduled transmission time of an RTCP packet */
479 size_t pmembers_; /* the estimated number of session members at the time tn was last recomputed */
480 size_t members_; /* the most current estimate for the number of session members */
481 size_t senders_; /* the most current estimate for the number of senders in the session */
482
483 /* The target RTCP bandwidth, i.e., the total bandwidth
484 * that will be used for RTCP packets by all members of this session,
485 * in octets per second. This will be a specified fraction of the
486 * "session bandwidth" parameter supplied to the application at startup. */
487 // TODO: Not used anywhere at the moment
488 size_t rtcp_bandwidth_;
489
490 /* Flag that is true if the application has sent data since
491 * the 2nd previous RTCP report was transmitted. */
492 // TODO: Only set, never read
493 bool we_sent_;
494
495 /* The average compound RTCP packet size, in octets,
496 * over all RTCP packets sent and received by this participant. The
497 * size includes lower-layer transport and network protocol headers
498 * (e.g., UDP and IP) as explained in Section 6.2 */
499 // TODO: Only set, never read
500 size_t avg_rtcp_pkt_pize_;
501
502 /* Number of RTCP packets and bytes sent and received by this participant */
503 // TODO: Only set, never read
504 size_t rtcp_pkt_count_;
505 size_t rtcp_byte_count_;
506
507 /* Number of RTCP packets sent */
508 uint32_t rtcp_pkt_sent_count_;
509
510 /* Flag that is true if the application has not yet sent an RTCP packet. */
511 // TODO: Only set, never read
512 bool initial_;
513
514 /* Copy of our own current SSRC */
515 const uint32_t ssrc_;
516
517 /* NTP timestamp associated with initial RTP timestamp (aka t = 0) */
518 uint64_t clock_start_;
519
520 /* Clock rate of the media ie. how fast does the time increase */
521 uint32_t clock_rate_;
522
523 /* The first value of RTP timestamp (aka t = 0) */
524 uint32_t rtp_ts_start_;
525
526 std::map<uint32_t, std::unique_ptr<rtcp_participant>> participants_;
527 uint8_t num_receivers_; // maximum is 32 at the moment (5 bits)
528
529 /* statistics for RTCP Sender and Receiver Reports */
530 struct sender_statistics our_stats;
531
532 /* If we expect frames from remote but haven't received anything from remote yet,
533 * the participant resides in this vector until he's moved to participants_ */
534 std::vector<std::unique_ptr<rtcp_participant>> initial_participants_;
535
536 /* Vector of sockets the RTCP runner is listening to
537 *
538 * The socket are also stored here (in addition to participants_ map) so they're easier
539 * to pass to poll when RTCP runner is listening to incoming packets */
540 std::vector<std::shared_ptr<uvgrtp::socket>> sockets_;
541
542 void (*sender_hook_)(uvgrtp::frame::rtcp_sender_report *);
543 void (*receiver_hook_)(uvgrtp::frame::rtcp_receiver_report *);
544 void (*sdes_hook_)(uvgrtp::frame::rtcp_sdes_packet *);
545 void (*app_hook_)(uvgrtp::frame::rtcp_app_packet *);
546
547 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_hook_f_;
548 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_hook_u_;
549 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_hook_f_;
550 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_hook_u_;
551 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_hook_f_;
552 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_hook_u_;
553 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_app_packet>)> app_hook_f_;
554 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_app_packet>)> app_hook_u_;
555
556 std::mutex sr_mutex_;
557 std::mutex rr_mutex_;
558 std::mutex sdes_mutex_;
559 std::mutex app_mutex_;
560
561 std::unique_ptr<std::thread> report_generator_;
562
563 bool is_active() const
564 {
565 return active_;
566 }
567
568 bool active_;
569
570 uint32_t interval_ms_;
571
572 std::mutex packet_mutex_;
573
574 // messages waiting to be sent
575 std::vector<uvgrtp::frame::rtcp_sdes_item> ourItems_; // always sent
576 std::vector<uint32_t> bye_ssrcs_; // sent once
577 std::map<std::string, std::deque<rtcp_app_packet>> app_packets_; // sent one at a time per name
578
580 char cname_[255];
581
582 size_t mtu_size_;
583 };
584}
585
586namespace uvg_rtp = uvgrtp;
RTCP instance handles all incoming and outgoing RTCP traffic, including report generation.
Definition: rtcp.hh:108
rtp_error_t install_receiver_hook(void(*hook)(uvgrtp::frame::rtcp_receiver_report *))
Install an RTCP Receiver Report hook.
rtp_error_t send_app_packet(const char *name, uint8_t subtype, uint32_t payload_len, const uint8_t *payload)
Send an RTCP APP packet.
rtp_error_t install_receiver_hook(std::function< void(std::unique_ptr< uvgrtp::frame::rtcp_receiver_report >)> rr_handler)
Install an RTCP Receiver Report hook.
rtp_error_t send_bye_packet(std::vector< uint32_t > ssrcs)
Send an RTCP BYE packet.
rtp_error_t install_sdes_hook(std::function< void(std::unique_ptr< uvgrtp::frame::rtcp_sdes_packet >)> sdes_handler)
Install an RTCP SDES packet hook.
rtp_error_t install_sender_hook(void(*hook)(uvgrtp::frame::rtcp_sender_report *))
Install an RTCP Sender Report hook.
void set_ts_info(uint64_t clock_start, uint32_t clock_rate, uint32_t rtp_ts_start)
Provide timestamping information for RTCP.
rtp_error_t send_sdes_packet(const std::vector< uvgrtp::frame::rtcp_sdes_item > &items)
Send an RTCP SDES packet.
rtp_error_t install_app_hook(std::function< void(std::unique_ptr< uvgrtp::frame::rtcp_app_packet >)> app_handler)
Install an RTCP APP packet hook.
rtp_error_t install_sender_hook(std::function< void(std::unique_ptr< uvgrtp::frame::rtcp_sender_report >)> sr_handler)
Install an RTCP Sender Report hook.
rtp_error_t remove_all_hooks()
Remove all installed hooks for RTCP.
rtp_error_t install_app_hook(void(*hook)(uvgrtp::frame::rtcp_app_packet *))
Install an RTCP APP packet hook.
rtp_error_t install_sdes_hook(void(*hook)(uvgrtp::frame::rtcp_sdes_packet *))
Install an RTCP SDES packet hook.
See RFC 3550 section 6.7
Definition: frame.hh:151
Header of for all RTCP packets defined in RFC 3550 section 6
Definition: frame.hh:74
See RFC 3550 section 6.4.2
Definition: frame.hh:117
See RFC 3550 section 6.5
Definition: frame.hh:132
See RFC 3550 section 6.5
Definition: frame.hh:145
See RFC 3550 section 6.4.1
Definition: frame.hh:124
See RFC 3550 section 5
Definition: frame.hh:53