AI: RTC: Support keep_original_ssrc to preserve SSRC and timestamps. v7.0.119 (#3850)
This commit is contained in:
parent
dc8b2a804d
commit
0c26a3c309
|
|
@ -960,6 +960,17 @@ vhost rtc.vhost.srs.com {
|
|||
# Overwrite by env SRS_VHOST_RTC_INIT_RATE_FROM_SDP for all vhosts.
|
||||
# Default: off
|
||||
init_rate_from_sdp off;
|
||||
# Whether keep original SSRC and timestamp when forwarding RTC packets.
|
||||
# When enabled, SRS will preserve the original SSRC and RTP timestamps from
|
||||
# publisher to player, which is helpful for end-to-end debugging and troubleshooting
|
||||
# (e.g., tracking packet loss or delays using Wireshark).
|
||||
# When disabled (default), SRS generates new SSRC for each player and rebuilds
|
||||
# timestamps to ensure continuous playback during stream restarts and support
|
||||
# play-before-publish scenarios.
|
||||
# @see https://github.com/ossrs/srs/issues/3850
|
||||
# Overwrite by env SRS_VHOST_RTC_KEEP_ORIGINAL_SSRC for all vhosts.
|
||||
# Default: off
|
||||
keep_original_ssrc off;
|
||||
}
|
||||
###############################################################
|
||||
# For transmuxing RTMP to RTC, it will impact the default values if RTC is on.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* v7.0, 2025-11-07, AI: RTC: Support keep_original_ssrc to preserve SSRC and timestamps. v7.0.119 (#3850)
|
||||
* v7.0, 2025-11-05, AI: WebRTC: Report video/audio codec info and frame stats in HTTP API. v7.0.118 (#4554)
|
||||
* v7.0, 2025-11-04, AI: SRT: Report video/audio codec info and frame stats in HTTP API. v7.0.117 (#4554)
|
||||
* v7.0, 2025-11-03, Merge [#4556](https://github.com/ossrs/srs/pull/4556): Fill missing defs for H264/AVC video levels. v7.0.116 (#4556)
|
||||
|
|
|
|||
|
|
@ -2340,7 +2340,7 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
} else if (n == "rtc") {
|
||||
for (int j = 0; j < (int)conf->directives_.size(); j++) {
|
||||
string m = conf->at(j)->name_;
|
||||
if (m != "enabled" && m != "nack" && m != "twcc" && m != "nack_no_copy" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check" && m != "dtls_role" && m != "dtls_version" && m != "drop_for_pt" && m != "rtc_to_rtmp" && m != "pli_for_rtmp" && m != "rtmp_to_rtc" && m != "keep_bframe" && m != "opus_bitrate" && m != "aac_bitrate" && m != "keep_avc_nalu_sei" && m != "init_rate_from_sdp") {
|
||||
if (m != "enabled" && m != "nack" && m != "twcc" && m != "nack_no_copy" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check" && m != "dtls_role" && m != "dtls_version" && m != "drop_for_pt" && m != "rtc_to_rtmp" && m != "pli_for_rtmp" && m != "rtmp_to_rtc" && m != "keep_bframe" && m != "opus_bitrate" && m != "aac_bitrate" && m != "keep_avc_nalu_sei" && m != "init_rate_from_sdp" && m != "keep_original_ssrc") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.rtc.%s of %s", m.c_str(), vhost->arg0().c_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -4084,6 +4084,25 @@ bool SrsConfig::get_rtc_init_rate_from_sdp(string vhost)
|
|||
return SRS_CONF_PREFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_keep_original_ssrc(string vhost)
|
||||
{
|
||||
SRS_OVERWRITE_BY_ENV_BOOL("srs.vhost.rtc.keep_original_ssrc"); // SRS_VHOST_RTC_KEEP_ORIGINAL_SSRC
|
||||
|
||||
static bool DEFAULT = false;
|
||||
|
||||
SrsConfDirective *conf = get_rtc(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("keep_original_ssrc");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PREFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
SrsConfDirective *SrsConfig::get_vhost(string vhost, bool try_default_vhost)
|
||||
{
|
||||
srs_assert(root_);
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ public:
|
|||
virtual int get_rtc_drop_for_pt(std::string vhost) = 0;
|
||||
virtual bool get_rtc_twcc_enabled(std::string vhost) = 0;
|
||||
virtual bool get_rtc_init_rate_from_sdp(std::string vhost) = 0;
|
||||
virtual bool get_rtc_keep_original_ssrc(std::string vhost) = 0;
|
||||
virtual bool get_srt_enabled() = 0;
|
||||
virtual bool get_srt_enabled(std::string vhost) = 0;
|
||||
virtual std::string get_srt_default_streamid() = 0;
|
||||
|
|
@ -911,6 +912,7 @@ public:
|
|||
int get_rtc_opus_bitrate(std::string vhost);
|
||||
int get_rtc_aac_bitrate(std::string vhost);
|
||||
bool get_rtc_init_rate_from_sdp(std::string vhost);
|
||||
bool get_rtc_keep_original_ssrc(std::string vhost);
|
||||
|
||||
// vhost specified section
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -553,17 +553,20 @@ srs_error_t SrsRtcPlayStream::initialize(ISrsRequest *req, std::map<uint32_t, Sr
|
|||
// TODO: FIXME: Support reload.
|
||||
nack_enabled_ = config_->get_rtc_nack_enabled(req->vhost_);
|
||||
nack_no_copy_ = config_->get_rtc_nack_no_copy(req->vhost_);
|
||||
srs_trace("RTC player nack=%d, nnc=%d", nack_enabled_, nack_no_copy_);
|
||||
bool keep_original_ssrc = config_->get_rtc_keep_original_ssrc(req->vhost_);
|
||||
srs_trace("RTC player nack=%d, nnc=%d, keep_original_ssrc=%d", nack_enabled_, nack_no_copy_, keep_original_ssrc);
|
||||
|
||||
// Setup tracks.
|
||||
for (map<uint32_t, SrsRtcAudioSendTrack *>::iterator it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) {
|
||||
SrsRtcAudioSendTrack *track = it->second;
|
||||
track->set_nack_no_copy(nack_no_copy_);
|
||||
track->set_keep_original_ssrc(keep_original_ssrc);
|
||||
}
|
||||
|
||||
for (map<uint32_t, SrsRtcVideoSendTrack *>::iterator it = video_tracks_.begin(); it != video_tracks_.end(); ++it) {
|
||||
SrsRtcVideoSendTrack *track = it->second;
|
||||
track->set_nack_no_copy(nack_no_copy_);
|
||||
track->set_keep_original_ssrc(keep_original_ssrc);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
@ -3718,6 +3721,7 @@ srs_error_t SrsRtcPlayerNegotiator::negotiate_play_capability(SrsRtcUserConfig *
|
|||
|
||||
bool nack_enabled = config_->get_rtc_nack_enabled(req->vhost_);
|
||||
bool twcc_enabled = config_->get_rtc_twcc_enabled(req->vhost_);
|
||||
bool keep_original_ssrc = config_->get_rtc_keep_original_ssrc(req->vhost_);
|
||||
|
||||
SrsSharedPtr<SrsRtcSource> source;
|
||||
if ((err = rtc_sources_->fetch_or_create(req, source)) != srs_success) {
|
||||
|
|
@ -3879,7 +3883,12 @@ srs_error_t SrsRtcPlayerNegotiator::negotiate_play_capability(SrsRtcUserConfig *
|
|||
}
|
||||
}
|
||||
|
||||
// When keep_original_ssrc is enabled, preserve the original SSRC from publisher.
|
||||
// Otherwise, generate a new SSRC for each player.
|
||||
// @see https://github.com/ossrs/srs/issues/3850
|
||||
if (!keep_original_ssrc) {
|
||||
track->ssrc_ = SrsRtcSSRCGenerator::instance()->generate_ssrc();
|
||||
}
|
||||
|
||||
// TODO: FIXME: set audio_payload rtcp_fbs_,
|
||||
// according by whether downlink is support transport algorithms.
|
||||
|
|
|
|||
|
|
@ -3521,6 +3521,7 @@ SrsRtcSendTrack::SrsRtcSendTrack(ISrsRtcPacketSender *sender, SrsRtcTrackDescrip
|
|||
sender_ = sender;
|
||||
track_desc_ = track_desc->copy();
|
||||
nack_no_copy_ = false;
|
||||
keep_original_ssrc_ = false;
|
||||
|
||||
// Make a different start of sequence number, for debugging.
|
||||
jitter_ts_ = new SrsRtcTsJitter(track_desc_->type_ == "audio" ? 10000 : 20000);
|
||||
|
|
@ -3594,6 +3595,13 @@ std::string SrsRtcSendTrack::get_track_id()
|
|||
|
||||
void SrsRtcSendTrack::rebuild_packet(SrsRtpPacket *pkt)
|
||||
{
|
||||
// If keep_original_ssrc is enabled, skip rebuilding sequence number and timestamp.
|
||||
// This preserves the original SSRC and timestamps for end-to-end debugging.
|
||||
// @see https://github.com/ossrs/srs/issues/3850
|
||||
if (keep_original_ssrc_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rebuild the sequence number.
|
||||
int16_t seq = pkt->header_.get_sequence();
|
||||
pkt->header_.set_sequence(jitter_seq_->correct(seq));
|
||||
|
|
|
|||
|
|
@ -1073,6 +1073,8 @@ SRS_DECLARE_PROTECTED: // clang-format on
|
|||
SRS_DECLARE_PRIVATE: // clang-format on
|
||||
// By config, whether no copy.
|
||||
bool nack_no_copy_;
|
||||
// By config, whether keep original SSRC and timestamp.
|
||||
bool keep_original_ssrc_;
|
||||
// The pithy print for special stage.
|
||||
SrsErrorPithyPrint *nack_epp;
|
||||
|
||||
|
|
@ -1083,6 +1085,8 @@ public:
|
|||
public:
|
||||
// SrsRtcSendTrack::set_nack_no_copy
|
||||
void set_nack_no_copy(bool v) { nack_no_copy_ = v; }
|
||||
// SrsRtcSendTrack::set_keep_original_ssrc
|
||||
void set_keep_original_ssrc(bool v) { keep_original_ssrc_ = v; }
|
||||
bool has_ssrc(uint32_t ssrc);
|
||||
SrsRtpPacket *fetch_rtp_packet(uint16_t seq);
|
||||
bool set_track_status(bool active);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 118
|
||||
#define VERSION_REVISION 119
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user