Commit ae9c02b3 authored by Max Kellermann's avatar Max Kellermann

decoder/flac: remember audio_format, not stream_info

parent 6f6d47dd
......@@ -37,6 +37,7 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
{
pcm_buffer_init(&data->buffer);
data->unsupported = false;
data->have_stream_info = false;
data->first_frame = 0;
data->next_frame = 0;
......@@ -81,38 +82,53 @@ bool
flac_data_get_audio_format(struct flac_data *data,
struct audio_format *audio_format)
{
GError *error = NULL;
if (data->unsupported)
return false;
if (!data->have_stream_info) {
g_warning("no STREAMINFO packet found");
return false;
}
data->sample_format = flac_sample_format(&data->stream_info);
*audio_format = data->audio_format;
return true;
}
static void
flac_got_stream_info(struct flac_data *data,
const FLAC__StreamMetadata_StreamInfo *stream_info)
{
if (data->have_stream_info || data->unsupported)
return;
if (!audio_format_init_checked(audio_format,
data->stream_info.sample_rate,
data->sample_format,
data->stream_info.channels, &error)) {
GError *error = NULL;
if (!audio_format_init_checked(&data->audio_format,
stream_info->sample_rate,
flac_sample_format(stream_info),
stream_info->channels, &error)) {
g_warning("%s", error->message);
g_error_free(error);
return false;
data->unsupported = true;
return;
}
data->frame_size = audio_format_frame_size(audio_format);
data->frame_size = audio_format_frame_size(&data->audio_format);
return true;
data->total_frames = stream_info->total_samples;
data->have_stream_info = true;
}
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
struct flac_data *data)
{
if (data->unsupported)
return;
struct replay_gain_info *rgi;
switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
data->stream_info = block->data.stream_info;
data->have_stream_info = true;
flac_got_stream_info(data, &block->data.stream_info);
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
......@@ -166,7 +182,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
buffer = pcm_buffer_get(&data->buffer, buffer_size);
flac_convert(buffer, frame->header.channels,
data->sample_format, buf,
data->audio_format.format, buf,
0, frame->header.blocksize);
if (nbytes > 0)
......
......@@ -38,8 +38,6 @@
struct flac_data {
struct pcm_buffer buffer;
enum sample_format sample_format;
/**
* The size of one frame in the output buffer.
*/
......@@ -51,12 +49,20 @@ struct flac_data {
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.
* Does the FLAC file contain an unsupported audio format?
*/
bool unsupported;
/**
* The validated audio format of the FLAC file. This
* attribute is defined if "have_stream_info" is true.
*/
struct audio_format audio_format;
/**
* The total number of frames in this song.
*/
FLAC__StreamMetadata_StreamInfo stream_info;
FLAC__uint64 total_frames;
/**
* The number of the first frame in this song. This is only
......
......@@ -251,12 +251,12 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
return false;
if (duration == 0)
duration = data->stream_info.total_samples;
duration = data->total_frames;
decoder_initialized(data->decoder, &audio_format,
seekable,
(float)duration /
(float)data->stream_info.sample_rate);
(float)data->audio_format.sample_rate);
return true;
}
......@@ -281,7 +281,7 @@ flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
if (cmd == DECODE_COMMAND_SEEK) {
FLAC__uint64 seek_sample = t_start +
decoder_seek_where(decoder) *
data->stream_info.sample_rate;
data->audio_format.sample_rate;
if (seek_sample >= t_start &&
(t_end == 0 || seek_sample <= t_end) &&
FLAC__stream_decoder_seek_absolute(flac_dec, seek_sample)) {
......
......@@ -302,8 +302,8 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream)
decoder_initialized(mpd_decoder, &audio_format,
input_stream->seekable,
(float)data.stream_info.total_samples /
(float)data.stream_info.sample_rate);
(float)data.total_frames /
(float)data.audio_format.sample_rate);
while (true) {
OggFLAC__seekable_stream_decoder_process_single(decoder);
......@@ -313,7 +313,7 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream)
}
if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) {
FLAC__uint64 seek_sample = decoder_seek_where(mpd_decoder) *
data.stream_info.sample_rate;
data.audio_format.sample_rate;
if (OggFLAC__seekable_stream_decoder_seek_absolute
(decoder, seek_sample)) {
data.next_frame = seek_sample;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment