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:
Danil Chapovalov
2017-11-27 17:23:04 +01:00
committed by Commit Bot
parent 2f061681cc
commit 327c43c29b
7 changed files with 64 additions and 2 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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};