Add histogram for percentage of sent frames that are limited in resolution due to bandwidth:

- "WebRTC.Video.BandwidthLimitedResolutionInPercent"

If the frame is bandwidth limited, the average number of disabled resolutions is logged:
- "WebRTC.Video.BandwidthLimitedResolutionsDisabled"

BUG=

Review URL: https://codereview.webrtc.org/1311533012

Cr-Commit-Position: refs/heads/master@{#10333}
This commit is contained in:
asapersson 2015-10-19 23:32:41 -07:00 committed by Commit bot
parent 42b1478639
commit da535c4055
4 changed files with 48 additions and 4 deletions

View File

@ -131,6 +131,15 @@ bool ValidSimulcastResolutions(const VideoCodec& codec, int num_streams) {
}
return true;
}
int NumStreamsDisabled(std::vector<bool>& streams) {
int num_disabled = 0;
for (bool stream : streams) {
if (!stream)
++num_disabled;
}
return num_disabled;
}
} // namespace
const float kTl1MaxTimeToDropFrames = 20.0f;
@ -951,6 +960,9 @@ void VP8EncoderImpl::PopulateCodecSpecific(
int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image,
bool only_predicting_from_key_frame) {
int bw_resolutions_disabled =
(encoders_.size() > 1) ? NumStreamsDisabled(send_stream_) : -1;
int stream_idx = static_cast<int>(encoders_.size()) - 1;
int result = WEBRTC_VIDEO_CODEC_OK;
for (size_t encoder_idx = 0; encoder_idx < encoders_.size();
@ -1018,6 +1030,9 @@ int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image,
encoded_images_[encoder_idx]
.adapt_reason_.quality_resolution_downscales =
quality_scaler_enabled_ ? quality_scaler_.downscale_shift() : -1;
// Report once per frame (lowest stream always sent).
encoded_images_[encoder_idx].adapt_reason_.bw_resolutions_disabled =
(stream_idx == 0) ? bw_resolutions_disabled : -1;
encoded_complete_callback_->Encoded(encoded_images_[encoder_idx],
&codec_specific, &frag_info);
} else if (codec_.mode == kScreensharing) {

View File

@ -81,6 +81,16 @@ void SendStatisticsProxy::UpdateHistograms() {
RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.QualityLimitedResolutionDownscales",
downscales, 20);
}
int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
if (bw_limited != -1) {
RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.BandwidthLimitedResolutionInPercent",
bw_limited);
}
int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
if (num_disabled != -1) {
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Video.BandwidthLimitedResolutionsDisabled", num_disabled, 10);
}
}
void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
@ -190,6 +200,14 @@ void SendStatisticsProxy::OnSendEncodedImage(
encoded_image.adapt_reason_.quality_resolution_downscales);
}
}
if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
bw_limited_frame_counter_.Add(bw_limited);
if (bw_limited) {
bw_resolutions_disabled_counter_.Add(
encoded_image.adapt_reason_.bw_resolutions_disabled);
}
}
// TODO(asapersson): This is incorrect if simulcast layers are encoded on
// different threads and there is no guarantee that one frame of all layers
@ -299,7 +317,7 @@ void SendStatisticsProxy::SampleCounter::Add(int sample) {
int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
if (num_samples < min_required_samples || num_samples == 0)
return -1;
return sum / num_samples;
return (sum + (num_samples / 2)) / num_samples;
}
void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {

View File

@ -87,8 +87,10 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
uint32_t ssrc) override;
private:
struct SampleCounter {
class SampleCounter {
public:
SampleCounter() : sum(0), num_samples(0) {}
~SampleCounter() {}
void Add(int sample);
int Avg(int min_required_samples) const;
@ -96,8 +98,10 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
int sum;
int num_samples;
};
struct BoolSampleCounter {
class BoolSampleCounter {
public:
BoolSampleCounter() : sum(0), num_samples(0) {}
~BoolSampleCounter() {}
void Add(bool sample);
int Percent(int min_required_samples) const;
int Permille(int min_required_samples) const;
@ -136,6 +140,8 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
BoolSampleCounter key_frame_counter_ GUARDED_BY(crit_);
BoolSampleCounter quality_limited_frame_counter_ GUARDED_BY(crit_);
SampleCounter quality_downscales_counter_ GUARDED_BY(crit_);
BoolSampleCounter bw_limited_frame_counter_ GUARDED_BY(crit_);
SampleCounter bw_resolutions_disabled_counter_ GUARDED_BY(crit_);
};
} // namespace webrtc

View File

@ -167,6 +167,7 @@ class VideoFrame {
VideoRotation rotation_;
};
// TODO(pbos): Rename EncodedFrame and reformat this class' members.
class EncodedImage {
public:
@ -176,11 +177,15 @@ class EncodedImage {
struct AdaptReason {
AdaptReason()
: quality_resolution_downscales(-1) {}
: quality_resolution_downscales(-1),
bw_resolutions_disabled(-1) {}
int quality_resolution_downscales; // Number of times this frame is down
// scaled in resolution due to quality.
// Or -1 if information is not provided.
int bw_resolutions_disabled; // Number of resolutions that are not sent
// due to bandwidth for this frame.
// Or -1 if information is not provided.
};
uint32_t _encodedWidth = 0;
uint32_t _encodedHeight = 0;