Added RTCMediaStreamTrackStats.jitterBufferDelay for audio
Description of this stat can be found here: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-jitterbufferdelay Bug: webrtc:8281 Change-Id: Ib2e8174f3449e68ad419ae2d58d5565fc9854023 Reviewed-on: https://webrtc-review.googlesource.com/3381 Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20069}
This commit is contained in:
committed by
Commit Bot
parent
652cc84069
commit
b0a0207838
@ -66,6 +66,7 @@ struct NetEqLifetimeStatistics {
|
||||
uint64_t total_samples_received = 0;
|
||||
uint64_t concealed_samples = 0;
|
||||
uint64_t concealment_events = 0;
|
||||
uint64_t jitter_buffer_delay_ms = 0;
|
||||
};
|
||||
|
||||
enum NetEqPlayoutMode {
|
||||
|
||||
@ -1950,7 +1950,8 @@ int NetEqImpl::ExtractPackets(size_t required_samples,
|
||||
assert(false); // Should always be able to extract a packet here.
|
||||
return -1;
|
||||
}
|
||||
stats_.StoreWaitingTime(packet->waiting_time->ElapsedMs());
|
||||
const uint64_t waiting_time_ms = packet->waiting_time->ElapsedMs();
|
||||
stats_.StoreWaitingTime(waiting_time_ms);
|
||||
RTC_DCHECK(!packet->empty());
|
||||
|
||||
if (first_packet) {
|
||||
@ -1990,6 +1991,8 @@ int NetEqImpl::ExtractPackets(size_t required_samples,
|
||||
}
|
||||
extracted_samples = packet->timestamp - first_timestamp + packet_duration;
|
||||
|
||||
stats_.JitterBufferDelay(extracted_samples, waiting_time_ms);
|
||||
|
||||
packet_list->push_back(std::move(*packet)); // Store packet in list.
|
||||
packet = rtc::Optional<Packet>(); // Ensure it's never used after the move.
|
||||
|
||||
|
||||
@ -522,6 +522,7 @@ class NetEqDecodingTestFaxMode : public NetEqDecodingTest {
|
||||
NetEqDecodingTestFaxMode() : NetEqDecodingTest() {
|
||||
config_.playout_mode = kPlayoutFax;
|
||||
}
|
||||
void TestJitterBufferDelay(bool apply_packet_loss);
|
||||
};
|
||||
|
||||
TEST_F(NetEqDecodingTestFaxMode, TestFrameWaitingTimeStatistics) {
|
||||
@ -1684,4 +1685,64 @@ TEST_F(NetEqDecodingTest, TestConcealmentEvents) {
|
||||
EXPECT_EQ(kNumConcealmentEvents, static_cast<int>(stats.concealment_events));
|
||||
}
|
||||
|
||||
// Test that the jitter buffer delay stat is computed correctly.
|
||||
void NetEqDecodingTestFaxMode::TestJitterBufferDelay(bool apply_packet_loss) {
|
||||
const int kNumPackets = 10;
|
||||
const int kDelayInNumPackets = 2;
|
||||
const int kPacketLenMs = 10; // All packets are of 10 ms size.
|
||||
const size_t kSamples = kPacketLenMs * 16;
|
||||
const size_t kPayloadBytes = kSamples * 2;
|
||||
RTPHeader rtp_info;
|
||||
rtp_info.ssrc = 0x1234; // Just an arbitrary SSRC.
|
||||
rtp_info.payloadType = 94; // PCM16b WB codec.
|
||||
rtp_info.markerBit = 0;
|
||||
const uint8_t payload[kPayloadBytes] = {0};
|
||||
bool muted;
|
||||
int packets_sent = 0;
|
||||
int packets_received = 0;
|
||||
int expected_delay = 0;
|
||||
while (packets_received < kNumPackets) {
|
||||
// Insert packet.
|
||||
if (packets_sent < kNumPackets) {
|
||||
rtp_info.sequenceNumber = packets_sent++;
|
||||
rtp_info.timestamp = rtp_info.sequenceNumber * kSamples;
|
||||
neteq_->InsertPacket(rtp_info, payload, 0);
|
||||
}
|
||||
|
||||
// Get packet.
|
||||
if (packets_sent > kDelayInNumPackets) {
|
||||
neteq_->GetAudio(&out_frame_, &muted);
|
||||
packets_received++;
|
||||
|
||||
// The delay reported by the jitter buffer never exceeds
|
||||
// the number of samples previously fetched with GetAudio
|
||||
// (hence the min()).
|
||||
int packets_delay = std::min(packets_received, kDelayInNumPackets + 1);
|
||||
|
||||
// The increase of the expected delay is the product of
|
||||
// the current delay of the jitter buffer in ms * the
|
||||
// number of samples that are sent for play out.
|
||||
int current_delay_ms = packets_delay * kPacketLenMs;
|
||||
expected_delay += current_delay_ms * kSamples;
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_packet_loss) {
|
||||
// Extra call to GetAudio to cause concealment.
|
||||
neteq_->GetAudio(&out_frame_, &muted);
|
||||
}
|
||||
|
||||
// Check jitter buffer delay.
|
||||
NetEqLifetimeStatistics stats = neteq_->GetLifetimeStatistics();
|
||||
EXPECT_EQ(expected_delay, static_cast<int>(stats.jitter_buffer_delay_ms));
|
||||
}
|
||||
|
||||
TEST_F(NetEqDecodingTestFaxMode, TestJitterBufferDelayWithoutLoss) {
|
||||
TestJitterBufferDelay(false);
|
||||
}
|
||||
|
||||
TEST_F(NetEqDecodingTestFaxMode, TestJitterBufferDelayWithLoss) {
|
||||
TestJitterBufferDelay(true);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -229,6 +229,11 @@ void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
|
||||
lifetime_stats_.total_samples_received += num_samples;
|
||||
}
|
||||
|
||||
void StatisticsCalculator::JitterBufferDelay(size_t num_samples,
|
||||
uint64_t waiting_time_ms) {
|
||||
lifetime_stats_.jitter_buffer_delay_ms += waiting_time_ms * num_samples;
|
||||
}
|
||||
|
||||
void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) {
|
||||
secondary_decoded_samples_ += num_samples;
|
||||
}
|
||||
|
||||
@ -75,6 +75,9 @@ class StatisticsCalculator {
|
||||
// time is increasing.
|
||||
void IncreaseCounter(size_t num_samples, int fs_hz);
|
||||
|
||||
// Update jitter buffer delay counter.
|
||||
void JitterBufferDelay(size_t num_samples, uint64_t waiting_time_ms);
|
||||
|
||||
// Stores new packet waiting time in waiting time statistics.
|
||||
void StoreWaitingTime(int waiting_time_ms);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user