1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

RTC: Refine RTCP dispatch in connection.

This commit is contained in:
winlin 2020-08-11 17:01:57 +08:00
parent 00582e0c36
commit e82e28d83e

View file

@ -1754,93 +1754,82 @@ srs_error_t SrsRtcConnection::dispatch_rtcp(SrsRtcpCommon* rtcp)
{
srs_error_t err = srs_success;
// TODO: FIXME: Refine the logic code, simple it.
map<uint32_t, SrsRtcPublishStream*>::iterator it_pub;
map<uint32_t, SrsRtcPlayStream*>::iterator it_player;
SrsRtcPlayStream* player = NULL;
SrsRtcPublishStream* publisher = NULL;
// For TWCC packet.
if (SrsRtcpType_rtpfb == rtcp->type() && 15 == rtcp->get_rc()) {
if(srs_success != (err = on_rtcp_feedback_twcc(rtcp->data(), rtcp->size()))) {
return srs_error_wrap(err, "twcc feedback");
}
}
if(SrsRtcpType_sr == rtcp->type()) {
it_pub = publishers_ssrc_map_.find(rtcp->get_ssrc());
if(publishers_ssrc_map_.end() == it_pub) {
srs_warn("SR: ssrc %d is unknown", rtcp->get_ssrc());
return err;
}
publisher = it_pub->second;
if(srs_success != (err = publisher->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle sr");
}
} else if(SrsRtcpType_rr == rtcp->type()) {
SrsRtcpRR* rr = dynamic_cast<SrsRtcpRR*>(rtcp);
srs_assert(NULL != rr);
if (rr->get_rb_ssrc() == 0) { //for native client
return err;
}
it_player = players_ssrc_map_.find(rr->get_rb_ssrc());
if(players_ssrc_map_.end() == it_player) {
srs_warn("RR: ssrc %d is unknown", rr->get_rb_ssrc());
return err;
}
player = it_player->second;
if(srs_success != (err = player->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle rr");
}
} else if(SrsRtcpType_rtpfb == rtcp->type()) {
if(1 == rtcp->get_rc()) {
//nack
SrsRtcpNack* nack = dynamic_cast<SrsRtcpNack*>(rtcp);
srs_assert(NULL != nack);
it_player = players_ssrc_map_.find(nack->get_media_ssrc());
if(players_ssrc_map_.end() == it_player) {
srs_warn("ftpfb: ssrc %d is unknown", nack->get_media_ssrc());
return err;
}
player = it_player->second;
if(srs_success != (err = player->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle nack");
}
} else if(15 == rtcp->get_rc()) {
// twcc
if(srs_success != (err = on_rtcp_feedback_twcc(rtcp->data(), rtcp->size()))) {
return srs_error_wrap(err, "handle twcc feedback");
}
}
} else if(SrsRtcpType_psfb == rtcp->type()) {
// For REMB packet.
if (SrsRtcpType_psfb == rtcp->type()) {
SrsRtcpPsfbCommon* psfb = dynamic_cast<SrsRtcpPsfbCommon*>(rtcp);
srs_assert(psfb != NULL);
//TODO: user const to replace 15
if(15 == psfb->get_rc()) {
return on_rtcp_feedback_remb(psfb);
}
}
it_player = players_ssrc_map_.find(psfb->get_media_ssrc());
if(players_ssrc_map_.end() == it_player) {
srs_warn("psfb: ssrc %d is unknown", psfb->get_media_ssrc());
return err;
}
player = it_player->second;
if(srs_success != (err = player->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle nack");
}
} else {
// try to find player to assign rtcp
it_player = players_ssrc_map_.find(rtcp->get_ssrc());
if(players_ssrc_map_.end() != it_player) {
player = it_player->second;
if(srs_success != (err = player->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle common rtcp");
}
// Ignore special packet.
if (SrsRtcpType_rr == rtcp->type()) {
SrsRtcpRR* rr = dynamic_cast<SrsRtcpRR*>(rtcp);
if (rr->get_rb_ssrc() == 0) { //for native client
return err;
}
}
// try to find publisher to assign rtcp
it_pub = publishers_ssrc_map_.find(rtcp->get_ssrc());
if(publishers_ssrc_map_.end() != it_pub) {
publisher = it_pub->second;
if(srs_success != (err = publisher->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle sr");
}
// The feedback packet for specified SSRC.
// For example, if got SR packet, we required a publisher to handle it.
uint32_t required_publisher_ssrc = 0, required_player_ssrc = 0;
if (SrsRtcpType_sr == rtcp->type()) {
required_publisher_ssrc = rtcp->get_ssrc();
} else if (SrsRtcpType_rr == rtcp->type()) {
SrsRtcpRR* rr = dynamic_cast<SrsRtcpRR*>(rtcp);
required_player_ssrc = rr->get_rb_ssrc();
} else if (SrsRtcpType_rtpfb == rtcp->type()) {
if(1 == rtcp->get_rc()) {
SrsRtcpNack* nack = dynamic_cast<SrsRtcpNack*>(rtcp);
required_player_ssrc = nack->get_media_ssrc();
}
} else if(SrsRtcpType_psfb == rtcp->type()) {
SrsRtcpPsfbCommon* psfb = dynamic_cast<SrsRtcpPsfbCommon*>(rtcp);
required_player_ssrc = psfb->get_media_ssrc();
}
// Find the publisher or player by SSRC, always try to got one.
SrsRtcPlayStream* player = NULL;
SrsRtcPublishStream* publisher = NULL;
if (true) {
uint32_t ssrc = required_publisher_ssrc? required_publisher_ssrc : rtcp->get_ssrc();
map<uint32_t, SrsRtcPublishStream*>::iterator it = publishers_ssrc_map_.find(ssrc);
if (it != publishers_ssrc_map_.end()) {
publisher = it->second;
}
}
if (true) {
uint32_t ssrc = required_player_ssrc? required_player_ssrc : rtcp->get_ssrc();
map<uint32_t, SrsRtcPlayStream*>::iterator it = players_ssrc_map_.find(ssrc);
if (it != players_ssrc_map_.end()) {
player = it->second;
}
}
// Ignore if packet is required by publisher or player.
if (required_publisher_ssrc && !publisher) {
srs_warn("SR: no ssrc %u in publishers", required_publisher_ssrc);
return err;
}
if (required_player_ssrc && !player) {
srs_warn("SR: no ssrc %u in players", required_player_ssrc);
return err;
}
// Handle packet by publisher or player.
if (publisher && srs_success != (err = publisher->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle rtcp");
}
if (player && srs_success != (err = player->on_rtcp(rtcp))) {
return srs_error_wrap(err, "handle rtcp");
}
return err;