mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
Merge branch '4.0release' into develop
This commit is contained in:
commit
79358673ef
6 changed files with 120 additions and 4 deletions
|
@ -63,6 +63,7 @@ The changelog for SRS.
|
|||
|
||||
## SRS 4.0 Changelog
|
||||
|
||||
* v4.0, 2022-09-03, For [#3167](https://github.com/ossrs/srs/issues/3167): WebRTC: Play stucked when republish. v4.0.260
|
||||
* v4.0, 2022-09-02, For [#307](https://github.com/ossrs/srs/issues/307): WebRTC: Support use domain name as CANDIDATE. v4.0.259
|
||||
* v4.0, 2022-08-29, Copy libxml2-dev for FFmpeg. v4.0.258
|
||||
* v4.0, 2022-08-24, STAT: Support config server_id and generate one if empty. v4.0.257
|
||||
|
|
|
@ -517,10 +517,12 @@ srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::map<uint32_t, Srs
|
|||
|
||||
void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
|
||||
{
|
||||
if (!desc) return;
|
||||
|
||||
// Refresh the relation for audio.
|
||||
// TODO: FIXME: Match by label?
|
||||
if (desc && desc->audio_track_desc_ && audio_tracks_.size() == 1) {
|
||||
if (! audio_tracks_.empty()) {
|
||||
if (!audio_tracks_.empty()) {
|
||||
uint32_t ssrc = desc->audio_track_desc_->ssrc_;
|
||||
SrsRtcAudioSendTrack* track = audio_tracks_.begin()->second;
|
||||
|
||||
|
@ -532,7 +534,7 @@ void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
|
|||
// Refresh the relation for video.
|
||||
// TODO: FIMXE: Match by label?
|
||||
if (desc && desc->video_track_descs_.size() == 1) {
|
||||
if (! video_tracks_.empty()) {
|
||||
if (!video_tracks_.empty()) {
|
||||
SrsRtcTrackDescription* vdesc = desc->video_track_descs_.at(0);
|
||||
uint32_t ssrc = vdesc->ssrc_;
|
||||
SrsRtcVideoSendTrack* track = video_tracks_.begin()->second;
|
||||
|
@ -541,6 +543,15 @@ void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
|
|||
video_tracks_.insert(make_pair(ssrc, track));
|
||||
}
|
||||
}
|
||||
|
||||
// Request keyframe(PLI) when stream changed.
|
||||
if (desc->audio_track_desc_) {
|
||||
pli_worker_->request_keyframe(desc->audio_track_desc_->ssrc_, cid_);
|
||||
}
|
||||
for (vector<SrsRtcTrackDescription*>::iterator it = desc->video_track_descs_.begin(); it != desc->video_track_descs_.end(); ++it) {
|
||||
SrsRtcTrackDescription* vdesc = *it;
|
||||
pli_worker_->request_keyframe(vdesc->ssrc_, cid_);
|
||||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcPlayStream::on_reload_vhost_play(string vhost)
|
||||
|
|
|
@ -2552,12 +2552,53 @@ srs_error_t SrsRtcVideoRecvTrack::check_send_nacks()
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsRtcJitter::SrsRtcJitter(uint32_t base)
|
||||
{
|
||||
pkt_base_ = pkt_last_ = 0;
|
||||
correct_last_ = correct_base_ = 0;
|
||||
base_ = base;
|
||||
init_ = false;
|
||||
}
|
||||
|
||||
SrsRtcJitter::~SrsRtcJitter()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t SrsRtcJitter::correct(uint32_t ts)
|
||||
{
|
||||
if (!init_) {
|
||||
init_ = true;
|
||||
correct_base_ = base_;
|
||||
srs_trace("RTC: Jitter init base=%u, ts=%u", base_, ts);
|
||||
}
|
||||
if (!pkt_base_) pkt_base_ = ts;
|
||||
|
||||
if (pkt_last_) {
|
||||
int32_t distance = srs_rtp_ts_distance(ts, pkt_last_);
|
||||
static int32_t max_deviation = 90 * 3 * 1000;
|
||||
if (distance > max_deviation || distance < -1 * max_deviation) {
|
||||
srs_trace("RTC: Jitter rebase ts=%u, last=%u, distance=%d, pkt-base=%u/%u, correct-base=%u/%u", ts, pkt_last_, distance, pkt_base_, ts, correct_base_, correct_last_);
|
||||
pkt_base_ = ts;
|
||||
correct_base_ = correct_last_;
|
||||
}
|
||||
}
|
||||
pkt_last_ = ts;
|
||||
|
||||
correct_last_ = correct_base_ + ts - pkt_base_;
|
||||
return correct_last_;
|
||||
}
|
||||
|
||||
SrsRtcSendTrack::SrsRtcSendTrack(SrsRtcConnection* session, SrsRtcTrackDescription* track_desc, bool is_audio)
|
||||
{
|
||||
session_ = session;
|
||||
track_desc_ = track_desc->copy();
|
||||
nack_no_copy_ = false;
|
||||
|
||||
seqno_ = 0;
|
||||
init_ = false;
|
||||
// Make a different start of sequence number, for debugging.
|
||||
jitter_ = new SrsRtcJitter(track_desc_->type_ == "audio" ? 10000 : 20000);
|
||||
|
||||
if (is_audio) {
|
||||
rtp_queue_ = new SrsRtpRingBuffer(100);
|
||||
} else {
|
||||
|
@ -2572,6 +2613,7 @@ SrsRtcSendTrack::~SrsRtcSendTrack()
|
|||
srs_freep(rtp_queue_);
|
||||
srs_freep(track_desc_);
|
||||
srs_freep(nack_epp);
|
||||
srs_freep(jitter_);
|
||||
}
|
||||
|
||||
bool SrsRtcSendTrack::has_ssrc(uint32_t ssrc)
|
||||
|
@ -2622,6 +2664,23 @@ std::string SrsRtcSendTrack::get_track_id()
|
|||
return track_desc_->id_;
|
||||
}
|
||||
|
||||
void SrsRtcSendTrack::rebuild_packet(SrsRtpPacket* pkt)
|
||||
{
|
||||
// Rebuild the sequence number.
|
||||
if (!init_) {
|
||||
init_ = true;
|
||||
// Make a different start of sequence number, for debugging.
|
||||
seqno_ = track_desc_->type_ == "audio" ? 1000 : 2000;
|
||||
srs_trace("RTC: Seqno rebuild %s track=%s, ssrc=%d, seqno=%d to %d", track_desc_->type_.c_str(), track_desc_->id_.c_str(),
|
||||
pkt->header.get_ssrc(), pkt->header.get_sequence(), seqno_);
|
||||
}
|
||||
pkt->header.set_sequence(seqno_++);
|
||||
|
||||
// Rebuild the timestamp.
|
||||
uint32_t ts = pkt->header.get_timestamp();
|
||||
pkt->header.set_timestamp(jitter_->correct(ts));
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket** ppkt)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -2699,10 +2758,16 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket* pkt)
|
|||
// TODO: FIXME: Should update PT for RTX.
|
||||
}
|
||||
|
||||
// Rebuild the sequence number and timestamp of packet, see https://github.com/ossrs/srs/issues/3167
|
||||
rebuild_packet(pkt);
|
||||
|
||||
if ((err = session_->do_send_packet(pkt)) != srs_success) {
|
||||
return srs_error_wrap(err, "raw send");
|
||||
}
|
||||
|
||||
srs_info("RTC: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
|
||||
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -2743,10 +2808,16 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket* pkt)
|
|||
// TODO: FIXME: Should update PT for RTX.
|
||||
}
|
||||
|
||||
// Rebuild the sequence number and timestamp of packet, see https://github.com/ossrs/srs/issues/3167
|
||||
rebuild_packet(pkt);
|
||||
|
||||
if ((err = session_->do_send_packet(pkt)) != srs_success) {
|
||||
return srs_error_wrap(err, "raw send");
|
||||
}
|
||||
|
||||
srs_info("RTC: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
|
||||
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -579,9 +579,29 @@ public:
|
|||
virtual srs_error_t check_send_nacks();
|
||||
};
|
||||
|
||||
class SrsRtcJitter
|
||||
{
|
||||
private:
|
||||
// The ts about packet.
|
||||
uint32_t pkt_base_;
|
||||
uint32_t pkt_last_;
|
||||
// The ts after corrected.
|
||||
uint32_t correct_base_;
|
||||
uint32_t correct_last_;
|
||||
// The base timestamp by config, start from it.
|
||||
uint32_t base_;
|
||||
// Whether initialized. Note that we should not use correct_base_(0) as init state, because it might flip back.
|
||||
bool init_;
|
||||
public:
|
||||
SrsRtcJitter(uint32_t base);
|
||||
virtual ~SrsRtcJitter();
|
||||
public:
|
||||
uint32_t correct(uint32_t ts);
|
||||
};
|
||||
|
||||
class SrsRtcSendTrack
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
// send track description
|
||||
SrsRtcTrackDescription* track_desc_;
|
||||
protected:
|
||||
|
@ -589,6 +609,13 @@ protected:
|
|||
SrsRtcConnection* session_;
|
||||
// NACK ARQ ring buffer.
|
||||
SrsRtpRingBuffer* rtp_queue_;
|
||||
protected:
|
||||
// Current sequence number.
|
||||
uint64_t seqno_;
|
||||
// Whether initialized. Note that we should not use seqno_(0) as init state, because it might flip back.
|
||||
bool init_;
|
||||
// The jitter to correct ts.
|
||||
SrsRtcJitter* jitter_;
|
||||
private:
|
||||
// By config, whether no copy.
|
||||
bool nack_no_copy_;
|
||||
|
@ -605,6 +632,8 @@ public:
|
|||
bool set_track_status(bool active);
|
||||
bool get_track_status();
|
||||
std::string get_track_id();
|
||||
protected:
|
||||
void rebuild_packet(SrsRtpPacket* pkt);
|
||||
public:
|
||||
// Note that we can set the pkt to NULL to avoid copy, for example, if the NACK cache the pkt and
|
||||
// set to NULL, nack nerver copy it but set the pkt to NULL.
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 259
|
||||
#define VERSION_REVISION 260
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,10 @@ inline int16_t srs_rtp_seq_distance(const uint16_t& prev_value, const uint16_t&
|
|||
{
|
||||
return (int16_t)(value - prev_value);
|
||||
}
|
||||
inline int32_t srs_rtp_ts_distance(const uint32_t& prev_value, const uint32_t& value)
|
||||
{
|
||||
return (int32_t)(value - prev_value);
|
||||
}
|
||||
|
||||
// For map to compare the sequence of RTP.
|
||||
struct SrsSeqCompareLess {
|
||||
|
|
Loading…
Reference in a new issue