OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 #include "webrtc/modules/audio_processing/audio_processing_impl.h" | 10 #include "webrtc/modules/audio_processing/audio_processing_impl.h" |
11 | 11 |
12 #include <math.h> | 12 #include <math.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "webrtc/base/array_view.h" | 18 #include "webrtc/base/array_view.h" |
19 #include "webrtc/base/criticalsection.h" | 19 #include "webrtc/base/atomicops.h" |
20 #include "webrtc/base/platform_thread.h" | 20 #include "webrtc/base/platform_thread.h" |
21 #include "webrtc/base/random.h" | 21 #include "webrtc/base/random.h" |
22 #include "webrtc/base/safe_conversions.h" | 22 #include "webrtc/base/safe_conversions.h" |
23 #include "webrtc/config.h" | 23 #include "webrtc/config.h" |
24 #include "webrtc/modules/audio_processing/test/test_utils.h" | 24 #include "webrtc/modules/audio_processing/test/test_utils.h" |
25 #include "webrtc/modules/include/module_common_types.h" | 25 #include "webrtc/modules/include/module_common_types.h" |
26 #include "webrtc/system_wrappers/include/clock.h" | 26 #include "webrtc/system_wrappers/include/clock.h" |
27 #include "webrtc/system_wrappers/include/event_wrapper.h" | 27 #include "webrtc/system_wrappers/include/event_wrapper.h" |
28 #include "webrtc/system_wrappers/include/sleep.h" | 28 #include "webrtc/system_wrappers/include/sleep.h" |
29 #include "webrtc/test/testsupport/perf_test.h" | 29 #include "webrtc/test/testsupport/perf_test.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 } | 161 } |
162 | 162 |
163 int sample_rate_hz = 16000; | 163 int sample_rate_hz = 16000; |
164 SettingsType simulation_settings = SettingsType::kDefaultApmDesktop; | 164 SettingsType simulation_settings = SettingsType::kDefaultApmDesktop; |
165 }; | 165 }; |
166 | 166 |
167 // Handler for the frame counters. | 167 // Handler for the frame counters. |
168 class FrameCounters { | 168 class FrameCounters { |
169 public: | 169 public: |
170 void IncreaseRenderCounter() { | 170 void IncreaseRenderCounter() { |
171 rtc::CritScope cs(&crit_); | 171 rtc::AtomicOps::Increment(&render_count_); |
172 render_count_++; | |
173 } | 172 } |
174 | 173 |
175 void IncreaseCaptureCounter() { | 174 void IncreaseCaptureCounter() { |
176 rtc::CritScope cs(&crit_); | 175 rtc::AtomicOps::Increment(&capture_count_); |
177 capture_count_++; | |
178 } | |
179 | |
180 int GetCaptureCounter() const { | |
181 rtc::CritScope cs(&crit_); | |
182 return capture_count_; | |
183 } | |
184 | |
185 int GetRenderCounter() const { | |
186 rtc::CritScope cs(&crit_); | |
187 return render_count_; | |
188 } | 176 } |
189 | 177 |
190 int CaptureMinusRenderCounters() const { | 178 int CaptureMinusRenderCounters() const { |
191 rtc::CritScope cs(&crit_); | 179 // The return value will be approximate, but that's good enough since |
192 return capture_count_ - render_count_; | 180 // by the time we return the value, it's not guaranteed to be correct |
181 // anyway. | |
182 return rtc::AtomicOps::AcquireLoad(&capture_count_) - | |
183 rtc::AtomicOps::AcquireLoad(&render_count_); | |
193 } | 184 } |
194 | 185 |
195 int RenderMinusCaptureCounters() const { | 186 int RenderMinusCaptureCounters() const { |
196 return -CaptureMinusRenderCounters(); | 187 return -CaptureMinusRenderCounters(); |
197 } | 188 } |
198 | 189 |
199 bool BothCountersExceedeThreshold(int threshold) const { | 190 bool BothCountersExceedeThreshold(int threshold) const { |
200 rtc::CritScope cs(&crit_); | 191 // TODO(tommi): We could use an event to signal this so that we don't need |
201 return (render_count_ > threshold && capture_count_ > threshold); | 192 // to be polling from the main thread and possibly steal cycles. |
193 const int capture_count = rtc::AtomicOps::AcquireLoad(&capture_count_); | |
194 const int render_count = rtc::AtomicOps::AcquireLoad(&render_count_); | |
195 return (render_count > threshold && capture_count > threshold); | |
202 } | 196 } |
203 | 197 |
204 private: | 198 private: |
205 rtc::CriticalSection crit_; | 199 int render_count_ = 0; |
206 int render_count_ GUARDED_BY(crit_) = 0; | 200 int capture_count_ = 0; |
207 int capture_count_ GUARDED_BY(crit_) = 0; | |
208 }; | 201 }; |
209 | 202 |
210 // Class that protects a flag using a lock. | 203 // Class that represents a flag that can only be raised. |
peah-webrtc
2016/01/26 08:48:45
This class should be replaced with an rtc:Event as
| |
211 class LockedFlag { | 204 class LockedFlag { |
212 public: | 205 public: |
213 bool get_flag() const { | 206 bool get_flag() const { |
214 rtc::CritScope cs(&crit_); | 207 return rtc::AtomicOps::AcquireLoad(&flag_); |
215 return flag_; | |
216 } | 208 } |
217 | 209 |
218 void set_flag() { | 210 void set_flag() { |
219 rtc::CritScope cs(&crit_); | 211 if (!get_flag()) // read-only operation to avoid affecting the cache-line. |
220 flag_ = true; | 212 rtc::AtomicOps::CompareAndSwap(&flag_, 0, 1); |
221 } | 213 } |
222 | 214 |
223 private: | 215 private: |
224 rtc::CriticalSection crit_; | 216 int flag_ = 0; |
225 bool flag_ GUARDED_BY(crit_) = false; | |
226 }; | 217 }; |
227 | 218 |
228 // Parent class for the thread processors. | 219 // Parent class for the thread processors. |
229 class TimedThreadApiProcessor { | 220 class TimedThreadApiProcessor { |
230 public: | 221 public: |
231 TimedThreadApiProcessor(ProcessorType processor_type, | 222 TimedThreadApiProcessor(ProcessorType processor_type, |
232 Random* rand_gen, | 223 Random* rand_gen, |
233 FrameCounters* shared_counters_state, | 224 FrameCounters* shared_counters_state, |
234 LockedFlag* capture_call_checker, | 225 LockedFlag* capture_call_checker, |
235 CallSimulator* test_framework, | 226 CallSimulator* test_framework, |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 frame_data_.output_stream_config.set_sample_rate_hz( | 406 frame_data_.output_stream_config.set_sample_rate_hz( |
416 simulation_config_->sample_rate_hz); | 407 simulation_config_->sample_rate_hz); |
417 frame_data_.output_stream_config.set_num_channels(1); | 408 frame_data_.output_stream_config.set_num_channels(1); |
418 frame_data_.output_stream_config.set_has_keyboard(false); | 409 frame_data_.output_stream_config.set_has_keyboard(false); |
419 } | 410 } |
420 | 411 |
421 bool ReadyToProcess() { | 412 bool ReadyToProcess() { |
422 switch (processor_type_) { | 413 switch (processor_type_) { |
423 case ProcessorType::kRender: | 414 case ProcessorType::kRender: |
424 return ReadyToProcessRender(); | 415 return ReadyToProcessRender(); |
425 break; | 416 |
426 case ProcessorType::kCapture: | 417 case ProcessorType::kCapture: |
427 return ReadyToProcessCapture(); | 418 return ReadyToProcessCapture(); |
428 break; | |
429 } | 419 } |
430 | 420 |
431 // Should not be reached, but the return statement is needed for the code to | 421 // Should not be reached, but the return statement is needed for the code to |
432 // build successfully on Android. | 422 // build successfully on Android. |
433 RTC_NOTREACHED(); | 423 RTC_NOTREACHED(); |
434 return false; | 424 return false; |
435 } | 425 } |
436 | 426 |
437 Random* rand_gen_ = nullptr; | 427 Random* rand_gen_ = nullptr; |
438 FrameCounters* frame_counters_ = nullptr; | 428 FrameCounters* frame_counters_ = nullptr; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
682 rtc::scoped_ptr<TimedThreadApiProcessor> capture_thread_state_; | 672 rtc::scoped_ptr<TimedThreadApiProcessor> capture_thread_state_; |
683 }; | 673 }; |
684 | 674 |
685 // Implements the callback functionality for the threads. | 675 // Implements the callback functionality for the threads. |
686 bool TimedThreadApiProcessor::Process() { | 676 bool TimedThreadApiProcessor::Process() { |
687 PrepareFrame(); | 677 PrepareFrame(); |
688 | 678 |
689 // Wait in a spinlock manner until it is ok to start processing. | 679 // Wait in a spinlock manner until it is ok to start processing. |
690 // Note that SleepMs is not applicable since it only allows sleeping | 680 // Note that SleepMs is not applicable since it only allows sleeping |
691 // on a millisecond basis which is too long. | 681 // on a millisecond basis which is too long. |
682 // TODO(tommi): This loop may affect the performance of the test that it's | |
683 // meant to measure. See if we could use events instead to signal readiness. | |
peah-webrtc
2016/01/26 08:48:45
Yes, I think an event would be better to use here
| |
692 while (!ReadyToProcess()) { | 684 while (!ReadyToProcess()) { |
693 } | 685 } |
694 | 686 |
695 int result = AudioProcessing::kNoError; | 687 int result = AudioProcessing::kNoError; |
696 switch (processor_type_) { | 688 switch (processor_type_) { |
697 case ProcessorType::kRender: | 689 case ProcessorType::kRender: |
698 result = ProcessRender(); | 690 result = ProcessRender(); |
699 break; | 691 break; |
700 case ProcessorType::kCapture: | 692 case ProcessorType::kCapture: |
701 result = ProcessCapture(); | 693 result = ProcessCapture(); |
(...skipping 13 matching lines...) Expand all Loading... | |
715 // Run test and verify that it did not time out. | 707 // Run test and verify that it did not time out. |
716 EXPECT_EQ(kEventSignaled, Run()); | 708 EXPECT_EQ(kEventSignaled, Run()); |
717 } | 709 } |
718 | 710 |
719 INSTANTIATE_TEST_CASE_P( | 711 INSTANTIATE_TEST_CASE_P( |
720 AudioProcessingPerformanceTest, | 712 AudioProcessingPerformanceTest, |
721 CallSimulator, | 713 CallSimulator, |
722 ::testing::ValuesIn(SimulationConfig::GenerateSimulationConfigs())); | 714 ::testing::ValuesIn(SimulationConfig::GenerateSimulationConfigs())); |
723 | 715 |
724 } // namespace webrtc | 716 } // namespace webrtc |
OLD | NEW |