Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: media/audio/win/audio_output_win_unittest.cc

Issue 10540034: Use 2 buffers on presumable good Windows boxes. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/win/audio_manager_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // We expect the amount of pending bytes will reaching 2 times of 603 // Audio output stream has either a double or triple buffer scheme.
604 // |bytes_100_ms| because the audio output stream has a triple buffer scheme. 604 // We expect the amount of pending bytes will reaching up to 2 times of
605 // |bytes_100_ms| depending on number of buffers used.
605 // From that it would decrease as we are playing the data but not providing 606 // 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 607 // 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. 608 // pending bytes will go down and eventually read zero.
608 InSequence s; 609 InSequence s;
610
609 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 611 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
610 Field(&AudioBuffersState::pending_bytes, 0))) 612 Field(&AudioBuffersState::pending_bytes, 0)))
611 .WillOnce(Return(bytes_100_ms)); 613 .WillOnce(Return(bytes_100_ms));
612 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 614 switch (NumberOfWaveOutBuffers()) {
613 Field(&AudioBuffersState::pending_bytes, 615 case 2:
614 bytes_100_ms))) 616 break; // Calls are the same as at end of 3-buffer scheme.
615 .WillOnce(Return(bytes_100_ms)); 617 case 3:
616 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 618 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
617 Field(&AudioBuffersState::pending_bytes, 619 Field(&AudioBuffersState::pending_bytes,
618 2 * bytes_100_ms))) 620 bytes_100_ms)))
619 .WillOnce(Return(bytes_100_ms)); 621 .WillOnce(Return(bytes_100_ms));
620 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 622 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
621 Field(&AudioBuffersState::pending_bytes, 623 Field(&AudioBuffersState::pending_bytes,
622 2 * bytes_100_ms))) 624 2 * bytes_100_ms)))
623 .Times(AnyNumber()) 625 .WillOnce(Return(bytes_100_ms));
624 .WillRepeatedly(Return(0)); 626 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
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 }
625 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 634 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
626 Field(&AudioBuffersState::pending_bytes, 635 Field(&AudioBuffersState::pending_bytes,
627 bytes_100_ms))) 636 bytes_100_ms)))
628 .Times(AnyNumber()) 637 .Times(AnyNumber())
629 .WillRepeatedly(Return(0)); 638 .WillRepeatedly(Return(0));
630 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 639 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms,
631 Field(&AudioBuffersState::pending_bytes, 0))) 640 Field(&AudioBuffersState::pending_bytes, 0)))
632 .Times(AnyNumber()) 641 .Times(AnyNumber())
633 .WillRepeatedly(Return(0)); 642 .WillRepeatedly(Return(0));
634 643
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 oas->Start(&source); 751 oas->Start(&source);
743 752
744 ::WaitForSingleObject(thread, INFINITE); 753 ::WaitForSingleObject(thread, INFINITE);
745 ::CloseHandle(thread); 754 ::CloseHandle(thread);
746 755
747 oas->Stop(); 756 oas->Stop();
748 oas->Close(); 757 oas->Close();
749 } 758 }
750 759
751 } // namespace media 760 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/win/audio_manager_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698