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 kNumBuffers = 3; | 79 const int kMaxNumBuffers = 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() % kNumBuffers == 2) { | 95 if (callback_count() % NumberOfWaveOutBuffers() == 2) { |
96 set_error(!CompareExistingIfNotNULL(2, dest)); | 96 set_error(!CompareExistingIfNotNULL(2, dest)); |
97 } else if (callback_count() % kNumBuffers == 1) { | 97 } else if (callback_count() % NumberOfWaveOutBuffers() == 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() > kNumBuffers) { | 102 if (callback_count() > kMaxNumBuffers) { |
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_[kNumBuffers]; | 117 void* buffer_address_[kMaxNumBuffers]; |
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() > kNumBuffers) { | 132 if (callback_count() > kMaxNumBuffers) { |
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(), kNumBuffers); | 315 EXPECT_GT(test_triple_buffer.callback_count(), kMaxNumBuffers); |
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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 // We expect the amount of pending bytes will reaching 2 times of | 603 // We expect the amount of pending bytes will reaching 2 times of |
604 // |bytes_100_ms| because the audio output stream has a triple buffer scheme. | 604 // |bytes_100_ms| because the audio output stream has a triple buffer scheme. |
scherkus (not reviewing)
2012/06/07 17:25:41
nit: update comment
enal1
2012/06/07 20:56:22
Done.
| |
605 // 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 |
606 // 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 |
607 // pending bytes will go down and eventually read zero. | 607 // pending bytes will go down and eventually read zero. |
608 InSequence s; | 608 InSequence s; |
609 | |
609 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 610 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
610 Field(&AudioBuffersState::pending_bytes, 0))) | 611 Field(&AudioBuffersState::pending_bytes, 0))) |
611 .WillOnce(Return(bytes_100_ms)); | 612 .WillOnce(Return(bytes_100_ms)); |
612 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 613 switch (NumberOfWaveOutBuffers()) { |
613 Field(&AudioBuffersState::pending_bytes, | 614 case 2: |
614 bytes_100_ms))) | 615 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
615 .WillOnce(Return(bytes_100_ms)); | 616 Field(&AudioBuffersState::pending_bytes, |
616 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 617 bytes_100_ms))) |
617 Field(&AudioBuffersState::pending_bytes, | 618 .Times(AnyNumber()) |
618 2 * bytes_100_ms))) | 619 .WillRepeatedly(Return(0)); |
619 .WillOnce(Return(bytes_100_ms)); | 620 break; |
620 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 621 case 3: |
621 Field(&AudioBuffersState::pending_bytes, | 622 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
622 2 * bytes_100_ms))) | 623 Field(&AudioBuffersState::pending_bytes, |
623 .Times(AnyNumber()) | 624 bytes_100_ms))) |
624 .WillRepeatedly(Return(0)); | 625 .WillOnce(Return(bytes_100_ms)); |
625 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 626 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
626 Field(&AudioBuffersState::pending_bytes, | 627 Field(&AudioBuffersState::pending_bytes, |
627 bytes_100_ms))) | 628 2 * bytes_100_ms))) |
628 .Times(AnyNumber()) | 629 .WillOnce(Return(bytes_100_ms)); |
629 .WillRepeatedly(Return(0)); | 630 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
631 Field(&AudioBuffersState::pending_bytes, | |
632 2 * bytes_100_ms))) | |
633 .Times(AnyNumber()) | |
634 .WillRepeatedly(Return(0)); | |
635 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | |
636 Field(&AudioBuffersState::pending_bytes, | |
637 bytes_100_ms))) | |
638 .Times(AnyNumber()) | |
639 .WillRepeatedly(Return(0)); | |
640 default: | |
641 ASSERT_TRUE(false) << "Unexpected number of buffers"; | |
642 } | |
630 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, | 643 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, |
631 Field(&AudioBuffersState::pending_bytes, 0))) | 644 Field(&AudioBuffersState::pending_bytes, 0))) |
632 .Times(AnyNumber()) | 645 .Times(AnyNumber()) |
633 .WillRepeatedly(Return(0)); | 646 .WillRepeatedly(Return(0)); |
634 | 647 |
635 oas->Start(&source); | 648 oas->Start(&source); |
636 ::Sleep(500); | 649 ::Sleep(500); |
637 oas->Stop(); | 650 oas->Stop(); |
638 oas->Close(); | 651 oas->Close(); |
639 } | 652 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 oas->Start(&source); | 755 oas->Start(&source); |
743 | 756 |
744 ::WaitForSingleObject(thread, INFINITE); | 757 ::WaitForSingleObject(thread, INFINITE); |
745 ::CloseHandle(thread); | 758 ::CloseHandle(thread); |
746 | 759 |
747 oas->Stop(); | 760 oas->Stop(); |
748 oas->Close(); | 761 oas->Close(); |
749 } | 762 } |
750 | 763 |
751 } // namespace media | 764 } // namespace media |
OLD | NEW |