Add support for multiple report blocks.

Use a weighted average of fraction loss for bandwidth estimation.

TEST=trybots and vie_auto_test --automated
BUG=1811
R=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2198004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4762 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org
2013-09-17 07:49:56 +00:00
parent fc10c5c97f
commit 28a331eede
11 changed files with 457 additions and 190 deletions

View File

@ -30,23 +30,44 @@ class RtcpBandwidthObserverImpl : public RtcpBandwidthObserver {
}
// Received RTCP receiver block.
virtual void OnReceivedRtcpReceiverReport(
const uint32_t ssrc,
const uint8_t fraction_loss,
const uint32_t rtt,
const uint32_t last_received_extended_high_seq_num,
const uint32_t now_ms) OVERRIDE {
uint32_t number_of_packets = 0;
std::map<uint32_t, uint32_t>::iterator it =
ssrc_to_last_received_extended_high_seq_num_.find(ssrc);
const ReportBlockList& report_blocks,
uint16_t rtt,
int64_t now_ms) OVERRIDE {
if (report_blocks.empty())
return;
int fraction_lost_aggregate = 0;
int total_number_of_packets = 0;
// Compute the a weighted average of the fraction loss from all report
// blocks.
for (ReportBlockList::const_iterator it = report_blocks.begin();
it != report_blocks.end(); ++it) {
std::map<uint32_t, uint32_t>::iterator seq_num_it =
ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
int number_of_packets = 0;
if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
number_of_packets = it->extendedHighSeqNum -
seq_num_it->second;
fraction_lost_aggregate += number_of_packets * it->fractionLost;
total_number_of_packets += number_of_packets;
if (it != ssrc_to_last_received_extended_high_seq_num_.end()) {
number_of_packets = last_received_extended_high_seq_num - it->second;
}
// Update last received for this SSRC.
ssrc_to_last_received_extended_high_seq_num_[ssrc] =
last_received_extended_high_seq_num;
owner_->OnReceivedRtcpReceiverReport(fraction_loss, rtt, number_of_packets,
now_ms);
ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
it->extendedHighSeqNum;
}
if (total_number_of_packets == 0)
fraction_lost_aggregate = 0;
else
fraction_lost_aggregate = (fraction_lost_aggregate +
total_number_of_packets / 2) / total_number_of_packets;
if (fraction_lost_aggregate > 255)
return;
owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
total_number_of_packets, now_ms);
}
private:
std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;

View File

