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

Side by Side Diff: media/audio/audio_output_mixer.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
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 "media/audio/audio_output_mixer.h" 5 #include "media/audio/audio_output_mixer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 29 matching lines...) Expand all
40 return true; 40 return true;
41 AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(params_); 41 AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(params_);
42 if (!stream) 42 if (!stream)
43 return false; 43 return false;
44 if (!stream->Open()) { 44 if (!stream->Open()) {
45 stream->Close(); 45 stream->Close();
46 return false; 46 return false;
47 } 47 }
48 pending_bytes_ = 0; // Just in case. 48 pending_bytes_ = 0; // Just in case.
49 physical_stream_.reset(stream); 49 physical_stream_.reset(stream);
50 physical_stream_->SetVolume(1.0);
51 physical_stream_->Start(this);
50 close_timer_.Reset(); 52 close_timer_.Reset();
51 return true; 53 return true;
52 } 54 }
53 55
54 bool AudioOutputMixer::StartStream( 56 bool AudioOutputMixer::StartStream(
55 AudioOutputStream::AudioSourceCallback* callback, 57 AudioOutputStream::AudioSourceCallback* callback,
56 AudioOutputProxy* stream_proxy) { 58 AudioOutputProxy* stream_proxy) {
57 DCHECK_EQ(MessageLoop::current(), message_loop_); 59 DCHECK_EQ(MessageLoop::current(), message_loop_);
58 60
59 // May need to re-open the physical stream if no active proxies and 61 // May need to re-open the physical stream if no active proxies and
60 // enough time had pass. 62 // enough time had pass.
61 OpenStream(); 63 OpenStream();
62 if (!physical_stream_.get()) 64 if (!physical_stream_.get())
63 return false; 65 return false;
64 66
65 double volume = 0.0; 67 double volume = 0.0;
66 stream_proxy->GetVolume(&volume); 68 stream_proxy->GetVolume(&volume);
67 bool should_start = proxies_.empty(); 69
68 { 70 base::AutoLock lock(lock_);
69 base::AutoLock lock(lock_); 71 ProxyData* proxy_data = &proxies_[stream_proxy];
70 ProxyData* proxy_data = &proxies_[stream_proxy]; 72 proxy_data->audio_source_callback = callback;
71 proxy_data->audio_source_callback = callback; 73 proxy_data->volume = volume;
72 proxy_data->volume = volume; 74 proxy_data->pending_bytes = 0;
73 proxy_data->pending_bytes = 0;
74 }
75 // We cannot start physical stream under the lock,
76 // OnMoreData() would try acquiring it...
77 if (should_start) {
78 physical_stream_->SetVolume(1.0);
79 physical_stream_->Start(this);
80 }
81 return true; 75 return true;
82 } 76 }
83 77
84 void AudioOutputMixer::StopStream(AudioOutputProxy* stream_proxy) { 78 void AudioOutputMixer::StopStream(AudioOutputProxy* stream_proxy) {
85 DCHECK_EQ(MessageLoop::current(), message_loop_); 79 DCHECK_EQ(MessageLoop::current(), message_loop_);
86 80
87 // Because of possible deadlock we cannot stop physical stream under the lock 81 base::AutoLock lock(lock_);
88 // (physical_stream_->Stop() can call OnError(), and it acquires the lock to 82 ProxyMap::iterator it = proxies_.find(stream_proxy);
89 // iterate through proxies), so acquire the lock, update proxy list, release 83 if (it != proxies_.end())
90 // the lock, and only then stop physical stream if necessary. 84 proxies_.erase(it);
91 bool stop_physical_stream = false; 85 if (physical_stream_.get())
92 {
93 base::AutoLock lock(lock_);
94 ProxyMap::iterator it = proxies_.find(stream_proxy);
95 if (it != proxies_.end()) {
96 proxies_.erase(it);
97 stop_physical_stream = proxies_.empty();
98 }
99 }
100 if (physical_stream_.get()) {
101 if (stop_physical_stream) {
102 physical_stream_->Stop();
103 pending_bytes_ = 0; // Just in case.
104 }
105 close_timer_.Reset(); 86 close_timer_.Reset();
106 }
107 } 87 }
108 88
109 void AudioOutputMixer::StreamVolumeSet(AudioOutputProxy* stream_proxy, 89 void AudioOutputMixer::StreamVolumeSet(AudioOutputProxy* stream_proxy,
110 double volume) { 90 double volume) {
111 DCHECK_EQ(MessageLoop::current(), message_loop_); 91 DCHECK_EQ(MessageLoop::current(), message_loop_);
112 92
113 ProxyMap::iterator it = proxies_.find(stream_proxy); 93 ProxyMap::iterator it = proxies_.find(stream_proxy);
114 94
115 // Do nothing if stream is not currently playing. 95 // Do nothing if stream is not currently playing.
116 if (it != proxies_.end()) { 96 if (it != proxies_.end()) {
(...skipping 20 matching lines...) Expand all
137 ClosePhysicalStream(); 117 ClosePhysicalStream();
138 118
139 // No AudioOutputProxy objects should hold a reference to us when we get 119 // No AudioOutputProxy objects should hold a reference to us when we get
140 // to this stage. 120 // to this stage.
141 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference"; 121 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference";
142 } 122 }
143 123
144 void AudioOutputMixer::ClosePhysicalStream() { 124 void AudioOutputMixer::ClosePhysicalStream() {
145 DCHECK_EQ(MessageLoop::current(), message_loop_); 125 DCHECK_EQ(MessageLoop::current(), message_loop_);
146 126
147 if (proxies_.empty() && physical_stream_.get() != NULL) 127 if (proxies_.empty() && physical_stream_.get() != NULL) {
128 physical_stream_->Stop();
148 physical_stream_.release()->Close(); 129 physical_stream_.release()->Close();
130 }
149 } 131 }
150 132
151 // AudioSourceCallback implementation. 133 // AudioSourceCallback implementation.
152 uint32 AudioOutputMixer::OnMoreData(uint8* dest, 134 uint32 AudioOutputMixer::OnMoreData(uint8* dest,
153 uint32 max_size, 135 uint32 max_size,
154 AudioBuffersState buffers_state) { 136 AudioBuffersState buffers_state) {
155 max_size = std::min(max_size, 137 max_size = std::min(max_size,
156 static_cast<uint32>(params_.GetBytesPerBuffer())); 138 static_cast<uint32>(params_.GetBytesPerBuffer()));
157 // TODO(enal): consider getting rid of lock as it is in time-critical code. 139 // TODO(enal): consider getting rid of lock as it is in time-critical code.
158 // E.g. swap |proxies_| with local variable, and merge 2 lists 140 // E.g. swap |proxies_| with local variable, and merge 2 lists
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 221 }
240 222
241 void AudioOutputMixer::WaitTillDataReady() { 223 void AudioOutputMixer::WaitTillDataReady() {
242 base::AutoLock lock(lock_); 224 base::AutoLock lock(lock_);
243 for (ProxyMap::iterator it = proxies_.begin(); it != proxies_.end(); ++it) { 225 for (ProxyMap::iterator it = proxies_.begin(); it != proxies_.end(); ++it) {
244 it->second.audio_source_callback->WaitTillDataReady(); 226 it->second.audio_source_callback->WaitTillDataReady();
245 } 227 }
246 } 228 }
247 229
248 } // namespace media 230 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698