10#include <sys/socket.h>
11#include <netinet/in.h>
30 typedef std::vector<std::pair<size_t, uint8_t*>> buf_vec;
38 struct sender_statistics {
40 uint32_t sent_pkts = 0;
41 uint32_t sent_bytes = 0;
42 bool sent_rtp_packet =
false;
45 struct receiver_statistics {
47 uint32_t received_pkts = 0;
48 uint32_t lost_pkts = 0;
49 uint32_t received_bytes = 0;
50 bool received_rtp_packet =
false;
52 uint32_t expected_pkts = 0;
53 uint32_t received_prior = 0;
54 uint32_t expected_prior = 0;
61 uint64_t initial_ntp = 0;
62 uint32_t initial_rtp = 0;
63 uint32_t clock_rate = 0;
66 uvgrtp::clock::hrc::hrc_t sr_ts;
69 uint32_t base_seq = 0;
74 struct rtcp_participant {
75 struct receiver_statistics stats;
77 uint32_t probation = 0;
88 struct rtcp_app_packet {
89 rtcp_app_packet(
const rtcp_app_packet& orig_packet) =
delete;
90 rtcp_app_packet(
const char* name, uint8_t subtype, uint32_t payload_len, std::unique_ptr<uint8_t[]> payload);
97 std::unique_ptr<uint8_t[]> payload;
121 rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::shared_ptr<std::atomic<std::uint32_t>> ssrc, std::string cname,
int rce_flags);
122 rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::shared_ptr<std::atomic<std::uint32_t>> ssrc, std::string cname, std::shared_ptr<uvgrtp::srtcp> srtcp,
int rce_flags);
137 rtp_error_t generate_report();
143 rtp_error_t handle_incoming_packet(uint8_t *buffer,
size_t size);
177 rtp_error_t
send_app_packet(
const char *name, uint8_t subtype, uint32_t payload_len,
const uint8_t *payload);
213 rtp_error_t add_initial_participant(uint32_t clock_rate);
225 rtp_error_t reset_rtcp_state(uint32_t ssrc);
231 uint32_t get_rtcp_interval_ms()
const;
237 rtp_error_t set_rtcp_interval_ms(int32_t new_interval);
242 void set_session_bandwidth(uint32_t kbps);
244 std::shared_ptr<uvgrtp::socket> get_socket()
const;
253 rtp_error_t set_network_addresses(std::string local_addr, std::string remote_addr,
254 uint16_t local_port, uint16_t dst_port,
bool ipv6);
257 std::vector<uint32_t> get_participants()
const;
274 void set_ts_info(uint64_t clock_start, uint32_t clock_rate, uint32_t rtp_ts_start);
302 rtp_error_t
install_sender_hook(std::function<
void(std::unique_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_handler);
326 rtp_error_t
install_receiver_hook(std::function<
void(std::unique_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_handler);
350 rtp_error_t
install_sdes_hook(std::function<
void(std::unique_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_handler);
374 rtp_error_t
install_app_hook(std::function<
void(std::unique_ptr<uvgrtp::frame::rtcp_app_packet>)> app_handler);
378 rtp_error_t
install_sender_hook(std::function<
void(std::shared_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_handler);
379 rtp_error_t
install_receiver_hook(std::function<
void(std::shared_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_handler);
380 rtp_error_t
install_sdes_hook(std::function<
void(std::shared_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_handler);
381 rtp_error_t
install_app_hook(std::function<
void(std::shared_ptr<uvgrtp::frame::rtcp_app_packet>)> app_handler);
394 rtp_error_t
install_send_app_hook(std::string app_name, std::function<std::unique_ptr<uint8_t[]>(uint8_t& subtype, uint32_t& payload_len)> app_sending_func);
405 rtp_error_t remove_send_app_hook(std::string app_name);
409 rtp_error_t update_sender_stats(
size_t pkt_size);
412 static rtp_error_t recv_packet_handler(
void *arg,
int rce_flags,
frame::rtp_frame **out);
415 static rtp_error_t send_packet_handler_vec(
void *arg, uvgrtp::buf_vec& buffers);
418 size_t rtcp_length_in_bytes(uint16_t length);
420 void set_payload_size(
size_t mtu_size);
425 rtp_error_t set_sdes_items(
const std::vector<uvgrtp::frame::rtcp_sdes_item>& items);
427 uint32_t size_of_ready_app_packets()
const;
428 uint32_t size_of_apps_from_hook(std::vector< std::shared_ptr<rtcp_app_packet>> packets)
const;
430 uint32_t size_of_compound_packet(uint16_t reports,
431 bool sr_packet,
bool rr_packet,
bool sdes_packet, uint32_t app_size,
bool bye_packet)
const;
434 void read_rtcp_header(
const uint8_t* buffer,
size_t& read_ptr,
436 void read_reports(
const uint8_t* buffer,
size_t& read_ptr,
size_t packet_end, uint8_t count,
437 std::vector<uvgrtp::frame::rtcp_report_block>& reports);
439 void read_ssrc(
const uint8_t* buffer,
size_t& read_ptr, uint32_t& out_ssrc);
444 rtp_error_t handle_sender_report_packet(uint8_t* buffer,
size_t& read_ptr,
size_t packet_end,
446 rtp_error_t handle_receiver_report_packet(uint8_t* buffer,
size_t& read_ptr,
size_t packet_end,
448 rtp_error_t handle_sdes_packet(uint8_t* buffer,
size_t& read_ptr,
size_t packet_end,
450 rtp_error_t handle_bye_packet(uint8_t* buffer,
size_t& read_ptr,
452 rtp_error_t handle_app_packet(uint8_t* buffer,
size_t& read_ptr,
size_t packet_end,
455 static void rtcp_runner(
rtcp *
rtcp);
457 static void rtcp_report_reader(
rtcp *
rtcp);
462 bool is_participant(uint32_t ssrc)
const;
471 bool collision_detected(uint32_t ssrc)
const;
474 rtp_error_t add_participant(uint32_t ssrc);
482 rtp_error_t init_participant_seq(uint32_t ssrc, uint16_t base_seq);
489 rtp_error_t update_participant_seq(uint32_t ssrc, uint16_t seq);
495 void update_rtcp_bandwidth(
size_t pkt_size);
499 void update_avg_rtcp_size(uint64_t packet_size);
504 double rtcp_interval(
int members,
int senders,
505 double rtcp_bw,
bool we_sent,
double avg_rtcp_size,
bool red_min,
bool randomisation);
511 rtp_error_t remove_timeout_ssrc(uint32_t ssrc);
516 void zero_stats(uvgrtp::sender_statistics *stats);
518 void zero_stats(uvgrtp::receiver_statistics *stats);
521 rtp_error_t send_rtcp_packet_to_participants(uint8_t* frame, uint32_t frame_size,
bool encrypt);
523 void free_participant(std::unique_ptr<rtcp_participant> participant);
525 void cleanup_participants();
528 std::shared_ptr<uvgrtp::srtcp> srtcp_;
546 uint32_t total_bandwidth_;
552 double rtcp_bandwidth_;
556 uint32_t reduced_minimum_;
565 std::string local_addr_;
566 std::string remote_addr_;
567 uint16_t local_port_;
575 size_t avg_rtcp_pkt_pize_;
579 uint64_t avg_rtcp_size_;
583 size_t rtcp_pkt_count_;
584 size_t rtcp_byte_count_;
587 uint32_t rtcp_pkt_sent_count_;
594 std::shared_ptr<std::atomic_uint> ssrc_;
597 uint64_t clock_start_;
600 uint32_t clock_rate_;
603 uint32_t rtp_ts_start_;
605 std::map<uint32_t, std::unique_ptr<rtcp_participant>> participants_;
606 uint8_t num_receivers_;
610 sockaddr_in socket_address_;
611 sockaddr_in6 socket_address_ipv6_;
617 std::map<uint32_t, uint32_t> ms_since_last_rep_;
620 struct sender_statistics our_stats;
624 std::vector<std::unique_ptr<rtcp_participant>> initial_participants_;
633 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_hook_f_;
634 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sender_report>)> sr_hook_u_;
635 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_hook_f_;
636 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_receiver_report>)> rr_hook_u_;
637 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_hook_f_;
638 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_sdes_packet>)> sdes_hook_u_;
639 std::function<void(std::shared_ptr<uvgrtp::frame::rtcp_app_packet>)> app_hook_f_;
640 std::function<void(std::unique_ptr<uvgrtp::frame::rtcp_app_packet>)> app_hook_u_;
642 std::mutex sr_mutex_;
643 std::mutex rr_mutex_;
644 std::mutex sdes_mutex_;
645 std::mutex app_mutex_;
646 mutable std::mutex participants_mutex_;
647 std::mutex send_app_mutex_;
649 std::unique_ptr<std::thread> report_generator_;
650 std::unique_ptr<std::thread> report_reader_;
651 std::shared_ptr<uvgrtp::socket> rtcp_socket_;
653 bool is_active()
const
660 std::atomic<uint32_t> interval_ms_;
662 std::shared_ptr<uvgrtp::rtp> rtp_ptr_;
664 std::mutex packet_mutex_;
667 std::vector<uvgrtp::frame::rtcp_sdes_item> ourItems_;
668 std::vector<uint32_t> bye_ssrcs_;
670 std::map<std::string, std::deque<rtcp_app_packet>> app_packets_;
672 std::multimap<std::string, std::function <std::unique_ptr<uint8_t[]>(uint8_t& subtype, uint32_t& payload_len)>> outgoing_app_hooks_;
684namespace uvg_rtp = uvgrtp;
RTCP instance handles all incoming and outgoing RTCP traffic, including report generation.
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_send_app_hook(std::string app_name, std::function< std::unique_ptr< uint8_t[]>(uint8_t &subtype, uint32_t &payload_len)> app_sending_func)
Install hook for one type of APP packets.
rtp_error_t install_sdes_hook(void(*hook)(uvgrtp::frame::rtcp_sdes_packet *))
Install an RTCP SDES packet hook.
See RFC 3550 section 6.4.2
See RFC 3550 section 6.4.1