@ -20,6 +20,21 @@ using webrtc::RtcpBandwidthObserver;
using webrtc::BitrateObserver;
using webrtc::BitrateController;
uint8_t WeightedLoss(int num_packets1, uint8_t fraction_loss1,
int num_packets2, uint8_t fraction_loss2) {
int weighted_sum = num_packets1 * fraction_loss1 +
num_packets2 * fraction_loss2;
int total_num_packets = num_packets1 + num_packets2;
return (weighted_sum + total_num_packets / 2) / total_num_packets;
}
webrtc::RTCPReportBlock CreateReportBlock(
uint32_t remote_ssrc, uint32_t source_ssrc,
uint8_t fraction_lost, uint32_t extended_high_sequence_number) {
return webrtc::RTCPReportBlock(remote_ssrc, source_ssrc, fraction_lost, 0,
extended_high_sequence_number, 0, 0, 0);
}
class TestBitrateObserver: public BitrateObserver {
public:
TestBitrateObserver()
@ -73,33 +88,49 @@ TEST_F(BitrateControllerTest, OneBitrateObserverOneRtcpObserver) {
bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
// Test start bitrate.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
webrtc::ReportBlockList report_blocks;
report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
EXPECT_EQ(0u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(0u, bitrate_observer.last_rtt_);
// Test bitrate increase 8% per second.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 801, 4001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 801));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001);
EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap.
// Test that a low REMB trigger immediately.
@ -124,44 +155,73 @@ TEST_F(BitrateControllerTest, OneBitrateObserverTwoRtcpObservers) {
bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
// Test start bitrate.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 1, 1);
webrtc::ReportBlockList report_blocks;
report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(
report_blocks, 100, 1);
EXPECT_EQ(0u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(0u, bitrate_observer.last_rtt_);
// Test bitrate increase 8% per second.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 501);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 21, 1001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 501);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
1001);
EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(100u, bitrate_observer.last_rtt_);
// Extra report should not change estimate.
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 31, 1501);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 31));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
1501);
EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
// Second report should not change estimate.
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 41, 2001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
2001);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
// Reports from only one bandwidth observer is ok.
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
3001);
EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
4001);
EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
5001);
EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
6001);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap.
second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
7001);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_); // Max cap.
// Test that a low REMB trigger immediately.
@ -177,6 +237,78 @@ TEST_F(BitrateControllerTest, OneBitrateObserverTwoRtcpObservers) {
delete second_bandwidth_observer;
}
TEST_F(BitrateControllerTest, OneBitrateObserverMultipleReportBlocks) {
TestBitrateObserver bitrate_observer;
uint32_t sequence_number[2] = {0, 0xFF00};
const uint32_t kStartBitrate = 200000;
const uint32_t kMinBitrate = 100000;
const uint32_t kMaxBitrate = 300000;
controller_->SetBitrateObserver(&bitrate_observer, kStartBitrate, kMinBitrate,
kMaxBitrate);
// Receive a high REMB, test bitrate increase.
bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
webrtc::ReportBlockList report_blocks;
int64_t time_ms = 1001;
uint32_t last_bitrate = 0;
// Ramp up to max bitrate.
for (int i = 0; i < 6; ++i) {
report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0]));
report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1]));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50,
time_ms);
EXPECT_GT(bitrate_observer.last_bitrate_, last_bitrate);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
last_bitrate = bitrate_observer.last_bitrate_;
time_ms += 1000;
sequence_number[0] += 20;
sequence_number[1] += 1;
report_blocks.clear();
}
EXPECT_EQ(kMaxBitrate, bitrate_observer.last_bitrate_);
// Packet loss on the first stream. Verify that bitrate decreases.
report_blocks.push_back(CreateReportBlock(1, 2, 50, sequence_number[0]));
report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1]));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate);
EXPECT_EQ(WeightedLoss(20, 50, 1, 0), bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
last_bitrate = bitrate_observer.last_bitrate_;
sequence_number[0] += 20;
sequence_number[1] += 20;
time_ms += 1000;
report_blocks.clear();
// Packet loss on the second stream. Verify that bitrate decreases.
report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0]));
report_blocks.push_back(CreateReportBlock(1, 3, 75, sequence_number[1]));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate);
EXPECT_EQ(WeightedLoss(20, 0, 20, 75), bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
last_bitrate = bitrate_observer.last_bitrate_;
sequence_number[0] += 20;
sequence_number[1] += 1;
time_ms += 1000;
report_blocks.clear();
// All packets lost on stream with few packets, no back-off.
report_blocks.push_back(CreateReportBlock(1, 2, 1, sequence_number[0]));
report_blocks.push_back(CreateReportBlock(1, 3, 255, sequence_number[1]));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(bitrate_observer.last_bitrate_, last_bitrate);
EXPECT_EQ(WeightedLoss(20, 1, 1, 255), bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
last_bitrate = bitrate_observer.last_bitrate_;
sequence_number[0] += 20;
sequence_number[1] += 1;
report_blocks.clear();
}
TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
TestBitrateObserver bitrate_observer_1;
TestBitrateObserver bitrate_observer_2;
@ -187,10 +319,14 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
// Test too low start bitrate, hence lower than sum of min.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
webrtc::ReportBlockList report_blocks;
report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
// Test bitrate increase 8% per second, distributed equally.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer_1.last_rtt_);
@ -199,47 +335,67 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer_2.last_rtt_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
EXPECT_EQ(112500u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(212500u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
EXPECT_EQ(126000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(226000u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001);
EXPECT_EQ(140580u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(240580u, bitrate_observer_2.last_bitrate_);
// Check that the bitrate sum honor our REMB.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(250000u, bitrate_observer_2.last_bitrate_);
// Remove REMB cap, higher than sum of max.
bandwidth_observer_->OnReceivedEstimatedBitrate(700000);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001);
EXPECT_EQ(166500u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(266500u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
EXPECT_EQ(184320u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(284320u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 161, 8001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 161));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 8001);
EXPECT_EQ(207130u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_); // Max cap.
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 181, 9001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 181));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 9001);
EXPECT_EQ(248700u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 201, 10001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 201));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 10001);
EXPECT_EQ(293596u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 221, 11001);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 221));
bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 11001);
EXPECT_EQ(300000u, bitrate_observer_1.last_bitrate_); // Max cap.
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);

