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

Side by Side Diff: media/audio/audio_output_mixer.cc

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

Powered by Google App Engine
This is Rietveld 408576698