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 "media/audio/audio_output_controller.h" | 5 #include "media/audio/audio_output_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 AudioOutputController::~AudioOutputController() { | 50 AudioOutputController::~AudioOutputController() { |
51 DCHECK_EQ(kClosed, state_); | 51 DCHECK_EQ(kClosed, state_); |
52 } | 52 } |
53 | 53 |
54 // static | 54 // static |
55 scoped_refptr<AudioOutputController> AudioOutputController::Create( | 55 scoped_refptr<AudioOutputController> AudioOutputController::Create( |
56 AudioManager* audio_manager, | 56 AudioManager* audio_manager, |
57 EventHandler* event_handler, | 57 EventHandler* event_handler, |
58 const AudioParameters& params, | 58 const AudioParameters& params, |
59 const std::string& output_device_id, | 59 const std::string& output_device_id, |
60 SyncReader* sync_reader) { | 60 SyncReader* sync_reader, |
| 61 const content::mojom::AudioOutput::CreateStreamCallback& callback) { |
61 DCHECK(audio_manager); | 62 DCHECK(audio_manager); |
62 DCHECK(sync_reader); | 63 DCHECK(sync_reader); |
63 | 64 |
64 if (!params.IsValid() || !audio_manager) | 65 if (!params.IsValid() || !audio_manager) |
65 return NULL; | 66 return NULL; |
66 | 67 |
67 scoped_refptr<AudioOutputController> controller(new AudioOutputController( | 68 scoped_refptr<AudioOutputController> controller(new AudioOutputController( |
68 audio_manager, event_handler, params, output_device_id, sync_reader)); | 69 audio_manager, event_handler, params, output_device_id, sync_reader)); |
69 controller->message_loop_->PostTask(FROM_HERE, base::Bind( | 70 controller->message_loop_->PostTask( |
70 &AudioOutputController::DoCreate, controller, false)); | 71 FROM_HERE, base::Bind(&AudioOutputController::DoCreate, controller, false, |
| 72 callback)); |
71 return controller; | 73 return controller; |
72 } | 74 } |
73 | 75 |
74 void AudioOutputController::Play() { | 76 void AudioOutputController::Play() { |
75 message_loop_->PostTask(FROM_HERE, base::Bind( | 77 message_loop_->PostTask(FROM_HERE, base::Bind( |
76 &AudioOutputController::DoPlay, this)); | 78 &AudioOutputController::DoPlay, this)); |
77 } | 79 } |
78 | 80 |
79 void AudioOutputController::Pause() { | 81 void AudioOutputController::Pause() { |
80 message_loop_->PostTask(FROM_HERE, base::Bind( | 82 message_loop_->PostTask(FROM_HERE, base::Bind( |
(...skipping 22 matching lines...) Expand all Loading... |
103 | 105 |
104 void AudioOutputController::SwitchOutputDevice( | 106 void AudioOutputController::SwitchOutputDevice( |
105 const std::string& output_device_id, const base::Closure& callback) { | 107 const std::string& output_device_id, const base::Closure& callback) { |
106 message_loop_->PostTaskAndReply( | 108 message_loop_->PostTaskAndReply( |
107 FROM_HERE, | 109 FROM_HERE, |
108 base::Bind(&AudioOutputController::DoSwitchOutputDevice, this, | 110 base::Bind(&AudioOutputController::DoSwitchOutputDevice, this, |
109 output_device_id), | 111 output_device_id), |
110 callback); | 112 callback); |
111 } | 113 } |
112 | 114 |
113 void AudioOutputController::DoCreate(bool is_for_device_change) { | 115 void AudioOutputController::DoCreate( |
| 116 bool is_for_device_change, |
| 117 const content::mojom::AudioOutput::CreateStreamCallback& callback) { |
114 DCHECK(message_loop_->BelongsToCurrentThread()); | 118 DCHECK(message_loop_->BelongsToCurrentThread()); |
115 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CreateTime"); | 119 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CreateTime"); |
116 TRACE_EVENT0("audio", "AudioOutputController::DoCreate"); | 120 TRACE_EVENT0("audio", "AudioOutputController::DoCreate"); |
117 | 121 |
118 // Close() can be called before DoCreate() is executed. | 122 // Close() can be called before DoCreate() is executed. |
119 if (state_ == kClosed) | 123 if (state_ == kClosed) |
120 return; | 124 return; |
121 | 125 |
122 DoStopCloseAndClearStream(); // Calls RemoveOutputDeviceChangeListener(). | 126 DoStopCloseAndClearStream(); // Calls RemoveOutputDeviceChangeListener(). |
123 DCHECK_EQ(kEmpty, state_); | 127 DCHECK_EQ(kEmpty, state_); |
124 | 128 |
125 stream_ = diverting_to_stream_ ? | 129 stream_ = diverting_to_stream_ ? diverting_to_stream_ |
126 diverting_to_stream_ : | 130 : audio_manager_->MakeAudioOutputStreamProxy( |
127 audio_manager_->MakeAudioOutputStreamProxy(params_, output_device_id_); | 131 params_, output_device_id_); |
128 if (!stream_) { | 132 if (!stream_) { |
129 state_ = kError; | 133 state_ = kError; |
130 handler_->OnError(); | 134 handler_->OnError(); |
131 return; | 135 return; |
132 } | 136 } |
133 | 137 |
134 if (!stream_->Open()) { | 138 if (!stream_->Open()) { |
135 DoStopCloseAndClearStream(); | 139 DoStopCloseAndClearStream(); |
136 state_ = kError; | 140 state_ = kError; |
137 handler_->OnError(); | 141 handler_->OnError(); |
138 return; | 142 return; |
139 } | 143 } |
140 | 144 |
141 // Everything started okay, so re-register for state change callbacks if | 145 // Everything started okay, so re-register for state change callbacks if |
142 // stream_ was created via AudioManager. | 146 // stream_ was created via AudioManager. |
143 if (stream_ != diverting_to_stream_) | 147 if (stream_ != diverting_to_stream_) |
144 audio_manager_->AddOutputDeviceChangeListener(this); | 148 audio_manager_->AddOutputDeviceChangeListener(this); |
145 | 149 |
146 // We have successfully opened the stream. Set the initial volume. | 150 // We have successfully opened the stream. Set the initial volume. |
147 stream_->SetVolume(volume_); | 151 stream_->SetVolume(volume_); |
148 | 152 |
149 // Finally set the state to kCreated. | 153 // Finally set the state to kCreated. |
150 state_ = kCreated; | 154 state_ = kCreated; |
151 | 155 |
152 // And then report we have been created if we haven't done so already. | 156 // And then report we have been created if we haven't done so already. |
153 if (!is_for_device_change) | 157 if (!is_for_device_change) |
154 handler_->OnCreated(); | 158 handler_->OnCreated(callback); |
155 } | 159 } |
156 | 160 |
157 void AudioOutputController::DoPlay() { | 161 void AudioOutputController::DoPlay() { |
158 DCHECK(message_loop_->BelongsToCurrentThread()); | 162 DCHECK(message_loop_->BelongsToCurrentThread()); |
159 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); | 163 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); |
160 TRACE_EVENT0("audio", "AudioOutputController::DoPlay"); | 164 TRACE_EVENT0("audio", "AudioOutputController::DoPlay"); |
161 | 165 |
162 // We can start from created or paused state. | 166 // We can start from created or paused state. |
163 if (state_ != kCreated && state_ != kPaused) | 167 if (state_ != kCreated && state_ != kPaused) |
164 return; | 168 return; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.DeviceChangeTime"); | 356 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.DeviceChangeTime"); |
353 TRACE_EVENT0("audio", "AudioOutputController::OnDeviceChange"); | 357 TRACE_EVENT0("audio", "AudioOutputController::OnDeviceChange"); |
354 | 358 |
355 // TODO(dalecurtis): Notify the renderer side that a device change has | 359 // TODO(dalecurtis): Notify the renderer side that a device change has |
356 // occurred. Currently querying the hardware information here will lead to | 360 // occurred. Currently querying the hardware information here will lead to |
357 // crashes on OSX. See http://crbug.com/158170. | 361 // crashes on OSX. See http://crbug.com/158170. |
358 | 362 |
359 // Recreate the stream (DoCreate() will first shut down an existing stream). | 363 // Recreate the stream (DoCreate() will first shut down an existing stream). |
360 // Exit if we ran into an error. | 364 // Exit if we ran into an error. |
361 const State original_state = state_; | 365 const State original_state = state_; |
362 DoCreate(true); | 366 DoCreate(true, content::mojom::AudioOutput::CreateStreamCallback()); |
363 if (!stream_ || state_ == kError) | 367 if (!stream_ || state_ == kError) |
364 return; | 368 return; |
365 | 369 |
366 // Get us back to the original state or an equivalent state. | 370 // Get us back to the original state or an equivalent state. |
367 switch (original_state) { | 371 switch (original_state) { |
368 case kPlaying: | 372 case kPlaying: |
369 DoPlay(); | 373 DoPlay(); |
370 return; | 374 return; |
371 case kCreated: | 375 case kCreated: |
372 case kPaused: | 376 case kPaused: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 DCHECK(message_loop_->BelongsToCurrentThread()); | 432 DCHECK(message_loop_->BelongsToCurrentThread()); |
429 | 433 |
430 // If we should be playing and we haven't, that's a wedge. | 434 // If we should be playing and we haven't, that's a wedge. |
431 if (state_ == kPlaying) { | 435 if (state_ == kPlaying) { |
432 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", | 436 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", |
433 base::AtomicRefCountIsOne(&on_more_io_data_called_)); | 437 base::AtomicRefCountIsOne(&on_more_io_data_called_)); |
434 } | 438 } |
435 } | 439 } |
436 | 440 |
437 } // namespace media | 441 } // namespace media |
OLD | NEW |