View File

@ -12,6 +12,7 @@
#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
#include <stddef.h>
#include <list>
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/clock.h"
@ -142,19 +143,42 @@ struct RTCPSenderInfo
uint32_t sendOctetCount;
};
struct RTCPReportBlock
{
struct RTCPReportBlock {
RTCPReportBlock()
: remoteSSRC(0), sourceSSRC(0), fractionLost(0), cumulativeLost(0),
extendedHighSeqNum(0), jitter(0), lastSR(0),
delaySinceLastSR(0) {}
RTCPReportBlock(uint32_t remote_ssrc,
uint32_t source_ssrc,
uint8_t fraction_lost,
uint32_t cumulative_lost,
uint32_t extended_high_sequence_number,
uint32_t jitter,
uint32_t last_sender_report,
uint32_t delay_since_last_sender_report)
: remoteSSRC(remote_ssrc),
sourceSSRC(source_ssrc),
fractionLost(fraction_lost),
cumulativeLost(cumulative_lost),
extendedHighSeqNum(extended_high_sequence_number),
jitter(jitter),
lastSR(last_sender_report),
delaySinceLastSR(delay_since_last_sender_report) {}
// Fields as described by RFC 3550 6.4.2.
uint32_t remoteSSRC; // SSRC of sender of this report.
uint32_t sourceSSRC; // SSRC of the RTP packet sender.
uint8_t fractionLost;
uint32_t cumulativeLost; // 24 bits valid
uint32_t cumulativeLost; // 24 bits valid.
uint32_t extendedHighSeqNum;
uint32_t jitter;
uint32_t lastSR;
uint32_t delaySinceLastSR;
};
typedef std::list<RTCPReportBlock> ReportBlockList;
class RtpData
{
public:
@ -249,11 +273,9 @@ class RtcpBandwidthObserver {
virtual void OnReceivedEstimatedBitrate(const uint32_t bitrate) = 0;
virtual void OnReceivedRtcpReceiverReport(
const uint32_t ssrc,
const uint8_t fraction_loss,
const uint32_t rtt,
const uint32_t last_received_extended_high_seqNum,
const uint32_t now_ms) = 0;
const ReportBlockList& report_blocks,
uint16_t rtt,
int64_t now_ms) = 0;
virtual ~RtcpBandwidthObserver() {}
};

View File

@ -46,7 +46,7 @@ RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
_cbRtcpIntraFrameObserver(NULL),
_criticalSectionRTCPReceiver(
CriticalSectionWrapper::CreateCriticalSection()),
_SSRC(0),
main_ssrc_(0),
_remoteSSRC(0),
_remoteSenderInfo(),
_lastReceivedSRNTPsecs(0),
@ -156,18 +156,19 @@ void RTCPReceiver::RegisterRtcpObservers(
_cbRtcpFeedback = feedback_callback;
}
void RTCPReceiver::SetSSRC(const uint32_t ssrc) {
void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
const std::set<uint32_t>& registered_ssrcs) {
uint32_t old_ssrc = 0;
{
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
old_ssrc = _SSRC;
_SSRC = ssrc;
old_ssrc = main_ssrc_;
main_ssrc_ = main_ssrc;
registered_ssrcs_ = registered_ssrcs;
}
{
CriticalSectionScoped lock(_criticalSectionFeedbacks);
if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
_cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
_cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
}
}
}
@ -405,7 +406,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
{
TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
"remote_ssrc", remoteSSRC,
"ssrc", _SSRC);
"ssrc", main_ssrc_);
if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
{
@ -436,7 +437,7 @@ RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
{
TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
"remote_ssrc", remoteSSRC,
"ssrc", _SSRC);
"ssrc", main_ssrc_);
rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
}
@ -467,7 +468,8 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
// which the information in this reception report block pertains.
// Filter out all report blocks that are not for us.
if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
registered_ssrcs_.end()) {
// This block is not for us ignore it.
return;
}
@ -564,11 +566,7 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
// rtcpPacketInformation
rtcpPacketInformation.AddReportInfo(
reportBlock->remoteReceiveBlock.fractionLost, (uint16_t) RTT,
reportBlock->remoteReceiveBlock.extendedHighSeqNum,
reportBlock->remoteReceiveBlock.jitter);
rtcpPacketInformation.AddReportInfo(*reportBlock);
}
RTCPReportBlockInformation*
@ -757,7 +755,7 @@ int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
i++) {
if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
// owner of bounding set
tmmbrOwner = true;
}
@ -799,7 +797,7 @@ RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
RTCPPacketInformation& rtcpPacketInformation)
{
const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
if (_SSRC != rtcpPacket.NACK.MediaSSRC)
if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
{
// Not to us.
rtcpParser.Iterate();
@ -879,7 +877,7 @@ RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
{
// Store VoIP metrics block if it's about me
// from OriginatorSSRC do we filter it?
@ -918,7 +916,7 @@ RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
RTCPPacketInformation& rtcpPacketInformation) {
const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
// Received a signal that we need to send a new key frame.
@ -977,7 +975,7 @@ RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
RTCPPacketInformation& rtcpPacketInformation,
const uint32_t senderSSRC)
{
if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
{
receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
@ -1160,7 +1158,7 @@ void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
const RTCPUtility::RTCPPacket& rtcpPacket,
RTCPPacketInformation& rtcpPacketInformation) {
// Is it our sender that is requested to generate a new keyframe
if (_SSRC != rtcpPacket.FIRItem.SSRC) {
if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
return;
}
// rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
@ -1271,7 +1269,7 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
{
// We don't want to hold this critsect when triggering the callbacks below.
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
local_ssrc = _SSRC;
local_ssrc = main_ssrc_;
}
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
_rtpRtcp.OnRequestSendReport();
@ -1322,15 +1320,12 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
_cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
rtcpPacketInformation.receiverEstimatedMaxBitrate);
}
if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
rtcpPacketInformation.reportBlock) {
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
int64_t now = _clock->TimeInMilliseconds();
_cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
rtcpPacketInformation.remoteSSRC,
rtcpPacketInformation.fractionLost,
rtcpPacketInformation.roundTripTime,
rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
rtcpPacketInformation.report_blocks,
rtcpPacketInformation.rtt,
now);
}
}

