RTC: Refine code

pull/1882/head
winlin 5 years ago
parent 69fc1ba711
commit 545a0efea3

@ -633,6 +633,21 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(SrsRequest* req, const SrsSdp& remo
SrsMediaDesc& local_media_desc = local_sdp.media_descs_.back(); SrsMediaDesc& local_media_desc = local_sdp.media_descs_.back();
// Whether feature enabled in remote extmap.
int remote_twcc_id = 0;
if (true) {
map<int, string> extmaps = remote_media_desc.get_extmaps();
for(map<int, string>::iterator it = extmaps.begin(); it != extmaps.end(); ++it) {
if (it->second == kTWCCExt) {
remote_twcc_id = it->first;
break;
}
}
}
if (twcc_enabled && remote_twcc_id) {
local_media_desc.extmaps_[remote_twcc_id] = kTWCCExt;
}
if (remote_media_desc.is_audio()) { if (remote_media_desc.is_audio()) {
// TODO: check opus format specific param // TODO: check opus format specific param
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus"); std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus");
@ -649,7 +664,7 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(SrsRequest* req, const SrsSdp& remo
payload_type.rtcp_fb_.push_back(rtcp_fb.at(j)); payload_type.rtcp_fb_.push_back(rtcp_fb.at(j));
} }
} }
if (twcc_enabled) { if (twcc_enabled && remote_twcc_id) {
if (rtcp_fb.at(j) == "transport-cc") { if (rtcp_fb.at(j) == "transport-cc") {
payload_type.rtcp_fb_.push_back(rtcp_fb.at(j)); payload_type.rtcp_fb_.push_back(rtcp_fb.at(j));
} }
@ -659,13 +674,6 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(SrsRequest* req, const SrsSdp& remo
// Only choose one match opus codec. // Only choose one match opus codec.
break; break;
} }
map<int, string> extmaps = remote_media_desc.get_extmaps();
for(map<int, string>::iterator it_ext = extmaps.begin(); it_ext != extmaps.end(); ++it_ext) {
if (it_ext->second == kTWCCExt) {
local_media_desc.extmaps_[it_ext->first] = kTWCCExt;
break;
}
}
if (local_media_desc.payload_types_.empty()) { if (local_media_desc.payload_types_.empty()) {
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type"); return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type");
@ -698,7 +706,7 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(SrsRequest* req, const SrsSdp& remo
payload_type.rtcp_fb_.push_back(rtcp_fb.at(j)); payload_type.rtcp_fb_.push_back(rtcp_fb.at(j));
} }
} }
if (twcc_enabled) { if (twcc_enabled && remote_twcc_id) {
if (rtcp_fb.at(j) == "transport-cc") { if (rtcp_fb.at(j) == "transport-cc") {
payload_type.rtcp_fb_.push_back(rtcp_fb.at(j)); payload_type.rtcp_fb_.push_back(rtcp_fb.at(j));
} }
@ -711,13 +719,6 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(SrsRequest* req, const SrsSdp& remo
backup_payloads.push_back(*iter); backup_payloads.push_back(*iter);
} }
map<int, string> extmaps = remote_media_desc.get_extmaps();
for(map<int, string>::iterator it_ext = extmaps.begin(); it_ext != extmaps.end(); ++it_ext) {
if (it_ext->second == kTWCCExt) {
local_media_desc.extmaps_[it_ext->first] = kTWCCExt;
break;
}
}
// Try my best to pick at least one media payload type. // Try my best to pick at least one media payload type.
if (local_media_desc.payload_types_.empty() && ! backup_payloads.empty()) { if (local_media_desc.payload_types_.empty() && ! backup_payloads.empty()) {

@ -295,7 +295,7 @@ SrsRtcPlayer::~SrsRtcPlayer()
srs_freep(video_queue_); srs_freep(video_queue_);
} }
srs_error_t SrsRtcPlayer::initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt) srs_error_t SrsRtcPlayer::initialize(uint32_t vssrc, uint32_t assrc, uint16_t v_pt, uint16_t a_pt)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
@ -481,6 +481,7 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcSource* source, const vector<SrsRtp
// Update stats. // Update stats.
info.nn_bytes += pkt->nb_bytes(); info.nn_bytes += pkt->nb_bytes();
// For audio, we transcoded AAC to opus in extra payloads.
if (pkt->is_audio()) { if (pkt->is_audio()) {
info.nn_audios++; info.nn_audios++;
pkt->header.set_ssrc(audio_ssrc); pkt->header.set_ssrc(audio_ssrc);
@ -526,6 +527,7 @@ srs_error_t SrsRtcPlayer::do_send_packets(const std::vector<SrsRtpPacket2*>& pkt
iov->iov_base = iov_base; iov->iov_base = iov_base;
iov->iov_len = kRtpPacketSize; iov->iov_len = kRtpPacketSize;
uint16_t twcc_sn = 0;
// Marshal packet to bytes in iovec. // Marshal packet to bytes in iovec.
if (true) { if (true) {
SrsBuffer stream((char*)iov->iov_base, iov->iov_len); SrsBuffer stream((char*)iov->iov_base, iov->iov_len);
@ -858,7 +860,7 @@ SrsRtcPublisher::SrsRtcPublisher(SrsRtcSession* session)
pt_to_drop_ = 0; pt_to_drop_ = 0;
nn_audio_frames = 0; nn_audio_frames = 0;
twcc_ext_id_ = 0; twcc_id_ = 0;
last_twcc_feedback_time_ = 0; last_twcc_feedback_time_ = 0;
twcc_fb_count_ = 0; twcc_fb_count_ = 0;
} }
@ -878,25 +880,28 @@ SrsRtcPublisher::~SrsRtcPublisher()
srs_freep(audio_queue_); srs_freep(audio_queue_);
} }
srs_error_t SrsRtcPublisher::initialize(uint32_t vssrc, uint32_t assrc, uint8_t twcc_ext_id, SrsRequest* r) srs_error_t SrsRtcPublisher::initialize(uint32_t vssrc, uint32_t assrc, int twcc_id, SrsRequest* r)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
video_ssrc = vssrc; video_ssrc = vssrc;
audio_ssrc = assrc; audio_ssrc = assrc;
twcc_ext_id_ = twcc_ext_id;
rtcp_twcc_.set_media_ssrc(video_ssrc);
req = r; req = r;
if (twcc_ext_id_ != 0) {
extension_types_.register_by_uri(twcc_ext_id_, kTWCCExt);
}
// TODO: FIXME: Support reload. // TODO: FIXME: Support reload.
nack_enabled_ = _srs_config->get_rtc_nack_enabled(session_->req->vhost); nack_enabled_ = _srs_config->get_rtc_nack_enabled(session_->req->vhost);
pt_to_drop_ = (uint16_t)_srs_config->get_rtc_drop_for_pt(session_->req->vhost); pt_to_drop_ = (uint16_t)_srs_config->get_rtc_drop_for_pt(session_->req->vhost);
bool twcc_enabled = _srs_config->get_rtc_twcc_enabled(req->vhost);
if (twcc_enabled) {
twcc_id_ = twcc_id;
}
srs_trace("RTC publisher video(ssrc=%u), audio(ssrc=%u), nack=%d, pt-drop=%u, twcc=%u/%d",
video_ssrc, audio_ssrc, nack_enabled_, pt_to_drop_, twcc_enabled, twcc_id);
srs_trace("RTC publisher video(ssrc=%u), audio(ssrc=%u), nack=%d, pt-drop=%u", if (twcc_id_) {
video_ssrc, audio_ssrc, nack_enabled_, pt_to_drop_); extension_types_.register_by_uri(twcc_id_, kTWCCExt);
rtcp_twcc_.set_media_ssrc(video_ssrc);
}
if ((err = report_timer->tick(0 * SRS_UTIME_MILLISECONDS)) != srs_success) { if ((err = report_timer->tick(0 * SRS_UTIME_MILLISECONDS)) != srs_success) {
return srs_error_wrap(err, "hourglass tick"); return srs_error_wrap(err, "hourglass tick");
@ -1149,7 +1154,7 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
// Decode the header first. // Decode the header first.
SrsRtpHeader h; SrsRtpHeader h;
if (pt_to_drop_ && twcc_ext_id_) { if (pt_to_drop_ && twcc_id_) {
SrsBuffer b(data, nb_data); SrsBuffer b(data, nb_data);
h.ignore_padding(true); h.set_extensions(&extension_types_); h.ignore_padding(true); h.set_extensions(&extension_types_);
if ((err = h.decode(&b)) != srs_success) { if ((err = h.decode(&b)) != srs_success) {
@ -1161,7 +1166,7 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
// 1. Client may send some padding packets with invalid SequenceNumber, which causes the SRTP fail. // 1. Client may send some padding packets with invalid SequenceNumber, which causes the SRTP fail.
// 2. Server may send multiple duplicated NACK to client, and got more than one ARQ packet, which also fail SRTP. // 2. Server may send multiple duplicated NACK to client, and got more than one ARQ packet, which also fail SRTP.
// so, we must parse the header before SRTP unprotect(which may fail and drop packet). // so, we must parse the header before SRTP unprotect(which may fail and drop packet).
if (twcc_ext_id_) { if (twcc_id_) {
uint16_t twcc_sn = 0; uint16_t twcc_sn = 0;
if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) { if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) {
if((err = on_twcc(twcc_sn)) != srs_success) { if((err = on_twcc(twcc_sn)) != srs_success) {
@ -2017,6 +2022,7 @@ srs_error_t SrsRtcSession::start_play()
uint32_t audio_ssrc = 0; uint32_t audio_ssrc = 0;
uint16_t video_payload_type = 0; uint16_t video_payload_type = 0;
uint16_t audio_payload_type = 0; uint16_t audio_payload_type = 0;
int twcc_id = -1;
for (size_t i = 0; i < local_sdp.media_descs_.size(); ++i) { for (size_t i = 0; i < local_sdp.media_descs_.size(); ++i) {
const SrsMediaDesc& media_desc = local_sdp.media_descs_[i]; const SrsMediaDesc& media_desc = local_sdp.media_descs_[i];
if (media_desc.is_audio()) { if (media_desc.is_audio()) {
@ -2025,10 +2031,17 @@ srs_error_t SrsRtcSession::start_play()
} else if (media_desc.is_video()) { } else if (media_desc.is_video()) {
video_ssrc = media_desc.ssrc_infos_[0].ssrc_; video_ssrc = media_desc.ssrc_infos_[0].ssrc_;
video_payload_type = media_desc.payload_types_[0].payload_type_; video_payload_type = media_desc.payload_types_[0].payload_type_;
//TODO: just judgement video media whether to support twcc
std::map<int, std::string> exts = media_desc.get_extmaps();
for(std::map<int, std::string>::iterator it = exts.begin(); it != exts.end(); ++it) {
if(kTWCCExt == it->second) {
twcc_id = it->first;
}
}
} }
} }
if ((err = player_->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type)) != srs_success) { if ((err = player_->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type, twcc_id)) != srs_success) {
return srs_error_wrap(err, "SrsRtcPlayer init"); return srs_error_wrap(err, "SrsRtcPlayer init");
} }
@ -2049,6 +2062,7 @@ srs_error_t SrsRtcSession::start_publish()
return err; return err;
} }
publisher_ = new SrsRtcPublisher(this); publisher_ = new SrsRtcPublisher(this);
// Request PLI for exists players? // Request PLI for exists players?
//publisher_->request_keyframe(); //publisher_->request_keyframe();

@ -211,7 +211,7 @@ public:
SrsRtcPlayer(SrsRtcSession* s, std::string parent_cid); SrsRtcPlayer(SrsRtcSession* s, std::string parent_cid);
virtual ~SrsRtcPlayer(); virtual ~SrsRtcPlayer();
public: public:
srs_error_t initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt); srs_error_t initialize(uint32_t vssrc, uint32_t assrc, uint16_t v_pt, uint16_t a_pt);
// interface ISrsReloadHandler // interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_play(std::string vhost); virtual srs_error_t on_reload_vhost_play(std::string vhost);
@ -270,7 +270,7 @@ private:
std::map<uint32_t, SrsNtp> last_sender_report_ntp; std::map<uint32_t, SrsNtp> last_sender_report_ntp;
private: private:
srs_utime_t last_twcc_feedback_time_; srs_utime_t last_twcc_feedback_time_;
uint8_t twcc_ext_id_; int twcc_id_;
uint8_t twcc_fb_count_; uint8_t twcc_fb_count_;
SrsRtcpTWCC rtcp_twcc_; SrsRtcpTWCC rtcp_twcc_;
SrsRtpExtensionTypes extension_types_; SrsRtpExtensionTypes extension_types_;
@ -278,7 +278,7 @@ public:
SrsRtcPublisher(SrsRtcSession* session); SrsRtcPublisher(SrsRtcSession* session);
virtual ~SrsRtcPublisher(); virtual ~SrsRtcPublisher();
public: public:
srs_error_t initialize(uint32_t vssrc, uint32_t assrc, uint8_t twcc_ext_id, SrsRequest* req); srs_error_t initialize(uint32_t vssrc, uint32_t assrc, int twcc_id, SrsRequest* req);
private: private:
void check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ssrc); void check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ssrc);
srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer* rtp_queue); srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer* rtp_queue);

Loading…
Cancel
Save