| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/video/send_statistics_proxy.h" | 11 #include "webrtc/video/send_statistics_proxy.h" |
| 12 | 12 |
| 13 #include <map> | 13 #include <map> |
| 14 #include <memory> | 14 #include <memory> |
| 15 #include <string> | 15 #include <string> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "webrtc/system_wrappers/include/metrics.h" | 18 #include "webrtc/system_wrappers/include/metrics.h" |
| 19 #include "webrtc/system_wrappers/include/metrics_default.h" | 19 #include "webrtc/system_wrappers/include/metrics_default.h" |
| 20 #include "webrtc/test/gtest.h" | 20 #include "webrtc/test/gtest.h" |
| 21 | 21 |
| 22 namespace webrtc { | 22 namespace webrtc { |
| 23 namespace { | 23 namespace { |
| 24 const uint32_t kFirstSsrc = 17; | 24 const uint32_t kFirstSsrc = 17; |
| 25 const uint32_t kSecondSsrc = 42; | 25 const uint32_t kSecondSsrc = 42; |
| 26 const uint32_t kFirstRtxSsrc = 18; | 26 const uint32_t kFirstRtxSsrc = 18; |
| 27 const uint32_t kSecondRtxSsrc = 43; | 27 const uint32_t kSecondRtxSsrc = 43; |
| 28 | 28 |
| 29 const int kMinRequiredSamples = 200; | |
| 30 const int kQpIdx0 = 21; | 29 const int kQpIdx0 = 21; |
| 31 const int kQpIdx1 = 39; | 30 const int kQpIdx1 = 39; |
| 32 } // namespace | 31 } // namespace |
| 33 | 32 |
| 34 class SendStatisticsProxyTest : public ::testing::Test { | 33 class SendStatisticsProxyTest : public ::testing::Test { |
| 35 public: | 34 public: |
| 36 SendStatisticsProxyTest() | 35 SendStatisticsProxyTest() |
| 37 : fake_clock_(1234), config_(GetTestConfig()), avg_delay_ms_(0), | 36 : fake_clock_(1234), config_(GetTestConfig()), avg_delay_ms_(0), |
| 38 max_delay_ms_(0) {} | 37 max_delay_ms_(0) {} |
| 39 virtual ~SendStatisticsProxyTest() {} | 38 virtual ~SendStatisticsProxyTest() {} |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 for (uint32_t i = 1; i <= 3; ++i) { | 307 for (uint32_t i = 1; i <= 3; ++i) { |
| 309 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 308 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 310 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded); | 309 EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded); |
| 311 } | 310 } |
| 312 } | 311 } |
| 313 | 312 |
| 314 TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) { | 313 TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) { |
| 315 const int kWidth = 640; | 314 const int kWidth = 640; |
| 316 const int kHeight = 480; | 315 const int kHeight = 480; |
| 317 | 316 |
| 318 for (int i = 0; i < kMinRequiredSamples; ++i) | 317 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) |
| 319 statistics_proxy_->OnIncomingFrame(kWidth, kHeight); | 318 statistics_proxy_->OnIncomingFrame(kWidth, kHeight); |
| 320 | 319 |
| 321 // No switch, stats should not be updated. | 320 // No switch, stats should not be updated. |
| 322 VideoEncoderConfig config; | 321 VideoEncoderConfig config; |
| 323 config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; | 322 config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; |
| 324 statistics_proxy_->OnEncoderReconfigured(config, 50); | 323 statistics_proxy_->OnEncoderReconfigured(config, 50); |
| 325 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels")); | 324 EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels")); |
| 326 | 325 |
| 327 // Switch to screenshare, real-time stats should be updated. | 326 // Switch to screenshare, real-time stats should be updated. |
| 328 config.content_type = VideoEncoderConfig::ContentType::kScreen; | 327 config.content_type = VideoEncoderConfig::ContentType::kScreen; |
| 329 statistics_proxy_->OnEncoderReconfigured(config, 50); | 328 statistics_proxy_->OnEncoderReconfigured(config, 50); |
| 330 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels")); | 329 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels")); |
| 331 } | 330 } |
| 332 | 331 |
| 332 TEST_F(SendStatisticsProxyTest, CpuLimitedResolutionUpdated) { |
| 333 const int kWidth = 640; |
| 334 const int kHeight = 480; |
| 335 |
| 336 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) |
| 337 statistics_proxy_->OnIncomingFrame(kWidth, kHeight); |
| 338 |
| 339 statistics_proxy_->OnCpuRestrictedResolutionChanged(true); |
| 340 |
| 341 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) |
| 342 statistics_proxy_->OnIncomingFrame(kWidth, kHeight); |
| 343 |
| 344 statistics_proxy_.reset(); |
| 345 EXPECT_EQ(1, |
| 346 metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent")); |
| 347 EXPECT_EQ( |
| 348 1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50)); |
| 349 } |
| 350 |
| 333 TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) { | 351 TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) { |
| 334 const int64_t kTimeSec = 3; | 352 const int64_t kTimeSec = 3; |
| 335 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000); | 353 fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000); |
| 336 statistics_proxy_.reset(); | 354 statistics_proxy_.reset(); |
| 337 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds")); | 355 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds")); |
| 338 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds", | 356 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds", |
| 339 kTimeSec)); | 357 kTimeSec)); |
| 340 } | 358 } |
| 341 | 359 |
| 342 TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) { | 360 TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) { |
| 343 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); | 361 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); |
| 344 statistics_proxy_.reset(); | 362 statistics_proxy_.reset(); |
| 345 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType")); | 363 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType")); |
| 346 } | 364 } |
| 347 | 365 |
| 348 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) { | 366 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) { |
| 349 EncodedImage encoded_image; | 367 EncodedImage encoded_image; |
| 350 CodecSpecificInfo codec_info; | 368 CodecSpecificInfo codec_info; |
| 351 codec_info.codecType = kVideoCodecVP8; | 369 codec_info.codecType = kVideoCodecVP8; |
| 352 | 370 |
| 353 for (int i = 0; i < kMinRequiredSamples; ++i) { | 371 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { |
| 354 codec_info.codecSpecific.VP8.simulcastIdx = 0; | 372 codec_info.codecSpecific.VP8.simulcastIdx = 0; |
| 355 encoded_image.qp_ = kQpIdx0; | 373 encoded_image.qp_ = kQpIdx0; |
| 356 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 374 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 357 codec_info.codecSpecific.VP8.simulcastIdx = 1; | 375 codec_info.codecSpecific.VP8.simulcastIdx = 1; |
| 358 encoded_image.qp_ = kQpIdx1; | 376 encoded_image.qp_ = kQpIdx1; |
| 359 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 377 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 360 } | 378 } |
| 361 statistics_proxy_.reset(); | 379 statistics_proxy_.reset(); |
| 362 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0")); | 380 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0")); |
| 363 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0)); | 381 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0)); |
| 364 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1")); | 382 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1")); |
| 365 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1)); | 383 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1)); |
| 366 } | 384 } |
| 367 | 385 |
| 368 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) { | 386 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) { |
| 369 VideoSendStream::Config config(nullptr); | 387 VideoSendStream::Config config(nullptr); |
| 370 config.rtp.ssrcs.push_back(kFirstSsrc); | 388 config.rtp.ssrcs.push_back(kFirstSsrc); |
| 371 statistics_proxy_.reset(new SendStatisticsProxy( | 389 statistics_proxy_.reset(new SendStatisticsProxy( |
| 372 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo)); | 390 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo)); |
| 373 | 391 |
| 374 EncodedImage encoded_image; | 392 EncodedImage encoded_image; |
| 375 CodecSpecificInfo codec_info; | 393 CodecSpecificInfo codec_info; |
| 376 codec_info.codecType = kVideoCodecVP8; | 394 codec_info.codecType = kVideoCodecVP8; |
| 377 | 395 |
| 378 for (int i = 0; i < kMinRequiredSamples; ++i) { | 396 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { |
| 379 codec_info.codecSpecific.VP8.simulcastIdx = 0; | 397 codec_info.codecSpecific.VP8.simulcastIdx = 0; |
| 380 encoded_image.qp_ = kQpIdx0; | 398 encoded_image.qp_ = kQpIdx0; |
| 381 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 399 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 382 } | 400 } |
| 383 statistics_proxy_.reset(); | 401 statistics_proxy_.reset(); |
| 384 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8")); | 402 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8")); |
| 385 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0)); | 403 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0)); |
| 386 } | 404 } |
| 387 | 405 |
| 388 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) { | 406 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) { |
| 389 EncodedImage encoded_image; | 407 EncodedImage encoded_image; |
| 390 CodecSpecificInfo codec_info; | 408 CodecSpecificInfo codec_info; |
| 391 codec_info.codecType = kVideoCodecVP9; | 409 codec_info.codecType = kVideoCodecVP9; |
| 392 codec_info.codecSpecific.VP9.num_spatial_layers = 2; | 410 codec_info.codecSpecific.VP9.num_spatial_layers = 2; |
| 393 | 411 |
| 394 for (int i = 0; i < kMinRequiredSamples; ++i) { | 412 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { |
| 395 encoded_image.qp_ = kQpIdx0; | 413 encoded_image.qp_ = kQpIdx0; |
| 396 codec_info.codecSpecific.VP9.spatial_idx = 0; | 414 codec_info.codecSpecific.VP9.spatial_idx = 0; |
| 397 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 415 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 398 encoded_image.qp_ = kQpIdx1; | 416 encoded_image.qp_ = kQpIdx1; |
| 399 codec_info.codecSpecific.VP9.spatial_idx = 1; | 417 codec_info.codecSpecific.VP9.spatial_idx = 1; |
| 400 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 418 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 401 } | 419 } |
| 402 statistics_proxy_.reset(); | 420 statistics_proxy_.reset(); |
| 403 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0")); | 421 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0")); |
| 404 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0)); | 422 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0)); |
| 405 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1")); | 423 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1")); |
| 406 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1)); | 424 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1)); |
| 407 } | 425 } |
| 408 | 426 |
| 409 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) { | 427 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) { |
| 410 VideoSendStream::Config config(nullptr); | 428 VideoSendStream::Config config(nullptr); |
| 411 config.rtp.ssrcs.push_back(kFirstSsrc); | 429 config.rtp.ssrcs.push_back(kFirstSsrc); |
| 412 statistics_proxy_.reset(new SendStatisticsProxy( | 430 statistics_proxy_.reset(new SendStatisticsProxy( |
| 413 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo)); | 431 &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo)); |
| 414 | 432 |
| 415 EncodedImage encoded_image; | 433 EncodedImage encoded_image; |
| 416 CodecSpecificInfo codec_info; | 434 CodecSpecificInfo codec_info; |
| 417 codec_info.codecType = kVideoCodecVP9; | 435 codec_info.codecType = kVideoCodecVP9; |
| 418 codec_info.codecSpecific.VP9.num_spatial_layers = 1; | 436 codec_info.codecSpecific.VP9.num_spatial_layers = 1; |
| 419 | 437 |
| 420 for (int i = 0; i < kMinRequiredSamples; ++i) { | 438 for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) { |
| 421 encoded_image.qp_ = kQpIdx0; | 439 encoded_image.qp_ = kQpIdx0; |
| 422 codec_info.codecSpecific.VP9.spatial_idx = 0; | 440 codec_info.codecSpecific.VP9.spatial_idx = 0; |
| 423 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); | 441 statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info); |
| 424 } | 442 } |
| 425 statistics_proxy_.reset(); | 443 statistics_proxy_.reset(); |
| 426 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9")); | 444 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9")); |
| 427 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0)); | 445 EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0)); |
| 428 } | 446 } |
| 429 | 447 |
| 430 TEST_F(SendStatisticsProxyTest, NoSubstreams) { | 448 TEST_F(SendStatisticsProxyTest, NoSubstreams) { |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 | 785 |
| 768 EXPECT_EQ( | 786 EXPECT_EQ( |
| 769 1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps")); | 787 1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps")); |
| 770 EXPECT_EQ(1, metrics::NumEvents( | 788 EXPECT_EQ(1, metrics::NumEvents( |
| 771 "WebRTC.Video.Screenshare.FecBitrateSentInKbps", | 789 "WebRTC.Video.Screenshare.FecBitrateSentInKbps", |
| 772 static_cast<int>((rtx_counters.fec.TotalBytes() * 2 * 8) / | 790 static_cast<int>((rtx_counters.fec.TotalBytes() * 2 * 8) / |
| 773 metrics::kMinRunTimeInSeconds / 1000))); | 791 metrics::kMinRunTimeInSeconds / 1000))); |
| 774 } | 792 } |
| 775 | 793 |
| 776 } // namespace webrtc | 794 } // namespace webrtc |
| OLD | NEW |