During scanning we might find a new, nested playlist (so inside another m3u),
which we will then save. When the scanner then reaches the actual playlist file,
we must make sure to scan the contents of it. This means the timestamp when
saving the first time has to be set to a dummy value.
Misc refactoring, e.g. alignment of how modules save tracks and playlists, incl
use of mfi and pli. Also try to avoid direct calls between library and player.
ffmpeg parses TDA, TDAT, TYE, TYER and TDR these days, so there is no need
to do that in forked-daapd. Also the parsing of TDA/TDAT was incorrect,
since it is MMDD.
This change aligns with iTunes behavior. It also means that a client that is
not long polling can use the revision number (cmsr) value to check for changes.
If the number of quality subscriptions reaches max then this bug will be
triggered, because we will incorrectly use the last element of the
output_buffer for a subscription, thus losing the zero terminator.
Extends the playlist table with media_kind to handle playlist queries like
this from Apple Music:
/databases/71/containers?session-id=12345678&revision-number=4&delta=0&query=('dmap.itemname:Library%20name','com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32','com.apple.itunes.extended-media-kind:128','com.apple.itunes.extended-media-kind:65537')&meta=dmap.itemid,dmap.itemname,dmap.persistentid,dmap.parentcontainerid,com.apple.itunes.is-podcast-playlist,com.apple.itunes.special-playlist,com.apple.itunes.smart-playlist,dmap.haschildcontainers,com.apple.itunes.saved-genius,dmap.objectextradata
Like with iTunes, it has adverse effects to announce support for DAAP groups,
so with this change we also check if user-agent is "Music" before deciding what
to announce.
Setting Cache-Control to "no-cache" tells a client to always make a
request to check if the version in the client cache is still valid
(response code 403 not modified).
The player will write 24 bit samples using 3 bytes, not 4, so the appropriate
sample format is SND_PCM_FORMAT_S24_3LE, not SND_PCM_FORMAT_S24_LE.
For extra protection we also use snd_pcm_bytes_to_frames() instead of BTOS(),
because that way we can be more certain that the buffer is not too short for
snd_pcm_writei().