config: allow for custom SSRC. Added thread safety
This commit is contained in:
parent
ce3aa62b3f
commit
db19b52dc5
|
@ -5,7 +5,7 @@
|
|||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
|
@ -345,6 +345,8 @@ namespace uvgrtp {
|
|||
|
||||
ssize_t fps_numerator_ = 30;
|
||||
ssize_t fps_denominator_ = 1;
|
||||
|
||||
std::shared_ptr<std::atomic<std::uint32_t>> ssrc_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <atomic>
|
||||
|
||||
namespace uvgrtp {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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_));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
|
23
src/rtcp.cc
23
src/rtcp.cc
|
@ -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),
|
||||
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), ssrc_(ssrc),
|
||||
num_receivers_(0),
|
||||
sender_hook_(nullptr),
|
||||
receiver_hook_(nullptr),
|
||||
|
@ -92,9 +92,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;
|
||||
}
|
||||
|
@ -232,7 +232,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)
|
||||
|
@ -1518,7 +1518,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;
|
||||
|
@ -1643,6 +1643,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
|
||||
|
@ -1665,7 +1666,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");
|
||||
|
@ -1678,7 +1679,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;
|
||||
|
@ -1726,7 +1727,7 @@ rtp_error_t uvgrtp::rtcp::generate_report()
|
|||
{
|
||||
uvgrtp::frame::rtcp_sdes_chunk chunk;
|
||||
chunk.items = ourItems_;
|
||||
chunk.ssrc = ssrc_;
|
||||
chunk.ssrc = *ssrc_.get();
|
||||
|
||||
// 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_,
|
||||
|
@ -1757,7 +1758,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");
|
||||
|
|
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "uvgrtp/util.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace uvgrtp {
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
|
Loading…
Reference in New Issue