diff options
-rw-r--r-- | src/decoder/_flac_common.c | 35 | ||||
-rw-r--r-- | src/decoder/_flac_common.h | 17 | ||||
-rw-r--r-- | src/decoder/flac_plugin.c | 16 | ||||
-rw-r--r-- | src/decoder/oggflac_plugin.c | 15 |
4 files changed, 51 insertions, 32 deletions
diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index 1e2ab6413..70fc2cbcc 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -58,19 +58,41 @@ flac_data_deinit(struct flac_data *data) tag_free(data->tag); } +bool +flac_data_get_audio_format(struct flac_data *data, + struct audio_format *audio_format) +{ + if (!data->have_stream_info) { + g_warning("no STREAMINFO packet found"); + return false; + } + + audio_format_init(audio_format, data->stream_info.sample_rate, + data->stream_info.bits_per_sample, + data->stream_info.channels); + + if (!audio_format_valid(audio_format)) { + g_warning("Invalid audio format: %u:%u:%u\n", + audio_format->sample_rate, + audio_format->bits, + audio_format->channels); + return false; + } + + data->frame_size = audio_format_frame_size(audio_format); + + return true; +} + void flac_metadata_common_cb(const FLAC__StreamMetadata * block, struct flac_data *data) { - const FLAC__StreamMetadata_StreamInfo *si = &(block->data.stream_info); - 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); break; + case FLAC__METADATA_TYPE_VORBIS_COMMENT: if (data->replay_gain_info) replay_gain_info_free(data->replay_gain_info); @@ -113,8 +135,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame, FLAC__uint64 nbytes) { enum decoder_command cmd; - size_t buffer_size = frame->header.blocksize * - audio_format_frame_size(&data->audio_format); + size_t buffer_size = frame->header.blocksize * data->frame_size; void *buffer; float position; unsigned bit_rate; diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h index 84b66285f..1d211fcfb 100644 --- a/src/decoder/_flac_common.h +++ b/src/decoder/_flac_common.h @@ -39,6 +39,11 @@ struct flac_data { struct pcm_buffer buffer; /** + * The size of one frame in the output buffer. + */ + unsigned frame_size; + + /** * Is the #stream_info member valid? */ bool have_stream_info; @@ -62,7 +67,6 @@ struct flac_data { */ FLAC__uint64 next_frame; - struct audio_format audio_format; FLAC__uint64 position; struct decoder *decoder; struct input_stream *input_stream; @@ -78,6 +82,17 @@ flac_data_init(struct flac_data *data, struct decoder * decoder, void flac_data_deinit(struct flac_data *data); +/** + * Obtains the audio format from the stream_info attribute, and copies + * it to the specified #audio_format object. This also updates the + * frame_size attribute. + * + * @return true on success, false the audio format is not supported + */ +bool +flac_data_get_audio_format(struct flac_data *data, + struct audio_format *audio_format); + void flac_metadata_common_cb(const FLAC__StreamMetadata * block, struct flac_data *data); diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c index 1841c3f72..2d14ab9df 100644 --- a/src/decoder/flac_plugin.c +++ b/src/decoder/flac_plugin.c @@ -391,28 +391,20 @@ static bool flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd, bool seekable, FLAC__uint64 duration) { + struct audio_format audio_format; + if (!FLAC__stream_decoder_process_until_end_of_metadata(sd)) { g_warning("problem reading metadata"); return false; } - if (!data->have_stream_info) { - g_warning("no STREAMINFO packet found"); + if (!flac_data_get_audio_format(data, &audio_format)) return false; - } - - if (!audio_format_valid(&data->audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - data->audio_format.sample_rate, - data->audio_format.bits, - data->audio_format.channels); - return false; - } if (duration == 0) duration = data->stream_info.total_samples; - decoder_initialized(data->decoder, &data->audio_format, + decoder_initialized(data->decoder, &audio_format, seekable, (float)duration / (float)data->stream_info.sample_rate); diff --git a/src/decoder/oggflac_plugin.c b/src/decoder/oggflac_plugin.c index 14b832bdb..3b6987c6d 100644 --- a/src/decoder/oggflac_plugin.c +++ b/src/decoder/oggflac_plugin.c @@ -288,6 +288,7 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) { OggFLAC__SeekableStreamDecoder *decoder = NULL; struct flac_data data; + struct audio_format audio_format; if (ogg_stream_type_detect(input_stream) != FLAC) return; @@ -302,20 +303,10 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) goto fail; } - if (!data.have_stream_info) { - g_warning("no STREAMINFO packet found"); + if (!flac_data_get_audio_format(&data, &audio_format)) goto fail; - } - - if (!audio_format_valid(&data.audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - data.audio_format.sample_rate, - data.audio_format.bits, - data.audio_format.channels); - goto fail; - } - decoder_initialized(mpd_decoder, &data.audio_format, + decoder_initialized(mpd_decoder, &audio_format, input_stream->seekable, (float)data.stream_info.total_samples / (float)data.stream_info.sample_rate); |