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:
parent
00582e0c36
commit
e82e28d83e
1 changed files with 65 additions and 76 deletions
|
@ -1754,93 +1754,82 @@ srs_error_t SrsRtcConnection::dispatch_rtcp(SrsRtcpCommon* rtcp)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
// TODO: FIXME: Refine the logic code, simple it.
|
// For TWCC packet.
|
||||||
map<uint32_t, SrsRtcPublishStream*>::iterator it_pub;
|
if (SrsRtcpType_rtpfb == rtcp->type() && 15 == rtcp->get_rc()) {
|
||||||
map<uint32_t, SrsRtcPlayStream*>::iterator it_player;
|
if(srs_success != (err = on_rtcp_feedback_twcc(rtcp->data(), rtcp->size()))) {
|
||||||
SrsRtcPlayStream* player = NULL;
|
return srs_error_wrap(err, "twcc feedback");
|
||||||
SrsRtcPublishStream* publisher = NULL;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(SrsRtcpType_sr == rtcp->type()) {
|
// For REMB packet.
|
||||||
it_pub = publishers_ssrc_map_.find(rtcp->get_ssrc());
|
if (SrsRtcpType_psfb == rtcp->type()) {
|
||||||
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()) {
|
|
||||||
SrsRtcpPsfbCommon* psfb = dynamic_cast<SrsRtcpPsfbCommon*>(rtcp);
|
SrsRtcpPsfbCommon* psfb = dynamic_cast<SrsRtcpPsfbCommon*>(rtcp);
|
||||||
srs_assert(psfb != NULL);
|
|
||||||
//TODO: user const to replace 15
|
//TODO: user const to replace 15
|
||||||
if(15 == psfb->get_rc()) {
|
if(15 == psfb->get_rc()) {
|
||||||
return on_rtcp_feedback_remb(psfb);
|
return on_rtcp_feedback_remb(psfb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
it_player = players_ssrc_map_.find(psfb->get_media_ssrc());
|
// Ignore special packet.
|
||||||
if(players_ssrc_map_.end() == it_player) {
|
if (SrsRtcpType_rr == rtcp->type()) {
|
||||||
srs_warn("psfb: ssrc %d is unknown", psfb->get_media_ssrc());
|
SrsRtcpRR* rr = dynamic_cast<SrsRtcpRR*>(rtcp);
|
||||||
return err;
|
if (rr->get_rb_ssrc() == 0) { //for native client
|
||||||
}
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// try to find publisher to assign rtcp
|
// The feedback packet for specified SSRC.
|
||||||
it_pub = publishers_ssrc_map_.find(rtcp->get_ssrc());
|
// For example, if got SR packet, we required a publisher to handle it.
|
||||||
if(publishers_ssrc_map_.end() != it_pub) {
|
uint32_t required_publisher_ssrc = 0, required_player_ssrc = 0;
|
||||||
publisher = it_pub->second;
|
if (SrsRtcpType_sr == rtcp->type()) {
|
||||||
if(srs_success != (err = publisher->on_rtcp(rtcp))) {
|
required_publisher_ssrc = rtcp->get_ssrc();
|
||||||
return srs_error_wrap(err, "handle sr");
|
} 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;
|
return err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue