2014-01-07 09:54:34 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "video/send_statistics_proxy.h"
|
2014-01-07 09:54:34 +00:00
|
|
|
|
2015-07-22 06:52:00 -07:00
|
|
|
#include <algorithm>
|
2019-09-09 11:26:45 +02:00
|
|
|
#include <array>
|
2015-11-10 16:34:50 -08:00
|
|
|
#include <cmath>
|
2018-08-15 08:57:54 +02:00
|
|
|
#include <limits>
|
2017-12-15 15:54:44 +01:00
|
|
|
#include <utility>
|
2014-01-07 09:54:34 +00:00
|
|
|
|
2020-04-01 13:43:08 +02:00
|
|
|
#include "absl/strings/match.h"
|
2019-09-09 11:26:45 +02:00
|
|
|
#include "api/video/video_codec_constants.h"
|
|
|
|
|
#include "api/video/video_codec_type.h"
|
|
|
|
|
#include "api/video_codecs/video_codec.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/video_coding/include/video_codec_interface.h"
|
|
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/logging.h"
|
2018-08-15 08:57:54 +02:00
|
|
|
#include "rtc_base/numerics/mod_ops.h"
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
#include "rtc_base/strings/string_builder.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "system_wrappers/include/metrics.h"
|
2014-01-07 09:54:34 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2015-10-27 01:32:00 -07:00
|
|
|
namespace {
|
2015-12-07 03:12:22 -08:00
|
|
|
const float kEncodeTimeWeigthFactor = 0.5f;
|
2017-10-16 12:19:23 +02:00
|
|
|
const size_t kMaxEncodedFrameMapSize = 150;
|
|
|
|
|
const int64_t kMaxEncodedFrameWindowMs = 800;
|
2018-08-15 08:57:54 +02:00
|
|
|
const uint32_t kMaxEncodedFrameTimestampDiff = 900000; // 10 sec.
|
2017-10-16 12:19:23 +02:00
|
|
|
const int64_t kBucketSizeMs = 100;
|
|
|
|
|
const size_t kBucketCount = 10;
|
2015-12-07 03:12:22 -08:00
|
|
|
|
2017-09-15 06:41:15 -07:00
|
|
|
const char kVp8ForcedFallbackEncoderFieldTrial[] =
|
2017-11-13 10:16:47 +01:00
|
|
|
"WebRTC-VP8-Forced-Fallback-Encoder-v2";
|
2017-09-15 06:41:15 -07:00
|
|
|
const char kVp8SwCodecName[] = "libvpx";
|
|
|
|
|
|
2015-10-27 01:32:00 -07:00
|
|
|
// Used by histograms. Values of entries should not be changed.
|
|
|
|
|
enum HistogramCodecType {
|
|
|
|
|
kVideoUnknown = 0,
|
|
|
|
|
kVideoVp8 = 1,
|
|
|
|
|
kVideoVp9 = 2,
|
|
|
|
|
kVideoH264 = 3,
|
|
|
|
|
kVideoMax = 64,
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-04 00:33:21 -08:00
|
|
|
const char* kRealtimePrefix = "WebRTC.Video.";
|
|
|
|
|
const char* kScreenPrefix = "WebRTC.Video.Screenshare.";
|
|
|
|
|
|
2015-12-03 08:10:08 -08:00
|
|
|
const char* GetUmaPrefix(VideoEncoderConfig::ContentType content_type) {
|
|
|
|
|
switch (content_type) {
|
|
|
|
|
case VideoEncoderConfig::ContentType::kRealtimeVideo:
|
2016-02-04 00:33:21 -08:00
|
|
|
return kRealtimePrefix;
|
2015-12-03 08:10:08 -08:00
|
|
|
case VideoEncoderConfig::ContentType::kScreen:
|
2016-02-04 00:33:21 -08:00
|
|
|
return kScreenPrefix;
|
2015-12-03 08:10:08 -08:00
|
|
|
}
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED();
|
2015-12-03 08:10:08 -08:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-27 01:32:00 -07:00
|
|
|
HistogramCodecType PayloadNameToHistogramCodecType(
|
|
|
|
|
const std::string& payload_name) {
|
2017-08-24 03:52:48 -07:00
|
|
|
VideoCodecType codecType = PayloadStringToCodecType(payload_name);
|
|
|
|
|
switch (codecType) {
|
2017-04-03 10:03:35 -07:00
|
|
|
case kVideoCodecVP8:
|
|
|
|
|
return kVideoVp8;
|
|
|
|
|
case kVideoCodecVP9:
|
|
|
|
|
return kVideoVp9;
|
|
|
|
|
case kVideoCodecH264:
|
|
|
|
|
return kVideoH264;
|
|
|
|
|
default:
|
|
|
|
|
return kVideoUnknown;
|
|
|
|
|
}
|
2015-10-27 01:32:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdateCodecTypeHistogram(const std::string& payload_name) {
|
2016-01-25 05:58:23 -08:00
|
|
|
RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.Encoder.CodecType",
|
|
|
|
|
PayloadNameToHistogramCodecType(payload_name),
|
|
|
|
|
kVideoMax);
|
2015-10-27 01:32:00 -07:00
|
|
|
}
|
2017-09-15 06:41:15 -07:00
|
|
|
|
2018-08-27 15:33:42 +02:00
|
|
|
bool IsForcedFallbackPossible(const CodecSpecificInfo* codec_info,
|
|
|
|
|
int simulcast_index) {
|
|
|
|
|
return codec_info->codecType == kVideoCodecVP8 && simulcast_index == 0 &&
|
2017-09-15 06:41:15 -07:00
|
|
|
(codec_info->codecSpecific.VP8.temporalIdx == 0 ||
|
|
|
|
|
codec_info->codecSpecific.VP8.temporalIdx == kNoTemporalIdx);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<int> GetFallbackMaxPixels(const std::string& group) {
|
2017-09-15 06:41:15 -07:00
|
|
|
if (group.empty())
|
2018-06-15 12:28:07 +02:00
|
|
|
return absl::nullopt;
|
2017-09-15 06:41:15 -07:00
|
|
|
|
|
|
|
|
int min_pixels;
|
2017-11-13 10:16:47 +01:00
|
|
|
int max_pixels;
|
|
|
|
|
int min_bps;
|
2017-11-16 14:04:52 +01:00
|
|
|
if (sscanf(group.c_str(), "-%d,%d,%d", &min_pixels, &max_pixels, &min_bps) !=
|
|
|
|
|
3) {
|
2018-06-15 12:28:07 +02:00
|
|
|
return absl::optional<int>();
|
2017-09-15 06:41:15 -07:00
|
|
|
}
|
|
|
|
|
|
2017-11-16 14:04:52 +01:00
|
|
|
if (min_pixels <= 0 || max_pixels <= 0 || max_pixels < min_pixels)
|
2018-06-15 12:28:07 +02:00
|
|
|
return absl::optional<int>();
|
2017-11-16 14:04:52 +01:00
|
|
|
|
2018-06-15 12:28:07 +02:00
|
|
|
return absl::optional<int>(max_pixels);
|
2017-09-15 06:41:15 -07:00
|
|
|
}
|
2017-11-16 14:04:52 +01:00
|
|
|
|
2022-03-14 12:52:48 +01:00
|
|
|
absl::optional<int> GetFallbackMaxPixelsIfFieldTrialEnabled(
|
2022-03-29 11:04:48 +02:00
|
|
|
const webrtc::FieldTrialsView& field_trials) {
|
2022-03-14 12:52:48 +01:00
|
|
|
std::string group = field_trials.Lookup(kVp8ForcedFallbackEncoderFieldTrial);
|
2020-04-01 13:43:08 +02:00
|
|
|
return (absl::StartsWith(group, "Enabled"))
|
|
|
|
|
? GetFallbackMaxPixels(group.substr(7))
|
|
|
|
|
: absl::optional<int>();
|
2017-11-16 14:04:52 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-14 12:52:48 +01:00
|
|
|
absl::optional<int> GetFallbackMaxPixelsIfFieldTrialDisabled(
|
2022-03-29 11:04:48 +02:00
|
|
|
const webrtc::FieldTrialsView& field_trials) {
|
2022-03-14 12:52:48 +01:00
|
|
|
std::string group = field_trials.Lookup(kVp8ForcedFallbackEncoderFieldTrial);
|
2020-04-01 13:43:08 +02:00
|
|
|
return (absl::StartsWith(group, "Disabled"))
|
|
|
|
|
? GetFallbackMaxPixels(group.substr(8))
|
|
|
|
|
: absl::optional<int>();
|
2017-11-16 14:04:52 +01:00
|
|
|
}
|
2015-10-27 01:32:00 -07:00
|
|
|
} // namespace
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
|
|
|
|
|
|
2015-12-03 08:10:08 -08:00
|
|
|
SendStatisticsProxy::SendStatisticsProxy(
|
|
|
|
|
Clock* clock,
|
|
|
|
|
const VideoSendStream::Config& config,
|
2022-03-14 12:52:48 +01:00
|
|
|
VideoEncoderConfig::ContentType content_type,
|
2022-03-29 11:04:48 +02:00
|
|
|
const FieldTrialsView& field_trials)
|
2015-07-22 06:52:00 -07:00
|
|
|
: clock_(clock),
|
Reland "Reland "Move rtp-specific config out of EncoderSettings.""
This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e.
Reason for revert: Intend to investigate and fix perf problems.
Original change's description:
> Revert "Reland "Move rtp-specific config out of EncoderSettings.""
>
> This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266.
>
> Reason for revert: Regression in ramp up perf tests.
>
> Original change's description:
> > Reland "Move rtp-specific config out of EncoderSettings."
> >
> > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c
> >
> > Original change's description:
> > > Move rtp-specific config out of EncoderSettings.
> > >
> > > In VideoSendStream::Config, move payload_name and payload_type from
> > > EncoderSettings to Rtp.
> > >
> > > EncoderSettings now contains configuration for VideoStreamEncoder only,
> > > and should perhaps be renamed in a follow up cl. It's no longer
> > > passed as an argument to VideoCodecInitializer::SetupCodec.
> > >
> > > The latter then needs a different way to know the codec type,
> > > which is provided by a new codec_type member in VideoEncoderConfig.
> > >
> > > Bug: webrtc:8830
> > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6
> > > Reviewed-on: https://webrtc-review.googlesource.com/62062
> > > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#22532}
> >
> > Bug: webrtc:8830
> > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019
> > Reviewed-on: https://webrtc-review.googlesource.com/63721
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Niels Moller <nisse@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#22595}
>
> TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
>
> Bug: webrtc:8830,chromium:827080
> Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef
> Reviewed-on: https://webrtc-review.googlesource.com/65520
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Reviewed-by: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22677}
TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: webrtc:8830, chromium:827080
Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f
Reviewed-on: https://webrtc-review.googlesource.com/66862
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
|
|
|
payload_name_(config.rtp.payload_name),
|
2016-09-01 01:17:40 -07:00
|
|
|
rtp_config_(config.rtp),
|
2022-03-14 12:52:48 +01:00
|
|
|
fallback_max_pixels_(
|
|
|
|
|
GetFallbackMaxPixelsIfFieldTrialEnabled(field_trials)),
|
|
|
|
|
fallback_max_pixels_disabled_(
|
|
|
|
|
GetFallbackMaxPixelsIfFieldTrialDisabled(field_trials)),
|
2015-12-03 08:10:08 -08:00
|
|
|
content_type_(content_type),
|
2016-07-27 00:39:09 -07:00
|
|
|
start_ms_(clock->TimeInMilliseconds()),
|
2015-12-07 03:12:22 -08:00
|
|
|
encode_time_(kEncodeTimeWeigthFactor),
|
2019-05-28 17:42:38 +02:00
|
|
|
quality_limitation_reason_tracker_(clock_),
|
2017-10-16 12:19:23 +02:00
|
|
|
media_byte_rate_tracker_(kBucketSizeMs, kBucketCount),
|
|
|
|
|
encoded_frame_rate_tracker_(kBucketSizeMs, kBucketCount),
|
2019-09-09 11:26:45 +02:00
|
|
|
last_num_spatial_layers_(0),
|
|
|
|
|
last_num_simulcast_streams_(0),
|
|
|
|
|
last_spatial_layer_use_{},
|
2019-10-09 18:06:58 +02:00
|
|
|
bw_limited_layers_(false),
|
2020-03-10 09:50:26 +00:00
|
|
|
internal_encoder_scaler_(false),
|
2016-02-24 07:55:00 -08:00
|
|
|
uma_container_(
|
|
|
|
|
new UmaSamplesContainer(GetUmaPrefix(content_type_), stats_, clock)) {
|
2014-04-28 13:00:21 +00:00
|
|
|
}
|
2014-01-07 09:54:34 +00:00
|
|
|
|
2016-02-24 07:55:00 -08:00
|
|
|
SendStatisticsProxy::~SendStatisticsProxy() {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-09-01 01:17:40 -07:00
|
|
|
uma_container_->UpdateHistograms(rtp_config_, stats_);
|
2016-07-27 00:39:09 -07:00
|
|
|
|
|
|
|
|
int64_t elapsed_sec = (clock_->TimeInMilliseconds() - start_ms_) / 1000;
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.SendStreamLifetimeInSeconds",
|
|
|
|
|
elapsed_sec);
|
2016-07-27 00:39:09 -07:00
|
|
|
|
|
|
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds)
|
2016-09-01 01:17:40 -07:00
|
|
|
UpdateCodecTypeHistogram(payload_name_);
|
2016-02-24 07:55:00 -08:00
|
|
|
}
|
2015-12-03 08:10:08 -08:00
|
|
|
|
2018-08-28 16:30:18 +02:00
|
|
|
SendStatisticsProxy::FallbackEncoderInfo::FallbackEncoderInfo() = default;
|
|
|
|
|
|
2015-12-03 08:10:08 -08:00
|
|
|
SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer(
|
2016-02-24 07:55:00 -08:00
|
|
|
const char* prefix,
|
|
|
|
|
const VideoSendStream::Stats& stats,
|
|
|
|
|
Clock* const clock)
|
2015-12-03 08:10:08 -08:00
|
|
|
: uma_prefix_(prefix),
|
2016-02-24 07:55:00 -08:00
|
|
|
clock_(clock),
|
2016-05-06 11:29:15 -07:00
|
|
|
input_frame_rate_tracker_(100, 10u),
|
2016-11-29 01:40:35 -08:00
|
|
|
input_fps_counter_(clock, nullptr, true),
|
|
|
|
|
sent_fps_counter_(clock, nullptr, true),
|
2017-02-06 05:18:35 -08:00
|
|
|
total_byte_counter_(clock, nullptr, true),
|
|
|
|
|
media_byte_counter_(clock, nullptr, true),
|
|
|
|
|
rtx_byte_counter_(clock, nullptr, true),
|
|
|
|
|
padding_byte_counter_(clock, nullptr, true),
|
|
|
|
|
retransmit_byte_counter_(clock, nullptr, true),
|
|
|
|
|
fec_byte_counter_(clock, nullptr, true),
|
2016-02-24 07:55:00 -08:00
|
|
|
first_rtcp_stats_time_ms_(-1),
|
2016-03-01 09:40:42 +01:00
|
|
|
first_rtp_stats_time_ms_(-1),
|
2017-12-15 15:54:44 +01:00
|
|
|
start_stats_(stats),
|
|
|
|
|
num_streams_(0),
|
|
|
|
|
num_pixels_highest_stream_(0) {
|
2017-02-06 05:18:35 -08:00
|
|
|
InitializeBitrateCounters(stats);
|
2018-08-15 08:57:54 +02:00
|
|
|
static_assert(
|
|
|
|
|
kMaxEncodedFrameTimestampDiff < std::numeric_limits<uint32_t>::max() / 2,
|
|
|
|
|
"has to be smaller than half range");
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
2015-12-03 08:10:08 -08:00
|
|
|
|
2016-02-24 07:55:00 -08:00
|
|
|
SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {}
|
2015-06-16 10:17:01 +02:00
|
|
|
|
2017-02-06 05:18:35 -08:00
|
|
|
void SendStatisticsProxy::UmaSamplesContainer::InitializeBitrateCounters(
|
|
|
|
|
const VideoSendStream::Stats& stats) {
|
|
|
|
|
for (const auto& it : stats.substreams) {
|
|
|
|
|
uint32_t ssrc = it.first;
|
|
|
|
|
total_byte_counter_.SetLast(it.second.rtp_stats.transmitted.TotalBytes(),
|
|
|
|
|
ssrc);
|
|
|
|
|
padding_byte_counter_.SetLast(it.second.rtp_stats.transmitted.padding_bytes,
|
|
|
|
|
ssrc);
|
|
|
|
|
retransmit_byte_counter_.SetLast(
|
|
|
|
|
it.second.rtp_stats.retransmitted.TotalBytes(), ssrc);
|
|
|
|
|
fec_byte_counter_.SetLast(it.second.rtp_stats.fec.TotalBytes(), ssrc);
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
switch (it.second.type) {
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kMedia:
|
|
|
|
|
media_byte_counter_.SetLast(it.second.rtp_stats.MediaPayloadBytes(),
|
|
|
|
|
ssrc);
|
|
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kRtx:
|
|
|
|
|
rtx_byte_counter_.SetLast(it.second.rtp_stats.transmitted.TotalBytes(),
|
2017-02-06 05:18:35 -08:00
|
|
|
ssrc);
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kFlexfec:
|
|
|
|
|
break;
|
2016-03-01 09:40:42 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-26 17:20:50 +01:00
|
|
|
void SendStatisticsProxy::UmaSamplesContainer::RemoveOld(int64_t now_ms) {
|
2017-10-16 12:19:23 +02:00
|
|
|
while (!encoded_frames_.empty()) {
|
|
|
|
|
auto it = encoded_frames_.begin();
|
|
|
|
|
if (now_ms - it->second.send_ms < kMaxEncodedFrameWindowMs)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Use max per timestamp.
|
|
|
|
|
sent_width_counter_.Add(it->second.max_width);
|
|
|
|
|
sent_height_counter_.Add(it->second.max_height);
|
2017-12-15 15:54:44 +01:00
|
|
|
|
|
|
|
|
// Check number of encoded streams per timestamp.
|
2018-08-27 15:33:42 +02:00
|
|
|
if (num_streams_ > static_cast<size_t>(it->second.max_simulcast_idx)) {
|
2017-12-15 15:54:44 +01:00
|
|
|
if (num_streams_ > 1) {
|
|
|
|
|
int disabled_streams =
|
|
|
|
|
static_cast<int>(num_streams_ - 1 - it->second.max_simulcast_idx);
|
|
|
|
|
// Can be limited in resolution or framerate.
|
|
|
|
|
uint32_t pixels = it->second.max_width * it->second.max_height;
|
|
|
|
|
bool bw_limited_resolution =
|
|
|
|
|
disabled_streams > 0 && pixels < num_pixels_highest_stream_;
|
|
|
|
|
bw_limited_frame_counter_.Add(bw_limited_resolution);
|
|
|
|
|
if (bw_limited_resolution) {
|
|
|
|
|
bw_resolutions_disabled_counter_.Add(disabled_streams);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-16 12:19:23 +02:00
|
|
|
encoded_frames_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SendStatisticsProxy::UmaSamplesContainer::InsertEncodedFrame(
|
2017-12-15 15:54:44 +01:00
|
|
|
const EncodedImage& encoded_frame,
|
2019-11-26 17:20:50 +01:00
|
|
|
int simulcast_idx) {
|
2017-10-16 12:19:23 +02:00
|
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
2019-11-26 17:20:50 +01:00
|
|
|
RemoveOld(now_ms);
|
2017-10-16 12:19:23 +02:00
|
|
|
if (encoded_frames_.size() > kMaxEncodedFrameMapSize) {
|
|
|
|
|
encoded_frames_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-15 08:57:54 +02:00
|
|
|
// Check for jump in timestamp.
|
|
|
|
|
if (!encoded_frames_.empty()) {
|
|
|
|
|
uint32_t oldest_timestamp = encoded_frames_.begin()->first;
|
2018-08-16 10:24:12 +02:00
|
|
|
if (ForwardDiff(oldest_timestamp, encoded_frame.Timestamp()) >
|
2018-08-15 08:57:54 +02:00
|
|
|
kMaxEncodedFrameTimestampDiff) {
|
|
|
|
|
// Gap detected, clear frames to have a sequence where newest timestamp
|
|
|
|
|
// is not too far away from oldest in order to distinguish old and new.
|
|
|
|
|
encoded_frames_.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-12 10:03:51 +02:00
|
|
|
auto it = encoded_frames_.find(encoded_frame.Timestamp());
|
2017-10-16 12:19:23 +02:00
|
|
|
if (it == encoded_frames_.end()) {
|
|
|
|
|
// First frame with this timestamp.
|
2017-12-15 15:54:44 +01:00
|
|
|
encoded_frames_.insert(
|
2018-08-16 10:24:12 +02:00
|
|
|
std::make_pair(encoded_frame.Timestamp(),
|
2017-12-15 15:54:44 +01:00
|
|
|
Frame(now_ms, encoded_frame._encodedWidth,
|
|
|
|
|
encoded_frame._encodedHeight, simulcast_idx)));
|
2017-10-16 12:19:23 +02:00
|
|
|
sent_fps_counter_.Add(1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it->second.max_width =
|
|
|
|
|
std::max(it->second.max_width, encoded_frame._encodedWidth);
|
|
|
|
|
it->second.max_height =
|
|
|
|
|
std::max(it->second.max_height, encoded_frame._encodedHeight);
|
2017-12-15 15:54:44 +01:00
|
|
|
it->second.max_simulcast_idx =
|
|
|
|
|
std::max(it->second.max_simulcast_idx, simulcast_idx);
|
2017-10-16 12:19:23 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 07:55:00 -08:00
|
|
|
void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
2018-07-17 16:03:46 +02:00
|
|
|
const RtpConfig& rtp_config,
|
2016-02-24 07:55:00 -08:00
|
|
|
const VideoSendStream::Stats& current_stats) {
|
2016-02-04 00:33:21 -08:00
|
|
|
RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix);
|
|
|
|
|
const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0;
|
2016-11-29 01:40:35 -08:00
|
|
|
const int kMinRequiredPeriodicSamples = 6;
|
2018-03-08 15:03:23 +01:00
|
|
|
char log_stream_buf[8 * 1024];
|
|
|
|
|
rtc::SimpleStringBuilder log_stream(log_stream_buf);
|
2016-11-01 11:45:46 -07:00
|
|
|
int in_width = input_width_counter_.Avg(kMinRequiredMetricsSamples);
|
|
|
|
|
int in_height = input_height_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-07-22 06:52:00 -07:00
|
|
|
if (in_width != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputWidthInPixels",
|
|
|
|
|
in_width);
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels",
|
|
|
|
|
in_height);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "InputWidthInPixels " << in_width << "\n"
|
|
|
|
|
<< uma_prefix_ << "InputHeightInPixels " << in_height << "\n";
|
2016-11-29 01:40:35 -08:00
|
|
|
}
|
|
|
|
|
AggregatedStats in_fps = input_fps_counter_.GetStats();
|
|
|
|
|
if (in_fps.num_samples >= kMinRequiredPeriodicSamples) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond",
|
2016-11-29 01:40:35 -08:00
|
|
|
in_fps.average);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "InputFramesPerSecond " << in_fps.ToString()
|
|
|
|
|
<< "\n";
|
2015-07-22 06:52:00 -07:00
|
|
|
}
|
2016-11-29 01:40:35 -08:00
|
|
|
|
2016-11-01 11:45:46 -07:00
|
|
|
int sent_width = sent_width_counter_.Avg(kMinRequiredMetricsSamples);
|
|
|
|
|
int sent_height = sent_height_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-07-22 06:52:00 -07:00
|
|
|
if (sent_width != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentWidthInPixels",
|
|
|
|
|
sent_width);
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels",
|
|
|
|
|
sent_height);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "SentWidthInPixels " << sent_width << "\n"
|
|
|
|
|
<< uma_prefix_ << "SentHeightInPixels " << sent_height << "\n";
|
2016-11-29 01:40:35 -08:00
|
|
|
}
|
|
|
|
|
AggregatedStats sent_fps = sent_fps_counter_.GetStats();
|
|
|
|
|
if (sent_fps.num_samples >= kMinRequiredPeriodicSamples) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond",
|
2016-11-29 01:40:35 -08:00
|
|
|
sent_fps.average);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "SentFramesPerSecond " << sent_fps.ToString()
|
|
|
|
|
<< "\n";
|
2015-07-22 06:52:00 -07:00
|
|
|
}
|
2016-11-29 01:40:35 -08:00
|
|
|
|
2017-08-30 02:30:20 -07:00
|
|
|
if (in_fps.num_samples > kMinRequiredPeriodicSamples &&
|
|
|
|
|
sent_fps.num_samples >= kMinRequiredPeriodicSamples) {
|
|
|
|
|
int in_fps_avg = in_fps.average;
|
|
|
|
|
if (in_fps_avg > 0) {
|
|
|
|
|
int sent_fps_avg = sent_fps.average;
|
|
|
|
|
int sent_to_in_fps_ratio_percent =
|
|
|
|
|
(100 * sent_fps_avg + in_fps_avg / 2) / in_fps_avg;
|
|
|
|
|
// If reported period is small, it may happen that sent_fps is larger than
|
|
|
|
|
// input_fps briefly on average. This should be treated as 100% sent to
|
|
|
|
|
// input ratio.
|
|
|
|
|
if (sent_to_in_fps_ratio_percent > 100)
|
|
|
|
|
sent_to_in_fps_ratio_percent = 100;
|
|
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(kIndex,
|
|
|
|
|
uma_prefix_ + "SentToInputFpsRatioPercent",
|
|
|
|
|
sent_to_in_fps_ratio_percent);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "SentToInputFpsRatioPercent "
|
|
|
|
|
<< sent_to_in_fps_ratio_percent << "\n";
|
2017-08-30 02:30:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-01 11:45:46 -07:00
|
|
|
int encode_ms = encode_time_counter_.Avg(kMinRequiredMetricsSamples);
|
2016-02-04 00:33:21 -08:00
|
|
|
if (encode_ms != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs",
|
|
|
|
|
encode_ms);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "EncodeTimeInMs " << encode_ms << "\n";
|
2016-02-04 00:33:21 -08:00
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int key_frames_permille =
|
|
|
|
|
key_frame_counter_.Permille(kMinRequiredMetricsSamples);
|
2015-10-05 02:36:17 -07:00
|
|
|
if (key_frames_permille != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "KeyFramesSentInPermille",
|
|
|
|
|
key_frames_permille);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "KeyFramesSentInPermille "
|
|
|
|
|
<< key_frames_permille << "\n";
|
2015-10-05 02:36:17 -07:00
|
|
|
}
|
2015-10-19 00:35:21 -07:00
|
|
|
int quality_limited =
|
2016-11-01 11:45:46 -07:00
|
|
|
quality_limited_frame_counter_.Percent(kMinRequiredMetricsSamples);
|
2015-10-19 00:35:21 -07:00
|
|
|
if (quality_limited != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(kIndex,
|
|
|
|
|
uma_prefix_ + "QualityLimitedResolutionInPercent",
|
|
|
|
|
quality_limited);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "QualityLimitedResolutionInPercent "
|
|
|
|
|
<< quality_limited << "\n";
|
2015-10-19 00:35:21 -07:00
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int downscales = quality_downscales_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-10-19 00:35:21 -07:00
|
|
|
if (downscales != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_ENUMERATION(
|
2016-02-04 00:33:21 -08:00
|
|
|
kIndex, uma_prefix_ + "QualityLimitedResolutionDownscales", downscales,
|
|
|
|
|
20);
|
2015-10-19 00:35:21 -07:00
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int cpu_limited =
|
|
|
|
|
cpu_limited_frame_counter_.Percent(kMinRequiredMetricsSamples);
|
|
|
|
|
if (cpu_limited != -1) {
|
|
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(
|
|
|
|
|
kIndex, uma_prefix_ + "CpuLimitedResolutionInPercent", cpu_limited);
|
|
|
|
|
}
|
|
|
|
|
int bw_limited =
|
|
|
|
|
bw_limited_frame_counter_.Percent(kMinRequiredMetricsSamples);
|
2015-10-19 23:32:41 -07:00
|
|
|
if (bw_limited != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(
|
2016-02-04 00:33:21 -08:00
|
|
|
kIndex, uma_prefix_ + "BandwidthLimitedResolutionInPercent",
|
|
|
|
|
bw_limited);
|
2015-10-19 23:32:41 -07:00
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int num_disabled =
|
|
|
|
|
bw_resolutions_disabled_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-10-19 23:32:41 -07:00
|
|
|
if (num_disabled != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_ENUMERATION(
|
2016-02-04 00:33:21 -08:00
|
|
|
kIndex, uma_prefix_ + "BandwidthLimitedResolutionsDisabled",
|
|
|
|
|
num_disabled, 10);
|
2015-10-19 23:32:41 -07:00
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int delay_ms = delay_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-11-04 00:59:03 -08:00
|
|
|
if (delay_ms != -1)
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayInMs",
|
|
|
|
|
delay_ms);
|
2015-11-04 00:59:03 -08:00
|
|
|
|
2016-11-01 11:45:46 -07:00
|
|
|
int max_delay_ms = max_delay_counter_.Avg(kMinRequiredMetricsSamples);
|
2015-11-04 00:59:03 -08:00
|
|
|
if (max_delay_ms != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayMaxInMs",
|
|
|
|
|
max_delay_ms);
|
2015-12-03 08:10:08 -08:00
|
|
|
}
|
2016-02-24 07:55:00 -08:00
|
|
|
|
2016-03-31 00:00:19 -07:00
|
|
|
for (const auto& it : qp_counters_) {
|
2016-11-01 11:45:46 -07:00
|
|
|
int qp_vp8 = it.second.vp8.Avg(kMinRequiredMetricsSamples);
|
2016-04-18 02:58:47 -07:00
|
|
|
if (qp_vp8 != -1) {
|
2016-03-31 00:00:19 -07:00
|
|
|
int spatial_idx = it.first;
|
|
|
|
|
if (spatial_idx == -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8",
|
|
|
|
|
qp_vp8);
|
2016-03-31 00:00:19 -07:00
|
|
|
} else if (spatial_idx == 0) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S0",
|
|
|
|
|
qp_vp8);
|
2016-03-31 00:00:19 -07:00
|
|
|
} else if (spatial_idx == 1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S1",
|
|
|
|
|
qp_vp8);
|
2016-03-31 00:00:19 -07:00
|
|
|
} else if (spatial_idx == 2) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S2",
|
|
|
|
|
qp_vp8);
|
2016-03-31 00:00:19 -07:00
|
|
|
} else {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "QP stats not recorded for VP8 spatial idx " << spatial_idx;
|
2016-03-31 00:00:19 -07:00
|
|
|
}
|
|
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
int qp_vp9 = it.second.vp9.Avg(kMinRequiredMetricsSamples);
|
2016-04-18 02:58:47 -07:00
|
|
|
if (qp_vp9 != -1) {
|
|
|
|
|
int spatial_idx = it.first;
|
|
|
|
|
if (spatial_idx == -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_500(kIndex, uma_prefix_ + "Encoded.Qp.Vp9",
|
|
|
|
|
qp_vp9);
|
2016-04-18 02:58:47 -07:00
|
|
|
} else if (spatial_idx == 0) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_500(kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S0",
|
|
|
|
|
qp_vp9);
|
2016-04-18 02:58:47 -07:00
|
|
|
} else if (spatial_idx == 1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_500(kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S1",
|
|
|
|
|
qp_vp9);
|
2016-04-18 02:58:47 -07:00
|
|
|
} else if (spatial_idx == 2) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_500(kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S2",
|
|
|
|
|
qp_vp9);
|
2016-04-18 02:58:47 -07:00
|
|
|
} else {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "QP stats not recorded for VP9 spatial layer " << spatial_idx;
|
2016-04-18 02:58:47 -07:00
|
|
|
}
|
|
|
|
|
}
|
2016-11-02 09:08:47 -07:00
|
|
|
int qp_h264 = it.second.h264.Avg(kMinRequiredMetricsSamples);
|
|
|
|
|
if (qp_h264 != -1) {
|
|
|
|
|
int spatial_idx = it.first;
|
2018-06-21 16:16:38 +02:00
|
|
|
if (spatial_idx == -1) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.H264",
|
|
|
|
|
qp_h264);
|
|
|
|
|
} else if (spatial_idx == 0) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.H264.S0",
|
|
|
|
|
qp_h264);
|
|
|
|
|
} else if (spatial_idx == 1) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.H264.S1",
|
|
|
|
|
qp_h264);
|
|
|
|
|
} else if (spatial_idx == 2) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.H264.S2",
|
|
|
|
|
qp_h264);
|
|
|
|
|
} else {
|
|
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "QP stats not recorded for H264 spatial idx " << spatial_idx;
|
|
|
|
|
}
|
2016-11-02 09:08:47 -07:00
|
|
|
}
|
2016-03-31 00:00:19 -07:00
|
|
|
}
|
|
|
|
|
|
2017-04-07 00:57:58 -07:00
|
|
|
if (first_rtp_stats_time_ms_ != -1) {
|
2017-05-15 23:40:18 -07:00
|
|
|
quality_adapt_timer_.Stop(clock_->TimeInMilliseconds());
|
|
|
|
|
int64_t elapsed_sec = quality_adapt_timer_.total_ms / 1000;
|
2017-04-07 00:57:58 -07:00
|
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
|
|
|
|
int quality_changes = current_stats.number_of_quality_adapt_changes -
|
|
|
|
|
start_stats_.number_of_quality_adapt_changes;
|
2018-01-08 08:49:53 +01:00
|
|
|
// Only base stats on changes during a call, discard initial changes.
|
|
|
|
|
int initial_changes =
|
|
|
|
|
initial_quality_changes_.down + initial_quality_changes_.up;
|
|
|
|
|
if (initial_changes <= quality_changes)
|
|
|
|
|
quality_changes -= initial_changes;
|
2017-04-07 00:57:58 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100(kIndex,
|
|
|
|
|
uma_prefix_ + "AdaptChangesPerMinute.Quality",
|
|
|
|
|
quality_changes * 60 / elapsed_sec);
|
|
|
|
|
}
|
2017-05-15 23:40:18 -07:00
|
|
|
cpu_adapt_timer_.Stop(clock_->TimeInMilliseconds());
|
|
|
|
|
elapsed_sec = cpu_adapt_timer_.total_ms / 1000;
|
2017-04-07 00:57:58 -07:00
|
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
|
|
|
|
int cpu_changes = current_stats.number_of_cpu_adapt_changes -
|
|
|
|
|
start_stats_.number_of_cpu_adapt_changes;
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_100(kIndex,
|
|
|
|
|
uma_prefix_ + "AdaptChangesPerMinute.Cpu",
|
|
|
|
|
cpu_changes * 60 / elapsed_sec);
|
|
|
|
|
}
|
2017-04-04 23:40:50 -07:00
|
|
|
}
|
|
|
|
|
|
2016-02-19 09:03:26 -08:00
|
|
|
if (first_rtcp_stats_time_ms_ != -1) {
|
2016-02-24 07:55:00 -08:00
|
|
|
int64_t elapsed_sec =
|
|
|
|
|
(clock_->TimeInMilliseconds() - first_rtcp_stats_time_ms_) / 1000;
|
|
|
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
|
|
|
|
int fraction_lost = report_block_stats_.FractionLostInPercent();
|
|
|
|
|
if (fraction_lost != -1) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(
|
2016-02-24 07:55:00 -08:00
|
|
|
kIndex, uma_prefix_ + "SentPacketsLostInPercent", fraction_lost);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "SentPacketsLostInPercent "
|
2018-10-05 13:47:12 +02:00
|
|
|
<< fraction_lost << "\n";
|
2016-02-24 07:55:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The RTCP packet type counters, delivered via the
|
|
|
|
|
// RtcpPacketTypeCounterObserver interface, are aggregates over the entire
|
|
|
|
|
// life of the send stream and are not reset when switching content type.
|
|
|
|
|
// For the purpose of these statistics though, we want new counts when
|
|
|
|
|
// switching since we switch histogram name. On every reset of the
|
|
|
|
|
// UmaSamplesContainer, we save the initial state of the counters, so that
|
|
|
|
|
// we can calculate the delta here and aggregate over all ssrcs.
|
|
|
|
|
RtcpPacketTypeCounter counters;
|
2016-09-01 01:17:40 -07:00
|
|
|
for (uint32_t ssrc : rtp_config.ssrcs) {
|
2016-02-24 07:55:00 -08:00
|
|
|
auto kv = current_stats.substreams.find(ssrc);
|
|
|
|
|
if (kv == current_stats.substreams.end())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
RtcpPacketTypeCounter stream_counters =
|
|
|
|
|
kv->second.rtcp_packet_type_counts;
|
|
|
|
|
kv = start_stats_.substreams.find(ssrc);
|
|
|
|
|
if (kv != start_stats_.substreams.end())
|
|
|
|
|
stream_counters.Subtract(kv->second.rtcp_packet_type_counts);
|
|
|
|
|
|
|
|
|
|
counters.Add(stream_counters);
|
|
|
|
|
}
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
|
|
|
|
uma_prefix_ + "NackPacketsReceivedPerMinute",
|
|
|
|
|
counters.nack_packets * 60 / elapsed_sec);
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
|
|
|
|
uma_prefix_ + "FirPacketsReceivedPerMinute",
|
|
|
|
|
counters.fir_packets * 60 / elapsed_sec);
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
|
|
|
|
uma_prefix_ + "PliPacketsReceivedPerMinute",
|
|
|
|
|
counters.pli_packets * 60 / elapsed_sec);
|
2016-02-24 07:55:00 -08:00
|
|
|
if (counters.nack_requests > 0) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(
|
2016-02-24 07:55:00 -08:00
|
|
|
kIndex, uma_prefix_ + "UniqueNackRequestsReceivedInPercent",
|
|
|
|
|
counters.UniqueNackRequestsInPercent());
|
|
|
|
|
}
|
2016-02-19 09:03:26 -08:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-01 09:40:42 +01:00
|
|
|
|
|
|
|
|
if (first_rtp_stats_time_ms_ != -1) {
|
|
|
|
|
int64_t elapsed_sec =
|
|
|
|
|
(clock_->TimeInMilliseconds() - first_rtp_stats_time_ms_) / 1000;
|
|
|
|
|
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
2016-12-19 06:50:53 -08:00
|
|
|
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "NumberOfPauseEvents",
|
|
|
|
|
target_rate_updates_.pause_resume_events);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "NumberOfPauseEvents "
|
|
|
|
|
<< target_rate_updates_.pause_resume_events << "\n";
|
2016-12-19 06:50:53 -08:00
|
|
|
|
|
|
|
|
int paused_time_percent =
|
|
|
|
|
paused_time_counter_.Percent(metrics::kMinRunTimeInSeconds * 1000);
|
|
|
|
|
if (paused_time_percent != -1) {
|
|
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(kIndex, uma_prefix_ + "PausedTimeInPercent",
|
|
|
|
|
paused_time_percent);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "PausedTimeInPercent "
|
|
|
|
|
<< paused_time_percent << "\n";
|
2016-12-19 06:50:53 -08:00
|
|
|
}
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
|
|
|
|
}
|
2016-12-19 06:50:53 -08:00
|
|
|
|
2017-09-15 06:41:15 -07:00
|
|
|
if (fallback_info_.is_possible) {
|
|
|
|
|
// Double interval since there is some time before fallback may occur.
|
|
|
|
|
const int kMinRunTimeMs = 2 * metrics::kMinRunTimeInSeconds * 1000;
|
|
|
|
|
int64_t elapsed_ms = fallback_info_.elapsed_ms;
|
|
|
|
|
int fallback_time_percent = fallback_active_counter_.Percent(kMinRunTimeMs);
|
|
|
|
|
if (fallback_time_percent != -1 && elapsed_ms >= kMinRunTimeMs) {
|
|
|
|
|
RTC_HISTOGRAMS_PERCENTAGE(
|
|
|
|
|
kIndex, uma_prefix_ + "Encoder.ForcedSwFallbackTimeInPercent.Vp8",
|
|
|
|
|
fallback_time_percent);
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_100(
|
|
|
|
|
kIndex, uma_prefix_ + "Encoder.ForcedSwFallbackChangesPerMinute.Vp8",
|
|
|
|
|
fallback_info_.on_off_events * 60 / (elapsed_ms / 1000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-06 05:18:35 -08:00
|
|
|
AggregatedStats total_bytes_per_sec = total_byte_counter_.GetStats();
|
|
|
|
|
if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "BitrateSentInKbps",
|
|
|
|
|
total_bytes_per_sec.average * 8 / 1000);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "BitrateSentInBps "
|
|
|
|
|
<< total_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
|
|
|
|
AggregatedStats media_bytes_per_sec = media_byte_counter_.GetStats();
|
|
|
|
|
if (media_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "MediaBitrateSentInKbps",
|
|
|
|
|
media_bytes_per_sec.average * 8 / 1000);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "MediaBitrateSentInBps "
|
|
|
|
|
<< media_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
|
|
|
|
AggregatedStats padding_bytes_per_sec = padding_byte_counter_.GetStats();
|
|
|
|
|
if (padding_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
|
|
|
|
uma_prefix_ + "PaddingBitrateSentInKbps",
|
|
|
|
|
padding_bytes_per_sec.average * 8 / 1000);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "PaddingBitrateSentInBps "
|
|
|
|
|
<< padding_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
|
|
|
|
AggregatedStats retransmit_bytes_per_sec =
|
|
|
|
|
retransmit_byte_counter_.GetStats();
|
|
|
|
|
if (retransmit_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
|
|
|
|
uma_prefix_ + "RetransmittedBitrateSentInKbps",
|
|
|
|
|
retransmit_bytes_per_sec.average * 8 / 1000);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "RetransmittedBitrateSentInBps "
|
|
|
|
|
<< retransmit_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
|
|
|
|
if (!rtp_config.rtx.ssrcs.empty()) {
|
|
|
|
|
AggregatedStats rtx_bytes_per_sec = rtx_byte_counter_.GetStats();
|
|
|
|
|
int rtx_bytes_per_sec_avg = -1;
|
|
|
|
|
if (rtx_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
rtx_bytes_per_sec_avg = rtx_bytes_per_sec.average;
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "RtxBitrateSentInBps "
|
|
|
|
|
<< rtx_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2017-02-06 05:18:35 -08:00
|
|
|
} else if (total_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
rtx_bytes_per_sec_avg = 0; // RTX enabled but no RTX data sent, record 0.
|
|
|
|
|
}
|
|
|
|
|
if (rtx_bytes_per_sec_avg != -1) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "RtxBitrateSentInKbps",
|
|
|
|
|
rtx_bytes_per_sec_avg * 8 / 1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (rtp_config.flexfec.payload_type != -1 ||
|
|
|
|
|
rtp_config.ulpfec.red_payload_type != -1) {
|
|
|
|
|
AggregatedStats fec_bytes_per_sec = fec_byte_counter_.GetStats();
|
|
|
|
|
if (fec_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
|
|
|
|
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "FecBitrateSentInKbps",
|
|
|
|
|
fec_bytes_per_sec.average * 8 / 1000);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "FecBitrateSentInBps "
|
|
|
|
|
<< fec_bytes_per_sec.ToStringWithMultiplier(8) << "\n";
|
2016-03-01 09:40:42 +01:00
|
|
|
}
|
|
|
|
|
}
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << "Frames encoded " << current_stats.frames_encoded << "\n"
|
|
|
|
|
<< uma_prefix_ << "DroppedFrames.Capturer "
|
|
|
|
|
<< current_stats.frames_dropped_by_capturer << "\n";
|
2017-10-23 10:45:37 +02:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.Capturer",
|
|
|
|
|
current_stats.frames_dropped_by_capturer);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "DroppedFrames.EncoderQueue "
|
|
|
|
|
<< current_stats.frames_dropped_by_encoder_queue << "\n";
|
2017-10-23 10:45:37 +02:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.EncoderQueue",
|
|
|
|
|
current_stats.frames_dropped_by_encoder_queue);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "DroppedFrames.Encoder "
|
|
|
|
|
<< current_stats.frames_dropped_by_encoder << "\n";
|
2017-10-23 10:45:37 +02:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.Encoder",
|
|
|
|
|
current_stats.frames_dropped_by_encoder);
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
log_stream << uma_prefix_ << "DroppedFrames.Ratelimiter "
|
2020-02-07 14:29:32 +01:00
|
|
|
<< current_stats.frames_dropped_by_rate_limiter << "\n";
|
2017-10-23 10:45:37 +02:00
|
|
|
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "DroppedFrames.Ratelimiter",
|
|
|
|
|
current_stats.frames_dropped_by_rate_limiter);
|
2020-02-07 14:29:32 +01:00
|
|
|
log_stream << uma_prefix_ << "DroppedFrames.CongestionWindow "
|
|
|
|
|
<< current_stats.frames_dropped_by_congestion_window;
|
2018-02-16 13:09:41 +01:00
|
|
|
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
RTC_LOG(LS_INFO) << log_stream.str();
|
2015-12-03 08:10:08 -08:00
|
|
|
}
|
|
|
|
|
|
2016-09-29 11:48:50 +02:00
|
|
|
void SendStatisticsProxy::OnEncoderReconfigured(
|
|
|
|
|
const VideoEncoderConfig& config,
|
2018-05-25 09:43:26 +02:00
|
|
|
const std::vector<VideoStream>& streams) {
|
2021-05-03 16:23:08 +02:00
|
|
|
// Called on VideoStreamEncoder's encoder_queue_.
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-09-29 11:48:50 +02:00
|
|
|
|
|
|
|
|
if (content_type_ != config.content_type) {
|
2016-09-01 01:17:40 -07:00
|
|
|
uma_container_->UpdateHistograms(rtp_config_, stats_);
|
2016-09-29 11:48:50 +02:00
|
|
|
uma_container_.reset(new UmaSamplesContainer(
|
|
|
|
|
GetUmaPrefix(config.content_type), stats_, clock_));
|
|
|
|
|
content_type_ = config.content_type;
|
2015-11-04 00:59:03 -08:00
|
|
|
}
|
2017-12-15 15:54:44 +01:00
|
|
|
uma_container_->encoded_frames_.clear();
|
|
|
|
|
uma_container_->num_streams_ = streams.size();
|
|
|
|
|
uma_container_->num_pixels_highest_stream_ =
|
|
|
|
|
streams.empty() ? 0 : (streams.back().width * streams.back().height);
|
2015-06-16 10:17:01 +02:00
|
|
|
}
|
2014-01-07 09:54:34 +00:00
|
|
|
|
2018-07-24 09:29:58 +02:00
|
|
|
void SendStatisticsProxy::OnEncodedFrameTimeMeasured(int encode_time_ms,
|
|
|
|
|
int encode_usage_percent) {
|
2019-04-02 15:05:21 +02:00
|
|
|
RTC_DCHECK_GE(encode_time_ms, 0);
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-02-05 11:13:28 +01:00
|
|
|
uma_container_->encode_time_counter_.Add(encode_time_ms);
|
|
|
|
|
encode_time_.Apply(1.0f, encode_time_ms);
|
2019-04-23 08:50:04 +02:00
|
|
|
stats_.avg_encode_time_ms = std::round(encode_time_.filtered());
|
2019-04-02 15:05:21 +02:00
|
|
|
stats_.total_encode_time_ms += encode_time_ms;
|
2018-07-24 09:29:58 +02:00
|
|
|
stats_.encode_usage_percent = encode_usage_percent;
|
2015-02-26 12:19:31 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-22 16:28:51 +02:00
|
|
|
void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
|
2017-04-07 00:57:58 -07:00
|
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2014-03-13 13:31:21 +00:00
|
|
|
stats_.suspended = is_suspended;
|
2016-11-29 01:40:35 -08:00
|
|
|
if (is_suspended) {
|
2017-02-06 05:18:35 -08:00
|
|
|
// Pause framerate (add min pause time since there may be frames/packets
|
|
|
|
|
// that are not yet sent).
|
|
|
|
|
const int64_t kMinMs = 500;
|
|
|
|
|
uma_container_->input_fps_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->sent_fps_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
// Pause bitrate stats.
|
|
|
|
|
uma_container_->total_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->media_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->rtx_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->padding_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->retransmit_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
|
|
|
|
uma_container_->fec_byte_counter_.ProcessAndPauseForDuration(kMinMs);
|
2017-04-07 00:57:58 -07:00
|
|
|
// Stop adaptation stats.
|
2017-05-15 23:40:18 -07:00
|
|
|
uma_container_->cpu_adapt_timer_.Stop(now_ms);
|
|
|
|
|
uma_container_->quality_adapt_timer_.Stop(now_ms);
|
2017-02-06 05:18:35 -08:00
|
|
|
} else {
|
2017-04-07 00:57:58 -07:00
|
|
|
// Start adaptation stats if scaling is enabled.
|
2020-06-11 10:45:29 +02:00
|
|
|
if (adaptation_limitations_.MaskedCpuCounts()
|
|
|
|
|
.resolution_adaptations.has_value())
|
2017-05-15 23:40:18 -07:00
|
|
|
uma_container_->cpu_adapt_timer_.Start(now_ms);
|
2020-06-11 10:45:29 +02:00
|
|
|
if (adaptation_limitations_.MaskedQualityCounts()
|
|
|
|
|
.resolution_adaptations.has_value())
|
2017-05-15 23:40:18 -07:00
|
|
|
uma_container_->quality_adapt_timer_.Start(now_ms);
|
2017-02-06 05:18:35 -08:00
|
|
|
// Stop pause explicitly for stats that may be zero/not updated for some
|
|
|
|
|
// time.
|
|
|
|
|
uma_container_->rtx_byte_counter_.ProcessAndStopPause();
|
|
|
|
|
uma_container_->padding_byte_counter_.ProcessAndStopPause();
|
|
|
|
|
uma_container_->retransmit_byte_counter_.ProcessAndStopPause();
|
|
|
|
|
uma_container_->fec_byte_counter_.ProcessAndStopPause();
|
2016-11-29 01:40:35 -08:00
|
|
|
}
|
2014-03-13 13:31:21 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
VideoSendStream::Stats SendStatisticsProxy::GetStats() {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2014-12-01 15:23:21 +00:00
|
|
|
PurgeOldStats();
|
2015-03-18 09:51:05 +00:00
|
|
|
stats_.input_frame_rate =
|
2021-11-10 11:23:56 +09:00
|
|
|
uma_container_->input_frame_rate_tracker_.ComputeRate();
|
2021-02-27 00:29:15 -08:00
|
|
|
stats_.frames =
|
|
|
|
|
uma_container_->input_frame_rate_tracker_.TotalSampleCount();
|
2017-09-06 12:32:35 -07:00
|
|
|
stats_.content_type =
|
|
|
|
|
content_type_ == VideoEncoderConfig::ContentType::kRealtimeVideo
|
|
|
|
|
? VideoContentType::UNSPECIFIED
|
|
|
|
|
: VideoContentType::SCREENSHARE;
|
2017-10-16 12:19:23 +02:00
|
|
|
stats_.encode_frame_rate = round(encoded_frame_rate_tracker_.ComputeRate());
|
|
|
|
|
stats_.media_bitrate_bps = media_byte_rate_tracker_.ComputeRate() * 8;
|
2019-05-28 17:42:38 +02:00
|
|
|
stats_.quality_limitation_durations_ms =
|
|
|
|
|
quality_limitation_reason_tracker_.DurationsMs();
|
2021-08-10 08:56:36 +02:00
|
|
|
|
|
|
|
|
for (auto& substream : stats_.substreams) {
|
|
|
|
|
uint32_t ssrc = substream.first;
|
|
|
|
|
if (encoded_frame_rate_trackers_.count(ssrc) > 0) {
|
|
|
|
|
substream.second.encode_frame_rate =
|
|
|
|
|
encoded_frame_rate_trackers_[ssrc]->ComputeRate();
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-11 13:44:02 +00:00
|
|
|
return stats_;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
void SendStatisticsProxy::PurgeOldStats() {
|
2015-05-15 11:33:39 +02:00
|
|
|
int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
|
2015-02-25 10:42:16 +00:00
|
|
|
for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
|
|
|
|
stats_.substreams.begin();
|
2014-12-01 15:23:21 +00:00
|
|
|
it != stats_.substreams.end(); ++it) {
|
|
|
|
|
uint32_t ssrc = it->first;
|
2015-05-15 11:33:39 +02:00
|
|
|
if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
|
|
|
|
|
it->second.width = 0;
|
|
|
|
|
it->second.height = 0;
|
|
|
|
|
}
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
|
|
|
|
|
uint32_t ssrc) {
|
|
|
|
|
std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
|
|
|
|
stats_.substreams.find(ssrc);
|
2014-01-07 09:54:34 +00:00
|
|
|
if (it != stats_.substreams.end())
|
|
|
|
|
return &it->second;
|
|
|
|
|
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
bool is_media = rtp_config_.IsMediaSsrc(ssrc);
|
2017-01-16 06:59:19 -08:00
|
|
|
bool is_flexfec = rtp_config_.flexfec.payload_type != -1 &&
|
|
|
|
|
ssrc == rtp_config_.flexfec.ssrc;
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
bool is_rtx = rtp_config_.IsRtxSsrc(ssrc);
|
2016-11-15 08:21:52 -08:00
|
|
|
if (!is_media && !is_flexfec && !is_rtx)
|
|
|
|
|
return nullptr;
|
2014-01-07 09:54:34 +00:00
|
|
|
|
2016-08-11 08:41:18 -07:00
|
|
|
// Insert new entry and return ptr.
|
|
|
|
|
VideoSendStream::StreamStats* entry = &stats_.substreams[ssrc];
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
if (is_media) {
|
|
|
|
|
entry->type = VideoSendStream::StreamStats::StreamType::kMedia;
|
|
|
|
|
} else if (is_rtx) {
|
|
|
|
|
entry->type = VideoSendStream::StreamStats::StreamType::kRtx;
|
|
|
|
|
} else if (is_flexfec) {
|
|
|
|
|
entry->type = VideoSendStream::StreamStats::StreamType::kFlexfec;
|
|
|
|
|
} else {
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED();
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
}
|
|
|
|
|
switch (entry->type) {
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kMedia:
|
|
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kRtx:
|
|
|
|
|
entry->referenced_media_ssrc =
|
|
|
|
|
rtp_config_.GetMediaSsrcAssociatedWithRtxSsrc(ssrc);
|
|
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kFlexfec:
|
|
|
|
|
entry->referenced_media_ssrc =
|
|
|
|
|
rtp_config_.GetMediaSsrcAssociatedWithFlexfecSsrc(ssrc);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-08-11 08:41:18 -07:00
|
|
|
|
|
|
|
|
return entry;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-15 11:33:39 +02:00
|
|
|
void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-05-15 11:33:39 +02:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2015-05-15 11:33:39 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
stats->total_bitrate_bps = 0;
|
|
|
|
|
stats->retransmit_bitrate_bps = 0;
|
|
|
|
|
stats->height = 0;
|
|
|
|
|
stats->width = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-05 08:34:04 -07:00
|
|
|
void SendStatisticsProxy::OnSetEncoderTargetRate(uint32_t bitrate_bps) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-12-19 06:50:53 -08:00
|
|
|
if (uma_container_->target_rate_updates_.last_ms == -1 && bitrate_bps == 0)
|
|
|
|
|
return; // Start on first non-zero bitrate, may initially be zero.
|
|
|
|
|
|
|
|
|
|
int64_t now = clock_->TimeInMilliseconds();
|
|
|
|
|
if (uma_container_->target_rate_updates_.last_ms != -1) {
|
|
|
|
|
bool was_paused = stats_.target_media_bitrate_bps == 0;
|
|
|
|
|
int64_t diff_ms = now - uma_container_->target_rate_updates_.last_ms;
|
|
|
|
|
uma_container_->paused_time_counter_.Add(was_paused, diff_ms);
|
|
|
|
|
|
|
|
|
|
// Use last to not include update when stream is stopped and video disabled.
|
|
|
|
|
if (uma_container_->target_rate_updates_.last_paused_or_resumed)
|
|
|
|
|
++uma_container_->target_rate_updates_.pause_resume_events;
|
|
|
|
|
|
|
|
|
|
// Check if video is paused/resumed.
|
|
|
|
|
uma_container_->target_rate_updates_.last_paused_or_resumed =
|
|
|
|
|
(bitrate_bps == 0) != was_paused;
|
|
|
|
|
}
|
|
|
|
|
uma_container_->target_rate_updates_.last_ms = now;
|
|
|
|
|
|
2015-02-26 13:15:22 +00:00
|
|
|
stats_.target_media_bitrate_bps = bitrate_bps;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-15 06:41:15 -07:00
|
|
|
void SendStatisticsProxy::UpdateEncoderFallbackStats(
|
2017-11-13 10:16:47 +01:00
|
|
|
const CodecSpecificInfo* codec_info,
|
2018-08-27 15:33:42 +02:00
|
|
|
int pixels,
|
|
|
|
|
int simulcast_index) {
|
|
|
|
|
UpdateFallbackDisabledStats(codec_info, pixels, simulcast_index);
|
2017-11-16 14:04:52 +01:00
|
|
|
|
2017-11-13 10:16:47 +01:00
|
|
|
if (!fallback_max_pixels_ || !uma_container_->fallback_info_.is_possible) {
|
2017-09-15 06:41:15 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-27 15:33:42 +02:00
|
|
|
if (!IsForcedFallbackPossible(codec_info, simulcast_index)) {
|
2017-09-15 06:41:15 -07:00
|
|
|
uma_container_->fallback_info_.is_possible = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FallbackEncoderInfo* fallback_info = &uma_container_->fallback_info_;
|
|
|
|
|
|
|
|
|
|
const int64_t now_ms = clock_->TimeInMilliseconds();
|
|
|
|
|
bool is_active = fallback_info->is_active;
|
2018-10-24 11:32:39 +02:00
|
|
|
if (encoder_changed_) {
|
2017-09-15 06:41:15 -07:00
|
|
|
// Implementation changed.
|
2018-10-24 11:32:39 +02:00
|
|
|
const bool last_was_vp8_software =
|
|
|
|
|
encoder_changed_->previous_encoder_implementation == kVp8SwCodecName;
|
|
|
|
|
is_active = encoder_changed_->new_encoder_implementation == kVp8SwCodecName;
|
|
|
|
|
encoder_changed_.reset();
|
|
|
|
|
if (!is_active && !last_was_vp8_software) {
|
2017-09-15 06:41:15 -07:00
|
|
|
// First or not a VP8 SW change, update stats on next call.
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-11-13 10:16:47 +01:00
|
|
|
if (is_active && (pixels > *fallback_max_pixels_)) {
|
2021-07-27 16:22:11 +02:00
|
|
|
// Pixels should not be above `fallback_max_pixels_`. If above skip to
|
2017-11-13 10:16:47 +01:00
|
|
|
// avoid fallbacks due to failure.
|
|
|
|
|
fallback_info->is_possible = false;
|
|
|
|
|
return;
|
2017-09-15 06:41:15 -07:00
|
|
|
}
|
2017-11-16 14:04:52 +01:00
|
|
|
stats_.has_entered_low_resolution = true;
|
2017-09-15 06:41:15 -07:00
|
|
|
++fallback_info->on_off_events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fallback_info->last_update_ms) {
|
|
|
|
|
int64_t diff_ms = now_ms - *(fallback_info->last_update_ms);
|
2021-07-27 16:22:11 +02:00
|
|
|
// If the time diff since last update is greater than `max_frame_diff_ms`,
|
2017-09-15 06:41:15 -07:00
|
|
|
// video is considered paused/muted and the change is not included.
|
|
|
|
|
if (diff_ms < fallback_info->max_frame_diff_ms) {
|
|
|
|
|
uma_container_->fallback_active_counter_.Add(fallback_info->is_active,
|
|
|
|
|
diff_ms);
|
|
|
|
|
fallback_info->elapsed_ms += diff_ms;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fallback_info->is_active = is_active;
|
|
|
|
|
fallback_info->last_update_ms.emplace(now_ms);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-16 14:04:52 +01:00
|
|
|
void SendStatisticsProxy::UpdateFallbackDisabledStats(
|
|
|
|
|
const CodecSpecificInfo* codec_info,
|
2018-08-27 15:33:42 +02:00
|
|
|
int pixels,
|
|
|
|
|
int simulcast_index) {
|
2017-11-16 14:04:52 +01:00
|
|
|
if (!fallback_max_pixels_disabled_ ||
|
|
|
|
|
!uma_container_->fallback_info_disabled_.is_possible ||
|
|
|
|
|
stats_.has_entered_low_resolution) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-27 15:33:42 +02:00
|
|
|
if (!IsForcedFallbackPossible(codec_info, simulcast_index) ||
|
2018-10-24 11:32:39 +02:00
|
|
|
stats_.encoder_implementation_name == kVp8SwCodecName) {
|
2017-11-16 14:04:52 +01:00
|
|
|
uma_container_->fallback_info_disabled_.is_possible = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pixels <= *fallback_max_pixels_disabled_ ||
|
|
|
|
|
uma_container_->fallback_info_disabled_.min_pixel_limit_reached) {
|
|
|
|
|
stats_.has_entered_low_resolution = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::OnMinPixelLimitReached() {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-11-16 14:04:52 +01:00
|
|
|
uma_container_->fallback_info_disabled_.min_pixel_limit_reached = true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
void SendStatisticsProxy::OnSendEncodedImage(
|
|
|
|
|
const EncodedImage& encoded_image,
|
2016-04-20 05:05:54 -07:00
|
|
|
const CodecSpecificInfo* codec_info) {
|
2018-08-27 15:33:42 +02:00
|
|
|
// Simulcast is used for VP8, H264 and Generic.
|
|
|
|
|
int simulcast_idx =
|
|
|
|
|
(codec_info && (codec_info->codecType == kVideoCodecVP8 ||
|
|
|
|
|
codec_info->codecType == kVideoCodecH264 ||
|
|
|
|
|
codec_info->codecType == kVideoCodecGeneric))
|
|
|
|
|
? encoded_image.SpatialIndex().value_or(0)
|
|
|
|
|
: 0;
|
2016-04-20 05:05:54 -07:00
|
|
|
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-10-24 01:46:43 -07:00
|
|
|
++stats_.frames_encoded;
|
2019-05-20 15:15:38 +02:00
|
|
|
// The current encode frame rate is based on previously encoded frames.
|
|
|
|
|
double encode_frame_rate = encoded_frame_rate_tracker_.ComputeRate();
|
|
|
|
|
// We assume that less than 1 FPS is not a trustworthy estimate - perhaps we
|
|
|
|
|
// just started encoding for the first time or after a pause. Assuming frame
|
|
|
|
|
// rate is at least 1 FPS is conservative to avoid too large increments.
|
|
|
|
|
if (encode_frame_rate < 1.0)
|
|
|
|
|
encode_frame_rate = 1.0;
|
|
|
|
|
double target_frame_size_bytes =
|
|
|
|
|
stats_.target_media_bitrate_bps / (8.0 * encode_frame_rate);
|
2021-08-10 01:22:31 +02:00
|
|
|
// `stats_.target_media_bitrate_bps` is set in
|
2019-05-20 15:15:38 +02:00
|
|
|
// SendStatisticsProxy::OnSetEncoderTargetRate.
|
|
|
|
|
stats_.total_encoded_bytes_target += round(target_frame_size_bytes);
|
2016-04-20 05:05:54 -07:00
|
|
|
if (codec_info) {
|
2018-10-24 11:32:39 +02:00
|
|
|
UpdateEncoderFallbackStats(
|
|
|
|
|
codec_info, encoded_image._encodedWidth * encoded_image._encodedHeight,
|
|
|
|
|
simulcast_idx);
|
2016-04-20 05:05:54 -07:00
|
|
|
}
|
|
|
|
|
|
2018-08-27 15:33:42 +02:00
|
|
|
if (static_cast<size_t>(simulcast_idx) >= rtp_config_.ssrcs.size()) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Encoded image outside simulcast range ("
|
|
|
|
|
<< simulcast_idx << " >= " << rtp_config_.ssrcs.size()
|
|
|
|
|
<< ").";
|
2014-12-01 15:23:21 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2016-09-01 01:17:40 -07:00
|
|
|
uint32_t ssrc = rtp_config_.ssrcs[simulcast_idx];
|
2014-12-01 15:23:21 +00:00
|
|
|
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2014-12-01 15:23:21 +00:00
|
|
|
return;
|
2021-08-10 08:56:36 +02:00
|
|
|
|
|
|
|
|
if (encoded_frame_rate_trackers_.count(ssrc) == 0) {
|
|
|
|
|
encoded_frame_rate_trackers_[ssrc] =
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
std::make_unique<rtc::RateTracker>(kBucketSizeMs, kBucketCount);
|
|
|
|
|
}
|
2021-08-10 08:56:36 +02:00
|
|
|
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
stats->frames_encoded++;
|
|
|
|
|
stats->total_encode_time_ms += encoded_image.timing_.encode_finish_ms -
|
|
|
|
|
encoded_image.timing_.encode_start_ms;
|
2020-11-11 12:42:56 +01:00
|
|
|
// Report resolution of the top spatial layer.
|
|
|
|
|
bool is_top_spatial_layer =
|
|
|
|
|
codec_info == nullptr || codec_info->end_of_picture;
|
2018-09-04 18:34:22 +02:00
|
|
|
|
2020-11-11 12:42:56 +01:00
|
|
|
if (!stats->width || !stats->height || is_top_spatial_layer) {
|
2018-09-04 18:34:22 +02:00
|
|
|
stats->width = encoded_image._encodedWidth;
|
|
|
|
|
stats->height = encoded_image._encodedHeight;
|
|
|
|
|
update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
|
|
|
|
|
}
|
2015-07-22 06:52:00 -07:00
|
|
|
|
2015-12-03 08:10:08 -08:00
|
|
|
uma_container_->key_frame_counter_.Add(encoded_image._frameType ==
|
2019-03-21 15:43:58 +01:00
|
|
|
VideoFrameType::kVideoFrameKey);
|
2015-10-19 00:35:21 -07:00
|
|
|
|
2016-10-31 06:53:47 -07:00
|
|
|
if (encoded_image.qp_ != -1) {
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
if (!stats->qp_sum)
|
|
|
|
|
stats->qp_sum = 0;
|
|
|
|
|
*stats->qp_sum += encoded_image.qp_;
|
2016-10-31 06:53:47 -07:00
|
|
|
|
|
|
|
|
if (codec_info) {
|
|
|
|
|
if (codec_info->codecType == kVideoCodecVP8) {
|
2018-08-27 15:33:42 +02:00
|
|
|
int spatial_idx = (rtp_config_.ssrcs.size() == 1) ? -1 : simulcast_idx;
|
2016-10-31 06:53:47 -07:00
|
|
|
uma_container_->qp_counters_[spatial_idx].vp8.Add(encoded_image.qp_);
|
|
|
|
|
} else if (codec_info->codecType == kVideoCodecVP9) {
|
2018-08-27 15:33:42 +02:00
|
|
|
int spatial_idx = encoded_image.SpatialIndex().value_or(-1);
|
2016-10-31 06:53:47 -07:00
|
|
|
uma_container_->qp_counters_[spatial_idx].vp9.Add(encoded_image.qp_);
|
2016-11-02 09:08:47 -07:00
|
|
|
} else if (codec_info->codecType == kVideoCodecH264) {
|
2018-08-27 15:33:42 +02:00
|
|
|
int spatial_idx = (rtp_config_.ssrcs.size() == 1) ? -1 : simulcast_idx;
|
2016-11-02 09:08:47 -07:00
|
|
|
uma_container_->qp_counters_[spatial_idx].h264.Add(encoded_image.qp_);
|
2016-10-31 06:53:47 -07:00
|
|
|
}
|
2016-04-18 02:58:47 -07:00
|
|
|
}
|
2016-03-31 00:00:19 -07:00
|
|
|
}
|
|
|
|
|
|
2018-02-28 16:35:03 +01:00
|
|
|
// If any of the simulcast streams have a huge frame, it should be counted
|
|
|
|
|
// as a single difficult input frame.
|
|
|
|
|
// https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats-hugeframessent
|
2018-06-05 15:21:32 +02:00
|
|
|
if (encoded_image.timing_.flags & VideoSendTiming::kTriggeredBySize) {
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
++stats->huge_frames_sent;
|
2018-02-28 16:35:03 +01:00
|
|
|
if (!last_outlier_timestamp_ ||
|
|
|
|
|
*last_outlier_timestamp_ < encoded_image.capture_time_ms_) {
|
|
|
|
|
last_outlier_timestamp_.emplace(encoded_image.capture_time_ms_);
|
|
|
|
|
++stats_.huge_frames_sent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 08:50:01 +01:00
|
|
|
media_byte_rate_tracker_.AddSamples(encoded_image.size());
|
2017-12-15 15:54:44 +01:00
|
|
|
|
2019-11-26 17:20:50 +01:00
|
|
|
if (uma_container_->InsertEncodedFrame(encoded_image, simulcast_idx)) {
|
2021-08-03 14:43:01 +02:00
|
|
|
// First frame seen with this timestamp, track overall fps.
|
2017-10-16 12:19:23 +02:00
|
|
|
encoded_frame_rate_tracker_.AddSamples(1);
|
2017-12-15 15:54:44 +01:00
|
|
|
}
|
2021-08-03 14:43:01 +02:00
|
|
|
// is_top_spatial_layer pertains only to SVC, will always be true for
|
|
|
|
|
// simulcast.
|
|
|
|
|
if (is_top_spatial_layer)
|
2021-08-10 08:56:36 +02:00
|
|
|
encoded_frame_rate_trackers_[ssrc]->AddSamples(1);
|
2017-12-15 15:54:44 +01:00
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
absl::optional<int> downscales =
|
2020-06-11 10:45:29 +02:00
|
|
|
adaptation_limitations_.MaskedQualityCounts().resolution_adaptations;
|
2020-04-16 11:34:32 +02:00
|
|
|
stats_.bw_limited_resolution |=
|
|
|
|
|
(downscales.has_value() && downscales.value() > 0);
|
2017-12-15 15:54:44 +01:00
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
if (downscales.has_value()) {
|
|
|
|
|
uma_container_->quality_limited_frame_counter_.Add(downscales.value() > 0);
|
|
|
|
|
if (downscales.value() > 0)
|
|
|
|
|
uma_container_->quality_downscales_counter_.Add(downscales.value());
|
2017-12-15 15:54:44 +01:00
|
|
|
}
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
2018-10-24 11:32:39 +02:00
|
|
|
void SendStatisticsProxy::OnEncoderImplementationChanged(
|
|
|
|
|
const std::string& implementation_name) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2018-10-24 11:32:39 +02:00
|
|
|
encoder_changed_ = EncoderChangeEvent{stats_.encoder_implementation_name,
|
|
|
|
|
implementation_name};
|
|
|
|
|
stats_.encoder_implementation_name = implementation_name;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-24 09:29:58 +02:00
|
|
|
int SendStatisticsProxy::GetInputFrameRate() const {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2018-07-24 09:29:58 +02:00
|
|
|
return round(uma_container_->input_frame_rate_tracker_.ComputeRate());
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-02 15:45:42 +02:00
|
|
|
int SendStatisticsProxy::GetSendFrameRate() const {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-10-16 12:19:23 +02:00
|
|
|
return round(encoded_frame_rate_tracker_.ComputeRate());
|
2016-06-02 15:45:42 +02:00
|
|
|
}
|
|
|
|
|
|
2015-07-22 06:52:00 -07:00
|
|
|
void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-12-03 08:10:08 -08:00
|
|
|
uma_container_->input_frame_rate_tracker_.AddSamples(1);
|
2016-11-29 01:40:35 -08:00
|
|
|
uma_container_->input_fps_counter_.Add(1);
|
2015-12-03 08:10:08 -08:00
|
|
|
uma_container_->input_width_counter_.Add(width);
|
|
|
|
|
uma_container_->input_height_counter_.Add(height);
|
2020-06-11 10:45:29 +02:00
|
|
|
if (adaptation_limitations_.MaskedCpuCounts()
|
|
|
|
|
.resolution_adaptations.has_value()) {
|
2017-04-19 02:01:06 -07:00
|
|
|
uma_container_->cpu_limited_frame_counter_.Add(
|
|
|
|
|
stats_.cpu_limited_resolution);
|
|
|
|
|
}
|
2017-10-19 17:32:17 +02:00
|
|
|
if (encoded_frame_rate_tracker_.TotalSampleCount() == 0) {
|
|
|
|
|
// Set start time now instead of when first key frame is encoded to avoid a
|
|
|
|
|
// too high initial estimate.
|
|
|
|
|
encoded_frame_rate_tracker_.AddSamples(0);
|
|
|
|
|
}
|
2016-11-01 11:45:46 -07:00
|
|
|
}
|
|
|
|
|
|
2018-07-24 09:29:58 +02:00
|
|
|
void SendStatisticsProxy::OnFrameDropped(DropReason reason) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2018-07-24 09:29:58 +02:00
|
|
|
switch (reason) {
|
|
|
|
|
case DropReason::kSource:
|
|
|
|
|
++stats_.frames_dropped_by_capturer;
|
|
|
|
|
break;
|
|
|
|
|
case DropReason::kEncoderQueue:
|
|
|
|
|
++stats_.frames_dropped_by_encoder_queue;
|
|
|
|
|
break;
|
|
|
|
|
case DropReason::kEncoder:
|
|
|
|
|
++stats_.frames_dropped_by_encoder;
|
|
|
|
|
break;
|
|
|
|
|
case DropReason::kMediaOptimization:
|
|
|
|
|
++stats_.frames_dropped_by_rate_limiter;
|
|
|
|
|
break;
|
2020-02-07 14:29:32 +01:00
|
|
|
case DropReason::kCongestionWindow:
|
|
|
|
|
++stats_.frames_dropped_by_congestion_window;
|
|
|
|
|
break;
|
2018-07-24 09:29:58 +02:00
|
|
|
}
|
2015-03-18 09:51:05 +00:00
|
|
|
}
|
|
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
void SendStatisticsProxy::ClearAdaptationStats() {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2020-06-11 10:45:29 +02:00
|
|
|
adaptation_limitations_.set_cpu_counts(VideoAdaptationCounters());
|
|
|
|
|
adaptation_limitations_.set_quality_counts(VideoAdaptationCounters());
|
2020-04-16 11:34:32 +02:00
|
|
|
UpdateAdaptationStats();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::UpdateAdaptationSettings(
|
|
|
|
|
VideoStreamEncoderObserver::AdaptationSettings cpu_settings,
|
|
|
|
|
VideoStreamEncoderObserver::AdaptationSettings quality_settings) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2020-06-11 10:45:29 +02:00
|
|
|
adaptation_limitations_.UpdateMaskingSettings(cpu_settings, quality_settings);
|
|
|
|
|
SetAdaptTimer(adaptation_limitations_.MaskedCpuCounts(),
|
2020-04-16 11:34:32 +02:00
|
|
|
&uma_container_->cpu_adapt_timer_);
|
2020-06-11 10:45:29 +02:00
|
|
|
SetAdaptTimer(adaptation_limitations_.MaskedQualityCounts(),
|
2020-04-16 11:34:32 +02:00
|
|
|
&uma_container_->quality_adapt_timer_);
|
|
|
|
|
UpdateAdaptationStats();
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-24 09:29:58 +02:00
|
|
|
void SendStatisticsProxy::OnAdaptationChanged(
|
2020-04-16 11:36:55 +02:00
|
|
|
VideoAdaptationReason reason,
|
2020-04-16 11:34:32 +02:00
|
|
|
const VideoAdaptationCounters& cpu_counters,
|
|
|
|
|
const VideoAdaptationCounters& quality_counters) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2020-04-16 11:34:32 +02:00
|
|
|
|
2020-06-11 10:45:29 +02:00
|
|
|
MaskedAdaptationCounts receiver =
|
|
|
|
|
adaptation_limitations_.MaskedQualityCounts();
|
|
|
|
|
adaptation_limitations_.set_cpu_counts(cpu_counters);
|
|
|
|
|
adaptation_limitations_.set_quality_counts(quality_counters);
|
2018-07-24 09:29:58 +02:00
|
|
|
switch (reason) {
|
2020-04-16 11:36:55 +02:00
|
|
|
case VideoAdaptationReason::kCpu:
|
2018-07-24 09:29:58 +02:00
|
|
|
++stats_.number_of_cpu_adapt_changes;
|
|
|
|
|
break;
|
2020-04-16 11:36:55 +02:00
|
|
|
case VideoAdaptationReason::kQuality:
|
2020-04-16 11:34:32 +02:00
|
|
|
TryUpdateInitialQualityResolutionAdaptUp(
|
|
|
|
|
receiver.resolution_adaptations,
|
2020-06-11 10:45:29 +02:00
|
|
|
adaptation_limitations_.MaskedQualityCounts().resolution_adaptations);
|
2018-07-24 09:29:58 +02:00
|
|
|
++stats_.number_of_quality_adapt_changes;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-10-09 18:06:58 +02:00
|
|
|
UpdateAdaptationStats();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::UpdateAdaptationStats() {
|
2020-06-11 10:45:29 +02:00
|
|
|
auto cpu_counts = adaptation_limitations_.MaskedCpuCounts();
|
|
|
|
|
auto quality_counts = adaptation_limitations_.MaskedQualityCounts();
|
2020-04-16 11:34:32 +02:00
|
|
|
|
|
|
|
|
bool is_cpu_limited = cpu_counts.resolution_adaptations > 0 ||
|
|
|
|
|
cpu_counts.num_framerate_reductions > 0;
|
|
|
|
|
bool is_bandwidth_limited = quality_counts.resolution_adaptations > 0 ||
|
|
|
|
|
quality_counts.num_framerate_reductions > 0 ||
|
2020-03-10 09:50:26 +00:00
|
|
|
bw_limited_layers_ || internal_encoder_scaler_;
|
2019-05-28 17:42:38 +02:00
|
|
|
if (is_bandwidth_limited) {
|
|
|
|
|
// We may be both CPU limited and bandwidth limited at the same time but
|
|
|
|
|
// there is no way to express this in standardized stats. Heuristically,
|
|
|
|
|
// bandwidth is more likely to be a limiting factor than CPU, and more
|
|
|
|
|
// likely to vary over time, so only when we aren't bandwidth limited do we
|
|
|
|
|
// want to know about our CPU being the bottleneck.
|
|
|
|
|
quality_limitation_reason_tracker_.SetReason(
|
|
|
|
|
QualityLimitationReason::kBandwidth);
|
|
|
|
|
} else if (is_cpu_limited) {
|
|
|
|
|
quality_limitation_reason_tracker_.SetReason(QualityLimitationReason::kCpu);
|
|
|
|
|
} else {
|
|
|
|
|
quality_limitation_reason_tracker_.SetReason(
|
|
|
|
|
QualityLimitationReason::kNone);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
stats_.cpu_limited_resolution = cpu_counts.resolution_adaptations > 0;
|
|
|
|
|
stats_.cpu_limited_framerate = cpu_counts.num_framerate_reductions > 0;
|
|
|
|
|
stats_.bw_limited_resolution = quality_counts.resolution_adaptations > 0;
|
|
|
|
|
stats_.bw_limited_framerate = quality_counts.num_framerate_reductions > 0;
|
2019-10-09 18:06:58 +02:00
|
|
|
// If bitrate allocator has disabled some layers frame-rate or resolution are
|
|
|
|
|
// limited depending on the encoder configuration.
|
|
|
|
|
if (bw_limited_layers_) {
|
|
|
|
|
switch (content_type_) {
|
|
|
|
|
case VideoEncoderConfig::ContentType::kRealtimeVideo: {
|
|
|
|
|
stats_.bw_limited_resolution = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case VideoEncoderConfig::ContentType::kScreen: {
|
|
|
|
|
stats_.bw_limited_framerate = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-10 09:50:26 +00:00
|
|
|
if (internal_encoder_scaler_) {
|
|
|
|
|
stats_.bw_limited_resolution = true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 17:42:38 +02:00
|
|
|
stats_.quality_limitation_reason =
|
|
|
|
|
quality_limitation_reason_tracker_.current_reason();
|
2019-10-09 18:06:58 +02:00
|
|
|
|
2021-08-10 01:22:31 +02:00
|
|
|
// `stats_.quality_limitation_durations_ms` depends on the current time
|
2019-05-28 17:42:38 +02:00
|
|
|
// when it is polled; it is updated in SendStatisticsProxy::GetStats().
|
2017-05-15 23:40:18 -07:00
|
|
|
}
|
|
|
|
|
|
2019-09-09 11:26:45 +02:00
|
|
|
void SendStatisticsProxy::OnBitrateAllocationUpdated(
|
|
|
|
|
const VideoCodec& codec,
|
|
|
|
|
const VideoBitrateAllocation& allocation) {
|
|
|
|
|
int num_spatial_layers = 0;
|
|
|
|
|
for (int i = 0; i < kMaxSpatialLayers; i++) {
|
|
|
|
|
if (codec.spatialLayers[i].active) {
|
|
|
|
|
num_spatial_layers++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int num_simulcast_streams = 0;
|
|
|
|
|
for (int i = 0; i < kMaxSimulcastStreams; i++) {
|
|
|
|
|
if (codec.simulcastStream[i].active) {
|
|
|
|
|
num_simulcast_streams++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::array<bool, kMaxSpatialLayers> spatial_layers;
|
|
|
|
|
for (int i = 0; i < kMaxSpatialLayers; i++) {
|
|
|
|
|
spatial_layers[i] = (allocation.GetSpatialLayerSum(i) > 0);
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-09-09 11:26:45 +02:00
|
|
|
|
2019-10-09 18:06:58 +02:00
|
|
|
bw_limited_layers_ = allocation.is_bw_limited();
|
|
|
|
|
UpdateAdaptationStats();
|
|
|
|
|
|
2019-09-09 11:26:45 +02:00
|
|
|
if (spatial_layers != last_spatial_layer_use_) {
|
|
|
|
|
// If the number of spatial layers has changed, the resolution change is
|
|
|
|
|
// not due to quality limitations, it is because the configuration
|
|
|
|
|
// changed.
|
|
|
|
|
if (last_num_spatial_layers_ == num_spatial_layers &&
|
|
|
|
|
last_num_simulcast_streams_ == num_simulcast_streams) {
|
|
|
|
|
++stats_.quality_limitation_resolution_changes;
|
|
|
|
|
}
|
|
|
|
|
last_spatial_layer_use_ = spatial_layers;
|
|
|
|
|
}
|
|
|
|
|
last_num_spatial_layers_ = num_spatial_layers;
|
|
|
|
|
last_num_simulcast_streams_ = num_simulcast_streams;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-10 09:50:26 +00:00
|
|
|
// Informes observer if an internal encoder scaler has reduced video
|
2021-07-27 16:22:11 +02:00
|
|
|
// resolution or not. `is_scaled` is a flag indicating if the video is scaled
|
2020-03-10 09:50:26 +00:00
|
|
|
// down.
|
|
|
|
|
void SendStatisticsProxy::OnEncoderInternalScalerUpdate(bool is_scaled) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2020-03-10 09:50:26 +00:00
|
|
|
internal_encoder_scaler_ = is_scaled;
|
|
|
|
|
UpdateAdaptationStats();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-08 08:49:53 +01:00
|
|
|
// TODO(asapersson): Include fps changes.
|
|
|
|
|
void SendStatisticsProxy::OnInitialQualityResolutionAdaptDown() {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2018-01-08 08:49:53 +01:00
|
|
|
++uma_container_->initial_quality_changes_.down;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::TryUpdateInitialQualityResolutionAdaptUp(
|
2020-04-16 11:34:32 +02:00
|
|
|
absl::optional<int> old_quality_downscales,
|
|
|
|
|
absl::optional<int> updated_quality_downscales) {
|
2018-01-08 08:49:53 +01:00
|
|
|
if (uma_container_->initial_quality_changes_.down == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
if (old_quality_downscales.has_value() &&
|
|
|
|
|
old_quality_downscales.value() > 0 &&
|
|
|
|
|
updated_quality_downscales.value_or(-1) <
|
|
|
|
|
old_quality_downscales.value()) {
|
2018-01-08 08:49:53 +01:00
|
|
|
// Adapting up in quality.
|
|
|
|
|
if (uma_container_->initial_quality_changes_.down >
|
|
|
|
|
uma_container_->initial_quality_changes_.up) {
|
|
|
|
|
++uma_container_->initial_quality_changes_.up;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
void SendStatisticsProxy::SetAdaptTimer(const MaskedAdaptationCounts& counts,
|
2018-07-24 09:29:58 +02:00
|
|
|
StatsTimer* timer) {
|
2020-04-16 11:34:32 +02:00
|
|
|
if (counts.resolution_adaptations || counts.num_framerate_reductions) {
|
2017-05-15 23:40:18 -07:00
|
|
|
// Adaptation enabled.
|
|
|
|
|
if (!stats_.suspended)
|
|
|
|
|
timer->Start(clock_->TimeInMilliseconds());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
timer->Stop(clock_->TimeInMilliseconds());
|
2016-11-29 01:44:11 -08:00
|
|
|
}
|
|
|
|
|
|
2015-02-19 12:47:00 +00:00
|
|
|
void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
|
|
|
|
uint32_t ssrc,
|
|
|
|
|
const RtcpPacketTypeCounter& packet_counter) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2015-02-19 12:47:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
stats->rtcp_packet_type_counts = packet_counter;
|
2016-02-24 07:55:00 -08:00
|
|
|
if (uma_container_->first_rtcp_stats_time_ms_ == -1)
|
|
|
|
|
uma_container_->first_rtcp_stats_time_ms_ = clock_->TimeInMilliseconds();
|
2015-02-19 12:47:00 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 10:44:24 +02:00
|
|
|
void SendStatisticsProxy::OnReportBlockDataUpdated(
|
|
|
|
|
ReportBlockData report_block_data) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-05-27 10:44:24 +02:00
|
|
|
VideoSendStream::StreamStats* stats =
|
|
|
|
|
GetStatsEntry(report_block_data.report_block().source_ssrc);
|
|
|
|
|
if (!stats)
|
|
|
|
|
return;
|
2021-05-14 15:39:23 +02:00
|
|
|
const RTCPReportBlock& report_block = report_block_data.report_block();
|
2021-05-18 12:48:12 +02:00
|
|
|
uma_container_->report_block_stats_.Store(
|
|
|
|
|
/*ssrc=*/report_block.source_ssrc,
|
|
|
|
|
/*packets_lost=*/report_block.packets_lost,
|
|
|
|
|
/*extended_highest_sequence_number=*/
|
|
|
|
|
report_block.extended_highest_sequence_number);
|
2021-05-14 15:39:23 +02:00
|
|
|
|
2019-05-27 10:44:24 +02:00
|
|
|
stats->report_block_data = std::move(report_block_data);
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
void SendStatisticsProxy::DataCountersUpdated(
|
|
|
|
|
const StreamDataCounters& counters,
|
|
|
|
|
uint32_t ssrc) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2017-02-06 05:18:35 -08:00
|
|
|
RTC_DCHECK(stats) << "DataCountersUpdated reported for unknown ssrc " << ssrc;
|
2014-01-07 09:54:34 +00:00
|
|
|
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
if (stats->type == VideoSendStream::StreamStats::StreamType::kFlexfec) {
|
2016-11-25 03:52:46 -08:00
|
|
|
// The same counters are reported for both the media ssrc and flexfec ssrc.
|
|
|
|
|
// Bitrate stats are summed for all SSRCs. Use fec stats from media update.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
stats->rtp_stats = counters;
|
2017-04-04 23:40:50 -07:00
|
|
|
if (uma_container_->first_rtp_stats_time_ms_ == -1) {
|
|
|
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
|
|
|
uma_container_->first_rtp_stats_time_ms_ = now_ms;
|
2017-05-15 23:40:18 -07:00
|
|
|
uma_container_->cpu_adapt_timer_.Restart(now_ms);
|
|
|
|
|
uma_container_->quality_adapt_timer_.Restart(now_ms);
|
2017-04-04 23:40:50 -07:00
|
|
|
}
|
2017-02-06 05:18:35 -08:00
|
|
|
|
|
|
|
|
uma_container_->total_byte_counter_.Set(counters.transmitted.TotalBytes(),
|
|
|
|
|
ssrc);
|
|
|
|
|
uma_container_->padding_byte_counter_.Set(counters.transmitted.padding_bytes,
|
|
|
|
|
ssrc);
|
|
|
|
|
uma_container_->retransmit_byte_counter_.Set(
|
|
|
|
|
counters.retransmitted.TotalBytes(), ssrc);
|
|
|
|
|
uma_container_->fec_byte_counter_.Set(counters.fec.TotalBytes(), ssrc);
|
[Stats] Explicit RTP-RTX and RTP-FEC mappings. Unblocks simulcast stats.
--- Background ---
The webrtc::VideoSendStream::StreamStats are converted into
VideoSenderInfo objects which turn into "outbound-rtp" stats objects in
getStats() (or "ssrc" objects in legacy getStats()).
StreamStats are created for each type of substream: RTP media streams,
RTX streams and FlexFEC streams - each with individual packet counters.
The RTX stream is responsible for retransmissions of a referenced media
stream and the FlexFEC stream is responsible for FEC of a referenced
media stream. RTX/FEC streams do not show up as separate objects in
getStats(). Only the media streams become "outbound-rtp" objects, but
their packet and byte counters have to include the RTX and FEC counters.
--- Overview of this CL ---
This CL adds MergeInfoAboutOutboundRtpSubstreams(). It takes
StreamStats of all kinds as input, and outputs media-only StreamStats
- incorporating the RTX and FEC counters into the relevant media
StreamStats.
The merged StreamStats objects is a smaller set of objects than the
non-merged counterparts, but when aggregating all packet counters
together we end up with exact same packet and count as before.
Because WebRtcVideoSendStream::GetVideoSenderInfo() currently aggregates
the StreamStats into a single VideoSenderInfo (single "outbound-rtp"),
this CL should not have any observable side-effects. Prior to this CL:
aggregate StreamStats. After this CL: merge StreamStats and then
aggregate them.
However, when simulcast stats are implemented (WIP CL:
https://webrtc-review.googlesource.com/c/src/+/168120) each RTP media
stream should turn into an individual "outbound-rtp" object. We will
then no longer aggregate all StreamStats into a single "info". This CL
unblocks simulcast stats by providing StreamStats objects that could be
turned into individual VideoSenderInfos.
--- The Changes ---
1. Methods added to RtpConfig to be able to easily tell the relationship
between RTP, RTX and FEC ssrcs.
2. StreamStats gets a StreamType (kMedia, kRtx or kFlexfec) that
replaces the booleans (is_rtx, is_flexfec).
3. "referenced_media_ssrc" is added to StreamStats, making it possible
to tell which kRtx/kFlexFec stream stats need to be merged with which
kMedia StreamStats.
4. MergeInfoAboutOutboundRtpSubstreams() added and used.
Bug: webrtc:11439
Change-Id: Iaf9002041169a054ddfd32c7ea06bd1dc36c6bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170826
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30869}
2020-03-24 13:30:50 +01:00
|
|
|
switch (stats->type) {
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kMedia:
|
|
|
|
|
uma_container_->media_byte_counter_.Set(counters.MediaPayloadBytes(),
|
|
|
|
|
ssrc);
|
|
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kRtx:
|
|
|
|
|
uma_container_->rtx_byte_counter_.Set(counters.transmitted.TotalBytes(),
|
|
|
|
|
ssrc);
|
|
|
|
|
break;
|
|
|
|
|
case VideoSendStream::StreamStats::StreamType::kFlexfec:
|
|
|
|
|
break;
|
2017-02-06 05:18:35 -08:00
|
|
|
}
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2016-07-13 09:11:28 -07:00
|
|
|
void SendStatisticsProxy::Notify(uint32_t total_bitrate_bps,
|
|
|
|
|
uint32_t retransmit_bitrate_bps,
|
2014-01-07 09:54:34 +00:00
|
|
|
uint32_t ssrc) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2014-01-07 09:54:34 +00:00
|
|
|
return;
|
|
|
|
|
|
2016-07-13 09:11:28 -07:00
|
|
|
stats->total_bitrate_bps = total_bitrate_bps;
|
|
|
|
|
stats->retransmit_bitrate_bps = retransmit_bitrate_bps;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-18 13:50:16 +00:00
|
|
|
void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
|
|
|
|
uint32_t ssrc) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2014-01-07 09:54:34 +00:00
|
|
|
return;
|
|
|
|
|
|
2014-12-18 13:50:16 +00:00
|
|
|
stats->frame_counts = frame_counts;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-11 13:44:02 +00:00
|
|
|
void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
|
|
|
|
int max_delay_ms,
|
2019-05-16 18:38:20 +02:00
|
|
|
uint64_t total_delay_ms,
|
2014-07-11 13:44:02 +00:00
|
|
|
uint32_t ssrc) {
|
2020-07-08 13:13:32 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2016-04-04 17:56:10 +02:00
|
|
|
if (!stats)
|
2014-07-11 13:44:02 +00:00
|
|
|
return;
|
|
|
|
|
stats->avg_delay_ms = avg_delay_ms;
|
|
|
|
|
stats->max_delay_ms = max_delay_ms;
|
2019-05-16 18:38:20 +02:00
|
|
|
stats->total_packet_send_delay_ms = total_delay_ms;
|
2015-11-04 00:59:03 -08:00
|
|
|
|
2015-12-03 08:10:08 -08:00
|
|
|
uma_container_->delay_counter_.Add(avg_delay_ms);
|
|
|
|
|
uma_container_->max_delay_counter_.Add(max_delay_ms);
|
2014-07-11 13:44:02 +00:00
|
|
|
}
|
|
|
|
|
|
2017-04-04 23:40:50 -07:00
|
|
|
void SendStatisticsProxy::StatsTimer::Start(int64_t now_ms) {
|
|
|
|
|
if (start_ms == -1)
|
|
|
|
|
start_ms = now_ms;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::StatsTimer::Stop(int64_t now_ms) {
|
|
|
|
|
if (start_ms != -1) {
|
|
|
|
|
total_ms += now_ms - start_ms;
|
|
|
|
|
start_ms = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::StatsTimer::Restart(int64_t now_ms) {
|
|
|
|
|
total_ms = 0;
|
|
|
|
|
if (start_ms != -1)
|
|
|
|
|
start_ms = now_ms;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-22 06:52:00 -07:00
|
|
|
void SendStatisticsProxy::SampleCounter::Add(int sample) {
|
|
|
|
|
sum += sample;
|
|
|
|
|
++num_samples;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-19 06:50:53 -08:00
|
|
|
int SendStatisticsProxy::SampleCounter::Avg(
|
|
|
|
|
int64_t min_required_samples) const {
|
2015-07-22 06:52:00 -07:00
|
|
|
if (num_samples < min_required_samples || num_samples == 0)
|
|
|
|
|
return -1;
|
2016-12-19 06:50:53 -08:00
|
|
|
return static_cast<int>((sum + (num_samples / 2)) / num_samples);
|
2015-07-22 06:52:00 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-05 02:36:17 -07:00
|
|
|
void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {
|
|
|
|
|
if (sample)
|
|
|
|
|
++sum;
|
|
|
|
|
++num_samples;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-19 06:50:53 -08:00
|
|
|
void SendStatisticsProxy::BoolSampleCounter::Add(bool sample, int64_t count) {
|
|
|
|
|
if (sample)
|
|
|
|
|
sum += count;
|
|
|
|
|
num_samples += count;
|
|
|
|
|
}
|
2015-10-05 02:36:17 -07:00
|
|
|
int SendStatisticsProxy::BoolSampleCounter::Percent(
|
2016-12-19 06:50:53 -08:00
|
|
|
int64_t min_required_samples) const {
|
2015-10-05 02:36:17 -07:00
|
|
|
return Fraction(min_required_samples, 100.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SendStatisticsProxy::BoolSampleCounter::Permille(
|
2016-12-19 06:50:53 -08:00
|
|
|
int64_t min_required_samples) const {
|
2015-10-05 02:36:17 -07:00
|
|
|
return Fraction(min_required_samples, 1000.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SendStatisticsProxy::BoolSampleCounter::Fraction(
|
2016-12-19 06:50:53 -08:00
|
|
|
int64_t min_required_samples,
|
|
|
|
|
float multiplier) const {
|
2015-10-05 02:36:17 -07:00
|
|
|
if (num_samples < min_required_samples || num_samples == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
|
|
|
|
|
}
|
2020-04-16 11:34:32 +02:00
|
|
|
|
|
|
|
|
SendStatisticsProxy::MaskedAdaptationCounts
|
|
|
|
|
SendStatisticsProxy::Adaptations::MaskedCpuCounts() const {
|
|
|
|
|
return Mask(cpu_counts_, cpu_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendStatisticsProxy::MaskedAdaptationCounts
|
|
|
|
|
SendStatisticsProxy::Adaptations::MaskedQualityCounts() const {
|
|
|
|
|
return Mask(quality_counts_, quality_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::Adaptations::set_cpu_counts(
|
|
|
|
|
const VideoAdaptationCounters& cpu_counts) {
|
|
|
|
|
cpu_counts_ = cpu_counts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::Adaptations::set_quality_counts(
|
|
|
|
|
const VideoAdaptationCounters& quality_counts) {
|
|
|
|
|
quality_counts_ = quality_counts;
|
|
|
|
|
}
|
2020-06-11 10:45:29 +02:00
|
|
|
|
|
|
|
|
VideoAdaptationCounters SendStatisticsProxy::Adaptations::cpu_counts() const {
|
|
|
|
|
return cpu_counts_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VideoAdaptationCounters SendStatisticsProxy::Adaptations::quality_counts()
|
|
|
|
|
const {
|
|
|
|
|
return quality_counts_;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 11:34:32 +02:00
|
|
|
void SendStatisticsProxy::Adaptations::UpdateMaskingSettings(
|
|
|
|
|
VideoStreamEncoderObserver::AdaptationSettings cpu_settings,
|
|
|
|
|
VideoStreamEncoderObserver::AdaptationSettings quality_settings) {
|
|
|
|
|
cpu_settings_ = std::move(cpu_settings);
|
|
|
|
|
quality_settings_ = std::move(quality_settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendStatisticsProxy::MaskedAdaptationCounts
|
|
|
|
|
SendStatisticsProxy::Adaptations::Mask(
|
|
|
|
|
const VideoAdaptationCounters& counters,
|
|
|
|
|
const VideoStreamEncoderObserver::AdaptationSettings& settings) const {
|
|
|
|
|
MaskedAdaptationCounts masked_counts;
|
|
|
|
|
if (settings.resolution_scaling_enabled) {
|
|
|
|
|
masked_counts.resolution_adaptations = counters.resolution_adaptations;
|
|
|
|
|
}
|
|
|
|
|
if (settings.framerate_scaling_enabled) {
|
|
|
|
|
masked_counts.num_framerate_reductions = counters.fps_adaptations;
|
|
|
|
|
}
|
|
|
|
|
return masked_counts;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
} // namespace webrtc
|