View File

@ -13,6 +13,7 @@
#include <map>
#include <vector>
#include <set>
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h"
@ -39,7 +40,8 @@ public:
int64_t LastReceived();
int64_t LastReceivedReceiverReport() const;
void SetSSRC( const uint32_t ssrc);
void SetSsrcs(uint32_t main_ssrc,
const std::set<uint32_t>& registered_ssrcs);
void SetRelaySSRC( const uint32_t ssrc);
int32_t SetRemoteSSRC( const uint32_t ssrc);
uint32_t RemoteSSRC() const;
@ -211,8 +213,9 @@ protected:
RtcpIntraFrameObserver* _cbRtcpIntraFrameObserver;
CriticalSectionWrapper* _criticalSectionRTCPReceiver;
uint32_t _SSRC;
uint32_t main_ssrc_;
uint32_t _remoteSSRC;
std::set<uint32_t> registered_ssrcs_;
// Received send report
RTCPSenderInfo _remoteSenderInfo;

View File

@ -26,11 +26,7 @@ RTCPPacketInformation::RTCPPacketInformation()
applicationName(0),
applicationData(),
applicationLength(0),
reportBlock(false),
fractionLost(0),
roundTripTime(0),
lastReceivedExtendedHighSeqNum(0),
jitter(0),
rtt(0),
interArrivalJitter(0),
sliPictureId(0),
rpsiPictureId(0),
@ -95,16 +91,11 @@ RTCPPacketInformation::AddNACKPacket(const uint16_t packetID)
}
void
RTCPPacketInformation::AddReportInfo(const uint8_t fraction,
const uint16_t rtt,
const uint32_t extendedHighSeqNum,
const uint32_t j)
RTCPPacketInformation::AddReportInfo(
const RTCPReportBlockInformation& report_block_info)
{
reportBlock = true;
fractionLost = fraction;
roundTripTime = rtt;
jitter = j;
lastReceivedExtendedHighSeqNum = extendedHighSeqNum;
this->rtt = report_block_info.RTT;
report_blocks.push_back(report_block_info.remoteReceiveBlock);
}
RTCPReportBlockInformation::RTCPReportBlockInformation():

