Chromium Code Reviews| 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 |