aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-11 19:25:15 +0100
committerMax Kellermann <max@duempel.org>2009-11-11 19:25:15 +0100
commit7b13776f2dd2feeb4bd28e8cf023ec81474e4eaa (patch)
treee8d91ee2f20a4af43a2fce380f5a5c744f0b61d8 /src
parentf937ec9a7c6b2439cda68c9cfdaa603258f8a0d4 (diff)
downloadmpd-7b13776f2dd2feeb4bd28e8cf023ec81474e4eaa.tar.gz
mpd-7b13776f2dd2feeb4bd28e8cf023ec81474e4eaa.tar.xz
mpd-7b13776f2dd2feeb4bd28e8cf023ec81474e4eaa.zip
decoder/flac: store the whole stream info object, not duration
We don't want to work with floating point values if possible. Get the integer number of frames from the FLAC__StreamMetadata_StreamInfo object, and convert it into a float duration on demand. This patch adds a check if the STREAMINFO packet has been received yet.
Diffstat (limited to 'src')
-rw-r--r--src/decoder/_flac_common.c5
-rw-r--r--src/decoder/_flac_common.h14
-rw-r--r--src/decoder/flac_plugin.c14
-rw-r--r--src/decoder/oggflac_plugin.c10
4 files changed, 36 insertions, 7 deletions
diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c
index 812ca6dae..fbeab43a7 100644
--- a/src/decoder/_flac_common.c
+++ b/src/decoder/_flac_common.c
@@ -35,6 +35,7 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
{
pcm_buffer_init(&data->buffer);
+ data->have_stream_info = false;
data->next_frame = 0;
data->time = 0;
@@ -65,9 +66,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
+ data->stream_info = block->data.stream_info;
+ data->have_stream_info = true;
+
audio_format_init(&data->audio_format, si->sample_rate,
si->bits_per_sample, si->channels);
- data->total_time = ((float)si->total_samples) / (si->sample_rate);
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if (data->replay_gain_info)
diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h
index e1e76932b..895cdf1b9 100644
--- a/src/decoder/_flac_common.h
+++ b/src/decoder/_flac_common.h
@@ -39,6 +39,19 @@ struct flac_data {
struct pcm_buffer buffer;
/**
+ * Is the #stream_info member valid?
+ */
+ bool have_stream_info;
+
+ /**
+ * A copy of the stream info object passed to the metadata
+ * callback. Once we drop support for libFLAC 1.1.2, we can
+ * remove this attribute, and use
+ * FLAC__stream_decoder_get_total_samples() etc.
+ */
+ FLAC__StreamMetadata_StreamInfo stream_info;
+
+ /**
* The number of the next frame which is going to be decoded.
*/
FLAC__uint64 next_frame;
@@ -46,7 +59,6 @@ struct flac_data {
float time;
unsigned int bit_rate;
struct audio_format audio_format;
- float total_time;
FLAC__uint64 position;
struct decoder *decoder;
struct input_stream *input_stream;
diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c
index 98bcd64d3..7a4f11451 100644
--- a/src/decoder/flac_plugin.c
+++ b/src/decoder/flac_plugin.c
@@ -400,6 +400,11 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
return false;
}
+ if (!data->have_stream_info) {
+ g_warning("no STREAMINFO packet found");
+ return false;
+ }
+
if (!audio_format_valid(&data->audio_format)) {
g_warning("Invalid audio format: %u:%u:%u\n",
data->audio_format.sample_rate,
@@ -408,12 +413,13 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
return false;
}
- if (duration != 0)
- data->total_time = (float)duration /
- (float)data->audio_format.sample_rate;
+ if (duration == 0)
+ duration = data->stream_info.total_samples;
decoder_initialized(data->decoder, &data->audio_format,
- seekable, data->total_time);
+ seekable,
+ (float)duration /
+ (float)data->audio_format.sample_rate);
return true;
}
diff --git a/src/decoder/oggflac_plugin.c b/src/decoder/oggflac_plugin.c
index 3f8d640f3..ffd622600 100644
--- a/src/decoder/oggflac_plugin.c
+++ b/src/decoder/oggflac_plugin.c
@@ -237,6 +237,12 @@ full_decoder_init_and_read_metadata(struct flac_data *data,
goto fail;
}
+ if (!data->have_stream_info) {
+ OggFLAC__seekable_stream_decoder_delete(decoder);
+ g_warning("no STREAMINFO packet found");
+ return NULL;
+ }
+
return decoder;
fail:
@@ -316,7 +322,9 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream)
}
decoder_initialized(mpd_decoder, &data.audio_format,
- input_stream->seekable, data.total_time);
+ input_stream->seekable,
+ (float)data.stream_info.total_samples /
+ (float)data.audio_format.sample_rate);
while (true) {
OggFLAC__seekable_stream_decoder_process_single(decoder);