View File

@ -11,7 +11,6 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_HELP_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_HELP_H_
#include <list>
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" // RTCPReportBlock
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
@ -24,58 +23,6 @@ namespace webrtc {
namespace RTCPHelp
{
class RTCPPacketInformation
{
public:
RTCPPacketInformation();
~RTCPPacketInformation();
void AddVoIPMetric(const RTCPVoIPMetric* metric);
void AddApplicationData(const uint8_t* data,
const uint16_t size);
void AddNACKPacket(const uint16_t packetID);
void ResetNACKPacketIdArray();
void AddReportInfo(const uint8_t fractionLost,
const uint16_t rtt,
const uint32_t extendedHighSeqNum,
const uint32_t jitter);
uint32_t rtcpPacketTypeFlags; // RTCPPacketTypeFlags bit field
uint32_t remoteSSRC;
std::list<uint16_t> nackSequenceNumbers;
uint8_t applicationSubType;
uint32_t applicationName;
uint8_t* applicationData;
uint16_t applicationLength;
bool reportBlock;
uint8_t fractionLost;
uint16_t roundTripTime;
uint32_t lastReceivedExtendedHighSeqNum;
uint32_t jitter;
uint32_t interArrivalJitter;
uint8_t sliPictureId;
uint64_t rpsiPictureId;
uint32_t receiverEstimatedMaxBitrate;
uint32_t ntp_secs;
uint32_t ntp_frac;
uint32_t rtp_timestamp;
RTCPVoIPMetric* VoIPMetric;
private:
DISALLOW_COPY_AND_ASSIGN(RTCPPacketInformation);
};
class RTCPReportBlockInformation
{
public:
@ -94,6 +41,51 @@ public:
uint32_t numAverageCalcs;
};
class RTCPPacketInformation
{
public:
RTCPPacketInformation();
~RTCPPacketInformation();
void AddVoIPMetric(const RTCPVoIPMetric* metric);
void AddApplicationData(const uint8_t* data,
const uint16_t size);
void AddNACKPacket(const uint16_t packetID);
void ResetNACKPacketIdArray();
void AddReportInfo(const RTCPReportBlockInformation& report_block_info);
uint32_t rtcpPacketTypeFlags; // RTCPPacketTypeFlags bit field
uint32_t remoteSSRC;
std::list<uint16_t> nackSequenceNumbers;
uint8_t applicationSubType;
uint32_t applicationName;
uint8_t* applicationData;
uint16_t applicationLength;
ReportBlockList report_blocks;
uint16_t rtt;
uint32_t interArrivalJitter;
uint8_t sliPictureId;
uint64_t rpsiPictureId;
uint32_t receiverEstimatedMaxBitrate;
uint32_t ntp_secs;
uint32_t ntp_frac;
uint32_t rtp_timestamp;
RTCPVoIPMetric* VoIPMetric;
private:
DISALLOW_COPY_AND_ASSIGN(RTCPPacketInformation);
};
class RTCPReceiveInformation
{
public:

View File

@ -33,6 +33,20 @@ class PacketBuilder {
public:
static const int kMaxPacketSize = 1024;
struct ReportBlock {
ReportBlock(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss,
uint32_t cumulative_loss)
: ssrc(ssrc),
extended_max(extended_max),
fraction_loss(fraction_loss),
cumulative_loss(cumulative_loss) {}
uint32_t ssrc;
uint32_t extended_max;
uint8_t fraction_loss;
uint32_t cumulative_loss;
};
PacketBuilder()
: pos_(0),
pos_of_len_(0) {
@ -42,7 +56,7 @@ class PacketBuilder {
void Add8(uint8_t byte) {
EXPECT_LT(pos_, kMaxPacketSize - 1);
buffer_[pos_] = byte;
++ pos_;
++pos_;
}
void Add16(uint16_t word) {
@ -93,11 +107,30 @@ class PacketBuilder {
}
void AddRrPacket(uint32_t sender_ssrc, uint32_t rtp_ssrc,
uint32_t extended_max) {
AddRtcpHeader(201, 1);
uint32_t extended_max, uint8_t fraction_loss,
uint32_t cumulative_loss) {
ReportBlock report_block(rtp_ssrc, extended_max, fraction_loss,
cumulative_loss);
std::list<ReportBlock> report_block_vector(&report_block,
&report_block + 1);
AddRrPacketMultipleReportBlocks(sender_ssrc, report_block_vector);
}
void AddRrPacketMultipleReportBlocks(
uint32_t sender_ssrc, const std::list<ReportBlock>& report_blocks) {
AddRtcpHeader(201, report_blocks.size());
Add32(sender_ssrc);
for (std::list<ReportBlock>::const_iterator it = report_blocks.begin();
it != report_blocks.end(); ++it) {
AddReportBlock(it->ssrc, it->extended_max, it->fraction_loss,
it->cumulative_loss);
}
}
void AddReportBlock(uint32_t rtp_ssrc, uint32_t extended_max,
uint8_t fraction_loss, uint32_t cumulative_loss) {
Add32(rtp_ssrc);
Add32(0); // No loss.
Add32((fraction_loss << 24) + cumulative_loss);
Add32(extended_max);
Add32(0); // Jitter.
Add32(0); // Last SR.
@ -211,12 +244,8 @@ class RtcpReceiverTest : public ::testing::Test {
rtcp_packet_info_.applicationSubType =
rtcpPacketInformation.applicationSubType;
rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName;
rtcp_packet_info_.reportBlock = rtcpPacketInformation.reportBlock;
rtcp_packet_info_.fractionLost = rtcpPacketInformation.fractionLost;
rtcp_packet_info_.roundTripTime = rtcpPacketInformation.roundTripTime;
rtcp_packet_info_.lastReceivedExtendedHighSeqNum =
rtcpPacketInformation.lastReceivedExtendedHighSeqNum;
rtcp_packet_info_.jitter = rtcpPacketInformation.jitter;
rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks;
rtcp_packet_info_.rtt = rtcpPacketInformation.rtt;
rtcp_packet_info_.interArrivalJitter =
rtcpPacketInformation.interArrivalJitter;
rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId;
@ -263,7 +292,9 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
const uint32_t kSourceSsrc = 0x40506;
const int64_t kRtcpIntervalMs = 1000;
rtcp_receiver_->SetSSRC(kSourceSsrc);
std::set<uint32_t> ssrcs;
ssrcs.insert(kSourceSsrc);
rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
uint32_t sequence_number = 1234;
system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
@ -274,7 +305,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
// Add a RR and advance the clock just enough to not trigger a timeout.
PacketBuilder p1;
p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0);
EXPECT_EQ(0, InjectRtcpPacket(p1.packet(), p1.length()));
system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
@ -283,7 +314,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
// Add a RR with the same extended max as the previous RR to trigger a
// sequence number timeout, but not a RR timeout.
PacketBuilder p2;
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0);
EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
system_clock_.AdvanceTimeMilliseconds(2);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
@ -301,7 +332,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
// Add a new RR with increase sequence number to reset timers.
PacketBuilder p3;
sequence_number++;
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0);
EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
@ -309,7 +340,7 @@ TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
// Verify we can get a timeout again once we've received new RR.
system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
PacketBuilder p4;
p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number);
p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0);
EXPECT_EQ(0, InjectRtcpPacket(p4.packet(), p4.length()));
system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
@ -323,11 +354,47 @@ TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
EXPECT_EQ(-1, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
}
TEST_F(RtcpReceiverTest, TwoReportBlocks) {
const uint32_t kSenderSsrc = 0x10203;
const int kNumSsrcs = 2;
const uint32_t kSourceSsrcs[kNumSsrcs] = {0x40506, 0x50607};
uint32_t sequence_numbers[kNumSsrcs] = {10, 12423};
std::set<uint32_t> ssrcs(kSourceSsrcs, kSourceSsrcs + kNumSsrcs);
rtcp_receiver_->SetSsrcs(kSourceSsrcs[0], ssrcs);
PacketBuilder packet;
std::list<PacketBuilder::ReportBlock> report_blocks;
report_blocks.push_back(PacketBuilder::ReportBlock(
kSourceSsrcs[0], sequence_numbers[0], 10, 5));
report_blocks.push_back(PacketBuilder::ReportBlock(
kSourceSsrcs[1], sequence_numbers[1], 0, 0));
packet.AddRrPacketMultipleReportBlocks(kSenderSsrc, report_blocks);
EXPECT_EQ(0, InjectRtcpPacket(packet.packet(), packet.length()));
ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size());
EXPECT_EQ(10, rtcp_packet_info_.report_blocks.front().fractionLost);
EXPECT_EQ(0, rtcp_packet_info_.report_blocks.back().fractionLost);
PacketBuilder packet2;
report_blocks.clear();
report_blocks.push_back(PacketBuilder::ReportBlock(
kSourceSsrcs[0], sequence_numbers[0], 0, 0));
report_blocks.push_back(PacketBuilder::ReportBlock(
kSourceSsrcs[1], sequence_numbers[1], 20, 10));
packet2.AddRrPacketMultipleReportBlocks(kSenderSsrc, report_blocks);
EXPECT_EQ(0, InjectRtcpPacket(packet2.packet(), packet2.length()));
ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size());
EXPECT_EQ(0, rtcp_packet_info_.report_blocks.front().fractionLost);
EXPECT_EQ(20, rtcp_packet_info_.report_blocks.back().fractionLost);
}
TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
const uint32_t kMediaFlowSsrc = 0x2040608;
const uint32_t kSenderSsrc = 0x10203;
const uint32_t kMediaRecipientSsrc = 0x101;
rtcp_receiver_->SetSSRC(kMediaFlowSsrc); // Matches "media source" above.
std::set<uint32_t> ssrcs;
ssrcs.insert(kMediaFlowSsrc); // Matches "media source" above.
rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);
PacketBuilder p;
p.AddSrPacket(kSenderSsrc);
@ -362,7 +429,9 @@ TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
p.Add32(kOtherMediaFlowSsrc); // This SSRC is not what we're sending.
p.AddTmmbrBandwidth(30000, 0, 0);
rtcp_receiver_->SetSSRC(kMediaFlowSsrc);
std::set<uint32_t> ssrcs;
ssrcs.insert(kMediaFlowSsrc);
rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);
EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
}
@ -371,7 +440,9 @@ TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
const uint32_t kMediaFlowSsrc = 0x2040608;
const uint32_t kSenderSsrc = 0x10203;
const uint32_t kMediaRecipientSsrc = 0x101;
rtcp_receiver_->SetSSRC(kMediaFlowSsrc); // Matches "media source" above.
std::set<uint32_t> ssrcs;
ssrcs.insert(kMediaFlowSsrc); // Matches "media source" above.
rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);
PacketBuilder p;
p.AddSrPacket(kSenderSsrc);
@ -390,7 +461,9 @@ TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
const uint32_t kMediaFlowSsrc = 0x2040608;
const uint32_t kSenderSsrc = 0x10203;
const uint32_t kMediaRecipientSsrc = 0x101;
rtcp_receiver_->SetSSRC(kMediaFlowSsrc); // Matches "media source" above.
std::set<uint32_t> ssrcs;
ssrcs.insert(kMediaFlowSsrc); // Matches "media source" above.
rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);
// Inject 3 packets "from" kMediaRecipientSsrc, Ssrc+1, Ssrc+2.
// The times of arrival are starttime + 0, starttime + 5 and starttime + 10.

