It is now clear that multi-library support will not happen, so remove whatever
provisions were in the code for that.
It comes with a small change to the configuration file, too.
With this, DB schema version went to 9.
Transcoded (decoded) files will now always come out in signed, little endian,
16bit, 44100 Hz, stereo format regardless of the format of the input file.
This in effect fixes transcoding (and playback on some devices) for files that
do not match this format.
There's probably a discussion to be had regarding handling of 48 kHz and 96 kHz
content, though, as downsampling to 44.1 kHz to have the client or final output
device upsample again is clearly not an optimal solution.
Add the setup_fail_codec label and jump to it if an error occurs once the
codec has been opened. In the raw input codepath, don't use this label until
the file is properly opened, as it also closes the fd and frees the raw
buffer.
This also fixes a file descriptor leak in the case where an error happened
after the file was opened in the raw input codepath.
ffmpeg doesn't convert ID3v2 tag names to generic metadata names, so
add the ID3v2 tag names to the table to pick them up.
This fixes scanning of MP3 files in various cases.
More in this post and its attachment:
<http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2009-September/076213.html>
Thanks to Raivo Hool for bringing up the issue and fix.
Store groups (only album groups supported at the moment) in the DB,
so their ids are persistent for the duration of the forked-daapd session.
Those ids are used to, among other things, retrieve artwork, so we must
provide ourselves some persistence here.
This brings us to schema version 8.
Due to the two Murmur64 implementations for 64 and 32bit machines, the
hash is not compatible when moving the SQLite DB between 32/64 bit hosts.
So we'll recompute all the songalbumids at startup, just in case.
songalbumid is used a lot in queries from Remote; computing the hash for
each row is a major waste of time on big libraries and slow machines, so
let's store the hash in the table.
This brings us to schema version 7.
Some metadata were filtered out from the reply by directly checking
for their hash, including the hash value in the code. Remove the magic
values and compare dfm->field against the relevant dmap_* field as for
other special cases.
Update field types, add new fields (commented out). This fixes a number
of mis-assigned types. Update generated from the result of a /content-codes
request.
Introduce struct dmap_field holding the field tag, description and
DMAP type and use it in struct dmap_field_map to replace the tag,
desc and type fields.
This enables semi-automated updates of the DMAP fields information
from the output of a /content-codes request.
Most of the unsigned DMAP types were missing and assignments were incorrect
between signed and unsigned types. Fix all of this, and add (preliminary)
support for the new types.
This code in daap_reply_songlist_generic() is redundant with code
in (new) dmap_add_field() and can be removed, with a tweak: we must
ensure the val integer is always 0 if not used to override a value in
the transcoding case.
lseek() returns an off_t and not an int, using an int to store and
test the return value means we'll error out when the position in the file
gets past INT_MAX.
The pairing hash actually uses standard MD5, so let's simplify the
code by using a standard MD5 implementation. Now that function is
readable and understandable by mere mortals.
Thanks to Jeff Sharkey for posting that simplified version.
eventfd has less overhead than a pipe, works as a counter and uses a
single fd. Use it on Linux if available (that should be pretty much
always given the glibc and kernel requirements).
512k might be a bit too much, as it can take time to read 512k from the
filesystem (and we're using a blocking read) or from the decoder. Going
down to 64k will make this more manageable and improve the response time
when streaming to multiple clients at the same time.
evbuffer_read() is really meant to read from sockets and not regular
files. It also looks like evbuffer_read() was causing issues with large
files, locking up a little below 2 GB for an unknown reason (couldn't
reproduce).
Try to be a bit more strict about integer types, use off_t or int64_t for
file size and file offsets.
Replace safe_ato*() by safe_atoi32() and safe_atoi64(), fix integer types
at call sites to match.
Hinting the OS about our behaviour shouldn't make a big difference in
performance but it will help the OS manage its disk cache and can reduce
memory pressure on small systems.
DAAP queries from Remote won't need HTTP authentication as they all
require a valid session-id; Remote can only obtain a valid session-id
if its pairing-guid is known to us (it did pair successfully with us).
Stock evhttp has no means to detect when an incoming connection gets
closed by the client; it will notice the connection has gone down only
when sending back a reply.
For DAAP update requests working as a push mechanism with an HTTP request
stalled by the server until there actually is an update available, we need
to be notified when a connection goes down so we can perform proper cleanup
and not retain memory.
Do so by extending the close detection mechanism used for outgoing connections
and the connection failure callback we already have in place for streaming.
Get rid of strlcpy() and its implementation entirely, it doesn't buy anything
over snprintf(). Use evutil_snprintf() so as to match the rest of the code.
media_kind=2 (Movies) indicates a regular video, that is, a video that
isn't a TV Show (media_kind=64).
Also fix up the system playlist for Movies, and that brings us to DB
schema_version 5.
The filescanner dereferences symlinks as it encounters them, but it did
not dereference the top-level library directories given in the config.
Also the playlist scanner always dereferences the filenames.
As a result, there was a mismatch between the paths in the files table and
the paths in the playlistitems table if the library directory given in the
config contain a symlink somewhere along the way.
Remote is the iPod/iPhone application that can act as a remote control for
iTunes. Remote must be paired with an iTunes instance before it can control
it; this pairing process includes a challenge/response autentication.
This pairing agent makes it possible to pair Remote with a forked-daapd
instance. It is the very first step for Remote support.
The default playlist (called "Library") doesn't actually have a purpose; I
though it was needed for RSP (SoundBridge) but it doesn't look like it makes
any difference with or without this playlist.
Start replacing inotify in the filescanner with kqueue. Only a stub at
this point, kqueue/kevent doesn't deliver nearly as much information
as inotify does. This will require some work, and someone willing to
do that work.