Compare commits

...

7 Commits

Author SHA1 Message Date
Max Kellermann
d0119548c1 release v0.18.10 2014-04-10 13:36:38 +02:00
Marcello Desantis
95ac6071b9 decoder/sndfile: work around libsndfile bug on partial read 2014-04-09 23:58:56 +02:00
Weng Xuetian
3a4e667078 PlaylistEdit: don't interrupt playback when current song gets deleted 2014-04-09 23:10:14 +02:00
Max Kellermann
ce18c36ed9 decoder/ffmpeg: handle unknown stream start time 2014-03-18 09:16:09 +01:00
Max Kellermann
8e39cf62e7 decoder/ffmpeg: pass AVSEEK_FLAG_ANY to av_seek_frame()
This corrects a major mistake from commit 724a59aa - there was one
small thing that commit was supposed to do, and it failed.
AV_TIME_BASE is not a seek flag.
2014-03-18 09:10:36 +01:00
Max Kellermann
a9e351e00d decoder/gme: fix memory leak in container_scan() 2014-03-06 13:12:39 +01:00
Max Kellermann
d65841a2db configure.ac: prepare for 0.18.10 2014-03-06 13:08:30 +01:00
6 changed files with 64 additions and 20 deletions

8
NEWS

@@ -1,3 +1,11 @@
ver 0.18.10 (2014/04/10)
* decoder
- ffmpeg: fix seeking bug
- ffmpeg: handle unknown stream start time
- gme: fix memory leak
- sndfile: work around libsndfile bug on partial read
* don't interrupt playback when current song gets deleted
ver 0.18.9 (2014/03/02)
* protocol
- "findadd" requires the "add" permission

@@ -1,6 +1,6 @@
AC_PREREQ(2.60)
AC_INIT(mpd, 0.18.9, mpd-devel@musicpd.org)
AC_INIT(mpd, 0.18.10, mpd-devel@musicpd.org)
VERSION_MAJOR=0
VERSION_MINOR=18

@@ -234,12 +234,8 @@ playlist::DeleteInternal(PlayerControl &pc,
if (playing && current == (int)songOrder) {
const bool paused = pc.GetState() == PlayerState::PAUSE;
/* the current song is going to be deleted: stop the player */
pc.Stop();
playing = false;
/* see which song is going to be played instead */
/* the current song is going to be deleted: see which
song is going to be played instead */
current = queue.GetNextOrder(current);
if (current == (int)songOrder)
@@ -248,10 +244,12 @@ playlist::DeleteInternal(PlayerControl &pc,
if (current >= 0 && !paused)
/* play the song after the deleted one */
PlayOrder(pc, current);
else
/* no songs left to play, stop playback
completely */
Stop(pc);
else {
/* stop the player */
pc.Stop();
playing = false;
}
*queued_p = nullptr;
} else if (current == (int)songOrder)

@@ -197,6 +197,29 @@ time_to_ffmpeg(double t, const AVRational time_base)
time_base);
}
/**
* Replace #AV_NOPTS_VALUE with the given fallback.
*/
static constexpr int64_t
timestamp_fallback(int64_t t, int64_t fallback)
{
return gcc_likely(t != int64_t(AV_NOPTS_VALUE))
? t
: fallback;
}
/**
* Accessor for AVStream::start_time that replaces AV_NOPTS_VALUE with
* zero. We can't use AV_NOPTS_VALUE in calculations, and we simply
* assume that the stream's start time is zero, which appears to be
* the best way out of that situation.
*/
static int64_t
start_time_fallback(const AVStream &stream)
{
return timestamp_fallback(stream.start_time, 0);
}
static void
copy_interleave_frame2(uint8_t *dest, uint8_t **src,
unsigned nframes, unsigned nchannels,
@@ -263,7 +286,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
{
if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE)
decoder_timestamp(decoder,
time_from_ffmpeg(packet->pts - stream->start_time,
time_from_ffmpeg(packet->pts - start_time_fallback(*stream),
stream->time_base));
AVPacket packet2 = *packet;
@@ -493,10 +516,10 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
int64_t where =
time_to_ffmpeg(decoder_seek_where(decoder),
av_stream->time_base) +
av_stream->start_time;
start_time_fallback(*av_stream);
if (av_seek_frame(format_context, audio_stream, where,
AV_TIME_BASE) < 0)
AVSEEK_FLAG_ANY) < 0)
decoder_seek_error(decoder);
else {
avcodec_flush_buffers(codec_context);

@@ -117,6 +117,7 @@ gme_container_scan(const char *path_fs, const unsigned int tnum)
}
const unsigned num_songs = gme_track_count(emu);
gme_delete(emu);
/* if it only contains a single tune, don't treat as container */
if (num_songs < 2)
return nullptr;

@@ -55,14 +55,28 @@ sndfile_vio_read(void *ptr, sf_count_t count, void *user_data)
{
InputStream &is = *(InputStream *)user_data;
sf_count_t total_bytes = 0;
Error error;
size_t nbytes = is.LockRead(ptr, count, error);
if (nbytes == 0 && error.IsDefined()) {
LogError(error);
return -1;
}
return nbytes;
/* this loop is necessary because libsndfile chokes on partial
reads */
do {
size_t nbytes = is.LockRead((char *)ptr + total_bytes,
count - total_bytes, error);
if (nbytes == 0) {
if (error.IsDefined()) {
LogError(error);
return -1;
}
break;
}
total_bytes += nbytes;
} while (total_bytes < count);
return total_bytes;
}
static sf_count_t