1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <math.h>
12
13 #include <numeric>
14 #include <vector>
15
16 #include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
17
18 #ifdef WEBRTC_IOS
19 const int kMinimumReasonableDelayEstimateMs = 30;
20 #else
21 const int kMinimumReasonableDelayEstimateMs = 45;
22 #endif // !WEBRTC_IOS
23
24 class VideoSyncTest : public AfterStreamingFixture {
25 protected:
26 // This test will verify that delay estimates converge (e.g. the standard
27 // deviation for the last five seconds' estimates is less than 20) without
28 // manual observation. The test runs for 15 seconds, sampling once per second.
29 // All samples are checked so they are greater than |min_estimate|.
CollectEstimatesDuring15Seconds(int min_estimate)30 int CollectEstimatesDuring15Seconds(int min_estimate) {
31 Sleep(1000);
32
33 std::vector<int> all_delay_estimates;
34 for (int second = 0; second < 15; second++) {
35 int jitter_buffer_delay_ms = 0;
36 int playout_buffer_delay_ms = 0;
37 EXPECT_EQ(0, voe_vsync_->GetDelayEstimate(channel_,
38 &jitter_buffer_delay_ms,
39 &playout_buffer_delay_ms));
40
41 EXPECT_GT(jitter_buffer_delay_ms, min_estimate) <<
42 "The delay estimate can not conceivably get lower than " <<
43 min_estimate << " ms, it's unrealistic.";
44
45 all_delay_estimates.push_back(jitter_buffer_delay_ms);
46 Sleep(1000);
47 }
48
49 return ComputeStandardDeviation(
50 all_delay_estimates.begin() + 10, all_delay_estimates.end());
51 }
52
CheckEstimatesConvergeReasonablyWell(int min_estimate)53 void CheckEstimatesConvergeReasonablyWell(int min_estimate) {
54 float standard_deviation = CollectEstimatesDuring15Seconds(min_estimate);
55 EXPECT_LT(standard_deviation, 30.0f);
56 }
57
58 // Computes the standard deviation by first estimating the sample variance
59 // with an unbiased estimator.
ComputeStandardDeviation(std::vector<int>::const_iterator start,std::vector<int>::const_iterator end) const60 float ComputeStandardDeviation(std::vector<int>::const_iterator start,
61 std::vector<int>::const_iterator end) const {
62 int num_elements = end - start;
63 int mean = std::accumulate(start, end, 0) / num_elements;
64 assert(num_elements > 1);
65
66 float variance = 0;
67 for (; start != end; ++start) {
68 variance += (*start - mean) * (*start - mean) / (num_elements - 1);
69 }
70 return sqrt(variance);
71 }
72 };
73
TEST_F(VideoSyncTest,CanNotGetPlayoutTimestampWhilePlayingWithoutSettingItFirst)74 TEST_F(VideoSyncTest,
75 CanNotGetPlayoutTimestampWhilePlayingWithoutSettingItFirst) {
76 unsigned int ignored;
77 EXPECT_EQ(-1, voe_vsync_->GetPlayoutTimestamp(channel_, ignored));
78 }
79
TEST_F(VideoSyncTest,CannotSetInitTimestampWhilePlaying)80 TEST_F(VideoSyncTest, CannotSetInitTimestampWhilePlaying) {
81 EXPECT_EQ(-1, voe_vsync_->SetInitTimestamp(channel_, 12345));
82 }
83
TEST_F(VideoSyncTest,CannotSetInitSequenceNumberWhilePlaying)84 TEST_F(VideoSyncTest, CannotSetInitSequenceNumberWhilePlaying) {
85 EXPECT_EQ(-1, voe_vsync_->SetInitSequenceNumber(channel_, 123));
86 }
87
TEST_F(VideoSyncTest,CanSetInitTimestampWhileStopped)88 TEST_F(VideoSyncTest, CanSetInitTimestampWhileStopped) {
89 EXPECT_EQ(0, voe_base_->StopSend(channel_));
90 EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
91 }
92
TEST_F(VideoSyncTest,CanSetInitSequenceNumberWhileStopped)93 TEST_F(VideoSyncTest, CanSetInitSequenceNumberWhileStopped) {
94 EXPECT_EQ(0, voe_base_->StopSend(channel_));
95 EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
96 }
97
98 // TODO(phoglund): pending investigation in
99 // http://code.google.com/p/webrtc/issues/detail?id=438
TEST_F(VideoSyncTest,DISABLED_DelayEstimatesStabilizeDuring15sAndAreNotTooLow)100 TEST_F(VideoSyncTest,
101 DISABLED_DelayEstimatesStabilizeDuring15sAndAreNotTooLow) {
102 EXPECT_EQ(0, voe_base_->StopSend(channel_));
103 EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
104 EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
105 EXPECT_EQ(0, voe_base_->StartSend(channel_));
106
107 CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
108 }
109
110 // TODO(phoglund): pending investigation in
111 // http://code.google.com/p/webrtc/issues/detail?id=438
TEST_F(VideoSyncTest,DISABLED_DelayEstimatesStabilizeAfterNetEqMinDelayChanges45s)112 TEST_F(VideoSyncTest,
113 DISABLED_DelayEstimatesStabilizeAfterNetEqMinDelayChanges45s) {
114 EXPECT_EQ(0, voe_base_->StopSend(channel_));
115 EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
116 EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
117 EXPECT_EQ(0, voe_base_->StartSend(channel_));
118
119 CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
120 EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 200));
121 CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
122 EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 0));
123 CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
124 }
125
TEST_F(VideoSyncTest,CanGetPlayoutBufferSize)126 TEST_F(VideoSyncTest, CanGetPlayoutBufferSize) {
127 int ignored;
128 EXPECT_EQ(0, voe_vsync_->GetPlayoutBufferSize(ignored));
129 }
130