View File

@ -246,12 +246,8 @@ class TestTransport : public Transport,
rtcp_packet_info_.applicationSubType =
rtcpPacketInformation.applicationSubType;
rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName;
rtcp_packet_info_.reportBlock = rtcpPacketInformation.reportBlock;
rtcp_packet_info_.fractionLost = rtcpPacketInformation.fractionLost;
rtcp_packet_info_.roundTripTime = rtcpPacketInformation.roundTripTime;
rtcp_packet_info_.lastReceivedExtendedHighSeqNum =
rtcpPacketInformation.lastReceivedExtendedHighSeqNum;
rtcp_packet_info_.jitter = rtcpPacketInformation.jitter;
rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks;
rtcp_packet_info_.rtt = rtcpPacketInformation.rtt;
rtcp_packet_info_.interArrivalJitter =
rtcpPacketInformation.interArrivalJitter;
rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId;

View File

@ -111,10 +111,10 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
configuration.rtcp_feedback);
rtcp_sender_.RegisterSendTransport(configuration.outgoing_transport);
// Make sure that RTCP objects are aware of our SSRC
// Make sure that RTCP objects are aware of our SSRC.
uint32_t SSRC = rtp_sender_.SSRC();
rtcp_sender_.SetSSRC(SSRC);
rtcp_receiver_.SetSSRC(SSRC);
SetRtcpReceiverSsrcs(SSRC);
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id_, "%s created", __FUNCTION__);
}
@ -261,6 +261,8 @@ int32_t ModuleRtpRtcpImpl::Process() {
int32_t ModuleRtpRtcpImpl::SetRTXSendStatus(RtxMode mode, bool set_ssrc,
uint32_t ssrc) {
rtp_sender_.SetRTXStatus(mode, set_ssrc, ssrc);
return 0;
}
@ -410,8 +412,9 @@ int32_t ModuleRtpRtcpImpl::SetSSRC(const uint32_t ssrc) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SetSSRC(%d)", ssrc);
rtp_sender_.SetSSRC(ssrc);
rtcp_receiver_.SetSSRC(ssrc);
rtcp_sender_.SetSSRC(ssrc);
SetRtcpReceiverSsrcs(ssrc);
return 0; // TODO(pwestin): change to void.
}
@ -510,8 +513,9 @@ int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
// Make sure that RTCP objects are aware of our SSRC (it could have changed
// Due to collision)
uint32_t SSRC = rtp_sender_.SSRC();
rtcp_receiver_.SetSSRC(SSRC);
rtcp_sender_.SetSSRC(SSRC);
SetRtcpReceiverSsrcs(SSRC);
return 0;
}
return 0;
@ -1459,7 +1463,7 @@ void ModuleRtpRtcpImpl::SetRemoteSSRC(const uint32_t ssrc) {
}
// Change local SSRC and inform all objects about the new SSRC.
rtcp_sender_.SetSSRC(new_ssrc);
rtcp_receiver_.SetSSRC(new_ssrc);
SetRtcpReceiverSsrcs(new_ssrc);
}
}
@ -1587,4 +1591,17 @@ int64_t ModuleRtpRtcpImpl::RtcpReportInterval() {
else
return RTCP_INTERVAL_VIDEO_MS;
}
void ModuleRtpRtcpImpl::SetRtcpReceiverSsrcs(uint32_t main_ssrc) {
std::set<uint32_t> ssrcs;
ssrcs.insert(main_ssrc);
RtxMode rtx_mode = kRtxOff;
uint32_t rtx_ssrc = 0;
int rtx_payload_type = 0;
rtp_sender_.RTXStatus(&rtx_mode, &rtx_ssrc, &rtx_payload_type);
if (rtx_mode != kRtxOff)
ssrcs.insert(rtx_ssrc);
rtcp_receiver_.SetSsrcs(main_ssrc, ssrcs);
}
} // Namespace webrtc

View File

@ -377,6 +377,7 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
private:
int64_t RtcpReportInterval();
void SetRtcpReceiverSsrcs(uint32_t main_ssrc);
int32_t id_;
const bool audio_;