Implement recieving NACK in RtcpTranceiver
Bug: webrtc:8239 Change-Id: I41d6c3252bbffeab66ded7ed294f82134351541a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/254800 Reviewed-by: Emil Lundmark <lndmrk@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36254}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
16af378884
commit
ef6b028c92
@ -97,6 +97,9 @@ class RtpStreamRtcpHandler {
|
|||||||
int last_clock_rate_ = 90'000;
|
int last_clock_rate_ = 90'000;
|
||||||
};
|
};
|
||||||
virtual RtpStats SentStats() = 0;
|
virtual RtpStats SentStats() = 0;
|
||||||
|
|
||||||
|
virtual void OnNack(uint32_t sender_ssrc,
|
||||||
|
rtc::ArrayView<const uint16_t> sequence_numbers) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RtcpTransceiverConfig {
|
struct RtcpTransceiverConfig {
|
||||||
|
@ -351,10 +351,34 @@ void RtcpTransceiverImpl::HandlePayloadSpecificFeedback(
|
|||||||
void RtcpTransceiverImpl::HandleRtpFeedback(
|
void RtcpTransceiverImpl::HandleRtpFeedback(
|
||||||
const rtcp::CommonHeader& rtcp_packet_header,
|
const rtcp::CommonHeader& rtcp_packet_header,
|
||||||
Timestamp now) {
|
Timestamp now) {
|
||||||
// Transport feedback is the only message handled right now.
|
switch (rtcp_packet_header.fmt()) {
|
||||||
if (rtcp_packet_header.fmt() !=
|
case rtcp::Nack::kFeedbackMessageType:
|
||||||
rtcp::TransportFeedback::kFeedbackMessageType ||
|
HandleNack(rtcp_packet_header);
|
||||||
config_.network_link_observer == nullptr) {
|
break;
|
||||||
|
case rtcp::TransportFeedback::kFeedbackMessageType:
|
||||||
|
HandleTransportFeedback(rtcp_packet_header, now);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcpTransceiverImpl::HandleNack(
|
||||||
|
const rtcp::CommonHeader& rtcp_packet_header) {
|
||||||
|
rtcp::Nack nack;
|
||||||
|
if (local_senders_.empty() || !nack.Parse(rtcp_packet_header)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto it = local_senders_by_ssrc_.find(nack.media_ssrc());
|
||||||
|
if (it != local_senders_by_ssrc_.end()) {
|
||||||
|
it->second->handler->OnNack(nack.sender_ssrc(), nack.packet_ids());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcpTransceiverImpl::HandleTransportFeedback(
|
||||||
|
const rtcp::CommonHeader& rtcp_packet_header,
|
||||||
|
Timestamp now) {
|
||||||
|
RTC_DCHECK_EQ(rtcp_packet_header.fmt(),
|
||||||
|
rtcp::TransportFeedback::kFeedbackMessageType);
|
||||||
|
if (config_.network_link_observer == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rtcp::TransportFeedback feedback;
|
rtcp::TransportFeedback feedback;
|
||||||
|
@ -105,6 +105,9 @@ class RtcpTransceiverImpl {
|
|||||||
Timestamp now);
|
Timestamp now);
|
||||||
void HandleRtpFeedback(const rtcp::CommonHeader& rtcp_packet_header,
|
void HandleRtpFeedback(const rtcp::CommonHeader& rtcp_packet_header,
|
||||||
Timestamp now);
|
Timestamp now);
|
||||||
|
void HandleNack(const rtcp::CommonHeader& rtcp_packet_header);
|
||||||
|
void HandleTransportFeedback(const rtcp::CommonHeader& rtcp_packet_header,
|
||||||
|
Timestamp now);
|
||||||
void HandleExtendedReports(const rtcp::CommonHeader& rtcp_packet_header,
|
void HandleExtendedReports(const rtcp::CommonHeader& rtcp_packet_header,
|
||||||
Timestamp now);
|
Timestamp now);
|
||||||
// Extended Reports blocks handlers.
|
// Extended Reports blocks handlers.
|
||||||
|
@ -40,6 +40,7 @@ namespace {
|
|||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
|
using ::testing::ElementsAreArray;
|
||||||
using ::testing::Ge;
|
using ::testing::Ge;
|
||||||
using ::testing::NiceMock;
|
using ::testing::NiceMock;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
@ -82,6 +83,10 @@ class MockRtpStreamRtcpHandler : public RtpStreamRtcpHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MOCK_METHOD(RtpStats, SentStats, (), (override));
|
MOCK_METHOD(RtpStats, SentStats, (), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnNack,
|
||||||
|
(uint32_t, rtc::ArrayView<const uint16_t>),
|
||||||
|
(override));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int num_calls_ = 0;
|
int num_calls_ = 0;
|
||||||
@ -1044,6 +1049,30 @@ TEST(RtcpTransceiverImplTest, SendsNack) {
|
|||||||
EXPECT_EQ(rtcp_parser.nack()->packet_ids(), kMissingSequenceNumbers);
|
EXPECT_EQ(rtcp_parser.nack()->packet_ids(), kMissingSequenceNumbers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RtcpTransceiverImplTest, ReceivesNack) {
|
||||||
|
static constexpr uint32_t kRemoteSsrc = 4321;
|
||||||
|
static constexpr uint32_t kMediaSsrc1 = 1234;
|
||||||
|
static constexpr uint32_t kMediaSsrc2 = 1235;
|
||||||
|
std::vector<uint16_t> kMissingSequenceNumbers = {34, 37, 38};
|
||||||
|
RtcpTransceiverConfig config = DefaultTestConfig();
|
||||||
|
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||||
|
|
||||||
|
MockRtpStreamRtcpHandler local_stream1;
|
||||||
|
MockRtpStreamRtcpHandler local_stream2;
|
||||||
|
EXPECT_CALL(local_stream1,
|
||||||
|
OnNack(kRemoteSsrc, ElementsAreArray(kMissingSequenceNumbers)));
|
||||||
|
EXPECT_CALL(local_stream2, OnNack).Times(0);
|
||||||
|
|
||||||
|
EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc1, &local_stream1));
|
||||||
|
EXPECT_TRUE(rtcp_transceiver.AddMediaSender(kMediaSsrc2, &local_stream2));
|
||||||
|
|
||||||
|
rtcp::Nack nack;
|
||||||
|
nack.SetSenderSsrc(kRemoteSsrc);
|
||||||
|
nack.SetMediaSsrc(kMediaSsrc1);
|
||||||
|
nack.SetPacketIds(kMissingSequenceNumbers);
|
||||||
|
rtcp_transceiver.ReceivePacket(nack.Build(), config.clock->CurrentTime());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) {
|
TEST(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) {
|
||||||
const uint32_t kSenderSsrc = 1234;
|
const uint32_t kSenderSsrc = 1234;
|
||||||
const uint32_t kRemoteSsrc = 4321;
|
const uint32_t kRemoteSsrc = 4321;
|
||||||
|
Reference in New Issue
Block a user