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/win/audio_device_listener_win.h" | 5 #include "media/audio/win/audio_device_listener_win.h" |
6 | 6 |
7 #include <Audioclient.h> | 7 #include <Audioclient.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 return; | 61 return; |
62 | 62 |
63 HRESULT hr = device_enumerator->RegisterEndpointNotificationCallback(this); | 63 HRESULT hr = device_enumerator->RegisterEndpointNotificationCallback(this); |
64 if (FAILED(hr)) { | 64 if (FAILED(hr)) { |
65 LOG(ERROR) << "RegisterEndpointNotificationCallback failed: " | 65 LOG(ERROR) << "RegisterEndpointNotificationCallback failed: " |
66 << std::hex << hr; | 66 << std::hex << hr; |
67 return; | 67 return; |
68 } | 68 } |
69 | 69 |
70 device_enumerator_ = device_enumerator; | 70 device_enumerator_ = device_enumerator; |
71 | |
72 default_render_device_id_ = GetDeviceId(eRender, eConsole); | |
henrika_webrtc
2015/07/21 09:42:24
Nice to get rid of all these ;-)
| |
73 default_capture_device_id_ = GetDeviceId(eCapture, eConsole); | |
74 default_communications_render_device_id_ = | |
75 GetDeviceId(eRender, eCommunications); | |
76 default_communications_capture_device_id_ = | |
77 GetDeviceId(eCapture, eCommunications); | |
78 } | 71 } |
79 | 72 |
80 AudioDeviceListenerWin::~AudioDeviceListenerWin() { | 73 AudioDeviceListenerWin::~AudioDeviceListenerWin() { |
81 DCHECK(thread_checker_.CalledOnValidThread()); | 74 DCHECK(thread_checker_.CalledOnValidThread()); |
82 if (device_enumerator_.get()) { | 75 if (device_enumerator_.get()) { |
83 HRESULT hr = | 76 HRESULT hr = |
84 device_enumerator_->UnregisterEndpointNotificationCallback(this); | 77 device_enumerator_->UnregisterEndpointNotificationCallback(this); |
85 LOG_IF(ERROR, FAILED(hr)) << "UnregisterEndpointNotificationCallback() " | 78 LOG_IF(ERROR, FAILED(hr)) << "UnregisterEndpointNotificationCallback() " |
86 << "failed: " << std::hex << hr; | 79 << "failed: " << std::hex << hr; |
87 } | 80 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 } | 126 } |
134 | 127 |
135 STDMETHODIMP AudioDeviceListenerWin::OnDefaultDeviceChanged( | 128 STDMETHODIMP AudioDeviceListenerWin::OnDefaultDeviceChanged( |
136 EDataFlow flow, ERole role, LPCWSTR new_default_device_id) { | 129 EDataFlow flow, ERole role, LPCWSTR new_default_device_id) { |
137 // Only listen for console and communication device changes. | 130 // Only listen for console and communication device changes. |
138 if ((role != eConsole && role != eCommunications) || | 131 if ((role != eConsole && role != eCommunications) || |
139 (flow != eRender && flow != eCapture)) { | 132 (flow != eRender && flow != eCapture)) { |
140 return S_OK; | 133 return S_OK; |
141 } | 134 } |
142 | 135 |
143 // Grab a pointer to the appropriate ID member. | |
144 // Note that there are three "?:"'s here to select the right ID. | |
145 std::string* current_device_id = | |
146 flow == eRender ? ( | |
147 role == eConsole ? | |
148 &default_render_device_id_ : | |
149 &default_communications_render_device_id_ | |
150 ) : ( | |
151 role == eConsole ? | |
152 &default_capture_device_id_ : | |
153 &default_communications_capture_device_id_ | |
154 ); | |
155 | |
156 // If no device is now available, |new_default_device_id| will be NULL. | 136 // If no device is now available, |new_default_device_id| will be NULL. |
157 std::string new_device_id; | 137 std::string new_device_id; |
158 if (new_default_device_id) | 138 if (new_default_device_id) |
159 new_device_id = base::WideToUTF8(new_default_device_id); | 139 new_device_id = base::WideToUTF8(new_default_device_id); |
160 | 140 |
141 // Only output device changes should be forwarded. Do not attempt to filter | |
142 // changes based on device id since some devices may not change their device | |
143 // id and instead trigger some internal flow change: http://crbug.com/506712 | |
144 // | |
145 // We rate limit device changes to avoid a single device change causing back | |
146 // to back changes for eCommunications and eConsole; this is worth doing as | |
147 // it provides a substantially faster resumption of playback. | |
148 bool did_run_listener_cb = false; | |
149 const base::TimeTicks now = base::TimeTicks::Now(); | |
150 if (flow == eRender && | |
151 now - last_device_change_time_ > base::TimeDelta::FromMilliseconds(250)) { | |
henrika_webrtc
2015/07/21 09:42:23
How did you come up with 250?
DaleCurtis
2015/07/21 19:03:36
Dice roll! Well actually... I physically couldn't
henrika (OOO until Aug 14)
2015/07/22 07:58:20
Acknowledged.
| |
152 last_device_change_time_ = now; | |
153 listener_cb_.Run(); | |
154 did_run_listener_cb = true; | |
henrika_webrtc
2015/07/21 09:42:23
Is did_run_listener_cb ever used?
DaleCurtis
2015/07/21 19:03:36
In the DVLOG() below.
henrika (OOO until Aug 14)
2015/07/22 07:58:20
Acknowledged.
| |
155 } | |
156 | |
161 DVLOG(1) << "OnDefaultDeviceChanged() " | 157 DVLOG(1) << "OnDefaultDeviceChanged() " |
162 << "new_default_device: " | 158 << "new_default_device: " |
163 << (new_default_device_id ? | 159 << (new_default_device_id |
164 CoreAudioUtil::GetFriendlyName(new_device_id) : "No device") | 160 ? CoreAudioUtil::GetFriendlyName(new_device_id) |
161 : "no device") | |
165 << ", flow: " << FlowToString(flow) | 162 << ", flow: " << FlowToString(flow) |
166 << ", role: " << RoleToString(role); | 163 << ", role: " << RoleToString(role) |
167 | 164 << ", notified manager: " << (did_run_listener_cb ? "Yes" : "No"); |
168 // Only fire a state change event if the device has actually changed. | |
169 // TODO(dalecurtis): This still seems to fire an extra event on my machine for | |
170 // an unplug event (probably others too); e.g., we get two transitions to a | |
171 // new default device id. | |
172 if (new_device_id.compare(*current_device_id) == 0) | |
173 return S_OK; | |
174 | |
175 // Store the new id in the member variable (that current_device_id points to). | |
176 *current_device_id = new_device_id; | |
177 listener_cb_.Run(); | |
178 | 165 |
179 return S_OK; | 166 return S_OK; |
180 } | 167 } |
181 | 168 |
182 } // namespace media | 169 } // namespace media |
OLD | NEW |