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.
This commit is contained in:
parent
f937ec9a7c
commit
7b13776f2d
|
@ -35,6 +35,7 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
|
||||||
{
|
{
|
||||||
pcm_buffer_init(&data->buffer);
|
pcm_buffer_init(&data->buffer);
|
||||||
|
|
||||||
|
data->have_stream_info = false;
|
||||||
data->next_frame = 0;
|
data->next_frame = 0;
|
||||||
|
|
||||||
data->time = 0;
|
data->time = 0;
|
||||||
|
@ -65,9 +66,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
|
||||||
|
|
||||||
switch (block->type) {
|
switch (block->type) {
|
||||||
case FLAC__METADATA_TYPE_STREAMINFO:
|
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,
|
audio_format_init(&data->audio_format, si->sample_rate,
|
||||||
si->bits_per_sample, si->channels);
|
si->bits_per_sample, si->channels);
|
||||||
data->total_time = ((float)si->total_samples) / (si->sample_rate);
|
|
||||||
break;
|
break;
|
||||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||||
if (data->replay_gain_info)
|
if (data->replay_gain_info)
|
||||||
|
|
|
@ -38,6 +38,19 @@
|
||||||
struct flac_data {
|
struct flac_data {
|
||||||
struct pcm_buffer buffer;
|
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.
|
* The number of the next frame which is going to be decoded.
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +59,6 @@ struct flac_data {
|
||||||
float time;
|
float time;
|
||||||
unsigned int bit_rate;
|
unsigned int bit_rate;
|
||||||
struct audio_format audio_format;
|
struct audio_format audio_format;
|
||||||
float total_time;
|
|
||||||
FLAC__uint64 position;
|
FLAC__uint64 position;
|
||||||
struct decoder *decoder;
|
struct decoder *decoder;
|
||||||
struct input_stream *input_stream;
|
struct input_stream *input_stream;
|
||||||
|
|
|
@ -400,6 +400,11 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data->have_stream_info) {
|
||||||
|
g_warning("no STREAMINFO packet found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!audio_format_valid(&data->audio_format)) {
|
if (!audio_format_valid(&data->audio_format)) {
|
||||||
g_warning("Invalid audio format: %u:%u:%u\n",
|
g_warning("Invalid audio format: %u:%u:%u\n",
|
||||||
data->audio_format.sample_rate,
|
data->audio_format.sample_rate,
|
||||||
|
@ -408,12 +413,13 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duration != 0)
|
if (duration == 0)
|
||||||
data->total_time = (float)duration /
|
duration = data->stream_info.total_samples;
|
||||||
(float)data->audio_format.sample_rate;
|
|
||||||
|
|
||||||
decoder_initialized(data->decoder, &data->audio_format,
|
decoder_initialized(data->decoder, &data->audio_format,
|
||||||
seekable, data->total_time);
|
seekable,
|
||||||
|
(float)duration /
|
||||||
|
(float)data->audio_format.sample_rate);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,6 +237,12 @@ full_decoder_init_and_read_metadata(struct flac_data *data,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data->have_stream_info) {
|
||||||
|
OggFLAC__seekable_stream_decoder_delete(decoder);
|
||||||
|
g_warning("no STREAMINFO packet found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return decoder;
|
return decoder;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -316,7 +322,9 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder_initialized(mpd_decoder, &data.audio_format,
|
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) {
|
while (true) {
|
||||||
OggFLAC__seekable_stream_decoder_process_single(decoder);
|
OggFLAC__seekable_stream_decoder_process_single(decoder);
|
||||||
|
|
Loading…
Reference in New Issue