aboutsummaryrefslogtreecommitdiffstats
path: root/src/player_thread.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* event_pipe: replaced PIPE_EVENT_SIGNAL with main_notifyMax Kellermann2009-01-021-1/+2
| | | | | | There is only one location using PIPE_EVENT_SIGNAL: to synchronize player_command() with player_command_finished(). Use the "notify" library instead of the event_pipe here.
* event_pipe: added pipe_event enum and callbacksMax Kellermann2009-01-011-3/+3
| | | | | | | | | Make the event_pipe (formerly main_notify) send/receive a set of events, with a callback for each one. The default event PIPE_EVENT_SIGNAL does not have a callback. It is still there for waking up the main thread, when it is waiting for the player thread.
* event_pipe: renamed functions from main_notify_* to event_pipe_*Max Kellermann2009-01-011-4/+4
| | | | Continuing the previous patch.
* main_notify: renamed source to event_pipe.cMax Kellermann2009-01-011-1/+1
| | | | | | We are going to migrate away from the concept of notifying the main thread. There should be events sent to it instead. This patch starts a series to implement that.
* player_thread: use GLib loggingMax Kellermann2008-12-291-8/+10
|
* player_thread: migrate from pthread to glib threadsThomas Jansen2008-12-281-8/+6
|
* decoder: terminate decoder thread before MPD cleanupMax Kellermann2008-12-281-0/+1
| | | | | | When MPD exits, it should manually free all resources in use, to allow easy memory leak debugging. Make the decoder thread terminate during that.
* player: set elapsed=0 at song changeMarc Pavot2008-11-251-0/+1
| | | | | | | | | | | | I have found something that looks like a bug in MPD: - When a song is finished, the next one is played and the 'player' event is emitted. - When the client sends the status command just after this event, the songid is the new one but the 'elapsed' time is not reseted to 0. This is problem because I have implemented the solution using a timer on client side to compute the elapsed time but with this bug the elapsed time continues to be incremented on a new song.
* player_thread.c: replaced mpd_unused by G_GNUC_UNUSEDThomas Jansen2008-11-241-1/+3
|
* player: disable music_pipe_check_format()Max Kellermann2008-11-241-0/+2
| | | | | | The music pipe audio format bugs seem to be fixed (hopefully). Disable music_pipe_check_format() for now, since it consumes a lot of CPU cycles.
* player: don't queue song when there are 2 songs in the pipeMax Kellermann2008-11-141-0/+5
| | | | | | | | | Don't send a "next song" request to the main thread when the current song hasn't started playing yet, i.e. there are already two different songs in the music pipe. This would erase information about the song boundary within the music pipe, and thus triggered an assertion failure. The bug could occur when playing very short songs which fit into the pipe as a whole.
* player: wake up decoder before waiting for xfade chunksMax Kellermann2008-11-141-0/+1
| | | | | | Fix a deadlock: when the decoder waited for buffer space, the player could enter a deadlock situation because it waits for more chunks for crossfading chunks. Signal the decoder before entering notify_wait().
* player: chop the tail of the music pipe after CANCELMax Kellermann2008-11-131-0/+1
| | | | | | When a CANCEL command is received, the player should drop all chunks of the next song. Added new funciton music_pipe_chop() which is used for that.
* music_pipe: continuously check the sample format of all chunksMax Kellermann2008-11-131-0/+6
| | | | | Provide a debug function which asserts on the sample format of all chunks. Call this function in each iteration of the player main loop.
* player: assert that there was no previous "next song chunk"Max Kellermann2008-11-131-0/+1
| | | | | When assigning the next_song_chunk variable, it must have been empty. If not, there may be 3 songs overlapping in the music pipe.
* player: fix race condition during tag updateMax Kellermann2008-11-111-2/+4
| | | | | | | | | When a tag is updated, the old tag was freed before the new one was created. Reverse the order to be sure that other threads always see a valid pointer. This still leaves a possible race condition, but it will be addressed later.
* decoder: converted dc.error to a dc.state valueMax Kellermann2008-11-081-2/+2
| | | | | | The player did not care about the exact error value, it only checked whether an error has occured. This could fit well into decoder_control.state - introduce a new state "DECODE_STATE_ERROR".
* player: no CamelCaseMax Kellermann2008-11-031-28/+28
| | | | | Renamed variables and internal functions. Most of the player_control.h API remains in CamelCase for now.
* decoder: no CamelCaseMax Kellermann2008-11-031-2/+2
| | | | Renamed variables and functions.
* player: don't play empty chunksMax Kellermann2008-11-021-0/+3
| | | | | An empty chunk may happen when it only contains a tag, but no PCM data. Don't call playAudio() then.
* player: copy stream tag to the song structMax Kellermann2008-11-021-5/+19
| | | | | | Non-local songs used to have no tags. If the decoder sends us a tag, we should incorporate it into the song struct. This way, clients can always show the correct song name (if provided by the server).
* player: added player.songMax Kellermann2008-11-021-0/+7
| | | | | Always remember which song is currently being sent to the audio device.
* player: send chunk tag to audio deviceMax Kellermann2008-11-021-0/+3
| | | | | If a chunk contains a tag, send it to the audio output device. Few output plugins support this, e.g. shout has support for sending tags.
* music_pipe: no CamelCaseMax Kellermann2008-11-021-4/+4
| | | | Rename all variables and struct members.
* music_pipe: more wrapper functionsMax Kellermann2008-11-021-8/+6
| | | | | | Replace all direct music_pipe struct accesses with wrapper functions. The compiled machine code is the same, but this way, we can change struct internals more easily.
* decoder: replaced music_pipe.audioFormat with dc.out_audio_formatMax Kellermann2008-11-021-6/+6
| | | | | | | .. and rename dc.audioFormat to dc.in_audio_format. The music pipe does not need to know the audio format, and its former "audioFormat" property indicated the format of the most recently added chunk, which might be confusing when you are reading the oldest chunks.
* music_pipe: renamed ob_* functions to music_pipe_*Max Kellermann2008-11-021-16/+17
| | | | Rename all functions to the new prefix.
* music_pipe: renamed struct output_buffer to struct music_pipeMax Kellermann2008-11-021-3/+5
| | | | .. and rename ob_chunk to struct music_chunk.
* decoder: use bool for return values and flagsMax Kellermann2008-10-301-4/+4
| | | | | Don't return 0/-1 on success/error, but true/false. Instead of int, use bool for storing flags.
* output: always call cancel() before stop()Max Kellermann2008-10-291-4/+2
| | | | | | Stopping an audio output device without cancelling its buffer doesn't make sense. Combine the two operations, which saves several cancel calls.
* output: use bool for return values and flagsMax Kellermann2008-10-291-5/+4
| | | | | Don't return 0/-1 on success/error, but true/false. Instead of int, use bool for storing flags.
* player: handle songs shorter than the initial bufferMax Kellermann2008-10-291-1/+2
| | | | | | | When the decoder exited before the buffer has grown big enough ("buffer_before_play"), the player thread waited forever. Add an additional check which disables buffering as soon as the decoder exits.
* player: added variable "play_audio_format"Max Kellermann2008-10-291-2/+4
| | | | | | | | | The local variable "play_audio_format" is updated every time the player starts playing a new song. This way, we always know exactly which audio format is current. The old code broke when a new song had a different format: ob.audio_format is the format of the next song, not of the current one - using this caused breakage for the software volume control.
* player: request new song only if there is no pending commandMax Kellermann2008-10-291-1/+2
| | | | | | | Request the next song from the playlist (by clearing pc.next_song) only if the player command is empty. If it is not, the player may be clearing the song that has already been queued, leading to an assertion failure.
* player: reset pc.command when decoder startup failsMax Kellermann2008-10-271-0/+1
| | | | | | | When the decoder failed to start, the function do_play() returned, still having pc.command==PLAY. This is because pc.command was reset only when the decoder started up successfully. Add another player_command_finished() call in the error handler.
* player: don't clear command before do_play() returnsMax Kellermann2008-10-241-1/+0
| | | | | | | | | This bug caused the audio output devices to stay open, although MPD wasn't playing: quitDecode() resetted player_control.command, assuming that the command was STOP. This way, player_task() didn't see the CLOSE_AUDIO command, and the device was kept open. Don't clear player_control.command in quitDecode().
* player: don't send partial frames of silenceMax Kellermann2008-10-231-1/+7
| | | | | | Another partial frame fix: the silence buffer was 1020 bytes, which had room for 127.5 24 bit stereo frames. Don't send the partial last frame in this case.
* pcm_utils: no CamelCaseMax Kellermann2008-10-211-2/+2
| | | | Renamed all functions which were still in CamelCase.
* player: replaced buffered_before_play with buffering flagMax Kellermann2008-10-121-9/+10
| | | | | | buffered_before_play was copied to struct player because it was used to disable buffering when seeking. Instead of mainaining a copy of this number, move just the flag to the player struct.
* player: added commands QUEUE and CANCELMax Kellermann2008-10-121-29/+48
| | | | | | QUEUE adds a new song to the player's queue. CANCEL clears the queue. These two commands replace the old and complex queueState and queueLockState code.
* player: added struct playerMax Kellermann2008-10-121-48/+75
| | | | | The player struct holds the local variables which used to be passed to all those helper functions in player_thread.c.
* player: removed player_control.fileTimeMax Kellermann2008-10-111-1/+2
| | | | | | | This variable is superfluous, it is only used to copy its value to player_control.totalTime. Since the original source of this value (song->tag->time) will still be available at this point, we can safely remove fileTime.
* player: don't wake up decoder after every frameMax Kellermann2008-10-101-1/+7
| | | | | | | The decoder was woken up after each chunk which had been played. That caused a lot of superfluous context switches. Wake up the decoder only when a certain amount of the buffer has been consumed. This formula is somewhat arbitrary, and has to be proven experimentally.
* player: added player_control.audio_formatMax Kellermann2008-10-101-6/+2
| | | | This replaces the attributes bits, channels, sampleRate.
* audio_format: renamed sampleRate to sample_rateMax Kellermann2008-10-101-1/+1
| | | | | The last bit of CamelCase in audio_format.h. Additionally, rename a bunch of local variables.
* song: removed CamelCaseMax Kellermann2008-10-081-2/+2
| | | | CamelCase is ugly... rename all functions.
* use the "bool" data type instead of "int"Max Kellermann2008-10-081-4/+4
| | | | "bool" should be used in C99 programs for boolean values.
* song: converted typedef Song to struct songMax Kellermann2008-10-081-0/+1
| | | | Again, a data type which can be forward-declared.
* audio_output: added method pause()Max Kellermann2008-09-291-1/+1
| | | | | | | | | | | | pause() puts the audio output into pause mode: if supported, it may perform a special action, which keeps the device open, but does not play anything. Output plugins like "shout" might want to play silence during pause, so their clients won't be disconnected. Plugins which do not support pausing will simply be closed, and have to be reopened when unpaused. This pach includes an implementation for the shout plugin, which sends silence chunks.
* notify: protect notify->pending with the mutexMax Kellermann2008-09-261-2/+0
| | | | | | | | | | There was a known deadlocking bug in the notify library: when the other thread set notify->pending after the according check in notify_wait(), the latter thread was deadlocked. Resolve this by synchronizing all accesses to notify->pending with the notify object's mutex. Since notify_signal_sync() was never used, we can remove it. As a consequence, we don't need notify_enter() and notify_leave() anymore; eliminate them, too.