| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
Seek the decoder to the start of the range before beginning with
playback. Stop the decoder when the end of the range has been
reached. Add the start position to the seek position. Expose the
duration of the range, not the full song file.
|
| |
|
| |
|
|
|
|
| |
At this point, the function may be called from the SEEK handler.
|
|
|
|
|
|
|
|
|
|
| |
When waiting for the decoder to provide more data, the player thread
generates silence chunks if needed. However, it forgot to initialize
the chunk.times attribute, which had now an undefined value. This
patch sets it to -1.0, meaning "value is undefined". Add a ">= 0.0"
check to audio_output_all_check(). This fixes spurious relative
seeking errors, because sometimes, the "elapsed" value falls back to
0.0.
|
|
|
|
|
|
| |
After we've been hit by Large File Support problems several times in
the past week (which only occur on 32 bit platforms, which I don't
have), this is yet another attempt to fix the issue.
|
|
|
|
|
|
|
|
| |
When there's no queued song, and the current one has finished playing,
first make sure that the hardware outputs have really finished playing
the last chunk: call the drain() method in all audio outputs. Without
this patch, MPD stopped playback shortly before the ALSA sound card
had finished playing.
|
|
|
|
|
| |
If no song was queued, then player_control.next_song might contain the
value for the next QUEUE command. We must not reset that.
|
|
|
|
|
|
|
| |
When the decoder finishes the "queued" song very quickly (before the
"current" song finishes playing), an assertion in do_play() fails
because it thinks that it should start decoding the queued song,
although that has in fact just finished.
|
|
|
|
| |
Simplify several expressions.
|
|
|
|
| |
Don't access attributes without the lock.
|
|
|
|
| |
Don't access decoder_control attributes directly.
|
|
|
|
| |
Lock the player_control object when modifying its attributes.
|
| |
|
|
|
|
| |
These two variables are redundant, we need only one of them.
|
|
|
|
| |
It's not used if pc.error==PLAYER_ERROR_AUDIO.
|
|
|
|
|
| |
The START command returns without blocking; we don't need the
asynchronous decoder start anymore.
|
|
|
|
|
|
|
| |
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().
|
|
|
|
|
| |
Allocate a decoder_control object where needed, and pass it around.
This will allow more than one decoder thread one day.
|
|
|
|
| |
Simply use "return" instead of g_thread_exit().
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
With these methods, an output plugin can allocate some global
resources only if it is actually enabled. The method enable() is
called after daemonization, which allows for more sophisticated
resource allocation during that method.
|
|
|
|
|
|
|
| |
When the audio output fails to open, MPD pauses playback, but doesn't
reset player.play_audio_format. This leads to an assertion failure in
audio_output_all_check() on the next REFRESH command, because no audio
output is open.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Tracking the "elapsed" time from the chunks which we have sent to the
output pipe is very imprecise: since we have implemented the music
pipe, we're sending large number of chunks at once, giving the
"elapsed" time stamp a resolution of usually more than a second.
This patch changes the source of this information to the outputs. If
a chunk has been played by all outputs, the "elapsed" time stamp is
updated.
The new command PLAYER_COMMAND_REFRESH makes the player thread update
its status information: it tells the outputs to update the chunk time
stamp. After that, player_control.elapsed_time is current.
|
|
|
|
|
|
| |
pc.next_song might be non-NULL even if player.queued==true: when the
decoder has started decoding the next song, but the result hasn't been
read yet.
|
|
|
|
|
| |
Sending PLAYER_COMMAND_STOP followed by PLAYER_COMMAND_QUEUE does the
same. PLAYER_COMMAND_PLAY is redundant.
|
|
|
|
|
|
| |
Replace decoder_control.notify with decoder_control.mutex and
decoder_control.cond. Lock the mutex on all accesses to
decoder_control.command and decoder_control.state.
|
|
|
|
|
|
|
| |
Calculate the total play time with the audio_format object each time,
using audio_format_time_to_size(). The function
audioFormatSizeToTime() is not needed anymore, and will be removed
with this patch.
|
| |
|
|
|
|
|
| |
Very few lines to log a song URI when it has been entirely played.
Then mpd logs can be parsed to do statistics.
|
|
|
|
|
|
|
|
|
|
| |
Do all the software volume stuff inside each output thread, not in the
player thread. This allows one software mixer per output device, and
also allows the user to configure the mixer type (hardware or
software) for each audio output.
This moves the global "mixer_type" setting into the "audio_output"
section, deprecating the "mixer_enabled" flag.
|
|
|
|
|
|
| |
When the decoder is finished, break out of the player loop only after
another player.pipe check. We did check the pipe size a few lines
above, but that check was kind of racy.
|
|
|
|
|
|
|
| |
When a music_chunk only contains a tag but no PCM data, play_chunk()
returns true without freeing the chunk. The caller now assumes that
the chunk is moved into some music_pipe and does not bother to free it
either.
|
|
|
|
|
|
| |
To check for leaked music_chunk objects, free the music buffer on
CLOSE_AUDIO. This invokes an assertion check which ensures that all
chunks have been returned to the buffer.
|
|
|
|
|
|
| |
When all audio outputs have been closed due to failures, pause the
playback instead of stopping it. This way, the user may resume
at the current position after the problem has been dealt with.
|
|
|
|
|
|
|
|
|
| |
When no audio outputs could be opened while seeking, leave MPD seeked
at that position and pause playback. The user may continue from this
point at any time, as soon as the audio outputs are fixed. The old
behaviour triggered an assertion failure: the failure wasn't passed
properly to the do_play() function, which attempted to play audio
chunks.
|
|
|
|
|
|
|
| |
When the decoder initialization has not been completed yet, all calls
to dc_seek() will fail, because dc.seekable is not initialized yet.
Wait for the decoder to complete its initialization, i.e. until it has
called decoder_initialized().
|
|
|
|
|
|
| |
Synchronization with the output thread will be implemented in
output_all.c, not in player_thread.c. Currently, that's just a simple
g_usleep(1ms).
|
|
|
|
|
| |
If a music_chunk does not contain any PCM data, then the "times" and
"bit_rate" attributes are undefined.
|
|
|
|
|
|
|
|
| |
This updates the copyright header to all be the same, which is
pretty much an update of where to mail request for a copy of the GPL
and the years of the MPD project. This also puts all committers under
'The Music Player Project' umbrella. These entries should go
individually in the AUTHORS file, for consistancy.
|
| |
|
|
|
|
|
| |
Replaced both player_stop_decoder() invocations with player_dc_stop(),
which also cleans up the pipe.
|
|
|
|
|
| |
In the "CANCEL" command handler, the decoder is stopped twice: first
by player_dc_stop(), then by dc_stop(). Remove the latter.
|
|
|
|
|
|
| |
After a seek, wait until enough new chunks are decoded before starting
playback. If this takes too long, send silence chunks to the audio
outputs meanwhile.
|
|
|
|
|
|
|
| |
When playback is unpaused, pass the audio_format to
audio_output_all_open(). Don't assume that output_all.c remembers the
previous audio format. Also check if there has been an audio format
yet.
|
| |
|