Skip to content

Commit

Permalink
config: allow for custom SSRC. Added thread safety
Browse files Browse the repository at this point in the history
  • Loading branch information
vechtomo committed Dec 7, 2022
1 parent c72b9ec commit 2806a1e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 29 deletions.
4 changes: 3 additions & 1 deletion include/uvgrtp/media_stream.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <unordered_map>
#include <memory>
#include <string>

#include <atomic>

#ifndef _WIN32
#include <sys/socket.h>
Expand Down Expand Up @@ -315,6 +315,8 @@ namespace uvgrtp {
std::shared_ptr<uvgrtp::rtp> rtp_;
std::shared_ptr<uvgrtp::rtcp> rtcp_;

std::shared_ptr<std::atomic<std::uint32_t>> ssrc_;

sockaddr_in remote_sockaddr_;
std::string remote_address_;
std::string local_address_;
Expand Down
7 changes: 4 additions & 3 deletions include/uvgrtp/rtcp.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <memory>
#include <mutex>
#include <deque>
#include <atomic>

namespace uvgrtp {

Expand Down Expand Up @@ -108,8 +109,8 @@ namespace uvgrtp {
class rtcp {
public:
/// \cond DO_NOT_DOCUMENT
rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_flags);
rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, std::shared_ptr<uvgrtp::srtcp> srtcp, int rce_flags);
rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::shared_ptr<std::atomic<std::uint32_t>> ssrc, std::string cname, int rce_flags);
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);
~rtcp();

/* start the RTCP runner thread
Expand Down Expand Up @@ -512,7 +513,7 @@ namespace uvgrtp {
bool initial_;

/* Copy of our own current SSRC */
const uint32_t ssrc_;
std::shared_ptr<std::atomic_uint> ssrc_;

/* NTP timestamp associated with initial RTP timestamp (aka t = 0) */
uint64_t clock_start_;
Expand Down
7 changes: 7 additions & 0 deletions include/uvgrtp/util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,13 @@ enum RTP_CTX_CONFIGURATION_FLAGS {
* See RCC_FPS_NUMERATOR for more info.
*/
RCC_FPS_DENOMINATOR = 9,

/** Set the SSRC of the stream manually
*
* By default SSRC is generated randomly
*/
RCC_SSRC = 10,

/// \cond DO_NOT_DOCUMENT
RCC_LAST
/// \endcond
Expand Down
23 changes: 15 additions & 8 deletions src/media_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ uvgrtp::media_stream::media_stream(std::string cname, std::string remote_addr,
holepuncher_(std::unique_ptr<uvgrtp::holepuncher>(new uvgrtp::holepuncher(socket_))),
cname_(cname),
fps_numerator_(30),
fps_denominator_(1)
fps_denominator_(1),
ssrc_(std::make_shared<std::atomic<std::uint32_t>>(uvgrtp::random::generate_32()))
{}

uvgrtp::media_stream::~media_stream()
Expand Down Expand Up @@ -257,8 +258,8 @@ rtp_error_t uvgrtp::media_stream::init()

reception_flow_ = std::unique_ptr<uvgrtp::reception_flow> (new uvgrtp::reception_flow());

rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_));
rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, cname_, rce_flags_));
rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_, ssrc_));
rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, ssrc_, cname_, rce_flags_));

socket_->install_handler(rtcp_.get(), rtcp_->send_packet_handler_vec);

Expand All @@ -277,7 +278,7 @@ rtp_error_t uvgrtp::media_stream::init(std::shared_ptr<uvgrtp::zrtp> zrtp)

reception_flow_ = std::unique_ptr<uvgrtp::reception_flow> (new uvgrtp::reception_flow());

rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_));
rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_, ssrc_));

bool perform_dh = !(rce_flags_ & RCE_ZRTP_MULTISTREAM_MODE);
if (!perform_dh)
Expand Down Expand Up @@ -313,7 +314,7 @@ rtp_error_t uvgrtp::media_stream::init(std::shared_ptr<uvgrtp::zrtp> zrtp)

zrtp->dh_has_finished(); // only after the DH stream has gotten its keys, do we let non-DH stream perform ZRTP

rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, cname_, srtcp_, rce_flags_));
rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, ssrc_, cname_, srtcp_, rce_flags_));

socket_->install_handler(rtcp_.get(), rtcp_->send_packet_handler_vec);
socket_->install_handler(srtp_.get(), srtp_->send_packet_handler);
Expand Down Expand Up @@ -345,7 +346,7 @@ rtp_error_t uvgrtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt)

