Chromium Code Reviews| 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 <memory> | 11 #include <memory> |
| 12 | 12 |
| 13 #include "webrtc/video/overuse_frame_detector.h" | 13 #include "webrtc/video/overuse_frame_detector.h" |
| 14 | 14 |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 #include "webrtc/base/event.h" | |
| 18 #include "webrtc/system_wrappers/include/clock.h" | 19 #include "webrtc/system_wrappers/include/clock.h" |
| 19 #include "webrtc/video_frame.h" | 20 #include "webrtc/video_frame.h" |
| 20 | 21 |
| 21 namespace webrtc { | 22 namespace webrtc { |
| 23 | |
| 24 using ::testing::Invoke; | |
| 25 | |
| 22 namespace { | 26 namespace { |
| 23 const int kWidth = 640; | 27 const int kWidth = 640; |
| 24 const int kHeight = 480; | 28 const int kHeight = 480; |
| 25 const int kFrameInterval33ms = 33; | 29 const int kFrameInterval33ms = 33; |
| 26 const int kProcessIntervalMs = 5000; | 30 const int kProcessIntervalMs = 5000; |
| 27 const int kProcessTime5ms = 5; | 31 const int kProcessTime5ms = 5; |
| 28 } // namespace | 32 } // namespace |
| 29 | 33 |
| 30 class MockCpuOveruseObserver : public CpuOveruseObserver { | 34 class MockCpuOveruseObserver : public CpuOveruseObserver { |
| 31 public: | 35 public: |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 43 normaluse_(0) {} | 47 normaluse_(0) {} |
| 44 virtual ~CpuOveruseObserverImpl() {} | 48 virtual ~CpuOveruseObserverImpl() {} |
| 45 | 49 |
| 46 void OveruseDetected() { ++overuse_; } | 50 void OveruseDetected() { ++overuse_; } |
| 47 void NormalUsage() { ++normaluse_; } | 51 void NormalUsage() { ++normaluse_; } |
| 48 | 52 |
| 49 int overuse_; | 53 int overuse_; |
| 50 int normaluse_; | 54 int normaluse_; |
| 51 }; | 55 }; |
| 52 | 56 |
| 57 class OveruseFrameDetectorUnderTest : public OveruseFrameDetector { | |
| 58 public: | |
| 59 OveruseFrameDetectorUnderTest(Clock* clock, | |
| 60 const CpuOveruseOptions& options, | |
| 61 CpuOveruseObserver* overuse_observer, | |
| 62 EncodedFrameObserver* encoder_timing, | |
| 63 CpuOveruseMetricsObserver* metrics_observer) | |
| 64 : OveruseFrameDetector(clock, | |
| 65 options, | |
| 66 overuse_observer, | |
| 67 encoder_timing, | |
| 68 metrics_observer) {} | |
| 69 ~OveruseFrameDetectorUnderTest() {} | |
| 70 | |
| 71 using OveruseFrameDetector::CheckForOveruse; | |
| 72 }; | |
| 73 | |
| 53 class OveruseFrameDetectorTest : public ::testing::Test, | 74 class OveruseFrameDetectorTest : public ::testing::Test, |
| 54 public CpuOveruseMetricsObserver { | 75 public CpuOveruseMetricsObserver { |
| 55 protected: | 76 protected: |
| 56 void SetUp() override { | 77 void SetUp() override { |
| 57 clock_.reset(new SimulatedClock(1234)); | 78 clock_.reset(new SimulatedClock(1234)); |
| 58 observer_.reset(new MockCpuOveruseObserver()); | 79 observer_.reset(new MockCpuOveruseObserver()); |
| 59 options_.min_process_count = 0; | 80 options_.min_process_count = 0; |
| 60 ReinitializeOveruseDetector(); | 81 ReinitializeOveruseDetector(); |
| 61 } | 82 } |
| 62 | 83 |
| 63 void ReinitializeOveruseDetector() { | 84 void ReinitializeOveruseDetector() { |
| 64 overuse_detector_.reset(new OveruseFrameDetector( | 85 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
| 65 clock_.get(), options_, observer_.get(), nullptr, this)); | 86 clock_.get(), options_, observer_.get(), nullptr, this)); |
| 66 } | 87 } |
| 67 | 88 |
| 68 void OnEncodedFrameTimeMeasured(int encode_time_ms, | 89 void OnEncodedFrameTimeMeasured(int encode_time_ms, |
| 69 const CpuOveruseMetrics& metrics) override { | 90 const CpuOveruseMetrics& metrics) override { |
| 70 metrics_ = metrics; | 91 metrics_ = metrics; |
| 71 } | 92 } |
| 72 | 93 |
| 73 int InitialUsage() { | 94 int InitialUsage() { |
| 74 return ((options_.low_encode_usage_threshold_percent + | 95 return ((options_.low_encode_usage_threshold_percent + |
| 75 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5; | 96 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5; |
| 76 } | 97 } |
| 77 | 98 |
| 78 void InsertAndSendFramesWithInterval(int num_frames, | 99 void InsertAndSendFramesWithInterval(int num_frames, |
| 79 int interval_ms, | 100 int interval_ms, |
| 80 int width, | 101 int width, |
| 81 int height, | 102 int height, |
| 82 int delay_ms) { | 103 int delay_ms) { |
| 83 VideoFrame frame; | 104 VideoFrame frame; |
| 84 frame.CreateEmptyFrame(width, height, width, width / 2, width / 2); | 105 frame.CreateEmptyFrame(width, height, width, width / 2, width / 2); |
| 85 uint32_t timestamp = 0; | 106 uint32_t timestamp = 0; |
| 86 while (num_frames-- > 0) { | 107 while (num_frames-- > 0) { |
| 87 frame.set_timestamp(timestamp); | 108 frame.set_timestamp(timestamp); |
| 88 overuse_detector_->FrameCaptured(frame); | 109 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); |
| 89 clock_->AdvanceTimeMilliseconds(delay_ms); | 110 clock_->AdvanceTimeMilliseconds(delay_ms); |
| 90 overuse_detector_->FrameSent(timestamp); | 111 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); |
| 91 clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms); | 112 clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms); |
| 92 timestamp += interval_ms * 90; | 113 timestamp += interval_ms * 90; |
| 93 } | 114 } |
| 94 } | 115 } |
| 95 | 116 |
| 96 void ForceUpdate(int width, int height) { | 117 void ForceUpdate(int width, int height) { |
| 97 // Insert one frame, wait a second and then put in another to force update | 118 // Insert one frame, wait a second and then put in another to force update |
| 98 // the usage. From the tests where these are used, adding another sample | 119 // the usage. From the tests where these are used, adding another sample |
| 99 // doesn't affect the expected outcome (this is mainly to check initial | 120 // doesn't affect the expected outcome (this is mainly to check initial |
| 100 // values and whether the overuse detector has been reset or not). | 121 // values and whether the overuse detector has been reset or not). |
| 101 InsertAndSendFramesWithInterval(2, 1000, width, height, kFrameInterval33ms); | 122 InsertAndSendFramesWithInterval(2, 1000, width, height, kFrameInterval33ms); |
| 102 } | 123 } |
| 103 void TriggerOveruse(int num_times) { | 124 void TriggerOveruse(int num_times) { |
| 104 const int kDelayMs = 32; | 125 const int kDelayMs = 32; |
| 105 for (int i = 0; i < num_times; ++i) { | 126 for (int i = 0; i < num_times; ++i) { |
| 106 InsertAndSendFramesWithInterval( | 127 InsertAndSendFramesWithInterval( |
| 107 1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs); | 128 1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs); |
| 108 overuse_detector_->Process(); | 129 overuse_detector_->CheckForOveruse(); |
| 109 } | 130 } |
| 110 } | 131 } |
| 111 | 132 |
| 112 void TriggerUnderuse() { | 133 void TriggerUnderuse() { |
| 113 const int kDelayMs1 = 5; | 134 const int kDelayMs1 = 5; |
| 114 const int kDelayMs2 = 6; | 135 const int kDelayMs2 = 6; |
| 115 InsertAndSendFramesWithInterval( | 136 InsertAndSendFramesWithInterval( |
| 116 1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1); | 137 1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1); |
| 117 InsertAndSendFramesWithInterval( | 138 InsertAndSendFramesWithInterval( |
| 118 1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2); | 139 1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2); |
| 119 overuse_detector_->Process(); | 140 overuse_detector_->CheckForOveruse(); |
| 120 } | 141 } |
| 121 | 142 |
| 122 int UsagePercent() { return metrics_.encode_usage_percent; } | 143 int UsagePercent() { return metrics_.encode_usage_percent; } |
| 123 | 144 |
| 124 CpuOveruseOptions options_; | 145 CpuOveruseOptions options_; |
| 125 std::unique_ptr<SimulatedClock> clock_; | 146 std::unique_ptr<SimulatedClock> clock_; |
| 126 std::unique_ptr<MockCpuOveruseObserver> observer_; | 147 std::unique_ptr<MockCpuOveruseObserver> observer_; |
| 127 std::unique_ptr<OveruseFrameDetector> overuse_detector_; | 148 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_; |
| 128 CpuOveruseMetrics metrics_; | 149 CpuOveruseMetrics metrics_; |
| 129 }; | 150 }; |
| 130 | 151 |
| 131 | 152 |
| 132 // UsagePercent() > high_encode_usage_threshold_percent => overuse. | 153 // UsagePercent() > high_encode_usage_threshold_percent => overuse. |
| 133 // UsagePercent() < low_encode_usage_threshold_percent => underuse. | 154 // UsagePercent() < low_encode_usage_threshold_percent => underuse. |
| 134 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { | 155 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { |
| 135 // usage > high => overuse | 156 // usage > high => overuse |
| 136 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); | 157 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); |
| 137 TriggerOveruse(options_.high_threshold_consecutive_count); | 158 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 138 } | 159 } |
| 139 | 160 |
| 140 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { | 161 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { |
| 141 // usage > high => overuse | 162 // usage > high => overuse |
| 142 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); | 163 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); |
| 143 TriggerOveruse(options_.high_threshold_consecutive_count); | 164 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 144 // usage < low => underuse | 165 // usage < low => underuse |
| 145 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1)); | 166 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1)); |
| 146 TriggerUnderuse(); | 167 TriggerUnderuse(); |
| 147 } | 168 } |
| 148 | 169 |
| 149 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { | 170 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) { |
| 150 overuse_detector_.reset( | 171 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
| 151 new OveruseFrameDetector(clock_.get(), options_, nullptr, nullptr, this)); | 172 clock_.get(), options_, nullptr, nullptr, this)); |
| 152 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); | 173 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); |
| 153 TriggerOveruse(options_.high_threshold_consecutive_count); | 174 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 154 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); | 175 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); |
| 155 TriggerUnderuse(); | 176 TriggerUnderuse(); |
| 156 } | 177 } |
| 157 | 178 |
| 158 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { | 179 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { |
| 159 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2); | 180 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2); |
| 160 TriggerOveruse(options_.high_threshold_consecutive_count); | 181 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 161 TriggerOveruse(options_.high_threshold_consecutive_count); | 182 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 162 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1)); | 183 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1)); |
| 163 TriggerUnderuse(); | 184 TriggerUnderuse(); |
| 164 } | 185 } |
| 165 | 186 |
| 166 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { | 187 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) { |
| 167 options_.min_process_count = 1; | 188 options_.min_process_count = 1; |
| 168 CpuOveruseObserverImpl overuse_observer; | 189 CpuOveruseObserverImpl overuse_observer; |
| 169 overuse_detector_.reset(new OveruseFrameDetector( | 190 overuse_detector_.reset(new OveruseFrameDetectorUnderTest( |
| 170 clock_.get(), options_, &overuse_observer, nullptr, this)); | 191 clock_.get(), options_, &overuse_observer, nullptr, this)); |
| 171 InsertAndSendFramesWithInterval( | 192 InsertAndSendFramesWithInterval( |
| 172 1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); | 193 1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms); |
| 173 overuse_detector_->Process(); | 194 overuse_detector_->CheckForOveruse(); |
| 174 EXPECT_EQ(0, overuse_observer.normaluse_); | 195 EXPECT_EQ(0, overuse_observer.normaluse_); |
| 175 clock_->AdvanceTimeMilliseconds(kProcessIntervalMs); | 196 clock_->AdvanceTimeMilliseconds(kProcessIntervalMs); |
| 176 overuse_detector_->Process(); | 197 overuse_detector_->CheckForOveruse(); |
| 177 EXPECT_EQ(1, overuse_observer.normaluse_); | 198 EXPECT_EQ(1, overuse_observer.normaluse_); |
| 178 } | 199 } |
| 179 | 200 |
| 180 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { | 201 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { |
| 181 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); | 202 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); |
| 182 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64); | 203 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64); |
| 183 for (size_t i = 0; i < 64; ++i) { | 204 for (size_t i = 0; i < 64; ++i) { |
| 184 TriggerOveruse(options_.high_threshold_consecutive_count); | 205 TriggerOveruse(options_.high_threshold_consecutive_count); |
| 185 } | 206 } |
| 186 } | 207 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 | 281 |
| 261 TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) { | 282 TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) { |
| 262 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); | 283 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); |
| 263 static const int kIntervalMs = 33; | 284 static const int kIntervalMs = 33; |
| 264 static const size_t kNumFramesEncodingDelay = 3; | 285 static const size_t kNumFramesEncodingDelay = 3; |
| 265 VideoFrame frame; | 286 VideoFrame frame; |
| 266 frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); | 287 frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); |
| 267 for (size_t i = 0; i < 1000; ++i) { | 288 for (size_t i = 0; i < 1000; ++i) { |
| 268 // Unique timestamps. | 289 // Unique timestamps. |
| 269 frame.set_timestamp(static_cast<uint32_t>(i)); | 290 frame.set_timestamp(static_cast<uint32_t>(i)); |
| 270 overuse_detector_->FrameCaptured(frame); | 291 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); |
| 271 clock_->AdvanceTimeMilliseconds(kIntervalMs); | 292 clock_->AdvanceTimeMilliseconds(kIntervalMs); |
| 272 if (i > kNumFramesEncodingDelay) { | 293 if (i > kNumFramesEncodingDelay) { |
| 273 overuse_detector_->FrameSent( | 294 overuse_detector_->FrameSent( |
| 274 static_cast<uint32_t>(i - kNumFramesEncodingDelay)); | 295 static_cast<uint32_t>(i - kNumFramesEncodingDelay), |
| 296 clock_->TimeInMilliseconds()); | |
| 275 } | 297 } |
| 276 overuse_detector_->Process(); | 298 overuse_detector_->CheckForOveruse(); |
| 277 } | 299 } |
| 278 } | 300 } |
| 279 | 301 |
| 280 TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { | 302 TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) { |
| 281 // >85% encoding time should trigger overuse. | 303 // >85% encoding time should trigger overuse. |
| 282 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); | 304 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(testing::AtLeast(1)); |
| 283 static const int kIntervalMs = 33; | 305 static const int kIntervalMs = 33; |
| 284 static const int kDelayMs = 30; | 306 static const int kDelayMs = 30; |
| 285 VideoFrame frame; | 307 VideoFrame frame; |
| 286 frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); | 308 frame.CreateEmptyFrame(kWidth, kHeight, kWidth, kWidth / 2, kWidth / 2); |
| 287 uint32_t timestamp = 0; | 309 uint32_t timestamp = 0; |
| 288 for (size_t i = 0; i < 1000; ++i) { | 310 for (size_t i = 0; i < 1000; ++i) { |
| 289 frame.set_timestamp(timestamp); | 311 frame.set_timestamp(timestamp); |
| 290 overuse_detector_->FrameCaptured(frame); | 312 overuse_detector_->FrameCaptured(frame, clock_->TimeInMilliseconds()); |
| 291 // Encode and send first parts almost instantly. | 313 // Encode and send first parts almost instantly. |
| 292 clock_->AdvanceTimeMilliseconds(1); | 314 clock_->AdvanceTimeMilliseconds(1); |
| 293 overuse_detector_->FrameSent(timestamp); | 315 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); |
| 294 // Encode heavier part, resulting in >85% usage total. | 316 // Encode heavier part, resulting in >85% usage total. |
| 295 clock_->AdvanceTimeMilliseconds(kDelayMs - 1); | 317 clock_->AdvanceTimeMilliseconds(kDelayMs - 1); |
| 296 overuse_detector_->FrameSent(timestamp); | 318 overuse_detector_->FrameSent(timestamp, clock_->TimeInMilliseconds()); |
| 297 clock_->AdvanceTimeMilliseconds(kIntervalMs - kDelayMs); | 319 clock_->AdvanceTimeMilliseconds(kIntervalMs - kDelayMs); |
| 298 timestamp += kIntervalMs * 90; | 320 timestamp += kIntervalMs * 90; |
| 299 overuse_detector_->Process(); | 321 overuse_detector_->CheckForOveruse(); |
| 300 } | 322 } |
| 301 } | 323 } |
| 302 | 324 |
| 325 TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) { | |
| 326 rtc::TaskQueue queue("OveruseFrameDetectorTestQueu"); | |
|
åsapersson
2016/08/24 08:59:05
Queue
perkj_webrtc
2016/09/01 10:03:30
Done.
| |
| 327 | |
| 328 rtc::Event event(false, false); | |
| 329 queue.PostTask([this, &event] { | |
| 330 overuse_detector_->StartCheckForOveruse(); | |
| 331 event.Set(); | |
| 332 }); | |
| 333 event.Wait(rtc::Event::kForever); | |
| 334 | |
| 335 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then | |
| 336 // set |event| to end the test. | |
| 337 EXPECT_CALL(*(observer_.get()), NormalUsage()) | |
| 338 .WillOnce(Invoke([this, &event] { | |
| 339 overuse_detector_->StopCheckForOveruse(); | |
| 340 event.Set(); | |
| 341 })); | |
| 342 | |
| 343 queue.PostTask([this, &event] { | |
| 344 const int kDelayMs1 = 5; | |
| 345 const int kDelayMs2 = 6; | |
| 346 InsertAndSendFramesWithInterval(1300, kFrameInterval33ms, kWidth, kHeight, | |
| 347 kDelayMs1); | |
| 348 InsertAndSendFramesWithInterval(1, kFrameInterval33ms, kWidth, kHeight, | |
| 349 kDelayMs2); | |
| 350 }); | |
| 351 | |
| 352 EXPECT_TRUE(event.Wait(10000)); | |
| 353 } | |
| 354 | |
| 303 } // namespace webrtc | 355 } // namespace webrtc |
| OLD | NEW |