Add sending Nack to RtcpTransceiver
Bug: webrtc:8239 Change-Id: Idf27bb05958d9eceaf601078019f05444232581f Reviewed-on: https://webrtc-review.googlesource.com/26260 Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20907}
This commit is contained in:

committed by
Commit Bot

parent
2f061681cc
commit
327c43c29b
@ -11,6 +11,7 @@
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "modules/rtp_rtcp/source/byte_io.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||
@ -123,9 +124,13 @@ bool Nack::Create(uint8_t* packet,
|
||||
|
||||
void Nack::SetPacketIds(const uint16_t* nack_list, size_t length) {
|
||||
RTC_DCHECK(nack_list);
|
||||
SetPacketIds(std::vector<uint16_t>(nack_list, nack_list + length));
|
||||
}
|
||||
|
||||
void Nack::SetPacketIds(std::vector<uint16_t> nack_list) {
|
||||
RTC_DCHECK(packet_ids_.empty());
|
||||
RTC_DCHECK(packed_.empty());
|
||||
packet_ids_.assign(nack_list, nack_list + length);
|
||||
packet_ids_ = std::move(nack_list);
|
||||
Pack();
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ class Nack : public Rtpfb {
|
||||
bool Parse(const CommonHeader& packet);
|
||||
|
||||
void SetPacketIds(const uint16_t* nack_list, size_t length);
|
||||
void SetPacketIds(std::vector<uint16_t> nack_list);
|
||||
const std::vector<uint16_t>& packet_ids() const { return packet_ids_; }
|
||||
|
||||
size_t BlockLength() const override;
|
||||
|
@ -90,6 +90,22 @@ void RtcpTransceiver::UnsetRemb() {
|
||||
});
|
||||
}
|
||||
|
||||
void RtcpTransceiver::SendNack(uint32_t ssrc,
|
||||
std::vector<uint16_t> sequence_numbers) {
|
||||
// TODO(danilchap): Replace with lambda with move capture when available.
|
||||
struct Closure {
|
||||
void operator()() {
|
||||
if (ptr)
|
||||
ptr->SendNack(ssrc, std::move(sequence_numbers));
|
||||
}
|
||||
|
||||
rtc::WeakPtr<RtcpTransceiverImpl> ptr;
|
||||
uint32_t ssrc;
|
||||
std::vector<uint16_t> sequence_numbers;
|
||||
};
|
||||
task_queue_->PostTask(Closure{ptr_, ssrc, std::move(sequence_numbers)});
|
||||
}
|
||||
|
||||
void RtcpTransceiver::SendPictureLossIndication(std::vector<uint32_t> ssrcs) {
|
||||
// TODO(danilchap): Replace with lambda with move capture when available.
|
||||
struct Closure {
|
||||
|
@ -44,7 +44,10 @@ class RtcpTransceiver {
|
||||
// Stops sending REMB in following compound packets.
|
||||
void UnsetRemb();
|
||||
|
||||
// Request new key frame.
|
||||
// Reports missing packets, https://tools.ietf.org/html/rfc4585#section-6.2.1
|
||||
void SendNack(uint32_t ssrc, std::vector<uint16_t> sequence_numbers);
|
||||
|
||||
// Requests new key frame.
|
||||
// using PLI, https://tools.ietf.org/html/rfc4585#section-6.3.1.1
|
||||
void SendPictureLossIndication(std::vector<uint32_t> ssrcs);
|
||||
// using FIR, https://tools.ietf.org/html/rfc5104#section-4.3.1.2
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
||||
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
|
||||
@ -130,6 +131,18 @@ void RtcpTransceiverImpl::UnsetRemb() {
|
||||
remb_.reset();
|
||||
}
|
||||
|
||||
void RtcpTransceiverImpl::SendNack(uint32_t ssrc,
|
||||
std::vector<uint16_t> sequence_numbers) {
|
||||
RTC_DCHECK(!sequence_numbers.empty());
|
||||
SendImmediateFeedback([&](PacketSender* sender) {
|
||||
rtcp::Nack nack;
|
||||
nack.SetSenderSsrc(config_.feedback_ssrc);
|
||||
nack.SetMediaSsrc(ssrc);
|
||||
nack.SetPacketIds(std::move(sequence_numbers));
|
||||
sender->AppendPacket(nack);
|
||||
});
|
||||
}
|
||||
|
||||
void RtcpTransceiverImpl::SendPictureLossIndication(
|
||||
rtc::ArrayView<const uint32_t> ssrcs) {
|
||||
RTC_DCHECK(!ssrcs.empty());
|
||||
|
@ -44,6 +44,8 @@ class RtcpTransceiverImpl {
|
||||
void SetRemb(int bitrate_bps, std::vector<uint32_t> ssrcs);
|
||||
void UnsetRemb();
|
||||
|
||||
void SendNack(uint32_t ssrc, std::vector<uint16_t> sequence_numbers);
|
||||
|
||||
void SendPictureLossIndication(rtc::ArrayView<const uint32_t> ssrcs);
|
||||
void SendFullIntraRequest(rtc::ArrayView<const uint32_t> ssrcs);
|
||||
|
||||
|
@ -447,6 +447,28 @@ TEST(RtcpTransceiverImplTest,
|
||||
EXPECT_EQ(CompactNtpRttToMs(report_blocks[1].delay_since_last_sr()), 100);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, SendsNack) {
|
||||
const uint32_t kSenderSsrc = 1234;
|
||||
const uint32_t kRemoteSsrc = 4321;
|
||||
std::vector<uint16_t> kMissingSequenceNumbers = {34, 37, 38};
|
||||
MockTransport outgoing_transport;
|
||||
RtcpTransceiverConfig config;
|
||||
config.feedback_ssrc = kSenderSsrc;
|
||||
config.schedule_periodic_compound_packets = false;
|
||||
config.outgoing_transport = &outgoing_transport;
|
||||
RtcpTransceiverImpl rtcp_transceiver(config);
|
||||
RtcpPacketParser rtcp_parser;
|
||||
EXPECT_CALL(outgoing_transport, SendRtcp(_, _))
|
||||
.WillOnce(Invoke(&rtcp_parser, &RtcpPacketParser::Parse));
|
||||
|
||||
rtcp_transceiver.SendNack(kRemoteSsrc, kMissingSequenceNumbers);
|
||||
|
||||
EXPECT_EQ(rtcp_parser.nack()->num_packets(), 1);
|
||||
EXPECT_EQ(rtcp_parser.nack()->sender_ssrc(), kSenderSsrc);
|
||||
EXPECT_EQ(rtcp_parser.nack()->media_ssrc(), kRemoteSsrc);
|
||||
EXPECT_EQ(rtcp_parser.nack()->packet_ids(), kMissingSequenceNumbers);
|
||||
}
|
||||
|
||||
TEST(RtcpTransceiverImplTest, RequestKeyFrameWithPictureLossIndication) {
|
||||
const uint32_t kSenderSsrc = 1234;
|
||||
const uint32_t kRemoteSsrcs[] = {4321, 5321};
|
||||
|
Reference in New Issue
Block a user