reception_flow_ = std::unique_ptr<uvgrtp::reception_flow> (new uvgrtp::reception_flow());

rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_));
rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_, ssrc_));

srtp_ = std::shared_ptr<uvgrtp::srtp> (new uvgrtp::srtp(rce_flags_));

Expand All @@ -362,7 +363,7 @@ rtp_error_t uvgrtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt)
return free_resources(ret);
}

rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, cname_, srtcp_, rce_flags_));
rtcp_ = std::shared_ptr<uvgrtp::rtcp> (new uvgrtp::rtcp(rtp_, ssrc_, cname_, srtcp_, rce_flags_));

socket_->install_handler(rtcp_.get(), rtcp_->send_packet_handler_vec);
socket_->install_handler(srtp_.get(), srtp_->send_packet_handler);
Expand Down Expand Up @@ -660,7 +661,13 @@ rtp_error_t uvgrtp::media_stream::configure_ctx(int rcc_flag, ssize_t value)
media_->set_fps(fps_numerator_, fps_denominator_);
break;
}
case RCC_SSRC: {
if (value <= 0 || value > (ssize_t)UINT32_MAX)
return RTP_INVALID_VALUE;

*ssrc_ = (uint32_t)value;
break;
}
default:
return RTP_INVALID_VALUE;
}
Expand All @@ -685,7 +692,7 @@ uint32_t uvgrtp::media_stream::get_ssrc() const
return 0;
}

return rtp_->get_ssrc();
return *ssrc_.get();
}

rtp_error_t uvgrtp::media_stream::init_srtp_with_zrtp(int rce_flags, int type, std::shared_ptr<uvgrtp::base_srtp> srtp,
Expand Down
23 changes: 12 additions & 11 deletions src/rtcp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ constexpr int ESTIMATED_MAX_RECEPTION_TIME_MS = 10;

const uint32_t MAX_SUPPORTED_PARTICIPANTS = 31;

uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_flags):
rce_flags_(rce_flags), our_role_(RECEIVER),
uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::shared_ptr<std::atomic_uint> ssrc, std::string cname, int rce_flags):
rce_flags_(rce_flags), our_role_(RECEIVER), ssrc_(ssrc),
tp_(0), tc_(0), tn_(0), pmembers_(0),
members_(0), senders_(0), rtcp_bandwidth_(0),
we_sent_(false), avg_rtcp_pkt_pize_(0), rtcp_pkt_count_(0),
rtcp_pkt_sent_count_(0), initial_(true), ssrc_(rtp->get_ssrc()),
rtcp_pkt_sent_count_(0), initial_(true),
num_receivers_(0),
sender_hook_(nullptr),
receiver_hook_(nullptr),
Expand Down Expand Up @@ -89,9 +89,9 @@ uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname, int rce_
}
}

uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::string cname,
uvgrtp::rtcp::rtcp(std::shared_ptr<uvgrtp::rtp> rtp, std::shared_ptr<std::atomic_uint> ssrc, std::string cname,
std::shared_ptr<uvgrtp::srtcp> srtcp, int rce_flags):
rtcp(rtp, cname, rce_flags)
rtcp(rtp, ssrc, cname, rce_flags)
{
srtcp_ = srtcp;
}
Expand Down Expand Up @@ -229,7 +229,7 @@ rtp_error_t uvgrtp::rtcp::stop()
}

/* Send BYE packet with our SSRC to all participants */
return uvgrtp::rtcp::send_bye_packet({ ssrc_ });
return uvgrtp::rtcp::send_bye_packet({ *ssrc_.get() });
}

