OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <windows.h> | 5 #include <windows.h> |
6 #include <mmsystem.h> | 6 #include <mmsystem.h> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 void set_error(bool error) { | 70 void set_error(bool error) { |
71 had_error_ += error ? 1 : 0; | 71 had_error_ += error ? 1 : 0; |
72 } | 72 } |
73 | 73 |
74 private: | 74 private: |
75 int callback_count_; | 75 int callback_count_; |
76 int had_error_; | 76 int had_error_; |
77 }; | 77 }; |
78 | 78 |
79 const int kMaxNumBuffers = 3; | 79 const int kNumBuffers = 3; |
80 // Specializes TestSourceBasic to detect that the AudioStream is using | 80 // Specializes TestSourceBasic to detect that the AudioStream is using |
81 // triple buffering correctly. | 81 // triple buffering correctly. |
82 class TestSourceTripleBuffer : public TestSourceBasic { | 82 class TestSourceTripleBuffer : public TestSourceBasic { |
83 public: | 83 public: |
84 TestSourceTripleBuffer() { | 84 TestSourceTripleBuffer() { |
85 buffer_address_[0] = NULL; | 85 buffer_address_[0] = NULL; |
86 buffer_address_[1] = NULL; | 86 buffer_address_[1] = NULL; |
87 buffer_address_[2] = NULL; | 87 buffer_address_[2] = NULL; |
88 } | 88 } |
89 // Override of TestSourceBasic::OnMoreData. | 89 // Override of TestSourceBasic::OnMoreData. |
90 virtual uint32 OnMoreData(uint8* dest, | 90 virtual uint32 OnMoreData(uint8* dest, |
91 uint32 max_size, | 91 uint32 max_size, |
92 AudioBuffersState buffers_state) { | 92 AudioBuffersState buffers_state) { |
93 // Call the base, which increments the callback_count_. | 93 // Call the base, which increments the callback_count_. |
94 TestSourceBasic::OnMoreData(dest, max_size, buffers_state); | 94 TestSourceBasic::OnMoreData(dest, max_size, buffers_state); |
95 if (callback_count() % NumberOfWaveOutBuffers() == 2) { | 95 if (callback_count() % kNumBuffers == 2) { |
96 set_error(!CompareExistingIfNotNULL(2, dest)); | 96 set_error(!CompareExistingIfNotNULL(2, dest)); |
97 } else if (callback_count() % NumberOfWaveOutBuffers() == 1) { | 97 } else if (callback_count() % kNumBuffers == 1) { |
98 set_error(!CompareExistingIfNotNULL(1, dest)); | 98 set_error(!CompareExistingIfNotNULL(1, dest)); |
99 } else { | 99 } else { |
100 set_error(!CompareExistingIfNotNULL(0, dest)); | 100 set_error(!CompareExistingIfNotNULL(0, dest)); |
101 } | 101 } |
102 if (callback_count() > kMaxNumBuffers) { | 102 if (callback_count() > kNumBuffers) { |
103 set_error(buffer_address_[0] == buffer_address_[1]); | 103 set_error(buffer_address_[0] == buffer_address_[1]); |
104 set_error(buffer_address_[1] == buffer_address_[2]); | 104 set_error(buffer_address_[1] == buffer_address_[2]); |
105 } | 105 } |
106 return max_size; | 106 return max_size; |
107 } | 107 } |
108 | 108 |
109 private: | 109 private: |
110 bool CompareExistingIfNotNULL(uint32 index, void* address) { | 110 bool CompareExistingIfNotNULL(uint32 index, void* address) { |
111 void*& entry = buffer_address_[index]; | 111 void*& entry = buffer_address_[index]; |
112 if (!entry) | 112 if (!entry) |
113 entry = address; | 113 entry = address; |
114 return (entry == address); | 114 return (entry == address); |
115 } | 115 } |
116 | 116 |
117 void* buffer_address_[kMaxNumBuffers]; | 117 void* buffer_address_[kNumBuffers]; |
118 }; | 118 }; |
119 | 119 |
120 // Specializes TestSourceBasic to simulate a source that blocks for some time | 120 // Specializes TestSourceBasic to simulate a source that blocks for some time |
121 // in the OnMoreData callback. | 121 // in the OnMoreData callback. |
122 class TestSourceLaggy : public TestSourceBasic { | 122 class TestSourceLaggy : public TestSourceBasic { |
123 public: | 123 public: |
124 TestSourceLaggy(int laggy_after_buffer, int lag_in_ms) | 124 TestSourceLaggy(int laggy_after_buffer, int lag_in_ms) |
125 : laggy_after_buffer_(laggy_after_buffer), lag_in_ms_(lag_in_ms) { | 125 : laggy_after_buffer_(laggy_after_buffer), lag_in_ms_(lag_in_ms) { |
126 } | 126 } |
127 virtual uint32 OnMoreData(uint8* dest, | 127 virtual uint32 OnMoreData(uint8* dest, |
128 uint32 max_size, | 128 uint32 max_size, |
129 AudioBuffersState buffers_state) { | 129 AudioBuffersState buffers_state) { |
130 // Call the base, which increments the callback_count_. | 130 // Call the base, which increments the callback_count_. |
131 TestSourceBasic::OnMoreData(dest, max_size, buffers_state); | 131 TestSourceBasic::OnMoreData(dest, max_size, buffers_state); |
132 if (callback_count() > kMaxNumBuffers) { | 132 if (callback_count() > kNumBuffers) { |
133 ::Sleep(lag_in_ms_); | 133 ::Sleep(lag_in_ms_); |
134 } | 134 } |
135 return max_size; | 135 return max_size; |
136 } | 136 } |
137 private: | 137 private: |
138 int laggy_after_buffer_; | 138 int laggy_after_buffer_; |
139 int lag_in_ms_; | 139 int lag_in_ms_; |
140 }; | 140 }; |
141 | 141 |
142 class MockAudioSource : public AudioOutputStream::AudioSourceCallback { | 142 class MockAudioSource : public AudioOutputStream::AudioSourceCallback { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 } | 305 } |
306 | 306 |
307 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 307 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
308 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 308 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
309 16000, 16, 256)); | 309 16000, 16, 256)); |
310 ASSERT_TRUE(NULL != oas); | 310 ASSERT_TRUE(NULL != oas); |
311 TestSourceTripleBuffer test_triple_buffer; | 311 TestSourceTripleBuffer test_triple_buffer; |
312 EXPECT_TRUE(oas->Open()); | 312 EXPECT_TRUE(oas->Open()); |
313 oas->Start(&test_triple_buffer); | 313 oas->Start(&test_triple_buffer); |
314 ::Sleep(300); | 314 ::Sleep(300); |
315 EXPECT_GT(test_triple_buffer.callback_count(), kMaxNumBuffers); | 315 EXPECT_GT(test_triple_buffer.callback_count(), kNumBuffers); |
316 EXPECT_FALSE(test_triple_buffer.had_error()); | 316 EXPECT_FALSE(test_triple_buffer.had_error()); |
317 oas->Stop(); | 317 oas->Stop(); |
318 ::Sleep(500); | 318 ::Sleep(500); |
319 oas->Close(); | 319 oas->Close(); |
320 } | 320 } |
321 | 321 |
322 // Test potential deadlock situation if the source is slow or blocks for some | 322 // Test potential deadlock situation if the source is slow or blocks for some |
323 // time. The actual EXPECT_GT are mostly meaningless and the real test is that | 323 // time. The actual EXPECT_GT are mostly meaningless and the real test is that |
324 // the test completes in reasonable time. | 324 // the test completes in reasonable time. |
325 TEST(WinAudioTest, PCMWaveSlowSource) { | 325 TEST(WinAudioTest, PCMWaveSlowSource) { |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 593 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
594 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 594 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
595 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); | 595 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); |
596 ASSERT_TRUE(NULL != oas); | 596 ASSERT_TRUE(NULL != oas); |
597 | 597 |
598 NiceMock<MockAudioSource> source; | 598 NiceMock<MockAudioSource> source; |
599 EXPECT_TRUE(oas->Open()); | 599 EXPECT_TRUE(oas->Open()); |
600 | 600 |
601 uint32 bytes_100_ms = samples_100_ms * 2; | 601 uint32 bytes_100_ms = samples_100_ms * 2; |
602 | 602 |
603 // Audio output stream has either a double or triple buffer scheme. | 603 // We expect the amount of pending bytes will reaching 2 times of |
604 // We expect the amount of pending bytes will reaching up to 2 times of | 604 // |bytes_100_ms| because the audio output stream has a triple buffer scheme. |
605 // |bytes_100_ms| depending on number of buffers used. | |
606 // From that it would decrease as we are playing the data but not providing | 605 // From that it would decrease as we are playing the data but not providing |
607 // new one. And then we will try to provide zero data so the amount of | 606 // new one. And then we will try to provide zero data so the amount of |
608 // pending bytes will go down and eventually read zero. | 607 // pending bytes will go down and eventually read zero. |
609 InSequence s; | 608 InSequence s; |
610 | |
611 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 609 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
612 Field(&AudioBuffersState::pending_bytes, 0))) | 610 Field(&AudioBuffersState::pending_bytes, 0))) |
613 .WillOnce(Return(bytes_100_ms)); | 611 .WillOnce(Return(bytes_100_ms)); |
614 switch (NumberOfWaveOutBuffers()) { | 612 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
615 case 2: | 613 Field(&AudioBuffersState::pending_bytes, |
616 break; // Calls are the same as at end of 3-buffer scheme. | 614 bytes_100_ms))) |
617 case 3: | 615 .WillOnce(Return(bytes_100_ms)); |
618 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 616 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
619 Field(&AudioBuffersState::pending_bytes, | 617 Field(&AudioBuffersState::pending_bytes, |
620 bytes_100_ms))) | 618 2 * bytes_100_ms))) |
621 .WillOnce(Return(bytes_100_ms)); | 619 .WillOnce(Return(bytes_100_ms)); |
622 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 620 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
623 Field(&AudioBuffersState::pending_bytes, | 621 Field(&AudioBuffersState::pending_bytes, |
624 2 * bytes_100_ms))) | 622 2 * bytes_100_ms))) |
625 .WillOnce(Return(bytes_100_ms)); | 623 .Times(AnyNumber()) |
626 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 624 .WillRepeatedly(Return(0)); |
627 Field(&AudioBuffersState::pending_bytes, | |
628 2 * bytes_100_ms))) | |
629 .Times(AnyNumber()) | |
630 .WillRepeatedly(Return(0)); | |
631 default: | |
632 ASSERT_TRUE(false) << "Unexpected number of buffers"; | |
633 } | |
634 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 625 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
635 Field(&AudioBuffersState::pending_bytes, | 626 Field(&AudioBuffersState::pending_bytes, |
636 bytes_100_ms))) | 627 bytes_100_ms))) |
637 .Times(AnyNumber()) | 628 .Times(AnyNumber()) |
638 .WillRepeatedly(Return(0)); | 629 .WillRepeatedly(Return(0)); |
639 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 630 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
640 Field(&AudioBuffersState::pending_bytes, 0))) | 631 Field(&AudioBuffersState::pending_bytes, 0))) |
641 .Times(AnyNumber()) | 632 .Times(AnyNumber()) |
642 .WillRepeatedly(Return(0)); | 633 .WillRepeatedly(Return(0)); |
643 | 634 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 oas->Start(&source); | 742 oas->Start(&source); |
752 | 743 |
753 ::WaitForSingleObject(thread, INFINITE); | 744 ::WaitForSingleObject(thread, INFINITE); |
754 ::CloseHandle(thread); | 745 ::CloseHandle(thread); |
755 | 746 |
756 oas->Stop(); | 747 oas->Stop(); |
757 oas->Close(); | 748 oas->Close(); |
758 } | 749 } |
759 | 750 |
760 } // namespace media | 751 } // namespace media |
OLD | NEW |