| Commit message (Collapse) | Author | Files | Lines |
|
Seeing the "mpd_" prefix _everywhere_ is mind-numbing as the
mind needs to retrain itself to skip over the first 4 tokens of
a type to get to its meaning. So avoid having extra characters
on my terminal to make it easier to follow code at 2:30 am in
the morning.
Please report any new issues you may come across on Free
toolchains. I realize how difficult it can be to build/maintain
cross-compiling toolchains and I have no intention of forcing
people to upgrade their toolchains to build mpd.
Tested with gcc 2.95.4 and and gcc 4.3.1 on x86-32.
|
|
LOC reduction and less noise makes things easier for
tired old folks to follow.
|
|
|
|
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.
|
|
|
|
Getting rid of CamelCase; not having typedefs also allows us to
forward-declare the structures.
|
|
Also introduce MUTEFRAME_NONE; previously, the code used "0".
|
|
|
|
The return value of audio_linear_dither() is always casted to
mpd_sint16. Returning long does not make sense, and consumed 8 bytes
on a 64 bit platform.
|
|
The output buffer always contains mpd_sint16; declaring it with that
type saves several casts.
|
|
The previous patch removed all loop specific dependencies from the
num_samples formula; we can now calculate it before entering the loop.
|
|
The output buffer is always flushed after being appended to, which
allows us to assume it is always empty. Always start writing at
outputBuffer, don't remember outputPtr.
|
|
The previous patch made mp3Read() flush the output buffer in every
iteration, which means we can eliminate the flush check after invoking
mp3Read().
|
|
Since we try to fill the buffer in every iteration, we assume that we
should flush the output buffer at the end of each iteration.
|
|
Fill the whole output buffer at a time by using dither_buffer()'s
ability to decode blocks. Calculate how many samples fit into the
output buffer before each invocation.
|
|
Simplifying loops for performance: why check dropSamplesAtEnd in every
iteration, when we could modify the loop boundary? The (writable)
variable samplesLeft can be eliminated; add a write-once variable
pcm_length instead, which is used for the loop condition.
|
|
The variable samplesPerFrame is used only in one single closure. Make
it local to this closure. The compiler will probably convert it to a
register anyway.
|
|
|
|
Preparing for simplifying and thus speeding up the dithering code:
moved dithering to a separate function which contains a trivial loop.
With this patch, only one sample is dithered at a time, but the
following patches will allow us to dither a whole block at a time,
without complicated buffer length checks.
|
|
Performance improvement by moving stuff out of a loop: skip part of
the first frame before entering the loop.
|
|
Include only headers which are really required. This speeds up
compilation and helps detect cross-layer accesses.
[ew: minor fixups to not break on new core]
|
|
This has been tested for both playback of streams and
outputting to streams, and seems to work fine with minimal
locking. This reuses the sequence number infrastructure
in OutputBuffer for synchronizing metadata payloads; so
(IMNSHO) should be much more understandable than various
flags being set here and there..
It could still use some cleanup and much testing, but
synchronization issues should be minimal.
|
|
data->muteFrame won't necessarily get cleared when it
enters that block of code, so we don't signal the action
as complete until it is actually cleared.
|
|
This is a huge refactoring of the core mpd process. The
queueing/buffering mechanism is heavily reworked.
The player.c code has been merged into outputBuffer (the actual
ring buffering logic is handled by ringbuf.c); and decode.c
actually handles decoding stuff.
The end result is several hundreds of lines shorter, even though
we still have a lot of DEBUG statements left in there for
tracing and a lot of assertions, too.
|
|
We had functions names varied between
outputBufferFoo, fooOutputBuffer, and output_buffer_foo
That was too confusing for my little brain to handle.
And the global variable was somehow named 'cb' instead of
the more obvious 'ob'...
git-svn-id: https://svn.musicpd.org/mpd/trunk@7355 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
All of our main singleton data structures are implicitly shared,
so there's no reason to keep passing them around and around in
the stack and making our internal API harder to deal with.
git-svn-id: https://svn.musicpd.org/mpd/trunk@7354 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
This at least makes the argument list to a lot of our plugin
functions shorter and removes a good amount of line nois^W^Wcode,
hopefully making things easier to read and follow.
git-svn-id: https://svn.musicpd.org/mpd/trunk@7353 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@7287 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
It is way more complicated than it should be; and
locking it for thread-safety is too difficult.
[merged r7183 from branches/ew]
git-svn-id: https://svn.musicpd.org/mpd/trunk@7241 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
I initially started to do a heavy rewrite that changed the way processes
communicated, but that was too much to do at once. So this change only
focuses on replacing the player and decode processes with threads and
using condition variables instead of polling in loops; so the changeset
itself is quiet small.
* The shared output buffer variables will still need locking
to guard against race conditions. So in this effect, we're probably
just as buggy as before. The reduced context-switching overhead of
using threads instead of processes may even make bugs show up more or
less often...
* Basic functionality appears to be working for playing local (and NFS)
audio, including:
play, pause, stop, seek, previous, next, and main playlist editing
* I haven't tested HTTP streams yet, they should work.
* I've only tested ALSA and Icecast. ALSA works fine, Icecast
metadata seems to get screwy at times and breaks song
advancement in the playlist at times.
* state file loading works, too (after some last-minute hacks with
non-blocking wakeup functions)
* The non-blocking (*_nb) variants of the task management functions are
probably overused. They're more lenient and easier to use because
much of our code is still based on our previous polling-based system.
* It currently segfaults on exit. I haven't paid much attention
to the exit/signal-handling routines other than ensuring it
compiles. At least the state file seems to work. We don't
do any cleanups of the threads on exit, yet.
* Update is still done in a child process and not in a thread.
To do this in a thread, we'll need to ensure it does proper
locking and communication with the main thread; but should
require less memory in the end because we'll be updating
the database "in-place" rather than updating a copy and
then bulk-loading when done.
* We're more sensitive to bugs in 3rd party libraries now.
My plan is to eventually use a master process which forks()
and restarts the child when it dies:
locking and communication with the main thread; but should
require less memory in the end because we'll be updating
the database "in-place" rather than updating a copy and
then bulk-loading when done.
* We're more sensitive to bugs in 3rd party libraries now.
My plan is to eventually use a master process which forks()
and restarts the child when it dies:
master - just does waitpid() + fork() in a loop
\- main thread
\- decoder thread
\- player thread
At the beginning of every song, the main thread will set
a dirty flag and update the state file. This way, if we
encounter a song that triggers a segfault killing the
main thread, the master will start the replacement main
on the next song.
* The main thread still wakes up every second on select()
to check for signals; which affects power management.
[merged r7138 from branches/ew]
git-svn-id: https://svn.musicpd.org/mpd/trunk@7240 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
[ew: cleaned up the dirty union hack a bit]
Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn-id: https://svn.musicpd.org/mpd/trunk@7180 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn-id: https://svn.musicpd.org/mpd/trunk@7146 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn-id: https://svn.musicpd.org/mpd/trunk@7143 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
This will make refactoring features easier, especially now that
pthreads support and larger refactorings are on the horizon.
Hopefully, this will make porting to other platforms (even
non-UNIX-like ones for masochists) easier, too.
os_compat.h will house all the #includes for system headers
considered to be the "core" of MPD. Headers for optional
features will be left to individual source files.
git-svn-id: https://svn.musicpd.org/mpd/trunk@7130 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
DECODE_STATE_STOP is always set as dc->state, and dc->stop
is always cleared. So handle it in decodeStart once rather
than doing it in every plugin.
While we're at it, fix a long-standing (but difficult to
trigger) bug in mpc_decode where we failed to return
if mpc_decoder_initialize() fails.
git-svn-id: https://svn.musicpd.org/mpd/trunk@7122 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
the force flag will issue FATAL() if an invalid value is
specified
git-svn-id: https://svn.musicpd.org/mpd/trunk@6857 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
Parse ReplayGain info in LAME tags and use it if no ID3v2 ReplayGain tags
are found. This is currently a bit unsafe, as apparently some LAME tags
have bogus ReplayGain values. But I'm finding a lot of MP3s with valid
LAME tags that fail the LAME tag CRC check. So until I figure out why
that's happening, it's an unreliable method for checking if the LAME tag is
valid.
A big thanks to tmz for writing the original patch.
git-svn-id: https://svn.musicpd.org/mpd/trunk@6798 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@6468 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@5894 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@5834 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
Some compilers and linkers aren't smart enough to optimize this,
as global variables are implictly initialized to zero. As a
result, binaries are a bit smaller as more goes in the .bss and
less in the text section.
git-svn-id: https://svn.musicpd.org/mpd/trunk@5254 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
sendDataToOutputBuffer returns an int (and always has), and
using the existing 'ret' is fine in mp3Read().
git-svn-id: https://svn.musicpd.org/mpd/trunk@5246 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
MP3 playback, thus allowing songs that run longer than the Xing frame
claims (f.e., an MP3 created by catting two MP3s together) to continue
playing past the end.
git-svn-id: https://svn.musicpd.org/mpd/trunk@5157 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
assumption that non-seekable streams are live and any gapless info is
incorrect.
git-svn-id: https://svn.musicpd.org/mpd/trunk@5150 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
Instead, stop decoding as soon as we've found the frames/samples at the
"end" that we want drop.
git-svn-id: https://svn.musicpd.org/mpd/trunk@5149 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@5148 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
though in practice it should never matter.
git-svn-id: https://svn.musicpd.org/mpd/trunk@5147 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@4876 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
git-svn-id: https://svn.musicpd.org/mpd/trunk@4866 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|
|
I'm checking for zero-size allocations and assert()-ing them,
so we can more easily get backtraces and debug problems, but we'll
also allow -DNDEBUG people to live on the edge if they wish.
We do not rely on errno when checking for OOM errors because
some implementations of malloc do not set it, and malloc
is commonly overridden by userspace wrappers.
I've spent some time looking through the source and didn't find any
obvious places where we would explicitly allocate 0 bytes, so we
shouldn't trip any of those assertions.
We also avoid allocating zero bytes because C libraries don't
handle this consistently (some return NULL, some not); and it's
dangerous either way.
git-svn-id: https://svn.musicpd.org/mpd/trunk@4690 09075e82-0dd4-0310-85a5-a0d7c8717e4f
|