void uvgrtp::rtcp::rtcp_runner(rtcp* rtcp, int interval)
Expand Down Expand Up @@ -1515,7 +1515,7 @@ rtp_error_t uvgrtp::rtcp::send_rtcp_packet_to_participants(uint8_t* frame, uint3
rtp_error_t ret = RTP_OK;

if (encrypt && srtcp_ &&
(ret = srtcp_->handle_rtcp_encryption(rce_flags_, rtcp_pkt_sent_count_, ssrc_, frame, frame_size)) != RTP_OK)
(ret = srtcp_->handle_rtcp_encryption(rce_flags_, rtcp_pkt_sent_count_, *ssrc_.get(), frame, frame_size)) != RTP_OK)
{
UVG_LOG_DEBUG("Encryption failed. Not sending packet");
delete[] frame;
Expand Down Expand Up @@ -1640,6 +1640,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
// see https://datatracker.ietf.org/doc/html/rfc3550#section-6.4.1

size_t write_ptr = 0;
uint32_t ssrc = *ssrc_.get();
if (sr_packet)
{
// sender reports have sender information in addition compared to receiver reports
Expand All @@ -1662,7 +1663,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
uint64_t rtp_ts = expanded_ts_start + ts_since_start;

if (!construct_rtcp_header(frame, write_ptr, sender_report_size, reports, uvgrtp::frame::RTCP_FT_SR) ||
!construct_ssrc(frame, write_ptr, ssrc_) ||
!construct_ssrc(frame, write_ptr, ssrc) ||
!construct_sender_info(frame, write_ptr, ntp_ts, rtp_ts, our_stats.sent_pkts, our_stats.sent_bytes))
{
UVG_LOG_ERROR("Failed to construct SR");
Expand All @@ -1675,7 +1676,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
size_t receiver_report_size = get_rr_packet_size(rce_flags_, reports);

if (!construct_rtcp_header(frame, write_ptr, receiver_report_size, reports, uvgrtp::frame::RTCP_FT_RR) ||
!construct_ssrc(frame, write_ptr, ssrc_))
!construct_ssrc(frame, write_ptr, ssrc))
{
UVG_LOG_ERROR("Failed to construct RR");
return RTP_GENERIC_ERROR;
Expand Down Expand Up @@ -1724,7 +1725,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
// add the SDES packet after the SR/RR, mandatory, must contain CNAME
if (!construct_rtcp_header(frame, write_ptr, get_sdes_packet_size(ourItems_), num_receivers_,
uvgrtp::frame::RTCP_FT_SDES) ||
!construct_sdes_chunk(frame, write_ptr, { ssrc_, ourItems_ }))
!construct_sdes_chunk(frame, write_ptr, { ssrc, ourItems_ }))
{
UVG_LOG_ERROR("Failed to add SDES packet");
delete[] frame;
Expand All @@ -1750,7 +1751,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()

if (!construct_rtcp_header(frame, write_ptr, packet_size, secondField,
uvgrtp::frame::RTCP_FT_APP) ||
!construct_ssrc(frame, write_ptr, ssrc_) ||
!construct_ssrc(frame, write_ptr, ssrc) ||
!construct_app_packet(frame, write_ptr, next_packet.name, next_packet.payload, next_packet.payload_len))
{
UVG_LOG_ERROR("Failed to construct APP packet");
Expand Down
8 changes: 4 additions & 4 deletions src/rtp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

#define INVALID_TS UINT64_MAX

uvgrtp::rtp::rtp(rtp_format_t fmt):
ssrc_(uvgrtp::random::generate_32()),
uvgrtp::rtp::rtp(rtp_format_t fmt, std::shared_ptr<std::atomic<std::uint32_t>> ssrc):
ssrc_(ssrc),
ts_(uvgrtp::random::generate_32()),
seq_(uvgrtp::random::generate_32() & 0xffff),
fmt_(fmt),
Expand All @@ -40,7 +40,7 @@ uvgrtp::rtp::~rtp()

uint32_t uvgrtp::rtp::get_ssrc() const
{
return ssrc_;
return *ssrc_.get();
}

uint16_t uvgrtp::rtp::get_sequence() const
Expand Down Expand Up @@ -145,7 +145,7 @@ void uvgrtp::rtp::fill_header(uint8_t *buffer)
buffer[1] = (payload_ & 0x7f) | (0 << 7);

*(uint16_t *)&buffer[2] = htons(seq_);
*(uint32_t *)&buffer[8] = htonl(ssrc_);
*(uint32_t *)&buffer[8] = htonl(*ssrc_.get());

if (timestamp_ == INVALID_TS) {

Expand Down
6 changes: 4 additions & 2 deletions src/rtp.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "uvgrtp/util.hh"

#include <chrono>
#include <memory>
#include <atomic>

namespace uvgrtp {

Expand All @@ -14,7 +16,7 @@ namespace uvgrtp {

class rtp {
public:
rtp(rtp_format_t fmt);
rtp(rtp_format_t fmt, std::shared_ptr<std::atomic<std::uint32_t>> ssrc);
~rtp();

uint32_t get_ssrc() const;
Expand Down Expand Up @@ -44,7 +46,7 @@ namespace uvgrtp {

void set_default_clock_rate(rtp_format_t fmt);

uint32_t ssrc_;
std::shared_ptr<std::atomic<std::uint32_t>> ssrc_;
uint32_t ts_;
uint16_t seq_;
rtp_format_t fmt_;
Expand Down

0 comments on commit 2806a1e

Please sign in to comment.