Replacing NetEq discard rate with secondary discarded rate.
NetEq network statistics contains discard rate but has not been used and even not been implemented until recently. According to w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsdiscarded, this statistics needs to be replaced with an accumulative stats. Such work will be carried out separately. Meanwhile, we need to add a rate to reflect rate of discarded redundant packets. See webrtc:8025. In this CL, we replace the existing discard rate with secondary discarded rate, so as to 1. fulfill the requests on webrtc:8025 2. get ready to implement an accumulative statistics for discarded packets. BUG: webrtc:7903,webrtc:8025 Change-Id: Idbf143a105db76ca15f0af54848e1448f2a810ec Reviewed-on: https://chromium-review.googlesource.com/582863 Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Minyue Li <minyue@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19495}
This commit is contained in:
committed by
Commit Bot
parent
d950d9eda1
commit
0c3ca753c5
@ -65,7 +65,7 @@ const CallStatistics kCallStats = {
|
|||||||
const CodecInst kCodecInst = {
|
const CodecInst kCodecInst = {
|
||||||
123, "codec_name_recv", 96000, -187, 0, -103};
|
123, "codec_name_recv", 96000, -187, 0, -103};
|
||||||
const NetworkStatistics kNetworkStats = {
|
const NetworkStatistics kNetworkStats = {
|
||||||
123, 456, false, 0, 0, 789, 12, 345, 678, 901, -1, -1, -1, -1, -1, 0};
|
123, 456, false, 0, {}, 789, 12, 345, 678, 901, 0, -1, -1, -1, -1, -1, 0};
|
||||||
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
|
|||||||
@ -370,7 +370,9 @@ struct NetworkStatistics {
|
|||||||
// Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
|
// Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
|
||||||
uint16_t currentPacketLossRate;
|
uint16_t currentPacketLossRate;
|
||||||
// Late loss rate; fraction between 0 and 1, scaled to Q14.
|
// Late loss rate; fraction between 0 and 1, scaled to Q14.
|
||||||
uint16_t currentDiscardRate;
|
union {
|
||||||
|
RTC_DEPRECATED uint16_t currentDiscardRate;
|
||||||
|
};
|
||||||
// fraction (of original stream) of synthesized audio inserted through
|
// fraction (of original stream) of synthesized audio inserted through
|
||||||
// expansion (in Q14)
|
// expansion (in Q14)
|
||||||
uint16_t currentExpandRate;
|
uint16_t currentExpandRate;
|
||||||
@ -384,6 +386,8 @@ struct NetworkStatistics {
|
|||||||
uint16_t currentAccelerateRate;
|
uint16_t currentAccelerateRate;
|
||||||
// fraction of data coming from secondary decoding (in Q14)
|
// fraction of data coming from secondary decoding (in Q14)
|
||||||
uint16_t currentSecondaryDecodedRate;
|
uint16_t currentSecondaryDecodedRate;
|
||||||
|
// fraction of secondary data that is discarded (in Q14).
|
||||||
|
uint16_t currentSecondaryDiscardedRate;
|
||||||
// clock-drift in parts-per-million (negative or positive)
|
// clock-drift in parts-per-million (negative or positive)
|
||||||
int32_t clockDriftPPM;
|
int32_t clockDriftPPM;
|
||||||
// average packet waiting time in the jitter buffer (ms)
|
// average packet waiting time in the jitter buffer (ms)
|
||||||
|
|||||||
@ -320,12 +320,12 @@ void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
|
|||||||
acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
|
acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms;
|
||||||
acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false;
|
acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false;
|
||||||
acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate;
|
acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate;
|
||||||
acm_stat->currentDiscardRate = neteq_stat.packet_discard_rate;
|
|
||||||
acm_stat->currentExpandRate = neteq_stat.expand_rate;
|
acm_stat->currentExpandRate = neteq_stat.expand_rate;
|
||||||
acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate;
|
acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate;
|
||||||
acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate;
|
acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate;
|
||||||
acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate;
|
acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate;
|
||||||
acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate;
|
acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate;
|
||||||
|
acm_stat->currentSecondaryDiscardedRate = neteq_stat.secondary_discarded_rate;
|
||||||
acm_stat->clockDriftPPM = neteq_stat.clockdrift_ppm;
|
acm_stat->clockDriftPPM = neteq_stat.clockdrift_ppm;
|
||||||
acm_stat->addedSamples = neteq_stat.added_zero_samples;
|
acm_stat->addedSamples = neteq_stat.added_zero_samples;
|
||||||
acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms;
|
acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms;
|
||||||
|
|||||||
@ -35,7 +35,6 @@ struct NetEqNetworkStatistics {
|
|||||||
uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky
|
uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky
|
||||||
// jitter; 0 otherwise.
|
// jitter; 0 otherwise.
|
||||||
uint16_t packet_loss_rate; // Loss rate (network + late) in Q14.
|
uint16_t packet_loss_rate; // Loss rate (network + late) in Q14.
|
||||||
uint16_t packet_discard_rate; // Late loss rate in Q14.
|
|
||||||
uint16_t expand_rate; // Fraction (of original stream) of synthesized
|
uint16_t expand_rate; // Fraction (of original stream) of synthesized
|
||||||
// audio inserted through expansion (in Q14).
|
// audio inserted through expansion (in Q14).
|
||||||
uint16_t speech_expand_rate; // Fraction (of original stream) of synthesized
|
uint16_t speech_expand_rate; // Fraction (of original stream) of synthesized
|
||||||
@ -44,8 +43,10 @@ struct NetEqNetworkStatistics {
|
|||||||
// expansion (in Q14).
|
// expansion (in Q14).
|
||||||
uint16_t accelerate_rate; // Fraction of data removed through acceleration
|
uint16_t accelerate_rate; // Fraction of data removed through acceleration
|
||||||
// (in Q14).
|
// (in Q14).
|
||||||
uint16_t secondary_decoded_rate; // Fraction of data coming from secondary
|
uint16_t secondary_decoded_rate; // Fraction of data coming from FEC/RED
|
||||||
// decoding (in Q14).
|
// decoding (in Q14).
|
||||||
|
uint16_t secondary_discarded_rate; // Fraction of discarded FEC/RED data (in
|
||||||
|
// Q14).
|
||||||
int32_t clockdrift_ppm; // Average clock-drift in parts-per-million
|
int32_t clockdrift_ppm; // Average clock-drift in parts-per-million
|
||||||
// (positive or negative).
|
// (positive or negative).
|
||||||
size_t added_zero_samples; // Number of zero samples added in "off" mode.
|
size_t added_zero_samples; // Number of zero samples added in "off" mode.
|
||||||
|
|||||||
@ -19,8 +19,8 @@ namespace webrtc {
|
|||||||
|
|
||||||
class MockStatisticsCalculator : public StatisticsCalculator {
|
class MockStatisticsCalculator : public StatisticsCalculator {
|
||||||
public:
|
public:
|
||||||
// For current unittest, we mock only one method.
|
|
||||||
MOCK_METHOD1(PacketsDiscarded, void(size_t num_packets));
|
MOCK_METHOD1(PacketsDiscarded, void(size_t num_packets));
|
||||||
|
MOCK_METHOD1(SecondaryPacketsDiscarded, void(size_t num_packets));
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -136,12 +136,12 @@ struct NetEqNetworkStatsCheck {
|
|||||||
logic preferred_buffer_size_ms;
|
logic preferred_buffer_size_ms;
|
||||||
logic jitter_peaks_found;
|
logic jitter_peaks_found;
|
||||||
logic packet_loss_rate;
|
logic packet_loss_rate;
|
||||||
logic packet_discard_rate;
|
|
||||||
logic expand_rate;
|
logic expand_rate;
|
||||||
logic speech_expand_rate;
|
logic speech_expand_rate;
|
||||||
logic preemptive_rate;
|
logic preemptive_rate;
|
||||||
logic accelerate_rate;
|
logic accelerate_rate;
|
||||||
logic secondary_decoded_rate;
|
logic secondary_decoded_rate;
|
||||||
|
logic secondary_discarded_rate;
|
||||||
logic clockdrift_ppm;
|
logic clockdrift_ppm;
|
||||||
logic added_zero_samples;
|
logic added_zero_samples;
|
||||||
NetEqNetworkStatistics stats_ref;
|
NetEqNetworkStatistics stats_ref;
|
||||||
@ -201,12 +201,12 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
|||||||
CHECK_NETEQ_NETWORK_STATS(preferred_buffer_size_ms);
|
CHECK_NETEQ_NETWORK_STATS(preferred_buffer_size_ms);
|
||||||
CHECK_NETEQ_NETWORK_STATS(jitter_peaks_found);
|
CHECK_NETEQ_NETWORK_STATS(jitter_peaks_found);
|
||||||
CHECK_NETEQ_NETWORK_STATS(packet_loss_rate);
|
CHECK_NETEQ_NETWORK_STATS(packet_loss_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(packet_discard_rate);
|
|
||||||
CHECK_NETEQ_NETWORK_STATS(expand_rate);
|
CHECK_NETEQ_NETWORK_STATS(expand_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(speech_expand_rate);
|
CHECK_NETEQ_NETWORK_STATS(speech_expand_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(preemptive_rate);
|
CHECK_NETEQ_NETWORK_STATS(preemptive_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(accelerate_rate);
|
CHECK_NETEQ_NETWORK_STATS(accelerate_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(secondary_decoded_rate);
|
CHECK_NETEQ_NETWORK_STATS(secondary_decoded_rate);
|
||||||
|
CHECK_NETEQ_NETWORK_STATS(secondary_discarded_rate);
|
||||||
CHECK_NETEQ_NETWORK_STATS(clockdrift_ppm);
|
CHECK_NETEQ_NETWORK_STATS(clockdrift_ppm);
|
||||||
CHECK_NETEQ_NETWORK_STATS(added_zero_samples);
|
CHECK_NETEQ_NETWORK_STATS(added_zero_samples);
|
||||||
|
|
||||||
@ -249,12 +249,12 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
|||||||
kIgnore, // preferred_buffer_size_ms
|
kIgnore, // preferred_buffer_size_ms
|
||||||
kIgnore, // jitter_peaks_found
|
kIgnore, // jitter_peaks_found
|
||||||
kEqual, // packet_loss_rate
|
kEqual, // packet_loss_rate
|
||||||
kEqual, // packet_discard_rate
|
|
||||||
kEqual, // expand_rate
|
kEqual, // expand_rate
|
||||||
kEqual, // voice_expand_rate
|
kEqual, // voice_expand_rate
|
||||||
kIgnore, // preemptive_rate
|
kIgnore, // preemptive_rate
|
||||||
kEqual, // accelerate_rate
|
kEqual, // accelerate_rate
|
||||||
kEqual, // decoded_fec_rate
|
kEqual, // decoded_fec_rate
|
||||||
|
kEqual, // discarded_fec_rate
|
||||||
kIgnore, // clockdrift_ppm
|
kIgnore, // clockdrift_ppm
|
||||||
kEqual, // added_zero_samples
|
kEqual, // added_zero_samples
|
||||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
@ -273,7 +273,7 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
|||||||
expects.stats_ref.packet_loss_rate = 0;
|
expects.stats_ref.packet_loss_rate = 0;
|
||||||
expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0;
|
expects.stats_ref.expand_rate = expects.stats_ref.speech_expand_rate = 0;
|
||||||
expects.stats_ref.secondary_decoded_rate = 2006;
|
expects.stats_ref.secondary_decoded_rate = 2006;
|
||||||
expects.stats_ref.packet_discard_rate = 13374;
|
expects.stats_ref.secondary_discarded_rate = 14336;
|
||||||
RunTest(50, expects);
|
RunTest(50, expects);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,12 +283,12 @@ NetEqNetworkStatsTest(NetEqDecoder codec,
|
|||||||
kIgnore, // preferred_buffer_size_ms
|
kIgnore, // preferred_buffer_size_ms
|
||||||
kIgnore, // jitter_peaks_found
|
kIgnore, // jitter_peaks_found
|
||||||
kEqual, // packet_loss_rate
|
kEqual, // packet_loss_rate
|
||||||
kEqual, // packet_discard_rate
|
|
||||||
kEqual, // expand_rate
|
kEqual, // expand_rate
|
||||||
kEqual, // speech_expand_rate
|
kEqual, // speech_expand_rate
|
||||||
kIgnore, // preemptive_rate
|
kIgnore, // preemptive_rate
|
||||||
kEqual, // accelerate_rate
|
kEqual, // accelerate_rate
|
||||||
kEqual, // decoded_fec_rate
|
kEqual, // decoded_fec_rate
|
||||||
|
kEqual, // discard_fec_rate
|
||||||
kIgnore, // clockdrift_ppm
|
kIgnore, // clockdrift_ppm
|
||||||
kEqual, // added_zero_samples
|
kEqual, // added_zero_samples
|
||||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
|||||||
@ -75,12 +75,12 @@ void Convert(const webrtc::NetEqNetworkStatistics& stats_raw,
|
|||||||
stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms);
|
stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms);
|
||||||
stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found);
|
stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found);
|
||||||
stats->set_packet_loss_rate(stats_raw.packet_loss_rate);
|
stats->set_packet_loss_rate(stats_raw.packet_loss_rate);
|
||||||
stats->set_packet_discard_rate(stats_raw.packet_discard_rate);
|
|
||||||
stats->set_expand_rate(stats_raw.expand_rate);
|
stats->set_expand_rate(stats_raw.expand_rate);
|
||||||
stats->set_speech_expand_rate(stats_raw.speech_expand_rate);
|
stats->set_speech_expand_rate(stats_raw.speech_expand_rate);
|
||||||
stats->set_preemptive_rate(stats_raw.preemptive_rate);
|
stats->set_preemptive_rate(stats_raw.preemptive_rate);
|
||||||
stats->set_accelerate_rate(stats_raw.accelerate_rate);
|
stats->set_accelerate_rate(stats_raw.accelerate_rate);
|
||||||
stats->set_secondary_decoded_rate(stats_raw.secondary_decoded_rate);
|
stats->set_secondary_decoded_rate(stats_raw.secondary_decoded_rate);
|
||||||
|
stats->set_secondary_discarded_rate(stats_raw.secondary_discarded_rate);
|
||||||
stats->set_clockdrift_ppm(stats_raw.clockdrift_ppm);
|
stats->set_clockdrift_ppm(stats_raw.clockdrift_ppm);
|
||||||
stats->set_added_zero_samples(stats_raw.added_zero_samples);
|
stats->set_added_zero_samples(stats_raw.added_zero_samples);
|
||||||
stats->set_mean_waiting_time_ms(stats_raw.mean_waiting_time_ms);
|
stats->set_mean_waiting_time_ms(stats_raw.mean_waiting_time_ms);
|
||||||
@ -445,10 +445,10 @@ TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) {
|
|||||||
"759fef89a5de52bd17e733dc255c671ce86be909");
|
"759fef89a5de52bd17e733dc255c671ce86be909");
|
||||||
|
|
||||||
const std::string network_stats_checksum =
|
const std::string network_stats_checksum =
|
||||||
PlatformChecksum("f7c2158761a531dd2804d13da0480033faa7be12",
|
PlatformChecksum("5b4262ca328e5f066af5d34f3380521583dd20de",
|
||||||
"8b5e3c8247dce48cb33923eaa1a502ca91429d5e",
|
"80235b6d727281203acb63b98f9a9e85d95f7ec0",
|
||||||
"f7c2158761a531dd2804d13da0480033faa7be12",
|
"5b4262ca328e5f066af5d34f3380521583dd20de",
|
||||||
"f7c2158761a531dd2804d13da0480033faa7be12");
|
"5b4262ca328e5f066af5d34f3380521583dd20de");
|
||||||
|
|
||||||
const std::string rtcp_stats_checksum = PlatformChecksum(
|
const std::string rtcp_stats_checksum = PlatformChecksum(
|
||||||
"b8880bf9fed2487efbddcb8d94b9937a29ae521d",
|
"b8880bf9fed2487efbddcb8d94b9937a29ae521d",
|
||||||
@ -481,10 +481,10 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) {
|
|||||||
"721e1e0c6effe4b2401536a4eef11512c9fb709c");
|
"721e1e0c6effe4b2401536a4eef11512c9fb709c");
|
||||||
|
|
||||||
const std::string network_stats_checksum =
|
const std::string network_stats_checksum =
|
||||||
PlatformChecksum("dda4cee006d9369c7114a03790c5761346cf5e23",
|
PlatformChecksum("4e749c46e2611877120ac7a20cbbe555cfbd70ea",
|
||||||
"dda4cee006d9369c7114a03790c5761346cf5e23",
|
"4e749c46e2611877120ac7a20cbbe555cfbd70ea",
|
||||||
"dda4cee006d9369c7114a03790c5761346cf5e23",
|
"4e749c46e2611877120ac7a20cbbe555cfbd70ea",
|
||||||
"dda4cee006d9369c7114a03790c5761346cf5e23");
|
"4e749c46e2611877120ac7a20cbbe555cfbd70ea");
|
||||||
|
|
||||||
const std::string rtcp_stats_checksum = PlatformChecksum(
|
const std::string rtcp_stats_checksum = PlatformChecksum(
|
||||||
"e37c797e3de6a64dda88c9ade7a013d022a2e1e0",
|
"e37c797e3de6a64dda88c9ade7a013d022a2e1e0",
|
||||||
|
|||||||
@ -3,16 +3,18 @@ option optimize_for = LITE_RUNTIME;
|
|||||||
package webrtc.neteq_unittest;
|
package webrtc.neteq_unittest;
|
||||||
|
|
||||||
message NetEqNetworkStatistics {
|
message NetEqNetworkStatistics {
|
||||||
|
// Next field number 18.
|
||||||
optional uint32 current_buffer_size_ms = 1;
|
optional uint32 current_buffer_size_ms = 1;
|
||||||
optional uint32 preferred_buffer_size_ms = 2;
|
optional uint32 preferred_buffer_size_ms = 2;
|
||||||
optional uint32 jitter_peaks_found = 3;
|
optional uint32 jitter_peaks_found = 3;
|
||||||
optional uint32 packet_loss_rate = 4;
|
optional uint32 packet_loss_rate = 4;
|
||||||
optional uint32 packet_discard_rate = 5;
|
optional uint32 packet_discard_rate = 5 [deprecated = true];
|
||||||
optional uint32 expand_rate = 6;
|
optional uint32 expand_rate = 6;
|
||||||
optional uint32 speech_expand_rate = 7;
|
optional uint32 speech_expand_rate = 7;
|
||||||
optional uint32 preemptive_rate = 8;
|
optional uint32 preemptive_rate = 8;
|
||||||
optional uint32 accelerate_rate = 9;
|
optional uint32 accelerate_rate = 9;
|
||||||
optional uint32 secondary_decoded_rate = 10;
|
optional uint32 secondary_decoded_rate = 10;
|
||||||
|
optional uint32 secondary_discarded_rate = 17;
|
||||||
optional int32 clockdrift_ppm = 11;
|
optional int32 clockdrift_ppm = 11;
|
||||||
optional uint64 added_zero_samples = 12;
|
optional uint64 added_zero_samples = 12;
|
||||||
optional int32 mean_waiting_time_ms = 13;
|
optional int32 mean_waiting_time_ms = 13;
|
||||||
|
|||||||
@ -48,6 +48,16 @@ bool EqualSampleRates(uint8_t pt1,
|
|||||||
auto* di2 = decoder_database.GetDecoderInfo(pt2);
|
auto* di2 = decoder_database.GetDecoderInfo(pt2);
|
||||||
return di1 && di2 && di1->SampleRateHz() == di2->SampleRateHz();
|
return di1 && di2 && di1->SampleRateHz() == di2->SampleRateHz();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogPacketDiscarded(int codec_level, StatisticsCalculator* stats) {
|
||||||
|
RTC_CHECK(stats);
|
||||||
|
if (codec_level > 0) {
|
||||||
|
stats->SecondaryPacketsDiscarded(1);
|
||||||
|
} else {
|
||||||
|
stats->PacketsDiscarded(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
|
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
|
||||||
@ -99,8 +109,7 @@ int PacketBuffer::InsertPacket(Packet&& packet, StatisticsCalculator* stats) {
|
|||||||
// timestamp as |rit|, which has a higher priority, do not insert the new
|
// timestamp as |rit|, which has a higher priority, do not insert the new
|
||||||
// packet to list.
|
// packet to list.
|
||||||
if (rit != buffer_.rend() && packet.timestamp == rit->timestamp) {
|
if (rit != buffer_.rend() && packet.timestamp == rit->timestamp) {
|
||||||
RTC_CHECK(stats);
|
LogPacketDiscarded(packet.priority.codec_level, stats);
|
||||||
stats->PacketsDiscarded(1);
|
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,9 +118,8 @@ int PacketBuffer::InsertPacket(Packet&& packet, StatisticsCalculator* stats) {
|
|||||||
// packet.
|
// packet.
|
||||||
PacketList::iterator it = rit.base();
|
PacketList::iterator it = rit.base();
|
||||||
if (it != buffer_.end() && packet.timestamp == it->timestamp) {
|
if (it != buffer_.end() && packet.timestamp == it->timestamp) {
|
||||||
|
LogPacketDiscarded(packet.priority.codec_level, stats);
|
||||||
it = buffer_.erase(it);
|
it = buffer_.erase(it);
|
||||||
RTC_CHECK(stats);
|
|
||||||
stats->PacketsDiscarded(1);
|
|
||||||
}
|
}
|
||||||
buffer_.insert(it, std::move(packet)); // Insert the packet at that position.
|
buffer_.insert(it, std::move(packet)); // Insert the packet at that position.
|
||||||
|
|
||||||
@ -218,25 +226,24 @@ int PacketBuffer::DiscardNextPacket(StatisticsCalculator* stats) {
|
|||||||
return kBufferEmpty;
|
return kBufferEmpty;
|
||||||
}
|
}
|
||||||
// Assert that the packet sanity checks in InsertPacket method works.
|
// Assert that the packet sanity checks in InsertPacket method works.
|
||||||
RTC_DCHECK(!buffer_.front().empty());
|
const Packet& packet = buffer_.front();
|
||||||
|
RTC_DCHECK(!packet.empty());
|
||||||
|
LogPacketDiscarded(packet.priority.codec_level, stats);
|
||||||
buffer_.pop_front();
|
buffer_.pop_front();
|
||||||
RTC_CHECK(stats);
|
|
||||||
stats->PacketsDiscarded(1);
|
|
||||||
return kOK;
|
return kOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
|
void PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
|
||||||
uint32_t horizon_samples,
|
uint32_t horizon_samples,
|
||||||
StatisticsCalculator* stats) {
|
StatisticsCalculator* stats) {
|
||||||
const size_t old_size = buffer_.size();
|
buffer_.remove_if([timestamp_limit, horizon_samples, stats](const Packet& p) {
|
||||||
buffer_.remove_if([timestamp_limit, horizon_samples](const Packet& p) {
|
if (timestamp_limit == p.timestamp ||
|
||||||
return timestamp_limit != p.timestamp &&
|
!IsObsoleteTimestamp(p.timestamp, timestamp_limit, horizon_samples)) {
|
||||||
IsObsoleteTimestamp(p.timestamp, timestamp_limit, horizon_samples);
|
return false;
|
||||||
|
}
|
||||||
|
LogPacketDiscarded(p.priority.codec_level, stats);
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
if (old_size > buffer_.size()) {
|
|
||||||
RTC_CHECK(stats);
|
|
||||||
stats->PacketsDiscarded(old_size - buffer_.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit,
|
void PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit,
|
||||||
@ -246,20 +253,13 @@ void PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit,
|
|||||||
|
|
||||||
void PacketBuffer::DiscardPacketsWithPayloadType(uint8_t payload_type,
|
void PacketBuffer::DiscardPacketsWithPayloadType(uint8_t payload_type,
|
||||||
StatisticsCalculator* stats) {
|
StatisticsCalculator* stats) {
|
||||||
int packets_discarded = 0;
|
buffer_.remove_if([payload_type, stats](const Packet& p) {
|
||||||
for (auto it = buffer_.begin(); it != buffer_.end(); /* */) {
|
if (p.payload_type != payload_type) {
|
||||||
const Packet& packet = *it;
|
return false;
|
||||||
if (packet.payload_type == payload_type) {
|
|
||||||
it = buffer_.erase(it);
|
|
||||||
++packets_discarded;
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
LogPacketDiscarded(p.priority.codec_level, stats);
|
||||||
if (packets_discarded > 0) {
|
return true;
|
||||||
RTC_CHECK(stats);
|
});
|
||||||
stats->PacketsDiscarded(packets_discarded);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PacketBuffer::NumPacketsInBuffer() const {
|
size_t PacketBuffer::NumPacketsInBuffer() const {
|
||||||
|
|||||||
@ -292,9 +292,13 @@ TEST(PacketBuffer, ExtractOrderRedundancy) {
|
|||||||
packet_facts[i].payload_type,
|
packet_facts[i].payload_type,
|
||||||
kFrameSize);
|
kFrameSize);
|
||||||
Packet packet = gen.NextPacket(kPayloadLength);
|
Packet packet = gen.NextPacket(kPayloadLength);
|
||||||
packet.priority.red_level = packet_facts[i].primary ? 0 : 1;
|
packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
|
||||||
if (packet_facts[i].extract_order < 0) {
|
if (packet_facts[i].extract_order < 0) {
|
||||||
EXPECT_CALL(mock_stats, PacketsDiscarded(1));
|
if (packet.priority.codec_level > 0) {
|
||||||
|
EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
|
||||||
|
} else {
|
||||||
|
EXPECT_CALL(mock_stats, PacketsDiscarded(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPECT_CALL(check, Call(i));
|
EXPECT_CALL(check, Call(i));
|
||||||
EXPECT_EQ(PacketBuffer::kOK,
|
EXPECT_EQ(PacketBuffer::kOK,
|
||||||
@ -358,7 +362,8 @@ TEST(PacketBuffer, DiscardPackets) {
|
|||||||
// This will discard all remaining packets but one. The oldest packet is older
|
// This will discard all remaining packets but one. The oldest packet is older
|
||||||
// than the indicated horizon_samples, and will thus be left in the buffer.
|
// than the indicated horizon_samples, and will thus be left in the buffer.
|
||||||
constexpr size_t kSkipPackets = 1;
|
constexpr size_t kSkipPackets = 1;
|
||||||
EXPECT_CALL(mock_stats, PacketsDiscarded(kRemainingPackets - kSkipPackets));
|
EXPECT_CALL(mock_stats, PacketsDiscarded(1))
|
||||||
|
.Times(kRemainingPackets - kSkipPackets);
|
||||||
EXPECT_CALL(check, Call(17)); // Arbitrary id number.
|
EXPECT_CALL(check, Call(17)); // Arbitrary id number.
|
||||||
buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
|
buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
|
||||||
kRemainingPackets * ts_increment, &mock_stats);
|
kRemainingPackets * ts_increment, &mock_stats);
|
||||||
|
|||||||
@ -123,14 +123,14 @@ StatisticsCalculator::StatisticsCalculator()
|
|||||||
lost_timestamps_(0),
|
lost_timestamps_(0),
|
||||||
timestamps_since_last_report_(0),
|
timestamps_since_last_report_(0),
|
||||||
secondary_decoded_samples_(0),
|
secondary_decoded_samples_(0),
|
||||||
|
discarded_secondary_packets_(0),
|
||||||
delayed_packet_outage_counter_(
|
delayed_packet_outage_counter_(
|
||||||
"WebRTC.Audio.DelayedPacketOutageEventsPerMinute",
|
"WebRTC.Audio.DelayedPacketOutageEventsPerMinute",
|
||||||
60000, // 60 seconds report interval.
|
60000, // 60 seconds report interval.
|
||||||
100),
|
100),
|
||||||
excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs",
|
excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs",
|
||||||
60000, // 60 seconds report interval.
|
60000, // 60 seconds report interval.
|
||||||
1000) {
|
1000) {}
|
||||||
}
|
|
||||||
|
|
||||||
StatisticsCalculator::~StatisticsCalculator() = default;
|
StatisticsCalculator::~StatisticsCalculator() = default;
|
||||||
|
|
||||||
@ -141,6 +141,7 @@ void StatisticsCalculator::Reset() {
|
|||||||
expanded_speech_samples_ = 0;
|
expanded_speech_samples_ = 0;
|
||||||
expanded_noise_samples_ = 0;
|
expanded_noise_samples_ = 0;
|
||||||
secondary_decoded_samples_ = 0;
|
secondary_decoded_samples_ = 0;
|
||||||
|
discarded_secondary_packets_ = 0;
|
||||||
waiting_times_.clear();
|
waiting_times_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +185,10 @@ void StatisticsCalculator::PacketsDiscarded(size_t num_packets) {
|
|||||||
discarded_packets_ += num_packets;
|
discarded_packets_ += num_packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatisticsCalculator::SecondaryPacketsDiscarded(size_t num_packets) {
|
||||||
|
discarded_secondary_packets_ += num_packets;
|
||||||
|
}
|
||||||
|
|
||||||
void StatisticsCalculator::LostSamples(size_t num_samples) {
|
void StatisticsCalculator::LostSamples(size_t num_samples) {
|
||||||
lost_timestamps_ += num_samples;
|
lost_timestamps_ += num_samples;
|
||||||
}
|
}
|
||||||
@ -249,10 +254,6 @@ void StatisticsCalculator::GetNetworkStatistics(
|
|||||||
stats->packet_loss_rate =
|
stats->packet_loss_rate =
|
||||||
CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_);
|
CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_);
|
||||||
|
|
||||||
const size_t discarded_samples = discarded_packets_ * samples_per_packet;
|
|
||||||
stats->packet_discard_rate =
|
|
||||||
CalculateQ14Ratio(discarded_samples, timestamps_since_last_report_);
|
|
||||||
|
|
||||||
stats->accelerate_rate =
|
stats->accelerate_rate =
|
||||||
CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_);
|
CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_);
|
||||||
|
|
||||||
@ -271,6 +272,12 @@ void StatisticsCalculator::GetNetworkStatistics(
|
|||||||
CalculateQ14Ratio(secondary_decoded_samples_,
|
CalculateQ14Ratio(secondary_decoded_samples_,
|
||||||
timestamps_since_last_report_);
|
timestamps_since_last_report_);
|
||||||
|
|
||||||
|
const size_t discarded_secondary_samples =
|
||||||
|
discarded_secondary_packets_ * samples_per_packet;
|
||||||
|
stats->secondary_discarded_rate = CalculateQ14Ratio(
|
||||||
|
discarded_secondary_samples,
|
||||||
|
discarded_secondary_samples + secondary_decoded_samples_);
|
||||||
|
|
||||||
if (waiting_times_.size() == 0) {
|
if (waiting_times_.size() == 0) {
|
||||||
stats->mean_waiting_time_ms = -1;
|
stats->mean_waiting_time_ms = -1;
|
||||||
stats->median_waiting_time_ms = -1;
|
stats->median_waiting_time_ms = -1;
|
||||||
|
|||||||
@ -66,6 +66,9 @@ class StatisticsCalculator {
|
|||||||
// Reports that |num_packets| packets were discarded.
|
// Reports that |num_packets| packets were discarded.
|
||||||
virtual void PacketsDiscarded(size_t num_packets);
|
virtual void PacketsDiscarded(size_t num_packets);
|
||||||
|
|
||||||
|
// Reports that |num_packets| packets samples were discarded.
|
||||||
|
virtual void SecondaryPacketsDiscarded(size_t num_samples);
|
||||||
|
|
||||||
// Reports that |num_samples| were lost.
|
// Reports that |num_samples| were lost.
|
||||||
void LostSamples(size_t num_samples);
|
void LostSamples(size_t num_samples);
|
||||||
|
|
||||||
@ -165,6 +168,7 @@ class StatisticsCalculator {
|
|||||||
uint32_t timestamps_since_last_report_;
|
uint32_t timestamps_since_last_report_;
|
||||||
std::deque<int> waiting_times_;
|
std::deque<int> waiting_times_;
|
||||||
uint32_t secondary_decoded_samples_;
|
uint32_t secondary_decoded_samples_;
|
||||||
|
size_t discarded_secondary_packets_;
|
||||||
PeriodicUmaCount delayed_packet_outage_counter_;
|
PeriodicUmaCount delayed_packet_outage_counter_;
|
||||||
PeriodicUmaAverage excess_buffer_delay_;
|
PeriodicUmaAverage excess_buffer_delay_;
|
||||||
|
|
||||||
|
|||||||
@ -352,12 +352,12 @@ class StatsGetter : public NetEqGetAudioCallback {
|
|||||||
double preferred_buffer_size_ms = 0.0;
|
double preferred_buffer_size_ms = 0.0;
|
||||||
double jitter_peaks_found = 0.0;
|
double jitter_peaks_found = 0.0;
|
||||||
double packet_loss_rate = 0.0;
|
double packet_loss_rate = 0.0;
|
||||||
double packet_discard_rate = 0.0;
|
|
||||||
double expand_rate = 0.0;
|
double expand_rate = 0.0;
|
||||||
double speech_expand_rate = 0.0;
|
double speech_expand_rate = 0.0;
|
||||||
double preemptive_rate = 0.0;
|
double preemptive_rate = 0.0;
|
||||||
double accelerate_rate = 0.0;
|
double accelerate_rate = 0.0;
|
||||||
double secondary_decoded_rate = 0.0;
|
double secondary_decoded_rate = 0.0;
|
||||||
|
double secondary_discarded_rate = 0.0;
|
||||||
double clockdrift_ppm = 0.0;
|
double clockdrift_ppm = 0.0;
|
||||||
double added_zero_samples = 0.0;
|
double added_zero_samples = 0.0;
|
||||||
double mean_waiting_time_ms = 0.0;
|
double mean_waiting_time_ms = 0.0;
|
||||||
@ -410,12 +410,12 @@ class StatsGetter : public NetEqGetAudioCallback {
|
|||||||
a.preferred_buffer_size_ms += b.preferred_buffer_size_ms;
|
a.preferred_buffer_size_ms += b.preferred_buffer_size_ms;
|
||||||
a.jitter_peaks_found += b.jitter_peaks_found;
|
a.jitter_peaks_found += b.jitter_peaks_found;
|
||||||
a.packet_loss_rate += b.packet_loss_rate / 16384.0;
|
a.packet_loss_rate += b.packet_loss_rate / 16384.0;
|
||||||
a.packet_discard_rate += b.packet_discard_rate / 16384.0;
|
|
||||||
a.expand_rate += b.expand_rate / 16384.0;
|
a.expand_rate += b.expand_rate / 16384.0;
|
||||||
a.speech_expand_rate += b.speech_expand_rate / 16384.0;
|
a.speech_expand_rate += b.speech_expand_rate / 16384.0;
|
||||||
a.preemptive_rate += b.preemptive_rate / 16384.0;
|
a.preemptive_rate += b.preemptive_rate / 16384.0;
|
||||||
a.accelerate_rate += b.accelerate_rate / 16384.0;
|
a.accelerate_rate += b.accelerate_rate / 16384.0;
|
||||||
a.secondary_decoded_rate += b.secondary_decoded_rate / 16384.0;
|
a.secondary_decoded_rate += b.secondary_decoded_rate / 16384.0;
|
||||||
|
a.secondary_discarded_rate += b.secondary_discarded_rate / 16384.0;
|
||||||
a.clockdrift_ppm += b.clockdrift_ppm;
|
a.clockdrift_ppm += b.clockdrift_ppm;
|
||||||
a.added_zero_samples += b.added_zero_samples;
|
a.added_zero_samples += b.added_zero_samples;
|
||||||
a.mean_waiting_time_ms += b.mean_waiting_time_ms;
|
a.mean_waiting_time_ms += b.mean_waiting_time_ms;
|
||||||
@ -429,12 +429,12 @@ class StatsGetter : public NetEqGetAudioCallback {
|
|||||||
sum_stats.preferred_buffer_size_ms /= stats_.size();
|
sum_stats.preferred_buffer_size_ms /= stats_.size();
|
||||||
sum_stats.jitter_peaks_found /= stats_.size();
|
sum_stats.jitter_peaks_found /= stats_.size();
|
||||||
sum_stats.packet_loss_rate /= stats_.size();
|
sum_stats.packet_loss_rate /= stats_.size();
|
||||||
sum_stats.packet_discard_rate /= stats_.size();
|
|
||||||
sum_stats.expand_rate /= stats_.size();
|
sum_stats.expand_rate /= stats_.size();
|
||||||
sum_stats.speech_expand_rate /= stats_.size();
|
sum_stats.speech_expand_rate /= stats_.size();
|
||||||
sum_stats.preemptive_rate /= stats_.size();
|
sum_stats.preemptive_rate /= stats_.size();
|
||||||
sum_stats.accelerate_rate /= stats_.size();
|
sum_stats.accelerate_rate /= stats_.size();
|
||||||
sum_stats.secondary_decoded_rate /= stats_.size();
|
sum_stats.secondary_decoded_rate /= stats_.size();
|
||||||
|
sum_stats.secondary_discarded_rate /= stats_.size();
|
||||||
sum_stats.clockdrift_ppm /= stats_.size();
|
sum_stats.clockdrift_ppm /= stats_.size();
|
||||||
sum_stats.added_zero_samples /= stats_.size();
|
sum_stats.added_zero_samples /= stats_.size();
|
||||||
sum_stats.mean_waiting_time_ms /= stats_.size();
|
sum_stats.mean_waiting_time_ms /= stats_.size();
|
||||||
@ -644,13 +644,14 @@ int RunTest(int argc, char* argv[]) {
|
|||||||
printf(" output duration: %" PRId64 " ms\n", test_duration_ms);
|
printf(" output duration: %" PRId64 " ms\n", test_duration_ms);
|
||||||
auto stats = stats_getter.AverageStats();
|
auto stats = stats_getter.AverageStats();
|
||||||
printf(" packet_loss_rate: %f %%\n", 100.0 * stats.packet_loss_rate);
|
printf(" packet_loss_rate: %f %%\n", 100.0 * stats.packet_loss_rate);
|
||||||
printf(" packet_discard_rate: %f %%\n", 100.0 * stats.packet_discard_rate);
|
|
||||||
printf(" expand_rate: %f %%\n", 100.0 * stats.expand_rate);
|
printf(" expand_rate: %f %%\n", 100.0 * stats.expand_rate);
|
||||||
printf(" speech_expand_rate: %f %%\n", 100.0 * stats.speech_expand_rate);
|
printf(" speech_expand_rate: %f %%\n", 100.0 * stats.speech_expand_rate);
|
||||||
printf(" preemptive_rate: %f %%\n", 100.0 * stats.preemptive_rate);
|
printf(" preemptive_rate: %f %%\n", 100.0 * stats.preemptive_rate);
|
||||||
printf(" accelerate_rate: %f %%\n", 100.0 * stats.accelerate_rate);
|
printf(" accelerate_rate: %f %%\n", 100.0 * stats.accelerate_rate);
|
||||||
printf(" secondary_decoded_rate: %f %%\n",
|
printf(" secondary_decoded_rate: %f %%\n",
|
||||||
100.0 * stats.secondary_decoded_rate);
|
100.0 * stats.secondary_decoded_rate);
|
||||||
|
printf(" secondary_discarded_rate: %f %%\n",
|
||||||
|
100.0 * stats.secondary_discarded_rate);
|
||||||
printf(" clockdrift_ppm: %f ppm\n", stats.clockdrift_ppm);
|
printf(" clockdrift_ppm: %f ppm\n", stats.clockdrift_ppm);
|
||||||
printf(" mean_waiting_time_ms: %f ms\n", stats.mean_waiting_time_ms);
|
printf(" mean_waiting_time_ms: %f ms\n", stats.mean_waiting_time_ms);
|
||||||
printf(" median_waiting_time_ms: %f ms\n", stats.median_waiting_time_ms);
|
printf(" median_waiting_time_ms: %f ms\n", stats.median_waiting_time_ms);
|
||||||
|
|||||||
@ -752,8 +752,6 @@ void APITest::TestDelay(char side) {
|
|||||||
networkStat.jitterPeaksFound);
|
networkStat.jitterPeaksFound);
|
||||||
fprintf(stdout, "packet-size rate........ %d\n",
|
fprintf(stdout, "packet-size rate........ %d\n",
|
||||||
networkStat.currentPacketLossRate);
|
networkStat.currentPacketLossRate);
|
||||||
fprintf(stdout, "discard rate............ %d\n",
|
|
||||||
networkStat.currentDiscardRate);
|
|
||||||
fprintf(stdout, "expand rate............. %d\n",
|
fprintf(stdout, "expand rate............. %d\n",
|
||||||
networkStat.currentExpandRate);
|
networkStat.currentExpandRate);
|
||||||
fprintf(stdout, "speech expand rate...... %d\n",
|
fprintf(stdout, "speech expand rate...... %d\n",
|
||||||
@ -764,6 +762,8 @@ void APITest::TestDelay(char side) {
|
|||||||
networkStat.currentAccelerateRate);
|
networkStat.currentAccelerateRate);
|
||||||
fprintf(stdout, "Secondary decoded rate.. %d\n",
|
fprintf(stdout, "Secondary decoded rate.. %d\n",
|
||||||
networkStat.currentSecondaryDecodedRate);
|
networkStat.currentSecondaryDecodedRate);
|
||||||
|
fprintf(stdout, "Secondary discarded rate.%d\n",
|
||||||
|
networkStat.currentSecondaryDiscardedRate);
|
||||||
fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
|
fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM);
|
||||||
fprintf(stdout, "Mean waiting time....... %d\n",
|
fprintf(stdout, "Mean waiting time....... %d\n",
|
||||||
networkStat.meanWaitingTimeMs);
|
networkStat.meanWaitingTimeMs);
|
||||||
|
|||||||
Reference in New Issue
Block a user