Add histogram stats for average QP per frame for VP9 (for sent video streams):
- "WebRTC.Video.Encoded.Qp.Vp9" - "WebRTC.Video.Encoded.Qp.Vp9.S0" - "WebRTC.Video.Encoded.Qp.Vp9.S1" - "WebRTC.Video.Encoded.Qp.Vp9.S2" BUG= Review URL: https://codereview.webrtc.org/1870043002 Cr-Commit-Position: refs/heads/master@{#12402}
This commit is contained in:
parent
8056acc6f5
commit
5265fedffe
@ -694,6 +694,9 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
|
||||
encoded_image_.capture_time_ms_ = input_image_->render_time_ms();
|
||||
encoded_image_._encodedHeight = raw_->d_h;
|
||||
encoded_image_._encodedWidth = raw_->d_w;
|
||||
int qp = -1;
|
||||
vpx_codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp);
|
||||
encoded_image_.qp_ = qp;
|
||||
encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
|
||||
&frag_info);
|
||||
}
|
||||
|
||||
@ -69,6 +69,9 @@
|
||||
#define RTC_HISTOGRAM_COUNTS_200(name, sample) \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50)
|
||||
|
||||
#define RTC_HISTOGRAM_COUNTS_500(name, sample) \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50)
|
||||
|
||||
#define RTC_HISTOGRAM_COUNTS_1000(name, sample) \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50)
|
||||
|
||||
@ -89,6 +92,9 @@
|
||||
#define RTC_LOGGED_HISTOGRAM_COUNTS_200(name, sample) \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 200, 50)
|
||||
|
||||
#define RTC_LOGGED_HISTOGRAM_COUNTS_500(name, sample) \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 500, 50)
|
||||
|
||||
#define RTC_LOGGED_HISTOGRAM_COUNTS_1000(name, sample) \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50)
|
||||
|
||||
@ -175,6 +181,10 @@
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50))
|
||||
|
||||
#define RTC_HISTOGRAMS_COUNTS_500(index, name, sample) \
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50))
|
||||
|
||||
#define RTC_HISTOGRAMS_COUNTS_1000(index, name, sample) \
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50))
|
||||
@ -204,6 +214,10 @@
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 200, 50))
|
||||
|
||||
#define RTC_LOGGED_HISTOGRAMS_COUNTS_500(index, name, sample) \
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 500, 50))
|
||||
|
||||
#define RTC_LOGGED_HISTOGRAMS_COUNTS_1000(index, name, sample) \
|
||||
RTC_HISTOGRAMS_COMMON(index, name, sample, \
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50))
|
||||
|
||||
@ -194,26 +194,46 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
}
|
||||
|
||||
for (const auto& it : qp_counters_) {
|
||||
int qp = it.second.vp8.Avg(kMinRequiredSamples);
|
||||
if (qp != -1) {
|
||||
int qp_vp8 = it.second.vp8.Avg(kMinRequiredSamples);
|
||||
if (qp_vp8 != -1) {
|
||||
int spatial_idx = it.first;
|
||||
if (spatial_idx == -1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex, uma_prefix_ + "Encoded.Qp.Vp8",
|
||||
qp);
|
||||
qp_vp8);
|
||||
} else if (spatial_idx == 0) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S0", qp);
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S0", qp_vp8);
|
||||
} else if (spatial_idx == 1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S1", qp);
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S1", qp_vp8);
|
||||
} else if (spatial_idx == 2) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(kIndex,
|
||||
uma_prefix_ + "Encoded.Qp.Vp8.S2", qp);
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_200(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp8.S2", qp_vp8);
|
||||
} else {
|
||||
LOG(LS_WARNING) << "QP stats not recorded for VP8 spatial idx "
|
||||
<< spatial_idx;
|
||||
}
|
||||
}
|
||||
int qp_vp9 = it.second.vp9.Avg(kMinRequiredSamples);
|
||||
if (qp_vp9 != -1) {
|
||||
int spatial_idx = it.first;
|
||||
if (spatial_idx == -1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_500(kIndex, uma_prefix_ + "Encoded.Qp.Vp9",
|
||||
qp_vp9);
|
||||
} else if (spatial_idx == 0) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_500(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S0", qp_vp9);
|
||||
} else if (spatial_idx == 1) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_500(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S1", qp_vp9);
|
||||
} else if (spatial_idx == 2) {
|
||||
RTC_LOGGED_HISTOGRAMS_COUNTS_500(
|
||||
kIndex, uma_prefix_ + "Encoded.Qp.Vp9.S2", qp_vp9);
|
||||
} else {
|
||||
LOG(LS_WARNING) << "QP stats not recorded for VP9 spatial layer "
|
||||
<< spatial_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first_rtcp_stats_time_ms_ != -1) {
|
||||
@ -449,11 +469,19 @@ void SendStatisticsProxy::OnSendEncodedImage(
|
||||
}
|
||||
}
|
||||
|
||||
if (encoded_image.qp_ != -1 && rtp_video_header &&
|
||||
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_);
|
||||
if (encoded_image.qp_ != -1 && rtp_video_header) {
|
||||
if (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_);
|
||||
} else if (rtp_video_header->codec == kRtpVideoVp9) {
|
||||
int spatial_idx =
|
||||
(rtp_video_header->codecHeader.VP9.num_spatial_layers == 1)
|
||||
? -1
|
||||
: rtp_video_header->codecHeader.VP9.spatial_idx;
|
||||
uma_container_->qp_counters_[spatial_idx].vp9.Add(encoded_image.qp_);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(asapersson): This is incorrect if simulcast layers are encoded on
|
||||
|
||||
@ -126,7 +126,8 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
int64_t bitrate_update_ms;
|
||||
};
|
||||
struct QpCounters {
|
||||
SampleCounter vp8;
|
||||
SampleCounter vp8; // QP range: 0-127
|
||||
SampleCounter vp9; // QP range: 0-255
|
||||
};
|
||||
void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
|
||||
|
||||
@ -21,11 +21,16 @@
|
||||
#include "webrtc/test/histogram.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
const uint32_t kFirstSsrc = 17;
|
||||
const uint32_t kSecondSsrc = 42;
|
||||
const uint32_t kFirstRtxSsrc = 18;
|
||||
const uint32_t kSecondRtxSsrc = 43;
|
||||
|
||||
static const uint32_t kFirstSsrc = 17;
|
||||
static const uint32_t kSecondSsrc = 42;
|
||||
static const uint32_t kFirstRtxSsrc = 18;
|
||||
static const uint32_t kSecondRtxSsrc = 43;
|
||||
const int kMinRequiredSamples = 200;
|
||||
const int kQpIdx0 = 21;
|
||||
const int kQpIdx1 = 39;
|
||||
} // namespace
|
||||
|
||||
class SendStatisticsProxyTest : public ::testing::Test {
|
||||
public:
|
||||
@ -310,7 +315,6 @@ TEST_F(SendStatisticsProxyTest, OnEncodedFrameTimeMeasured) {
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
|
||||
test::ClearHistograms();
|
||||
const int kMinRequiredSamples = 200;
|
||||
const int kWidth = 640;
|
||||
const int kHeight = 480;
|
||||
|
||||
@ -329,11 +333,7 @@ TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
|
||||
|
||||
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;
|
||||
|
||||
@ -361,10 +361,7 @@ TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
|
||||
&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;
|
||||
|
||||
@ -378,6 +375,54 @@ TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
|
||||
EXPECT_EQ(kQpIdx0, test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp8"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
|
||||
test::ClearHistograms();
|
||||
EncodedImage encoded_image;
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.simulcastIdx = 0;
|
||||
rtp_video_header.codec = kRtpVideoVp9;
|
||||
rtp_video_header.codecHeader.VP9.num_spatial_layers = 2;
|
||||
|
||||
for (int i = 0; i < kMinRequiredSamples; ++i) {
|
||||
encoded_image.qp_ = kQpIdx0;
|
||||
rtp_video_header.codecHeader.VP9.spatial_idx = 0;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
encoded_image.qp_ = kQpIdx1;
|
||||
rtp_video_header.codecHeader.VP9.spatial_idx = 1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
|
||||
EXPECT_EQ(kQpIdx0,
|
||||
test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp9.S0"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp9.S1"));
|
||||
EXPECT_EQ(kQpIdx1,
|
||||
test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp9.S1"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
|
||||
VideoSendStream::Config config(nullptr);
|
||||
config.rtp.ssrcs.push_back(kFirstSsrc);
|
||||
statistics_proxy_.reset(new SendStatisticsProxy(
|
||||
&fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
|
||||
|
||||
test::ClearHistograms();
|
||||
EncodedImage encoded_image;
|
||||
RTPVideoHeader rtp_video_header;
|
||||
rtp_video_header.simulcastIdx = 0;
|
||||
rtp_video_header.codec = kRtpVideoVp9;
|
||||
rtp_video_header.codecHeader.VP9.num_spatial_layers = 1;
|
||||
|
||||
for (int i = 0; i < kMinRequiredSamples; ++i) {
|
||||
encoded_image.qp_ = kQpIdx0;
|
||||
rtp_video_header.codecHeader.VP9.spatial_idx = 0;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp9"));
|
||||
EXPECT_EQ(kQpIdx0, test::LastHistogramSample("WebRTC.Video.Encoded.Qp.Vp9"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, NoSubstreams) {
|
||||
uint32_t excluded_ssrc =
|
||||
std::max(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user