| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Lock the player_control object when modifying its attributes.
|
| |
|
|
|
|
|
| |
Asynchronous decoder startup is gone, and we don't need to check
command==DECODE_COMMAND_START anymore.
|
|
|
|
| |
These two variables are redundant, we need only one of them.
|
|
|
|
| |
It's not used if pc.error==PLAYER_ERROR_AUDIO.
|
|
|
|
|
|
| |
This is only a slight change to the previous locking behaviour: keep
the decoder unlocked during the loop, and lock it only while checking
decoder_control.command.
|
|
|
|
|
| |
The START command returns without blocking; we don't need the
asynchronous decoder start anymore.
|
|
|
|
|
| |
Return the result to the caller more quickly. This unifies error
handling: no error can be reported before the command is finished.
|
|
|
|
| |
They are just informational.
|
|
|
|
|
|
|
| |
Reintroduce a fix from commit 52a0653 (Warren Dukes): "don't call
snd_pcm_drain unless we're already in the RUNNING state". This prevents
ALSA with dmix from sometimes hanging when snd_pcm_drain is called, e.g.
when moving from one song to the next (as in mantis issue 2634).
|
| |
|
|
|
|
|
| |
When the "next" chunk to be played is NULL, return from ao_play()
immediately, without going over the "while" loop (no-op).
|
|
|
|
|
|
|
| |
While paused, the player thread re-locks its mutex and waits for a
signal. This is racy: when the command is set while the thread is
waiting for the lock, it may wait forever. This patch adds another
command check before player_wait().
|
|
|
|
|
|
|
| |
After CANCEL, the output thread waits for another signal before it
continues playback, to synchronize with the caller. There were some
situations where this signal wasn't sent properly. This patch adds an
explicit g_cond_signal() at two code positions.
|
|
|
|
|
| |
That variable has been superseded by "remove_notify" (defined in
update_remove.c).
|
|
|
|
|
|
| |
Don't wake up the target thread in every iteration of the wait() loop.
Waking it up once, right after the command has been set, must be
enough.
|
|
|
|
|
|
| |
These parameters must be protected with a mutex, too. Wrap everything
inside player_lock()/player_unlock(), and use player_command_locked()
instead of player_command().
|
|
|
|
|
|
|
| |
After CANCEL, call g_cond_wait() only if the new command is still
NONE. Problem is that ao_command_finished() has to unlock the
audio_output object, and in the meantime, the player thread might have
submitted a new command.
|
|
|
|
| |
Fix a minor memory leak.
|
|
|
|
|
| |
Changed songvec_load() to song_load(). Added start and end markers
for each song. Removed the "key" line, it's redundant.
|
| |
|
| |
|
| |
|
|
|
|
| |
The "music_root" global variable is allocated by db_init().
|
| |
|
|
|
|
|
|
|
| |
Use a single GString buffer object in all functions loading the
database. Enlarge it automatically for long lines. This eliminates
the maximum line length for tag values. There is still an upper limit
of 512 kB to prevent denial of service, but that's reasonable I guess.
|
|
|
|
|
|
| |
Allocate the directory object after the "directory:" line. Assign the
mtime from the input file to this new object, instead of to the parent
directory.
|
|
|
|
| |
Fix a minor memory leak in the error handler.
|
|
|
|
|
| |
The old code tried to recover, but what's the point of that? If a
directory is duplicate, something is wrong with the database file.
|
| |
|
|
|
|
| |
It's legal to pass decoder=NULL to decoder_read(). Add a check.
|
|
|
|
|
| |
Allocate a decoder_control object where needed, and pass it around.
This will allow more than one decoder thread one day.
|
|\
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
NEWS
configure.ac
src/decoder/ffmpeg_plugin.c
src/update.c
|
| | |
|
| |
| |
| |
| |
| |
| | |
Convert the metadata with the libavformat function av_metadata_conv().
This ensures that canonical tag names are provided by libavformat, and
we can remove the "artist" vs "author" workaround.
|
| |
| |
| |
| |
| |
| | |
When you disable the "follow_outside_symlinks" or the
"follow_inside_symlinks" setting, the next update should remove the
now-ignored files from the database.
|
| |
| |
| |
| |
| | |
Basically the same as the 0.15.5 patch "check again if output is open
on CANCEL". Same race condition, same fix.
|
| |
| |
| |
| | |
Simply use "return" instead of g_thread_exit().
|
| |
| |
| |
| |
| | |
When the songs of two albums are in the same directory, all songs of
an album should be right next to each others.
|
| |
| |
| |
| |
| | |
Moved some code to tag_get_value_checked(), to eliminate several NULL
checks.
|
| |
| |
| |
| |
| |
| | |
Use GMutex/GCond instead of the notify library. Manually lock the
player_control object before accessing the protected attributes. Use
the GCond object to notify the player thread and the main thread.
|
| |
| |
| |
| |
| |
| |
| |
| | |
Right after seeking and song change, the elapsed_time shows old
information, because the output thread didn't finish a full chunk
yet. This patch re-adds a second elapsed_time variable, and keeps
track of a fallback value, in case the output thread can't provide a
reliable value.
|
| |
| |
| |
| |
| |
| | |
Return false when there was no chunk in the pipe. If the function
returns true, then audio_output_task() will not wait for a notify from
the player thread. This fixes a race condition.
|
| |
| |
| |
| |
| |
| | |
Don't set the error in play_chunk(); do all the error handling in the
caller. The errored_song attribute isn't set anymore; it doesn't make
sense for PLAYER_ERROR_AUDIO.
|
| |
| |
| |
| | |
Call a version of audio_output_close() which doesn't lock recursively.
|
| | |
|
| |
| |
| |
| |
| | |
Always keep the audio_output object locked within the output thread,
unless a plugin method is called. This fixes several race conditions.
|
| |
| |
| |
| |
| |
| |
| | |
drain() is the opposite of cancel(): it waits until all data in the
buffer has finished playing. Instead of implicitly draining in the
close() method like the ALSA plugin has been doing it forever, let the
output thread decide whether to drain or to cancel.
|
| |
| |
| |
| |
| |
| | |
The recovery is for nothing if we get CLOSE afterwards. Let's not
recover in the cancel() method, and let the next play() call sort it
out.
|
| |
| |
| |
| | |
Don't call filter_close() right after ao_close().
|