aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/flac_plugin.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-11 13:59:45 +0100
committerMax Kellermann <max@duempel.org>2009-11-11 16:28:44 +0100
commitc1186693b5d481d0fc5cbb60730e80c37f31d080 (patch)
tree74ec9173475ae9963f034297ef3398757b6fd11d /src/decoder/flac_plugin.c
parent80b220a3a68b4f9c4d21fa416ff220e4262cde82 (diff)
downloadmpd-c1186693b5d481d0fc5cbb60730e80c37f31d080.tar.gz
mpd-c1186693b5d481d0fc5cbb60730e80c37f31d080.tar.xz
mpd-c1186693b5d481d0fc5cbb60730e80c37f31d080.zip
decoder/flac: merged code into flac_decoder_loop()
The decoder loop of flac_decode_internal(), flac_container_decode() and flac_filedecode_internal() is merged into this one function. This unifies the code, and uses the frame number to identify the end of a CUE sub song.
Diffstat (limited to 'src/decoder/flac_plugin.c')
-rw-r--r--src/decoder/flac_plugin.c156
1 files changed, 55 insertions, 101 deletions
diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c
index f7b8cdb96..e57c18b79 100644
--- a/src/decoder/flac_plugin.c
+++ b/src/decoder/flac_plugin.c
@@ -391,13 +391,63 @@ flac_tag_dup(const char *file)
}
static void
+flac_decoder_loop(struct flac_data *data, flac_decoder *flac_dec,
+ FLAC__uint64 t_start, FLAC__uint64 t_end)
+{
+ struct decoder *decoder = data->decoder;
+ enum decoder_command cmd;
+
+ while (true) {
+ if (data->tag != NULL && !tag_is_empty(data->tag)) {
+ cmd = decoder_tag(data->decoder, data->input_stream,
+ data->tag);
+ tag_free(data->tag);
+ data->tag = tag_new();
+ } else
+ cmd = decoder_get_command(decoder);
+
+ if (cmd == DECODE_COMMAND_SEEK) {
+ FLAC__uint64 seek_sample = t_start +
+ decoder_seek_where(decoder) *
+ data->audio_format.sample_rate;
+ if (seek_sample >= t_start &&
+ (t_end == 0 || seek_sample <= t_end) &&
+ flac_seek_absolute(flac_dec, seek_sample)) {
+ data->next_frame = seek_sample;
+ data->time = (float)(seek_sample - t_start) /
+ data->audio_format.sample_rate;
+ data->position = 0;
+ decoder_command_finished(decoder);
+ } else
+ decoder_seek_error(decoder);
+ } else if (cmd == DECODE_COMMAND_STOP ||
+ flac_get_state(flac_dec) == flac_decoder_eof)
+ break;
+
+ if (t_end != 0 && data->next_frame >= t_end)
+ /* end of this sub track */
+ break;
+
+ if (!flac_process_single(flac_dec)) {
+ cmd = decoder_get_command(decoder);
+ if (cmd != DECODE_COMMAND_SEEK)
+ break;
+ }
+ }
+
+ if (cmd != DECODE_COMMAND_STOP) {
+ flacPrintErroredState(flac_get_state(flac_dec));
+ flac_finish(flac_dec);
+ }
+}
+
+static void
flac_decode_internal(struct decoder * decoder,
struct input_stream *input_stream,
bool is_ogg)
{
flac_decoder *flac_dec;
struct flac_data data;
- enum decoder_command cmd;
const char *err = NULL;
if (!(flac_dec = flac_new()))
@@ -448,39 +498,7 @@ flac_decode_internal(struct decoder * decoder,
decoder_initialized(decoder, &data.audio_format,
input_stream->seekable, data.total_time);
- while (true) {
- if (!tag_is_empty(data.tag)) {
- cmd = decoder_tag(decoder, input_stream, data.tag);
- tag_free(data.tag);
- data.tag = tag_new();
- } else
- cmd = decoder_get_command(decoder);
-
- if (cmd == DECODE_COMMAND_SEEK) {
- FLAC__uint64 seek_sample = decoder_seek_where(decoder) *
- data.audio_format.sample_rate + 0.5;
- if (flac_seek_absolute(flac_dec, seek_sample)) {
- data.next_frame = seek_sample;
- data.time = ((float)seek_sample) /
- data.audio_format.sample_rate;
- data.position = 0;
- decoder_command_finished(decoder);
- } else
- decoder_seek_error(decoder);
- } else if (cmd == DECODE_COMMAND_STOP ||
- flac_get_state(flac_dec) == flac_decoder_eof)
- break;
-
- if (!flac_process_single(flac_dec)) {
- cmd = decoder_get_command(decoder);
- if (cmd != DECODE_COMMAND_SEEK)
- break;
- }
- }
- if (cmd != DECODE_COMMAND_STOP) {
- flacPrintErroredState(flac_get_state(flac_dec));
- flac_finish(flac_dec);
- }
+ flac_decoder_loop(&data, flac_dec, 0, 0);
fail:
flac_data_deinit(&data);
@@ -615,44 +633,9 @@ flac_container_decode(struct decoder* decoder,
// seek to song start (order is important: after decoder init)
flac_seek_absolute(flac_dec, (FLAC__uint64)t_start);
+ data.next_frame = t_start;
- while (true)
- {
- if (!flac_process_single(flac_dec))
- break;
-
- // we only need to break at the end of track if we are in "cue mode"
- if (data.time >= data.total_time)
- {
- flacPrintErroredState(flac_get_state(flac_dec));
- flac_finish(flac_dec);
- }
-
- if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK)
- {
- FLAC__uint64 seek_sample = t_start +
- (decoder_seek_where(decoder) * data.audio_format.sample_rate);
-
- if (seek_sample >= t_start && seek_sample <= t_end &&
- flac_seek_absolute(flac_dec, (FLAC__uint64)seek_sample)) {
- data.next_frame = seek_sample;
- data.time = (float)(seek_sample - t_start) /
- data.audio_format.sample_rate;
- data.position = 0;
-
- decoder_command_finished(decoder);
- } else
- decoder_seek_error(decoder);
- }
- else if (flac_get_state(flac_dec) == flac_decoder_eof)
- break;
- }
-
- if (decoder_get_command(decoder) != DECODE_COMMAND_STOP)
- {
- flacPrintErroredState(flac_get_state(flac_dec));
- flac_finish(flac_dec);
- }
+ flac_decoder_loop(&data, flac_dec, t_start, t_end);
fail:
if (pathname)
@@ -747,36 +730,7 @@ flac_filedecode_internal(struct decoder* decoder,
decoder_initialized(decoder, &data.audio_format,
true, data.total_time);
- while (true)
- {
- if (!flac_process_single(flac_dec))
- break;
-
- if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK)
- {
- FLAC__uint64 seek_sample = decoder_seek_where(decoder) *
- data.audio_format.sample_rate + 0.5;
- if (flac_seek_absolute(flac_dec, seek_sample))
- {
- data.next_frame = seek_sample;
- data.time = ((float)seek_sample) /
- data.audio_format.sample_rate;
- data.position = 0;
- decoder_command_finished(decoder);
- }
- else
- decoder_seek_error(decoder);
-
- }
- else if (flac_get_state(flac_dec) == flac_decoder_eof)
- break;
- }
-
- if (decoder_get_command(decoder) != DECODE_COMMAND_STOP)
- {
- flacPrintErroredState(flac_get_state(flac_dec));
- flac_finish(flac_dec);
- }
+ flac_decoder_loop(&data, flac_dec, 0, 0);
fail:
flac_data_deinit(&data);