summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-01-17 11:43:13 +0100
committerMax Kellermann <max@duempel.org>2009-01-17 11:43:13 +0100
commitf0377dab9110c8218b76405f8936f075d4d6aed5 (patch)
treed843531604a7c73f3ed27f88706fc3accbbe5280
parente3e7a3c680b3fe659312b00899198d9190993284 (diff)
oggvorbis: disable seeking on remote songs
When libvorbis knows that a song is seekable, it seeks around like crazy in the file before starting to decode it. This is very expensive on remote HTTP resources, and delays MPD for 10 or 20 seconds. This patch disables seeking on remote songs, because the advantages of quickly playing a song seem to weigh more than the theoretical ability of seeking for most MPD users. If users feel this feature is needed, we will make a configuration option for that.
-rw-r--r--NEWS1
-rw-r--r--src/decoder/oggvorbis_plugin.c30
2 files changed, 25 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index bf15c228e..1b891c3dc 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ MPD 0.14.1 - not yet released
- mp4: support the writer/composer tag
- id3: strip leading and trailing whitespace from ID3 tags
- oggvorbis: fix tremor support
+ - oggvorbis: disable seeking on remote files
* audio outputs:
- jack: allocate default port names (fixes a crash)
* update:
diff --git a/src/decoder/oggvorbis_plugin.c b/src/decoder/oggvorbis_plugin.c
index 9ec24e426..36f2eb132 100644
--- a/src/decoder/oggvorbis_plugin.c
+++ b/src/decoder/oggvorbis_plugin.c
@@ -19,6 +19,8 @@
/* TODO 'ogg' should probably be replaced with 'oggvorbis' in all instances */
#include "_ogg_common.h"
+#include "ls.h"
+#include "path.h"
#ifndef HAVE_TREMOR
#include <vorbis/vorbisfile.h>
@@ -47,8 +49,10 @@
#endif
typedef struct _OggCallbackData {
- struct input_stream *inStream;
struct decoder *decoder;
+
+ struct input_stream *inStream;
+ bool seekable;
} OggCallbackData;
static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
@@ -67,9 +71,11 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
{
const OggCallbackData *data = (const OggCallbackData *) vdata;
- if(decoder_get_command(data->decoder) == DECODE_COMMAND_STOP)
- return -1;
- return input_stream_seek(data->inStream, offset, whence) ? 0 : -1;
+
+ return data->seekable &&
+ decoder_get_command(data->decoder) != DECODE_COMMAND_STOP &&
+ input_stream_seek(data->inStream, offset, whence)
+ ? 0 : -1;
}
/* TODO: check Ogg libraries API and see if we can just not have this func */
@@ -198,6 +204,17 @@ static void putOggCommentsIntoOutputBuffer(struct decoder *decoder,
tag_free(tag);
}
+static bool
+oggvorbis_seekable(struct decoder *decoder)
+{
+ char buffer[MPD_PATH_MAX];
+
+ /* disable seeking on remote streams, because libvorbis seeks
+ around like crazy, and due to being very expensive, this
+ delays song playback my 10 or 20 seconds */
+ return !uri_has_scheme(decoder_get_url(decoder, buffer));
+}
+
/* public */
static void
oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
@@ -225,8 +242,9 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
moved it */
input_stream_seek(inStream, 0, SEEK_SET);
- data.inStream = inStream;
data.decoder = decoder;
+ data.inStream = inStream;
+ data.seekable = inStream->seekable && oggvorbis_seekable(decoder);
callbacks.read_func = ogg_read_cb;
callbacks.seek_func = ogg_seek_cb;
@@ -303,7 +321,7 @@ oggvorbis_decode(struct decoder *decoder, struct input_stream *inStream)
if (total_time < 0)
total_time = 0;
decoder_initialized(decoder, &audio_format,
- inStream->seekable,
+ data.seekable,
total_time);
initialized = true;
}