| 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 // Implementation of AudioInputStream for Mac OS X using the special AUHAL | 5 // Implementation of AudioInputStream for Mac OS X using the special AUHAL |
| 6 // input Audio Unit present in OS 10.4 and later. | 6 // input Audio Unit present in OS 10.4 and later. |
| 7 // The AUHAL input Audio Unit is for low-latency audio I/O. | 7 // The AUHAL input Audio Unit is for low-latency audio I/O. |
| 8 // | 8 // |
| 9 // Overview of operation: | 9 // Overview of operation: |
| 10 // | 10 // |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 const AudioObjectPropertyAddress addresses[], | 123 const AudioObjectPropertyAddress addresses[], |
| 124 void* context); | 124 void* context); |
| 125 OSStatus DevicePropertyChanged(AudioObjectID object_id, | 125 OSStatus DevicePropertyChanged(AudioObjectID object_id, |
| 126 UInt32 num_addresses, | 126 UInt32 num_addresses, |
| 127 const AudioObjectPropertyAddress addresses[]); | 127 const AudioObjectPropertyAddress addresses[]); |
| 128 | 128 |
| 129 // Updates the |device_property_changes_map_| on the main browser thread, | 129 // Updates the |device_property_changes_map_| on the main browser thread, |
| 130 // (CrBrowserMain) which is the same thread as this instance is created on. | 130 // (CrBrowserMain) which is the same thread as this instance is created on. |
| 131 void DevicePropertyChangedOnMainThread(const std::vector<UInt32>& properties); | 131 void DevicePropertyChangedOnMainThread(const std::vector<UInt32>& properties); |
| 132 | 132 |
| 133 // Updates |last_callback_time_| on the main browser thread. | |
| 134 void UpdateDataCallbackTimeOnMainThread(base::TimeTicks now_tick); | |
| 135 | |
| 136 // Registers OnDevicePropertyChanged() to receive notifications when device | 133 // Registers OnDevicePropertyChanged() to receive notifications when device |
| 137 // properties changes. | 134 // properties changes. |
| 138 void RegisterDeviceChangeListener(); | 135 void RegisterDeviceChangeListener(); |
| 139 // Stop listening for changes in device properties. | 136 // Stop listening for changes in device properties. |
| 140 void DeRegisterDeviceChangeListener(); | 137 void DeRegisterDeviceChangeListener(); |
| 141 | 138 |
| 142 // Gets the fixed capture hardware latency and store it during initialization. | 139 // Gets the fixed capture hardware latency and store it during initialization. |
| 143 // Returns 0 if not available. | 140 // Returns 0 if not available. |
| 144 double GetHardwareLatency(); | 141 double GetHardwareLatency(); |
| 145 | 142 |
| 146 // Gets the current capture delay value. | 143 // Gets the current capture delay value. |
| 147 double GetCaptureLatency(const AudioTimeStamp* input_time_stamp); | 144 double GetCaptureLatency(const AudioTimeStamp* input_time_stamp); |
| 148 | 145 |
| 149 // Gets the number of channels for a stream of audio data. | 146 // Gets the number of channels for a stream of audio data. |
| 150 int GetNumberOfChannelsFromStream(); | 147 int GetNumberOfChannelsFromStream(); |
| 151 | 148 |
| 152 // Issues the OnError() callback to the |sink_|. | 149 // Issues the OnError() callback to the |sink_|. |
| 153 void HandleError(OSStatus err); | 150 void HandleError(OSStatus err); |
| 154 | 151 |
| 155 // Helper function to check if the volume control is avialable on specific | 152 // Helper function to check if the volume control is avialable on specific |
| 156 // channel. | 153 // channel. |
| 157 bool IsVolumeSettableOnChannel(int channel); | 154 bool IsVolumeSettableOnChannel(int channel); |
| 158 | 155 |
| 159 // Helper methods to set and get atomic |input_callback_is_active_|. | 156 // Helper methods to set and get atomic |input_callback_is_active_|. |
| 160 void SetInputCallbackIsActive(bool active); | 157 void SetInputCallbackIsActive(bool active); |
| 161 bool GetInputCallbackIsActive(); | 158 bool GetInputCallbackIsActive(); |
| 162 | 159 |
| 163 // Checks if a stream was started successfully and the audio unit also starts | 160 // Checks if a stream was started successfully and the audio unit also starts |
| 164 // to call InputProc() as it should. This method is called once when a timer | 161 // to call InputProc() as it should. This method is called once when a timer |
| 165 // expires 5 seconds after calling Start(). | 162 // expires some time after calling Start(). |
| 166 void CheckInputStartupSuccess(); | 163 void CheckInputStartupSuccess(); |
| 167 | 164 |
| 168 // Checks (periodically) if a stream is alive by comparing the current time | |
| 169 // with the last timestamp stored in a data callback. Calls RestartAudio() | |
| 170 // when a restart is required. | |
| 171 void CheckIfInputStreamIsAlive(); | |
| 172 | |
| 173 // Uninitializes the audio unit if needed. | 165 // Uninitializes the audio unit if needed. |
| 174 void CloseAudioUnit(); | 166 void CloseAudioUnit(); |
| 175 | 167 |
| 176 // Called by CheckIfInputStreamIsAlive() on the main thread when an audio | |
| 177 // restarts is required. Restarts the existing audio stream reusing the | |
| 178 // current audio parameters. | |
| 179 void RestartAudio(); | |
| 180 | |
| 181 // Adds extra UMA stats when it has been detected that startup failed. | 168 // Adds extra UMA stats when it has been detected that startup failed. |
| 182 void AddHistogramsForFailedStartup(); | 169 void AddHistogramsForFailedStartup(); |
| 183 | 170 |
| 184 // Scans the map of all available property changes (notification types) and | 171 // Scans the map of all available property changes (notification types) and |
| 185 // filters out some that make sense to add to UMA stats. | 172 // filters out some that make sense to add to UMA stats. |
| 186 void AddDevicePropertyChangesToUMA(bool startup_failed); | 173 void AddDevicePropertyChangesToUMA(bool startup_failed); |
| 187 | 174 |
| 188 // Updates capture timestamp, current lost frames, and total lost frames and | 175 // Updates capture timestamp, current lost frames, and total lost frames and |
| 189 // glitches. | 176 // glitches. |
| 190 void UpdateCaptureTimestamp(const AudioTimeStamp* timestamp); | 177 void UpdateCaptureTimestamp(const AudioTimeStamp* timestamp); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 232 |
| 246 // Used to defer Start() to workaround http://crbug.com/160920. | 233 // Used to defer Start() to workaround http://crbug.com/160920. |
| 247 base::CancelableClosure deferred_start_cb_; | 234 base::CancelableClosure deferred_start_cb_; |
| 248 | 235 |
| 249 // Contains time of last successful call to AudioUnitRender(). | 236 // Contains time of last successful call to AudioUnitRender(). |
| 250 // Initialized first time in Start() and then updated for each valid | 237 // Initialized first time in Start() and then updated for each valid |
| 251 // audio buffer. Used to detect long error sequences and to take actions | 238 // audio buffer. Used to detect long error sequences and to take actions |
| 252 // if length of error sequence is above a certain limit. | 239 // if length of error sequence is above a certain limit. |
| 253 base::TimeTicks last_success_time_; | 240 base::TimeTicks last_success_time_; |
| 254 | 241 |
| 255 // Is set to true on the internal AUHAL IO thread in the first input callback | 242 // Flags to indicate if we have gotten an input callback. |
| 256 // after Start() has bee called. | 243 // |got_input_callback_| is only accessed on the OS audio thread in |
| 244 // OnDataIsAvailable() and is set to true when the first callback comes. It |
| 245 // acts as a gate to only set |input_callback_is_active_| atomically once. |
| 246 // |got_input_callback_| is reset to false in Stop() on the main thread. This |
| 247 // is safe since after stopping the audio unit there is no current callback |
| 248 // ongoing and no further callbacks coming. |
| 249 bool got_input_callback_; |
| 257 base::subtle::Atomic32 input_callback_is_active_; | 250 base::subtle::Atomic32 input_callback_is_active_; |
| 258 | 251 |
| 259 // Timer which triggers CheckInputStartupSuccess() to verify that input | 252 // Timer which triggers CheckInputStartupSuccess() to verify that input |
| 260 // callbacks have started as intended after a successful call to Start(). | 253 // callbacks have started as intended after a successful call to Start(). |
| 261 // This timer lives on the main browser thread. | 254 // This timer lives on the main browser thread. |
| 262 std::unique_ptr<base::OneShotTimer> input_callback_timer_; | 255 std::unique_ptr<base::OneShotTimer> input_callback_timer_; |
| 263 | 256 |
| 264 // Set to true if the Start() call was delayed. | 257 // Set to true if the Start() call was delayed. |
| 265 // See AudioManagerMac::ShouldDeferStreamStart() for details. | 258 // See AudioManagerMac::ShouldDeferStreamStart() for details. |
| 266 bool start_was_deferred_; | 259 bool start_was_deferred_; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 294 // callback audio thread. | 287 // callback audio thread. |
| 295 // These variables are only touched on the callback thread and then read | 288 // These variables are only touched on the callback thread and then read |
| 296 // in the dtor (when no longer receiving callbacks). | 289 // in the dtor (when no longer receiving callbacks). |
| 297 // NOTE: Float64 and UInt32 types are used for native API compatibility. | 290 // NOTE: Float64 and UInt32 types are used for native API compatibility. |
| 298 Float64 last_sample_time_; | 291 Float64 last_sample_time_; |
| 299 UInt32 last_number_of_frames_; | 292 UInt32 last_number_of_frames_; |
| 300 UInt32 total_lost_frames_; | 293 UInt32 total_lost_frames_; |
| 301 UInt32 largest_glitch_frames_; | 294 UInt32 largest_glitch_frames_; |
| 302 int glitches_detected_; | 295 int glitches_detected_; |
| 303 | 296 |
| 304 // Timer that provides periodic callbacks used to monitor if the input stream | |
| 305 // is alive or not. | |
| 306 std::unique_ptr<base::RepeatingTimer> check_alive_timer_; | |
| 307 | |
| 308 // Time tick set once in each input data callback. The time is measured on | |
| 309 // the real-time priority I/O thread but this member is modified and read | |
| 310 // on the main thread only. | |
| 311 base::TimeTicks last_callback_time_; | |
| 312 | |
| 313 // Counts number of times we get a signal of that a restart seems required. | |
| 314 // If it is above a threshold (kNumberOfIndicationsToTriggerRestart), the | |
| 315 // current audio stream is closed and a new (using same audio parameters) is | |
| 316 // started. | |
| 317 size_t number_of_restart_indications_; | |
| 318 | |
| 319 // Counts number of times RestartAudio() has been called. The max number of | |
| 320 // attempts is restricted by |kMaxNumberOfRestartAttempts|. | |
| 321 // Note that this counter is reset to zero after each successful restart. | |
| 322 size_t number_of_restart_attempts_; | |
| 323 | |
| 324 // Counts the total number of times RestartAudio() has been called. It is | |
| 325 // set to zero once in the constructor and then never reset again. | |
| 326 size_t total_number_of_restart_attempts_; | |
| 327 | |
| 328 // Callback to send statistics info. | 297 // Callback to send statistics info. |
| 329 AudioManager::LogCallback log_callback_; | 298 AudioManager::LogCallback log_callback_; |
| 330 | 299 |
| 331 // Used to ensure DevicePropertyChangedOnMainThread() is not called when | 300 // Used to ensure DevicePropertyChangedOnMainThread() is not called when |
| 332 // this object is destroyed. | 301 // this object is destroyed. |
| 333 // Note that, all member variables should appear before the WeakPtrFactory. | 302 // Note that, all member variables should appear before the WeakPtrFactory. |
| 334 base::WeakPtrFactory<AUAudioInputStream> weak_factory_; | 303 base::WeakPtrFactory<AUAudioInputStream> weak_factory_; |
| 335 | 304 |
| 336 DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream); | 305 DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream); |
| 337 }; | 306 }; |
| 338 | 307 |
| 339 } // namespace media | 308 } // namespace media |
| 340 | 309 |
| 341 #endif // MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_ | 310 #endif // MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_ |
| OLD | NEW |