When an async moodbar load completes, it checks to see if the song is still playing and should update the UI.
It however failed to check if the song was stopped, so it would load a moodbar when no song is playing.
It now checks the player state before emitting a change.
Fixes#4663
When tearing down the pipeline, there was a leak of a GstBus which holds a socketpair open.
Eventually the OS runs out of file descriptors and terminates Clementine.
The magnitude output from gstfastspectrum was not initialized for the first fft.
In some cases, the memory would contain data that upon math operations becomes nan.
This causes one or more colours of the moodbar to be generated blank, resulting in missing colours or just plain black moodbars.
Fix the parsing of some strange date formats in podcasts, and add a way to limit the number of podcast episodes shown, and hide listened podcasts. Fixes#3696, fixes#3475
BTW the compare was buggy (didn't compare against song2). This was OK though, as
we stable sort songs, and they are always ordered as far as I know (I remember
adding this sort just in case they will not be sent ordered on day).
Each time the song is changed, the podcast backend checks whether the
new song is a podcast and, if so, mark it as listened to. This requires
1-2 db queries, so do it off the main thread.
Time to change song before: 300 ms
after: 50 ms usually, 80 ms sometimes
When starting clementine, each playlist is loaded in turn.
When loading a playlist, the new tab order is committed to the db,
but we don't need to do that here because we know that once all the
playlists are loaded the tab order will be the same as it was initially.
This speeds startup substantially.
kstartperf:
Before: 3.5s
After: 1.5s
The playlist fetching uses QtConcurrent to make the playlist on a
different thread (possibly concurrently for each item).
However, profiling reveals that the slow operation is fetching
the rows from the SQLite database, making this redundant.
Instead move the whole playlist loading, including the database access,
into a single function, and call that function in a different thread via
QtConcurrent::run.
This has the side effect of moving all the concurrent stuff from
PlaylistBackend into the callers.
kstartperf measures:
Before: 7.5s cold
3.6 s warm
After: ~4.0 s cold
3.5 s warm