With the new speaker selection philosophy we aim to preserve user choice, so we
shouldn't unselect speakers just because they happen to be switched off when
the server is restarted.
With this commit auto reconnection per default will only be done for ATV4s and
HomePods. Reconnection is not always desirable, for instance if the device cuts
the connection because it is busy with something else, ref. issue #934.
The commit also adds an option to override auto reconnection, thus either
enabling it for other devices or disabling it for affected devices.
outputs_master_volume, output_device_list and output_buffer were defined in
outputs.h, but should only have been declared with extern.
Solve it by making output_buffer static/non-global (wasn't used anyway), and
the two others are now returned by functions.
* Make sure that vol_adjust() bases adjustments on the same speakers that the
user sees as active
* If a speaker fails during activation we unselect it, so that we don't keep
trying to start it, so we find a new master volume if required, and so it is
possible for the user to reselect it.
Before, we were ignoring progress metadata, and we were also updating clients
and db too early with input metadata (right when read from the input, instead of
waiting until playback (speakers) were at that position.
This change adds a complicated async chain of events from when the update is
received.
Moves speaker selection, volume handling and startup to outputs.c, plus adds
the ability to "resurrect" a speaker that disconnects.
The purpose of moving the code is to concentrate device handling in one place.
Also changes how we deal with speaker selection. The player will now generally
not alter a user selection, even if the device fails. The purpose of this is to
maintain selection both if the device briefly fails, and if the user switches
off the device (we stop playback) and later turns it on + starts new playback.
Otherwise we have a race condition between the worker and the input thread. If
the worker returns with metadata before the input thread has started reading,
then pb_session.pts will still be zero, which means metadata->pts will be zero
in finalize_cb(). That is an invalid time to give the outputs.
Also changes relative seeking behavior:
- seeking behind the the current track only switches to the previous
track, if we are not more than 3 seconds into the current track,
otherwise starts current track from the beginning
- seeking beyond the current track will start the next track from the
beginning
pb_suspend() + pb_resume() during track changes made the playback status
incorrect, i.e. pb_session.source_list/playing_now would not match what the
input was actually writing. This attempts to solve it by resetting the
session when pb_suspend() is called, so that the input, input_buffer and
source_list come into sync.
The fix in commit 3928ab6 broke resuming from an underrun, since it meant that
pb_resume() would flush the input buffer. With this fix it is possible to call
input_resume(), which will not flush the buffer if the source is already open.
Also renamed some functions in player.c for consistency.
Replace reading_next and reading_prev with a list of sources, so that we can
deal with short tracks, i.e. tracks where reading ends before playback starts.
With short tracks reading ends before playback starts, so event_read_eof comes
before event_play_start, which causes playing_now to point to a null
reading_now.
With this change it will point to a non-null reading_prev, but note that in the
hopefully rare case of multiple short tracks, the playing_now pointer will
still be incorrect.