+ return noErr;
+}
+
+/*
+ * Callback when streams of any audio device changed (e.g. SPDIF gets (un)available)
+ */
+static OSStatus StreamsChangedListener(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData)
+{
+ OSStatus err = noErr;
+ UInt32 i_param_size = 0;
+ AudioStreamID *p_streams = NULL;
+ int i_streams = 0;
+
+ VLC_UNUSED(inNumberAddresses);
+ VLC_UNUSED(inAddresses);
+
+ audio_output_t *p_aout = (audio_output_t *)inClientData;
+ if (!p_aout)
+ return -1;
+
+ aout_sys_t *p_sys = p_aout->sys;
+
+ msg_Dbg(p_aout, "available physical formats for audio device changed");
+ RebuildDeviceList(p_aout);
+
+ /*
+ * check if changed stream id belongs to current device
+ */
+ vlc_mutex_lock(&p_sys->var_lock);
+ AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
+ err = AudioObjectGetPropertyDataSize(p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size);
+ if (err != noErr) {
+ msg_Err(p_aout, "could not get number of streams [%4.4s]", (char *)&err);
+ return VLC_EGENERIC;
+ }
+
+ i_streams = i_param_size / sizeof(AudioStreamID);
+ p_streams = (AudioStreamID *)malloc(i_param_size);
+ if (p_streams == NULL)
+ return VLC_ENOMEM;
+
+ err = AudioObjectGetPropertyData(p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size, p_streams);
+ if (err != noErr) {
+ msg_Err(p_aout, "could not get list of streams [%4.4s]", (char *)&err);
+ return VLC_EGENERIC;
+ }
+ vlc_mutex_unlock(&p_sys->var_lock);
+
+ for (int i = 0; i < i_streams; i++) {
+ if (p_streams[i] == inObjectID) {
+ msg_Dbg(p_aout, "Restart aout as this affects current device");
+ aout_RestartRequest(p_aout, AOUT_RESTART_OUTPUT);
+ break;
+ }
+ }
+ free(p_streams);
+
+ return noErr;