aboutsummaryrefslogtreecommitdiffstats
path: root/src/player_thread.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* player: added some more assertionsMax Kellermann2009-02-101-0/+2
| | | | Assertions on pc.command and pc.next_song.
* player_thread: reset pc.next_song only if queuedMax Kellermann2009-02-101-1/+5
| | | | | | | When we reset pc.next_song if there is no song queued, this might cause a race condition: the next song to be played is cleared, while pc.command was already set. Clear the "next_song" only if there is a song queued for the current do_play() invocation.
* player_thread: reset pc.next_songMax Kellermann2009-02-101-0/+6
| | | | | | | After a player command (successful or not), reset pc.next_song, because the queue is supposed to be empty then. Otherwise, playlist.queued and pc.next_song may disagree, which triggers an assertion failure.
* player_thread: set player error when output device failsMax Kellermann2009-02-021-1/+4
| | | | | | When the output device fails to play a chunk, set pc.error to PLAYER_ERROR_AUDIO. This way, the playlist knows that it should not queue the next song.
* player_thread: start decoder thread in player threadMax Kellermann2009-01-251-0/+3
| | | | | Start the decoder thread when the player thread starts. The decoder thread is already stopped by the player thread.
* player_control: added player_control.threadMax Kellermann2009-01-251-2/+4
| | | | | player_control.thread contains the handle of the player thread, or NULL if the player thread isn't running.
* decoder_control: added decoder_control.threadMax Kellermann2009-01-251-1/+1
| | | | | decoder_control.thread contains the handle of the decoder thread, or NULL if the decoder thread isn't running.
* player_thread: emit PLAYLIST event when new song failsMax Kellermann2009-01-211-1/+1
| | | | | | Break from the loop instead of returning the function. This calls player_stop_decoder(), which in turn emits the PLAYLIST event. This allows the playlist to re-start the player.
* player_thread: check for decoder failure before seekingMax Kellermann2009-01-211-1/+4
| | | | | The function player_seek_decoder() starts the decoder, but does not check the return value of player_wait_for_decoder().
* player_thread: use bool instead of intMax Kellermann2009-01-211-12/+13
| | | | | Make player_wait_for_decoder() and play_chunk() return a bool instead of 0/-1.
* player_thread: request next song only if new one starts playingMax Kellermann2009-01-211-11/+0
| | | | | | | | | The player_thread loop requests the next song from the playlist as soon as the decoder finishes the song which is currently being played. This is superfluous, and can lead to synchronization errors and wrong results. The playlist already knows when the player starts playing the next song (player_wait_for_decoder() triggers the PLAYLIST event), and will then trigger the scheduler to provide the next song.
* player_thread: eliminated duplicate PLAYLIST eventMax Kellermann2009-01-201-2/+0
| | | | | player_wait_for_decoder() emits the PLAYLIST event on success, remove the duplicate PLAYLIST event in its caller.
* event_pipe: added "TAG" eventMax Kellermann2009-01-201-1/+1
| | | | | | The "TAG" event is emitted by the player thread when the current song's tag has changed. Split this event from "PLAYLIST" and make it a separate callback, which is more efficient.
* pcm_utils: moved code to pcm_volume.cMax Kellermann2009-01-071-1/+1
| | | | Moved the software volume code to a separate library.
* initialize GError pointersMax Kellermann2009-01-041-1/+1
| | | | | GLib mandates that you initialize all GError objects with NULL prior to passing it.
* song: allocate the result of song_get_url()Max Kellermann2009-01-041-8/+11
|
* player_thread: fix cross-fading duplicate chunk bugMax Kellermann2009-01-041-0/+8
| | | | | | | | When the decoder of the new song is not fast enough, the player thread has to wait for it for a moment. However the variable "nextChunk" was reset to -1 during that, making the next loop iteration assume that cross-fading has not begun yet. This patch overwrites it with "0" while waiting.
* player: emit PLAYLIST event when stream tag changesMax Kellermann2009-01-031-0/+7
| | | | | | | | Commit b3e2635a introduced a regression: when a stream tag was changed, the playlist version had to be updated. This was done in syncCurrentPlayerDecodeMetadata(), called by syncPlayerAndPlaylist(). After b3e2635a, this was not called anymore. Fix this by emitting PIPE_EVENT_PLAYLIST.
* 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.