Add histogram stats for average QP per frame for VP8 (for sent video streams):
- "WebRTC.Video.Encoded.Qp.Vp8" - "WebRTC.Video.Encoded.Qp.Vp8.S0" - "WebRTC.Video.Encoded.Qp.Vp8.S1" - "WebRTC.Video.Encoded.Qp.Vp8.S2" BUG= Review URL: https://codereview.webrtc.org/1523293002 Cr-Commit-Position: refs/heads/master@{#12174}
This commit is contained in:
parent
ff97631e3c
commit
118ef00594
@ -1040,6 +1040,10 @@ int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image,
|
||||
// Report once per frame (lowest stream always sent).
|
||||
encoded_images_[encoder_idx].adapt_reason_.bw_resolutions_disabled =
|
||||
(stream_idx == 0) ? bw_resolutions_disabled : -1;
|
||||
int qp_128 = -1;
|
||||
vpx_codec_control(&encoders_[encoder_idx], VP8E_GET_LAST_QUANTIZER,
|
||||
&qp_128);
|
||||
encoded_images_[encoder_idx].qp_ = qp_128;
|
||||
encoded_complete_callback_->Encoded(encoded_images_[encoder_idx],
|
||||
&codec_specific, &frag_info);
|
||||
} else if (codec_.mode == kScreensharing) {
|
||||
|
||||
@ -193,6 +193,29 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
kIndex, uma_prefix_ + "SendSideDelayMaxInMs", max_delay_ms);
|
||||
}
|
||||
|
||||
for (const auto& it : qp_counters_) {
|
||||
int qp = it.second.vp8.Avg(kMinRequiredSamples);
|
||||
if (qp != -1) {
|
||||
int spatial_idx = it.first;
|
||||
if (spatial_idx == -1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8",
|
||||
qp);
|
||||
} else if (spatial_idx == 0) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S0", qp);
|
||||
} else if (spatial_idx == 1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S1", qp);
|
||||
} else if (spatial_idx == 2) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S2", qp);
|
||||
} else {
|
||||
LOG(LS_WARNING) << "QP stats not recorded for VP8 spatial idx "
|
||||
<< spatial_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first_rtcp_stats_time_ms_ != -1) {
|
||||
int64_t elapsed_sec =
|
||||
(clock_->TimeInMilliseconds() - first_rtcp_stats_time_ms_) / 1000;
|
||||
@ -427,6 +450,13 @@ void SendStatisticsProxy::OnSendEncodedImage(
|
||||
}
|
||||
}
|
||||
|
||||
if (encoded_image.qp_ != -1 && rtp_video_header != nullptr &&
|
||||
rtp_video_header->codec == kRtpVideoVp8) {
|
||||
int spatial_idx =
|
||||
(config_.rtp.ssrcs.size() == 1) ? -1 : static_cast<int>(simulcast_idx);
|
||||
uma_container_->qp_counters_[spatial_idx].vp8.Add(encoded_image.qp_);
|
||||
}
|
||||
|
||||
// TODO(asapersson): This is incorrect if simulcast layers are encoded on
|
||||
// different threads and there is no guarantee that one frame of all layers
|
||||
// are encoded before the next start.
|
||||
|
||||
@ -125,6 +125,9 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
int64_t resolution_update_ms;
|
||||
int64_t bitrate_update_ms;
|
||||
};
|
||||
struct QpCounters {
|
||||
SampleCounter vp8;
|
||||
};
|
||||
void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
@ -172,6 +175,8 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
int64_t first_rtp_stats_time_ms_;
|
||||
ReportBlockStats report_block_stats_;
|
||||
const VideoSendStream::Stats start_stats_;
|
||||
std::map<int, QpCounters>
|
||||
qp_counters_; // QP counters mapped by spatial idx.
|
||||
};
|
||||
|
||||
std::unique_ptr<UmaSamplesContainer> uma_container_ GUARDED_BY(crit_);
|
||||
|
||||
@ -327,6 +327,57 @@ TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputWidthInPixels"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
|
||||
test::ClearHistograms();
|
||||
const int kMinRequiredSamples = 200;
|
||||
const int kQpIdx0 = 21;
|
||||
const int kQpIdx1 = 39;
|
||||
EncodedImage encoded_image;
|
||||
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.codec = kRtpVideoVp8;
|
||||
|
||||
for (int i = 0; i < kMinRequiredSamples; ++i) {
|
||||
rtp_video_header.simulcastIdx = 0;
|
||||
encoded_image.qp_ = kQpIdx0;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
rtp_video_header.simulcastIdx = 1;
|
||||
encoded_image.qp_ = kQpIdx1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
|
||||
EXPECT_EQ(kQpIdx0,
|
||||
test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp8.S0"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp8.S1"));
|
||||
EXPECT_EQ(kQpIdx1,
|
||||
test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp8.S1"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
|
||||
VideoSendStream::Config config(nullptr);
|
||||
config.rtp.ssrcs.push_back(kFirstSsrc);
|
||||
statistics_proxy_.reset(new SendStatisticsProxy(
|
||||
&fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
|
||||
|
||||
test::ClearHistograms();
|
||||
const int kMinRequiredSamples = 200;
|
||||
const int kQpIdx0 = 21;
|
||||
EncodedImage encoded_image;
|
||||
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.codec = kRtpVideoVp8;
|
||||
|
||||
for (int i = 0; i < kMinRequiredSamples; ++i) {
|
||||
rtp_video_header.simulcastIdx = 0;
|
||||
encoded_image.qp_ = kQpIdx0;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp8"));
|
||||
EXPECT_EQ(kQpIdx0, test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp8"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, NoSubstreams) {
|
||||
uint32_t excluded_ssrc =
|
||||
std::max(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user