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 |