Add jitterBufferDelay and jitterBufferEmittedCount stats for video
Bug: webrtc:10450 Change-Id: I6f586a3c6781450b9bfdcc31dc3f49f6289d70e0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138265 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Magnus Flodman <mflodman@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28096}
This commit is contained in:
parent
e4470cd8b4
commit
6737841533
@ -53,6 +53,8 @@ std::string VideoReceiveStream::Stats::ToString(int64_t time_ms) const {
|
||||
ss << "cur_delay_ms: " << current_delay_ms << ", ";
|
||||
ss << "targ_delay_ms: " << target_delay_ms << ", ";
|
||||
ss << "jb_delay_ms: " << jitter_buffer_ms << ", ";
|
||||
ss << "jb_cumulative_delay_seconds: " << jitter_buffer_delay_seconds << ", ";
|
||||
ss << "jb_emitted_count: " << jitter_buffer_emitted_count << ", ";
|
||||
ss << "min_playout_delay_ms: " << min_playout_delay_ms << ", ";
|
||||
ss << "sync_offset_ms: " << sync_offset_ms << ", ";
|
||||
ss << "cum_loss: " << rtcp_stats.packets_lost << ", ";
|
||||
|
||||
@ -77,6 +77,10 @@ class VideoReceiveStream {
|
||||
int current_delay_ms = 0;
|
||||
int target_delay_ms = 0;
|
||||
int jitter_buffer_ms = 0;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferdelay
|
||||
double jitter_buffer_delay_seconds = 0;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferemittedcount
|
||||
uint64_t jitter_buffer_emitted_count = 0;
|
||||
int min_playout_delay_ms = 0;
|
||||
int render_delay_ms = 10;
|
||||
int64_t interframe_delay_max_ms = -1;
|
||||
|
||||
@ -617,6 +617,12 @@ struct VideoReceiverInfo : public MediaReceiverInfo {
|
||||
int max_decode_ms = 0;
|
||||
// Jitter (network-related) latency.
|
||||
int jitter_buffer_ms = 0;
|
||||
// Jitter (network-related) latency (cumulative).
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferdelay
|
||||
double jitter_buffer_delay_seconds = 0;
|
||||
// Number of observations for cumulative jitter latency.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferemittedcount
|
||||
uint64_t jitter_buffer_emitted_count = 0;
|
||||
// Requested minimum playout latency.
|
||||
int min_playout_delay_ms = 0;
|
||||
// Requested latency to account for rendering delay.
|
||||
|
||||
@ -2734,6 +2734,8 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
info.current_delay_ms = stats.current_delay_ms;
|
||||
info.target_delay_ms = stats.target_delay_ms;
|
||||
info.jitter_buffer_ms = stats.jitter_buffer_ms;
|
||||
info.jitter_buffer_delay_seconds = stats.jitter_buffer_delay_seconds;
|
||||
info.jitter_buffer_emitted_count = stats.jitter_buffer_emitted_count;
|
||||
info.min_playout_delay_ms = stats.min_playout_delay_ms;
|
||||
info.render_delay_ms = stats.render_delay_ms;
|
||||
info.frames_received =
|
||||
|
||||
@ -5000,6 +5000,8 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
|
||||
stats.current_delay_ms = 4;
|
||||
stats.target_delay_ms = 5;
|
||||
stats.jitter_buffer_ms = 6;
|
||||
stats.jitter_buffer_delay_seconds = 60;
|
||||
stats.jitter_buffer_emitted_count = 6;
|
||||
stats.min_playout_delay_ms = 7;
|
||||
stats.render_delay_ms = 8;
|
||||
stats.width = 9;
|
||||
@ -5020,6 +5022,10 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
|
||||
EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
|
||||
EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
|
||||
EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
|
||||
EXPECT_EQ(stats.jitter_buffer_delay_seconds,
|
||||
info.receivers[0].jitter_buffer_delay_seconds);
|
||||
EXPECT_EQ(stats.jitter_buffer_emitted_count,
|
||||
info.receivers[0].jitter_buffer_emitted_count);
|
||||
EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
|
||||
EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
|
||||
EXPECT_EQ(stats.width, info.receivers[0].frame_width);
|
||||
|
||||
@ -675,6 +675,10 @@ ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
|
||||
video_track_stats->frame_height = static_cast<uint32_t>(
|
||||
video_receiver_info.frame_height);
|
||||
}
|
||||
video_track_stats->jitter_buffer_delay =
|
||||
video_receiver_info.jitter_buffer_delay_seconds;
|
||||
video_track_stats->jitter_buffer_emitted_count =
|
||||
video_receiver_info.jitter_buffer_emitted_count;
|
||||
video_track_stats->frames_received = video_receiver_info.frames_received;
|
||||
// TODO(hbos): When we support receiving simulcast, this should be the total
|
||||
// number of frames correctly decoded, independent of which SSRC it was
|
||||
|
||||
@ -1647,6 +1647,8 @@ TEST_F(RTCStatsCollectorTest,
|
||||
video_receiver_info_ssrc3.local_stats[0].ssrc = 3;
|
||||
video_receiver_info_ssrc3.frame_width = 6789;
|
||||
video_receiver_info_ssrc3.frame_height = 9876;
|
||||
video_receiver_info_ssrc3.jitter_buffer_delay_seconds = 2.5;
|
||||
video_receiver_info_ssrc3.jitter_buffer_emitted_count = 25;
|
||||
video_receiver_info_ssrc3.frames_received = 1000;
|
||||
video_receiver_info_ssrc3.frames_decoded = 995;
|
||||
video_receiver_info_ssrc3.frames_rendered = 990;
|
||||
@ -1694,6 +1696,8 @@ TEST_F(RTCStatsCollectorTest,
|
||||
expected_remote_video_track_ssrc3.detached = false;
|
||||
expected_remote_video_track_ssrc3.frame_width = 6789;
|
||||
expected_remote_video_track_ssrc3.frame_height = 9876;
|
||||
expected_remote_video_track_ssrc3.jitter_buffer_delay = 2.5;
|
||||
expected_remote_video_track_ssrc3.jitter_buffer_emitted_count = 25;
|
||||
expected_remote_video_track_ssrc3.frames_received = 1000;
|
||||
expected_remote_video_track_ssrc3.frames_decoded = 995;
|
||||
expected_remote_video_track_ssrc3.frames_dropped = 1000 - 990;
|
||||
|
||||
@ -555,24 +555,16 @@ class RTCStatsReportVerifier {
|
||||
verifier.TestMemberIsDefined(media_stream_track.ended);
|
||||
verifier.TestMemberIsDefined(media_stream_track.detached);
|
||||
verifier.TestMemberIsDefined(media_stream_track.kind);
|
||||
RTC_DCHECK(media_stream_track.remote_source.is_defined());
|
||||
// Video or audio media stream track?
|
||||
if (*media_stream_track.kind == RTCMediaStreamTrackKind::kVideo) {
|
||||
// The type of the referenced media source depends on kind.
|
||||
if (media_stream_track.remote_source.is_defined() &&
|
||||
!*media_stream_track.remote_source) {
|
||||
verifier.TestMemberIsIDReference(media_stream_track.media_source_id,
|
||||
RTCVideoSourceStats::kType);
|
||||
} else {
|
||||
// Remote tracks don't have media source stats.
|
||||
verifier.TestMemberIsUndefined(media_stream_track.media_source_id);
|
||||
}
|
||||
// Video-only members
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.frame_width);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.frame_height);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.frames_per_second);
|
||||
if (*media_stream_track.remote_source) {
|
||||
verifier.TestMemberIsUndefined(media_stream_track.media_source_id);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.frames_sent);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.huge_frames_sent);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
@ -594,6 +586,12 @@ class RTCStatsReportVerifier {
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.sum_squared_frame_durations);
|
||||
} else {
|
||||
verifier.TestMemberIsIDReference(media_stream_track.media_source_id,
|
||||
RTCVideoSourceStats::kType);
|
||||
// Local tracks have no jitter buffer.
|
||||
verifier.TestMemberIsUndefined(media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.frames_sent);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
@ -612,6 +610,12 @@ class RTCStatsReportVerifier {
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.sum_squared_frame_durations);
|
||||
}
|
||||
// Video-only members
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.frame_width);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.frame_height);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.frames_per_second);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.frames_corrupted);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.partial_frames_lost);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.full_frames_lost);
|
||||
@ -622,16 +626,69 @@ class RTCStatsReportVerifier {
|
||||
media_stream_track.echo_return_loss_enhancement);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.total_audio_energy);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.total_samples_duration);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.total_samples_received);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.delayed_packet_outage_samples);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.relative_packet_arrival_delay);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.interruption_count);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.total_interruption_duration);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(*media_stream_track.kind, RTCMediaStreamTrackKind::kAudio);
|
||||
// The type of the referenced media source depends on kind.
|
||||
if (media_stream_track.remote_source.is_defined() &&
|
||||
!*media_stream_track.remote_source) {
|
||||
verifier.TestMemberIsIDReference(media_stream_track.media_source_id,
|
||||
RTCAudioSourceStats::kType);
|
||||
} else {
|
||||
if (*media_stream_track.remote_source) {
|
||||
// Remote tracks don't have media source stats.
|
||||
verifier.TestMemberIsUndefined(media_stream_track.media_source_id);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.total_samples_received);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.inserted_samples_for_deceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.removed_samples_for_acceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.silent_concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.delayed_packet_outage_samples);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.relative_packet_arrival_delay);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.interruption_count);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.total_interruption_duration);
|
||||
} else {
|
||||
verifier.TestMemberIsIDReference(media_stream_track.media_source_id,
|
||||
RTCAudioSourceStats::kType);
|
||||
// Local audio tracks have no jitter buffer.
|
||||
verifier.TestMemberIsUndefined(media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.total_samples_received);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.delayed_packet_outage_samples);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.relative_packet_arrival_delay);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.interruption_count);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.total_interruption_duration);
|
||||
}
|
||||
// Video-only members should be undefined
|
||||
verifier.TestMemberIsUndefined(media_stream_track.frame_width);
|
||||
@ -666,53 +723,6 @@ class RTCStatsReportVerifier {
|
||||
verifier.MarkMemberTested(media_stream_track.echo_return_loss_enhancement,
|
||||
true);
|
||||
}
|
||||
// totalSamplesReceived, concealedSamples and concealmentEvents are only
|
||||
// present on inbound audio tracks.
|
||||
// jitterBufferDelay is currently only implemented for audio.
|
||||
if (*media_stream_track.kind == RTCMediaStreamTrackKind::kAudio &&
|
||||
*media_stream_track.remote_source) {
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.total_samples_received);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.inserted_samples_for_deceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.removed_samples_for_acceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.silent_concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.delayed_packet_outage_samples);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.relative_packet_arrival_delay);
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(
|
||||
media_stream_track.interruption_count);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
media_stream_track.total_interruption_duration);
|
||||
} else {
|
||||
verifier.TestMemberIsUndefined(media_stream_track.jitter_buffer_delay);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.jitter_buffer_emitted_count);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.total_samples_received);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.delayed_packet_outage_samples);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.relative_packet_arrival_delay);
|
||||
verifier.TestMemberIsUndefined(media_stream_track.interruption_count);
|
||||
verifier.TestMemberIsUndefined(
|
||||
media_stream_track.total_interruption_duration);
|
||||
}
|
||||
return verifier.ExpectAllMembersSuccessfullyTested();
|
||||
}
|
||||
|
||||
|
||||
@ -596,6 +596,10 @@ VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
|
||||
video_quality_observer_->SumSquaredFrameDurationsSec();
|
||||
stats_.content_type = last_content_type_;
|
||||
stats_.timing_frame_info = timing_frame_info_counter_.Max(now_ms);
|
||||
stats_.jitter_buffer_delay_seconds =
|
||||
static_cast<double>(current_delay_counter_.Sum(1).value_or(0)) /
|
||||
rtc::kNumMillisecsPerSec;
|
||||
stats_.jitter_buffer_emitted_count = current_delay_counter_.NumSamples();
|
||||
return stats_;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user