diff options
Diffstat (limited to 'src/decoder/mpg123_decoder_plugin.c')
-rw-r--r-- | src/decoder/mpg123_decoder_plugin.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/src/decoder/mpg123_decoder_plugin.c b/src/decoder/mpg123_decoder_plugin.c index 7b48ebfaf..657a9c889 100644 --- a/src/decoder/mpg123_decoder_plugin.c +++ b/src/decoder/mpg123_decoder_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 The Music Player Daemon Project + * Copyright (C) 2003-2011 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,10 +20,12 @@ #include "config.h" /* must be first for large file support */ #include "decoder_api.h" #include "audio_check.h" +#include "tag_handler.h" #include <glib.h> #include <mpg123.h> +#include <stdio.h> #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "mpg123" @@ -105,6 +107,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) int error; off_t num_samples; enum decoder_command cmd; + struct mpg123_frameinfo info; /* open the file */ @@ -124,10 +127,25 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) /* tell MPD core we're ready */ - decoder_initialized(decoder, &audio_format, false, + decoder_initialized(decoder, &audio_format, true, (float)num_samples / (float)audio_format.sample_rate); + if (mpg123_info(handle, &info) != MPG123_OK) { + info.vbr = MPG123_CBR; + info.bitrate = 0; + } + + switch (info.vbr) { + case MPG123_ABR: + info.bitrate = info.abr_rate; + break; + case MPG123_CBR: + break; + default: + info.bitrate = 0; + } + /* the decoder main loop */ do { @@ -144,11 +162,30 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) break; } + /* update bitrate for ABR/VBR */ + if (info.vbr != MPG123_CBR) { + /* FIXME: maybe skip, as too expensive? */ + /* FIXME: maybe, (info.vbr == MPG123_VBR) ? */ + if (mpg123_info (handle, &info) != MPG123_OK) + info.bitrate = 0; + } + /* send to MPD */ - cmd = decoder_data(decoder, NULL, buffer, nbytes, 0); + cmd = decoder_data(decoder, NULL, buffer, nbytes, info.bitrate); - /* seeking not yet implemented */ + if (cmd == DECODE_COMMAND_SEEK) { + off_t c = decoder_seek_where(decoder)*audio_format.sample_rate; + c = mpg123_seek(handle, c, SEEK_SET); + if (c < 0) + decoder_seek_error(decoder); + else { + decoder_command_finished(decoder); + decoder_timestamp(decoder, c/(double)audio_format.sample_rate); + } + + cmd = DECODE_COMMAND_NONE; + } } while (cmd == DECODE_COMMAND_NONE); /* cleanup */ @@ -156,41 +193,40 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) mpg123_delete(handle); } -static struct tag * -mpd_mpg123_tag_dup(const char *path_fs) +static bool +mpd_mpg123_scan_file(const char *path_fs, + const struct tag_handler *handler, void *handler_ctx) { struct audio_format audio_format; mpg123_handle *handle; int error; off_t num_samples; - struct tag *tag; handle = mpg123_new(NULL, &error); if (handle == NULL) { g_warning("mpg123_new() failed: %s", mpg123_plain_strerror(error)); - return NULL; + return false; } if (!mpd_mpg123_open(handle, path_fs, &audio_format)) { mpg123_delete(handle); - return NULL; + return false; } num_samples = mpg123_length(handle); if (num_samples <= 0) { mpg123_delete(handle); - return NULL; + return false; } - tag = tag_new(); - - tag->time = num_samples / audio_format.sample_rate; - /* ID3 tag support not yet implemented */ mpg123_delete(handle); - return tag; + + tag_handler_invoke_duration(handler, handler_ctx, + num_samples / audio_format.sample_rate); + return true; } static const char *const mpg123_suffixes[] = { @@ -204,6 +240,6 @@ const struct decoder_plugin mpg123_decoder_plugin = { .finish = mpd_mpg123_finish, .file_decode = mpd_mpg123_file_decode, /* streaming not yet implemented */ - .tag_dup = mpd_mpg123_tag_dup, + .scan_file = mpd_mpg123_scan_file, .suffixes = mpg123_suffixes, }; |