aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* player_thread: lock inside player_wait_for_decoder()Max Kellermann2009-11-031-7/+17
| | | | Lock the player_control object when modifying its attributes.
* player_thread: moved code to player_dc_start()Max Kellermann2009-11-031-5/+20
|
* decoder_control: don't check command in decoder_is_starting()Max Kellermann2009-11-031-5/+3
| | | | | Asynchronous decoder startup is gone, and we don't need to check command==DECODE_COMMAND_START anymore.
* decoder_control: merge next_song and current_songMax Kellermann2009-11-035-16/+16
| | | | These two variables are redundant, we need only one of them.
* player_thread: don't set errored_song on audio errorMax Kellermann2009-11-031-2/+0
| | | | It's not used if pc.error==PLAYER_ERROR_AUDIO.
* decoder_thread: unlock the decoder while checking the streamMax Kellermann2009-11-031-4/+4
| | | | | | 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.
* player_thread: don't start the decoder asynchronouslyMax Kellermann2009-11-033-17/+2
| | | | | The START command returns without blocking; we don't need the asynchronous decoder start anymore.
* decoder_thread: open input stream after command finishedMax Kellermann2009-11-031-5/+10
| | | | | Return the result to the caller more quickly. This unifies error handling: no error can be reported before the command is finished.
* decoder_control: make the song objects constMax Kellermann2009-11-033-4/+4
| | | | They are just informational.
* alsa_plugin.c: workaround snd_pcm_drain bugJeffrey Middleton2009-11-021-1/+2
| | | | | | | 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).
* output_thread: moved code to ao_next_chunk()Max Kellermann2009-11-021-6/+11
|
* output_thread: return from ao_play() if chunk->next is NULLMax Kellermann2009-11-021-5/+4
| | | | | When the "next" chunk to be played is NULL, return from ao_play() immediately, without going over the "while" loop (no-op).
* player_thread: check command before waiting during pauseMax Kellermann2009-11-021-1/+3
| | | | | | | 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().
* output: signal the output thread when CANCEL is finishedMax Kellermann2009-11-022-0/+34
| | | | | | | 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.
* update: removed unused variable "update_notify"Max Kellermann2009-11-022-11/+0
| | | | | That variable has been superseded by "remove_notify" (defined in update_remove.c).
* {decoder,player}_control: removed duplicate wakeupsMax Kellermann2009-11-023-7/+5
| | | | | | 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.
* player_control: lock player before setting seek parametersMax Kellermann2009-11-021-2/+6
| | | | | | 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().
* output_thread: check command before g_cond_wait()Max Kellermann2009-11-021-1/+2
| | | | | | | 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.
* song_save: free song object on errorMax Kellermann2009-11-011-0/+4
| | | | Fix a minor memory leak.
* song_save: load one song at a timeMax Kellermann2009-11-015-76/+34
| | | | | Changed songvec_load() to song_load(). Added start and end markers for each song. Removed the "key" line, it's redundant.
* database: save database format versionMax Kellermann2009-11-011-1/+17
|
* directory_save: partially revert the g_str_has_prefix() patchMax Kellermann2009-11-011-2/+2
|
* database: use strcmp() instead of g_str_has_prefix()Max Kellermann2009-11-013-6/+5
|
* database: removed redundant music_root allocationMax Kellermann2009-11-011-2/+0
| | | | The "music_root" global variable is allocated by db_init().
* replay_gain: trigger OPTIONS idle event on mode changeMax Kellermann2009-11-014-1/+26
|
* text_file: allocate line buffers dynamicallyMax Kellermann2009-11-019-59/+164
| | | | | | | 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.
* directory_save: allocate directory object earlier, assign mtimeMax Kellermann2009-11-011-12/+13
| | | | | | 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.
* directory_save: free directory on errorMax Kellermann2009-11-011-1/+3
| | | | Fix a minor memory leak in the error handler.
* directory_save: abort on duplicate subdirectoryMax Kellermann2009-11-011-7/+9
| | | | | 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.
* directory_save: moved code to directory_load_subdir()Max Kellermann2009-11-011-49/+63
|
* decoder_api: check decoder==NULL in decoder_read()Max Kellermann2009-11-011-1/+2
| | | | It's legal to pass decoder=NULL to decoder_read(). Add a check.
* decoder_control: removed the global variable "dc"Max Kellermann2009-10-3111-317/+377
| | | | | Allocate a decoder_control object where needed, and pass it around. This will allow more than one decoder thread one day.
* Merge branch 'v0.15.x'Max Kellermann2009-10-314-4/+21
|\ | | | | | | | | | | | | | | Conflicts: NEWS configure.ac src/decoder/ffmpeg_plugin.c src/update.c
| * decoder_control: removed unused DECODE_TYPE macrosMax Kellermann2009-10-311-3/+0
| |
| * decoder/ffmpeg: convert metadataMax Kellermann2009-10-282-4/+6
| | | | | | | | | | | | 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.
| * update: delete ignored symlinks from databaseMax Kellermann2009-10-272-1/+6
| | | | | | | | | | | | 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.
| * output_thread: check again if output is open on PAUSEMax Kellermann2009-10-212-0/+10
| | | | | | | | | | Basically the same as the 0.15.5 patch "check again if output is open on CANCEL". Same race condition, same fix.
| * Modify version string to post-release version 0.15.6~gitAvuton Olrich2009-10-182-1/+4
| |
* | player_thread: simplified thread destructionMax Kellermann2009-10-311-4/+2
| | | | | | | | Simply use "return" instead of g_thread_exit().
* | songvec: sort songs by album name first, then disc/track numberMax Kellermann2009-10-312-1/+31
| | | | | | | | | | When the songs of two albums are in the same directory, all songs of an album should be right next to each others.
* | songvec: simplified compare_tag_item()Max Kellermann2009-10-311-8/+10
| | | | | | | | | | Moved some code to tag_get_value_checked(), to eliminate several NULL checks.
* | player_control: protect command, state, error with a mutexMax Kellermann2009-10-3112-89/+263
| | | | | | | | | | | | 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.
* | {player,output}_thread: fixed elapsed_time quirksMax Kellermann2009-10-303-3/+23
| | | | | | | | | | | | | | | | 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.
* | output_thread: return bool from ao_play()Max Kellermann2009-10-291-4/+22
| | | | | | | | | | | | 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.
* | player_thread: set error status in play_next_chunk()Max Kellermann2009-10-291-4/+3
| | | | | | | | | | | | 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.
* | output_control: fixed deadlock in audio_output_update()Max Kellermann2009-10-291-1/+21
| | | | | | | | Call a version of audio_output_close() which doesn't lock recursively.
* | httpd: add config option to limit number of clientsViliam Mateicka2009-10-294-3/+31
| |
* | output: consistently lock audio output objectsMax Kellermann2009-10-297-50/+103
| | | | | | | | | | Always keep the audio_output object locked within the output thread, unless a plugin method is called. This fixes several race conditions.
* | output_plugin: added method "drain"Max Kellermann2009-10-293-14/+34
| | | | | | | | | | | | | | 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.
* | output/alsa: don't recover on CANCELMax Kellermann2009-10-292-1/+2
| | | | | | | | | | | | 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.