Closed ibc closed 7 months ago
CC @penguinol
I strongly fail to see how this crash can happen:
TransportCongestionControlServer
there is a timer that invokes its FillAndSendTransportCcFeedback()
.FillAndSendTransportCcFeedback()
is the only method that calls FeedbackRtpTransportPacket::SetBase()
and FeedbackRtpTransportPacket::AddPacket()
and it always calls the former first:
void TransportCongestionControlServer::FillAndSendTransportCcFeedback()
{
MS_TRACE();
if (!this->transportWideSeqNumberReceived)
{
return;
}
auto it = this->mapPacketArrivalTimes.lower_bound(this->transportCcFeedbackWideSeqNumStart);
if (it == this->mapPacketArrivalTimes.end())
{
return;
}
// Set base sequence num and reference time.
this->transportCcFeedbackPacket->SetBase(this->transportCcFeedbackWideSeqNumStart, it->second);
for (; it != this->mapPacketArrivalTimes.end(); ++it)
{
auto result =
this->transportCcFeedbackPacket->AddPacket(it->first, it->second, this->maxRtcpPacketLen);
FeedbackRtpTransportPacket::AddPacket()
is called before FeedbackRtpTransportPacket::SetBase()
is called, so this->baseSet
is always true when FeedbackRtpTransportPacket::AddPacket()
and hence the assertion should not fail:
MS_ASSERT(this->baseSet, "base not set");
this->baseSet
in FeedbackRtpTransportPacket
class is reset to false
.OPPPPS, HERE!
void TransportCongestionControlServer::TransportDisconnected()
{
MS_TRACE();
switch (this->bweType)
{
case RTC::BweType::TRANSPORT_CC:
{
this->transportCcFeedbackSendPeriodicTimer->Stop();
// Create a new feedback packet.
this->transportCcFeedbackPacket.reset(new RTC::RTCP::FeedbackRtpTransportPacket(0u, 0u));
break;
}
default:;
}
}
Here we are overriding this->transportCcFeedbackPacket
with a fresh packet so its baseSet
property is of course false
. However we are also stopping the timer so still I don't understand how the issue can happen.
Oh... we are reseting the packet in many other places!!!!! here the bug!!!
case RTC::RTCP::FeedbackRtpTransportPacket::AddPacketResult::MAX_SIZE_EXCEEDED:
{
// This should not happen.
MS_WARN_DEV("transport-cc feedback packet is exceeded");
// Create a new feedback packet.
this->transportCcFeedbackPacket.reset(new RTC::RTCP::FeedbackRtpTransportPacket(
this->transportCcFeedbackSenderSsrc, this->transportCcFeedbackMediaSsrc));
}
case RTC::RTCP::FeedbackRtpTransportPacket::AddPacketResult::FATAL:
{
// Create a new feedback packet.
this->transportCcFeedbackPacket.reset(new RTC::RTCP::FeedbackRtpTransportPacket(
this->transportCcFeedbackSenderSsrc, this->transportCcFeedbackMediaSsrc));
// Use current packet count.
// NOTE: Do not increment it since the previous ongoing feedback
// packet was not sent.
this->transportCcFeedbackPacket->SetFeedbackPacketCount(
this->transportCcFeedbackPacketCount);
break;
}
}
Issue description
Logs:
Core dump:
Clearly a regression in PR https://github.com/versatica/mediasoup/pull/1088 " Make transport-cc feedback work similarly to libwebrtc".