We have eliminated direct accesses to the audio_output struct from
the all output plugins. Make it opaque for them, and move its real
declaration to output_internal.h, similar to decoder_internal.h.
Pass the opaque structure to plugin.init() only, which will return the
plugin's data pointer on success, and NULL on failure. This data
pointer will be passed to all other methods instead of the
audio_output struct.
The JACK output plugin needs to reset its "opened" flag when the JACK
server fails. To prevent it from accessing the audio_output struct
directly introduce the API function audio_output_closed().
Reduce direct accesses to the audio_output struct from the plugins:
this time, eliminate all accesses to audio_output.name. The name is
required by some plugins for log messages.
Pass the globally configured audio_format as a const pointer to
plugin.init(). plugin.open() gets a writable pointer which contains
the audio_format requested by the plugin. Its initial value is either
the configured audio_format or the input file's audio_format.
To keep I/O nastiness and latencies away from the core, move the audio
output code to a separate thread, one per output. The thread is
created on demand, and currently runs until mpd exits.
Since flacSendChunk() is a trivial function and is only used in one
location, move the code there. The advantage is that calling
decoder_data() directly returns the decoder_command value, so we can
eliminate one decoder_get_command() call.
Support for bit rates except 16 bits (and 8 bits on little endian) has
always been broken. Since we added optimized functions for 8, 16,
24/32 bits, we can remove the generic flac_convert() function.
Instead of removing it, convert it to a wrapper function for
flac_convert_*().
flac_convert_16() runs a lot faster than the generic (and quite buggy)
function flac_convert(). flac_convert_16() is only used for
non-stereo files, since there is already flac_convert_stereo16().
By mistake, I casted the sample value to uint16_t, which is wrong.
This patch simplifies the code by using a int16_t pointer instead of
casting to int16_t* every time.
There is still a lot of duplicated code in flac_plugin.c and
oggflac_plugin.c. Move code from flac_plugin.c to _flac_common.c, and
use the new function flac_common_write() also in oggflac_plugin.c,
porting lots of optimizations over to it.
The inline function audio_format_sample_size() calculates how many
bytes each sample consumes. This function already takes into account
that 24 bit samples are 4 bytes long, not 3.
Instead of letting ALSA block for us (and potentially allowing
something stupid on certain hardware or drivers), we do the
sleeping ourselves. We calculate the sleep to be a fraction of
period_time to avoid oversleeping (and thus audible skipping).
A lot of the preparation was needed (and done in previous
months) in making update thread-safe, but here it is.
This was the first thing I made work inside a thread when I
started mpd-uclinux many years ago, and also the last thing I've
done in mainline mpd to work inside a thread, go figure.
pthreads with our existing signal blocking/handling is broken,
for now just sleep a bit in the child to prevent the CHLD handler
from being called too early. Also, improve error reporting when
handling SIGCHLD by storing the status to be called in the main
task (which can be logged, since we can't do logging inside the
sig handler).
Our linked-list implementation is wasteful and the
SongList isn't modified enough to benefit from being a linked
list. So use a more compact array of song pointers which
saves ~200K on a library with ~9K songs (on x86-32).
It hasn't been used in many years
commit 3a89afdd80
Author: Warren Dukes <warren.dukes@gmail.com>
Date: Sat Nov 20 20:28:32 2004 +0000
remove --update-db option
(SVN r2719)
This allows us to avoid the nasty repetition in strncmp(foo,
bar, strlen(foo)). We'll miss out on the compiler optimizing
strlen() into sizeof() - 1 for string literals for this; but we
don't use this it for performance-critical functions anyways...
This should save a few thousand ops. Not worth it to malloc
for such a small (3-words on 32-bit ARM and x86) structures.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
The function decodeFirstFrame() allocates memory based on data from
the mp3 header. This can make the buffer size allocation overflow, or
lead to a DoS attack with a very large buffer. Cap this buffer at 8
million frames, which should really be enough for reasonable files.
The assertion on "!client_is_expired(client)" was wrong, because
writing the command response may cause the client to become expired.
Replace that assertion with a check.
A crafted mp4 file could cause an integer overflow in mp4_decode
function in src/inputPlugins/mp4_plugin.c. mp4ff_num_samples()
function returns some tainted value. sizeof(float) * numSamples is an
integer overflow operation if numSamples is too huge, so xmalloc will
allocate a small memory region. I constructe a mp4 file, and use
faad2 to open the file. mp4ff_num_samples() returns -1. So I think mpd
bears from the same problem.