Chromium Code Reviews| Index: webrtc/video/receive_statistics_proxy.cc |
| diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc |
| index 61c264fcbe4eae9a547ac6201f9fd71bbe920999..d85ae4c647de26e8d49503d9c36864e7c52dcf9c 100644 |
| --- a/webrtc/video/receive_statistics_proxy.cc |
| +++ b/webrtc/video/receive_statistics_proxy.cc |
| @@ -12,8 +12,10 @@ |
| #include <algorithm> |
| #include <cmath> |
| +#include <sstream> |
| #include <utility> |
| +#include "webrtc/modules/pacing/alr_detector.h" |
| #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| #include "webrtc/rtc_base/checks.h" |
| #include "webrtc/rtc_base/logging.h" |
| @@ -45,6 +47,33 @@ const int kHighVarianceThreshold = 2; |
| // How large window we use to calculate the framerate/bitrate. |
| const int kRateStatisticsWindowSizeMs = 1000; |
| + |
| +std::string UmaPrefixForContentType(VideoContentType content_type) { |
| + std::stringstream ss; |
| + ss << "WebRTC.Video"; |
| + if (content_type.IsScreenshare()) { |
| + ss << ".Screenshare"; |
| + } |
| + return ss.str(); |
| +} |
| + |
| +std::string UmaSpatialSuffixForContentType(VideoContentType content_type) { |
| + std::stringstream ss; |
| + int simulcast_id = content_type.GetSimulcastId(); |
| + if (simulcast_id > 0) { |
| + ss << ".S" << simulcast_id - 1; |
| + } |
| + return ss.str(); |
| +} |
| + |
| +std::string UmaExperimentSuffixConentType(VideoContentType content_type) { |
|
sprang_webrtc
2017/08/25 13:56:29
nit: UmaExperimentSuffixForContentType
ilnik
2017/08/25 14:14:27
Done.
|
| + std::stringstream ss; |
| + int experiment_id = content_type.GetExperimentId(); |
| + if (experiment_id > 0) { |
| + ss << ".ExperimentGroup" << experiment_id - 1; |
| + } |
| + return ss.str(); |
| +} |
| } // namespace |
| ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
| @@ -74,10 +103,6 @@ ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
| render_fps_tracker_(100, 10u), |
| render_pixel_tracker_(100, 10u), |
| total_byte_tracker_(100, 10u), // bucket_interval_ms, bucket_count |
| - e2e_delay_max_ms_video_(-1), |
| - e2e_delay_max_ms_screenshare_(-1), |
| - interframe_delay_max_ms_video_(-1), |
| - interframe_delay_max_ms_screenshare_(-1), |
| freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), |
| first_report_block_time_ms_(-1), |
| avg_rtt_ms_(0), |
| @@ -95,38 +120,179 @@ ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { |
| } |
| void ReceiveStatisticsProxy::UpdateHistograms() { |
| - RTC_HISTOGRAM_COUNTS_100000( |
| - "WebRTC.Video.ReceiveStreamLifetimeInSeconds", |
| - (clock_->TimeInMilliseconds() - start_ms_) / 1000); |
| + const int kMinRequiredSamples = 200; |
| + |
| + int samples = static_cast<int>(render_fps_tracker_.TotalSampleCount()); |
| + if (samples >= kMinRequiredSamples) { |
| + RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", |
| + round(render_fps_tracker_.ComputeTotalRate())); |
| + RTC_HISTOGRAM_COUNTS_100000( |
| + "WebRTC.Video.RenderSqrtPixelsPerSecond", |
| + round(render_pixel_tracker_.ComputeTotalRate())); |
| + } |
| + |
| + // Slice on content type and simulcast id. |
| + for (auto it : content_specific_stats_) { |
| + auto content_type = it.first; |
| + if (content_type.GetExperimentId() == 0 && |
| + content_type.GetSimulcastId() == 0) { |
| + // Name of a metric sliced on simulcast is the same as sliced on |
| + // experiment because no slice information is available in both cases. |
| + // Don't report the metric here to not duplicate the metric. |
| + continue; |
| + } |
| + auto stats = it.second; |
| + std::string uma_prefix = UmaPrefixForContentType(content_type); |
| + std::string uma_suffix = UmaSpatialSuffixForContentType(content_type); |
| + // The same line of code can't report different histograms because of how |
| + // macro is done. Additional index needed to be different for all different |
| + // names. Since experiment can't change during call, we could report 4*2 |
| + // different content types (4 simulcast_ids x 2 content types). |
| + // Conveniently all of these are stored in 3 lower bits in VideoContentType. |
| + int idx = content_type.content_type & 0x07; |
| + int e2e_delay_ms = stats.e2e_delay_counter.Avg(kMinRequiredSamples); |
| + if (e2e_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".EndToEndDelayInMs" + uma_suffix, e2e_delay_ms); |
| + LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_suffix << " " |
| + << e2e_delay_ms; |
| + } |
| + int e2e_delay_max_ms = stats.e2e_delay_counter.Max(); |
| + if (e2e_delay_max_ms != -1 && e2e_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_100000( |
| + idx, uma_prefix + ".EndToEndDelayMaxInMs" + uma_suffix, |
| + e2e_delay_max_ms); |
| + LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs" << uma_suffix << " " |
| + << e2e_delay_max_ms; |
| + } |
| + int interframe_delay_ms = |
| + stats.interframe_delay_counter.Avg(kMinRequiredSamples); |
| + if (interframe_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".InterframeDelayInMs" + uma_suffix, |
| + interframe_delay_ms); |
| + LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs" << uma_suffix << " " |
| + << interframe_delay_ms; |
| + } |
| + int interframe_delay_max_ms = stats.interframe_delay_counter.Max(); |
| + if (interframe_delay_max_ms != -1 && interframe_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".InterframeDelayMaxInMs" + uma_suffix, |
| + interframe_delay_max_ms); |
| + LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs" << uma_suffix |
| + << " " << interframe_delay_max_ms; |
| + } |
| + |
| + float flow_duration_sec = stats.flow_duration_ms / 1000.0; |
| + if (flow_duration_sec >= metrics::kMinRunTimeInSeconds) { |
| + int media_bitrate_kbps = static_cast<int>(stats.total_media_bytes * 8 / |
| + flow_duration_sec / 1000); |
| + RTC_HISTOGRAM_COUNTS_10000( |
| + uma_prefix + ".MediaBitrateReceivedInKbps" + uma_suffix, |
| + media_bitrate_kbps); |
| + LOG(LS_INFO) << uma_prefix << ".MediaBitrateReceivedInKbps" << uma_suffix |
| + << " " << media_bitrate_kbps; |
| + } |
| + |
| + int qp = stats.qp_counter.Avg(kMinRequiredSamples); |
| + if (qp != -1) { |
| + RTC_HISTOGRAMS_COUNTS_200( |
| + idx, uma_prefix + ".Decoded.Vp8.Qp" + uma_suffix, qp); |
| + LOG(LS_INFO) << uma_prefix << ".Decoded.Vp8.Qp" << uma_suffix << " " |
| + << qp; |
| + } |
| + |
| + int width = stats.received_width.Avg(kMinRequiredSamples); |
| + if (width != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".ReceivedWidthInPixels" + uma_suffix, width); |
| + LOG(LS_INFO) << uma_prefix << ".ReceivedWidthInPixels" << uma_suffix |
| + << " " << width; |
| + } |
| + |
| + int height = stats.received_height.Avg(kMinRequiredSamples); |
| + if (height != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".ReceivedHeightInPixels" + uma_suffix, height); |
| + LOG(LS_INFO) << uma_prefix << ".ReceivedHeightInPixels" << uma_suffix |
| + << " " << height; |
| + } |
| + } |
| + |
| + std::string uma_prefix = UmaPrefixForContentType(last_content_type_); |
| + std::string uma_experiment_suffix = |
| + UmaExperimentSuffixConentType(last_content_type_); |
|
sprang_webrtc
2017/08/25 13:56:29
I think these might unfortunately change during th
ilnik
2017/08/25 14:14:27
Done.
|
| + int idx = (last_content_type_.IsScreenshare() ? 1 : 0) + |
| + (last_content_type_.GetExperimentId() << 1); |
| if (first_report_block_time_ms_ != -1 && |
| ((clock_->TimeInMilliseconds() - first_report_block_time_ms_) / 1000) >= |
| metrics::kMinRunTimeInSeconds) { |
| int fraction_lost = report_block_stats_.FractionLostInPercent(); |
| if (fraction_lost != -1) { |
| - RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", |
| - fraction_lost); |
| - LOG(LS_INFO) << "WebRTC.Video.ReceivedPacketsLostInPercent " |
| - << fraction_lost; |
| + RTC_HISTOGRAMS_PERCENTAGE( |
| + idx, |
| + uma_prefix + ".ReceivedPacketsLostInPercent" + uma_experiment_suffix, |
| + fraction_lost); |
| + LOG(LS_INFO) << uma_prefix << ".ReceivedPacketsLostInPercent" |
| + << uma_experiment_suffix << " " << fraction_lost; |
| } |
| } |
| - const int kMinRequiredSamples = 200; |
| - int samples = static_cast<int>(render_fps_tracker_.TotalSampleCount()); |
| - if (samples >= kMinRequiredSamples) { |
| - RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", |
| - round(render_fps_tracker_.ComputeTotalRate())); |
| - RTC_HISTOGRAM_COUNTS_100000( |
| - "WebRTC.Video.RenderSqrtPixelsPerSecond", |
| - round(render_pixel_tracker_.ComputeTotalRate())); |
| + int stream_duration_sec = (clock_->TimeInMilliseconds() - start_ms_) / 1000; |
| + RTC_HISTOGRAMS_COUNTS_100000( |
| + idx, |
| + uma_prefix + ".ReceiveStreamLifetimeInSeconds" + uma_experiment_suffix, |
| + stream_duration_sec); |
| + LOG(LS_INFO) << uma_prefix << ".ReceiveStreamLifetimeInSeconds" |
| + << uma_experiment_suffix << " " << stream_duration_sec; |
| + |
| + int e2e_delay_ms = e2e_delay_counter.Avg(kMinRequiredSamples); |
| + if (e2e_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".EndToEndDelayInMs" + uma_experiment_suffix, |
| + e2e_delay_ms); |
| + LOG(LS_INFO) << uma_prefix << ".EndToEndDelayInMs" << uma_experiment_suffix |
| + << " " << e2e_delay_ms; |
| + } |
| + int e2e_delay_max_ms = e2e_delay_counter.Max(); |
| + if (e2e_delay_max_ms != -1 && e2e_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_100000( |
| + idx, uma_prefix + ".EndToEndDelayMaxInMs" + uma_experiment_suffix, |
| + e2e_delay_max_ms); |
| + LOG(LS_INFO) << uma_prefix << ".EndToEndDelayMaxInMs" |
| + << uma_experiment_suffix << " " << e2e_delay_max_ms; |
| + } |
| + int interframe_delay_ms = interframe_delay_counter.Avg(kMinRequiredSamples); |
| + if (interframe_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".InterframeDelayInMs" + uma_experiment_suffix, |
| + interframe_delay_ms); |
| + LOG(LS_INFO) << uma_prefix << ".InterframeDelayInMs" |
| + << uma_experiment_suffix << " " << interframe_delay_ms; |
| + } |
| + int interframe_delay_max_ms = interframe_delay_counter.Max(); |
| + if (interframe_delay_max_ms != -1 && interframe_delay_ms != -1) { |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".InterframeDelayMaxInMs" + uma_experiment_suffix, |
| + interframe_delay_max_ms); |
| + LOG(LS_INFO) << uma_prefix << ".InterframeDelayMaxInMs" |
| + << uma_experiment_suffix << " " << interframe_delay_max_ms; |
| } |
| + |
| int width = render_width_counter_.Avg(kMinRequiredSamples); |
| int height = render_height_counter_.Avg(kMinRequiredSamples); |
| if (width != -1) { |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); |
| - LOG(LS_INFO) << "WebRTC.Video.ReceivedWidthInPixels " << width; |
| - LOG(LS_INFO) << "WebRTC.Video.ReceivedHeightInPixels " << height; |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".ReceivedWidthInPixels" + uma_experiment_suffix, |
| + width); |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".ReceivedHeightInPixels" + uma_experiment_suffix, |
| + height); |
| + LOG(LS_INFO) << uma_prefix << ".ReceivedWidthInPixels" |
| + << uma_experiment_suffix << " " << width; |
| + LOG(LS_INFO) << uma_prefix << ".ReceivedHeightInPixels" |
| + << uma_experiment_suffix << " " << height; |
| } |
| int sync_offset_ms = sync_offset_counter_.Avg(kMinRequiredSamples); |
| if (sync_offset_ms != -1) { |
| @@ -147,16 +313,20 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
| int num_key_frames = stats_.frame_counts.key_frames; |
| int key_frames_permille = |
| (num_key_frames * 1000 + num_total_frames / 2) / num_total_frames; |
| - RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", |
| - key_frames_permille); |
| - LOG(LS_INFO) << "WebRTC.Video.KeyFramesReceivedInPermille " |
| - << key_frames_permille; |
| + RTC_HISTOGRAMS_COUNTS_1000( |
| + idx, |
| + uma_prefix + ".KeyFramesReceivedInPermille" + uma_experiment_suffix, |
| + key_frames_permille); |
| + LOG(LS_INFO) << uma_prefix << ".KeyFramesReceivedInPermille" |
| + << uma_experiment_suffix << " " << key_frames_permille; |
| } |
| int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); |
| if (qp != -1) { |
| - RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); |
| - LOG(LS_INFO) << "WebRTC.Video.Decoded.Vp8.Qp " << qp; |
| + RTC_HISTOGRAMS_COUNTS_200( |
| + idx, uma_prefix + ".Decoded.Vp8.Qp" + uma_experiment_suffix, qp); |
| + LOG(LS_INFO) << uma_prefix << ".Decoded.Vp8.Qp" << uma_experiment_suffix |
| + << " " << qp; |
| } |
| int decode_ms = decode_time_counter_.Avg(kMinRequiredSamples); |
| if (decode_ms != -1) { |
| @@ -185,54 +355,6 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
| if (delay_ms != -1) |
| RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.OnewayDelayInMs", delay_ms); |
| - int e2e_delay_ms_video = e2e_delay_counter_video_.Avg(kMinRequiredSamples); |
| - if (e2e_delay_ms_video != -1) { |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs", |
| - e2e_delay_ms_video); |
| - LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video; |
| - } |
| - |
| - int e2e_delay_ms_screenshare = |
| - e2e_delay_counter_screenshare_.Avg(kMinRequiredSamples); |
| - if (e2e_delay_ms_screenshare != -1) { |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.EndToEndDelayInMs", |
| - e2e_delay_ms_screenshare); |
| - } |
| - |
| - int e2e_delay_max_ms_video = e2e_delay_max_ms_video_; |
| - if (e2e_delay_max_ms_video != -1) { |
| - RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.EndToEndDelayMaxInMs", |
| - e2e_delay_max_ms_video); |
| - } |
| - |
| - int e2e_delay_max_ms_screenshare = e2e_delay_max_ms_screenshare_; |
| - if (e2e_delay_max_ms_screenshare != -1) { |
| - RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.Screenshare.EndToEndDelayMaxInMs", |
| - e2e_delay_max_ms_screenshare); |
| - } |
| - |
| - int interframe_delay_ms_screenshare = |
| - interframe_delay_counter_screenshare_.Avg(kMinRequiredSamples); |
| - if (interframe_delay_ms_screenshare != -1) { |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.InterframeDelayInMs", |
| - interframe_delay_ms_screenshare); |
| - RTC_DCHECK_GE(interframe_delay_max_ms_screenshare_, |
| - interframe_delay_ms_screenshare); |
| - RTC_HISTOGRAM_COUNTS_10000( |
| - "WebRTC.Video.Screenshare.InterframeDelayMaxInMs", |
| - interframe_delay_max_ms_screenshare_); |
| - } |
| - |
| - int interframe_delay_ms_video = |
| - interframe_delay_counter_video_.Avg(kMinRequiredSamples); |
| - if (interframe_delay_ms_video != -1) { |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayInMs", |
| - interframe_delay_ms_video); |
| - RTC_DCHECK_GE(interframe_delay_max_ms_video_, interframe_delay_ms_video); |
| - RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InterframeDelayMaxInMs", |
| - interframe_delay_max_ms_video_); |
| - } |
| - |
| StreamDataCounters rtp = stats_.rtp_stats; |
| StreamDataCounters rtx; |
| for (auto it : rtx_stats_) |
| @@ -246,9 +368,13 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
| "WebRTC.Video.BitrateReceivedInKbps", |
| static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / |
| 1000)); |
| - RTC_HISTOGRAM_COUNTS_10000( |
| - "WebRTC.Video.MediaBitrateReceivedInKbps", |
| - static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000)); |
| + int media_bitrate_kbs = |
| + static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000); |
| + RTC_HISTOGRAMS_COUNTS_10000( |
| + idx, uma_prefix + ".MediaBitrateReceivedInKbps" + uma_experiment_suffix, |
| + media_bitrate_kbs); |
| + LOG(LS_INFO) << uma_prefix << ".MediaBitrateReceivedInKbps" |
| + << uma_experiment_suffix << " " << media_bitrate_kbs; |
| RTC_HISTOGRAM_COUNTS_10000( |
| "WebRTC.Video.PaddingBitrateReceivedInKbps", |
| static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / |
| @@ -523,6 +649,9 @@ void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional<uint8_t> qp, |
| uint64_t now = clock_->TimeInMilliseconds(); |
| rtc::CritScope lock(&crit_); |
| + |
| + ContentSpecificStats* content_specific_stats = |
| + &content_specific_stats_[content_type]; |
| ++stats_.frames_decoded; |
| if (qp) { |
| if (!stats_.qp_sum) { |
| @@ -534,6 +663,7 @@ void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional<uint8_t> qp, |
| stats_.qp_sum = rtc::Optional<uint64_t>(0); |
| } |
| *stats_.qp_sum += *qp; |
| + content_specific_stats->qp_counter.Add(*qp); |
| } else if (stats_.qp_sum) { |
| LOG(LS_WARNING) |
| << "QP sum was already set and no QP was given for a frame."; |
| @@ -545,17 +675,9 @@ void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional<uint8_t> qp, |
| int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; |
| RTC_DCHECK_GE(interframe_delay_ms, 0); |
| stats_.interframe_delay_sum_ms += interframe_delay_ms; |
| - if (last_content_type_ == VideoContentType::SCREENSHARE) { |
| - interframe_delay_counter_screenshare_.Add(interframe_delay_ms); |
| - if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { |
| - interframe_delay_max_ms_screenshare_ = interframe_delay_ms; |
| - } |
| - } else { |
| - interframe_delay_counter_video_.Add(interframe_delay_ms); |
| - if (interframe_delay_max_ms_video_ < interframe_delay_ms) { |
| - interframe_delay_max_ms_video_ = interframe_delay_ms; |
| - } |
| - } |
| + content_specific_stats->interframe_delay_counter.Add(interframe_delay_ms); |
| + content_specific_stats->flow_duration_ms += interframe_delay_ms; |
| + interframe_delay_counter.Add(interframe_delay_ms); |
| } |
| last_decoded_frame_time_ms_.emplace(now); |
| } |
| @@ -566,8 +688,9 @@ void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { |
| RTC_DCHECK_GT(width, 0); |
| RTC_DCHECK_GT(height, 0); |
| uint64_t now = clock_->TimeInMilliseconds(); |
| - |
| rtc::CritScope lock(&crit_); |
| + ContentSpecificStats* content_specific_stats = |
| + &content_specific_stats_[last_content_type_]; |
| renders_fps_estimator_.Update(1, now); |
| ++stats_.frames_rendered; |
| stats_.width = width; |
| @@ -576,18 +699,14 @@ void ReceiveStatisticsProxy::OnRenderedFrame(const VideoFrame& frame) { |
| render_height_counter_.Add(height); |
| render_fps_tracker_.AddSamples(1); |
| render_pixel_tracker_.AddSamples(sqrt(width * height)); |
| + content_specific_stats->received_width.Add(width); |
| + content_specific_stats->received_height.Add(height); |
| if (frame.ntp_time_ms() > 0) { |
| int64_t delay_ms = clock_->CurrentNtpInMilliseconds() - frame.ntp_time_ms(); |
| if (delay_ms >= 0) { |
| - if (last_content_type_ == VideoContentType::SCREENSHARE) { |
| - e2e_delay_max_ms_screenshare_ = |
| - std::max(delay_ms, e2e_delay_max_ms_screenshare_); |
| - e2e_delay_counter_screenshare_.Add(delay_ms); |
| - } else { |
| - e2e_delay_max_ms_video_ = std::max(delay_ms, e2e_delay_max_ms_video_); |
| - e2e_delay_counter_video_.Add(delay_ms); |
| - } |
| + content_specific_stats->e2e_delay_counter.Add(delay_ms); |
| + e2e_delay_counter.Add(delay_ms); |
| } |
| } |
| } |
| @@ -619,6 +738,13 @@ void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, |
| else |
| ++stats_.frame_counts.delta_frames; |
| + // Todo(ilnik): May be incorrect for the first frame of a new content type |
| + // stream. Leads to a bit incorrect |total_media_bytes| count. |
| + ContentSpecificStats* content_specific_stats = |
| + &content_specific_stats_[last_content_type_]; |
| + |
| + content_specific_stats->total_media_bytes += size_bytes; |
| + |
| int64_t now_ms = clock_->TimeInMilliseconds(); |
| frame_window_.insert(std::make_pair(now_ms, size_bytes)); |
| UpdateFramerate(now_ms); |
| @@ -659,6 +785,9 @@ void ReceiveStatisticsProxy::OnStreamInactive() { |
| void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { |
| sum += sample; |
| ++num_samples; |
| + if (!max || *max < sample) { |
| + max.emplace(sample); |
| + } |
| } |
| int ReceiveStatisticsProxy::SampleCounter::Avg( |
| @@ -668,9 +797,18 @@ int ReceiveStatisticsProxy::SampleCounter::Avg( |
| return static_cast<int>(sum / num_samples); |
| } |
| +int ReceiveStatisticsProxy::SampleCounter::Max() const { |
| + if (!max) { |
| + return -1; |
| + } else { |
| + return *max; |
| + } |
| +} |
| + |
| void ReceiveStatisticsProxy::SampleCounter::Reset() { |
| num_samples = 0; |
| sum = 0; |
| + max.reset(); |
| } |
| void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, |