From 48b1e6ec5696f9520929804c5f7bc8b53c5568fc Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Wed, 14 Jun 2006 01:42:10 +0000 Subject: [PATCH] improve behavior of -F to decode even if there is no metadata --- src/flac/decode.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/flac/decode.c b/src/flac/decode.c index 5940ab9..e88ae71 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -85,6 +85,7 @@ typedef struct { FLAC__bool is_big_endian; FLAC__bool is_unsigned_samples; + FLAC__bool got_stream_info; FLAC__uint64 total_samples; unsigned bps; unsigned channels; @@ -283,6 +284,12 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__ d->wave_chunk_size_fixup.needs_fixup = false; + d->total_samples = 0; + d->got_stream_info = false; + d->bps = 0; + d->channels = 0; + d->sample_rate = 0; + d->decoder.flac.file = 0; #ifdef FLAC__HAS_OGG d->decoder.ogg.file = 0; @@ -407,7 +414,8 @@ FLAC__bool DecoderSession_process(DecoderSession *d) if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during metadata decoding"); - return false; + if(!d->continue_through_decode_errors) + return false; } } else @@ -421,7 +429,8 @@ FLAC__bool DecoderSession_process(DecoderSession *d) if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during metadata decoding"); - return false; + if(!d->continue_through_decode_errors) + return false; } } if(d->abort_flag) @@ -541,6 +550,9 @@ int DecoderSession_finish_ok(DecoderSession *d) if(md5_failure) { flac__utils_printf(stderr, 1, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename); } + else if(!d->got_stream_info) { + flac__utils_printf(stderr, 1, "\r%s: WARNING, cannot check MD5 signature since there was no STREAMINFO\n", d->inbasefilename); + } else { flac__utils_printf(stderr, 2, "\r%s: %s \n", d->inbasefilename, d->test_only? "ok ":d->analysis_mode?"done ":"done"); } @@ -880,25 +892,44 @@ FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__F if(decoder_session->abort_flag) return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; - if(bps != decoder_session->bps) { + if(decoder_session->bps && bps != decoder_session->bps) { flac__utils_printf(stderr, 1, "%s: ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, decoder_session->bps); - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + if(!decoder_session->continue_through_decode_errors) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } - if(channels != decoder_session->channels) { + if(decoder_session->channels && channels != decoder_session->channels) { flac__utils_printf(stderr, 1, "%s: ERROR, channels is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, decoder_session->channels); - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + if(!decoder_session->continue_through_decode_errors) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } - if(frame->header.sample_rate != decoder_session->sample_rate) { + if(decoder_session->sample_rate && frame->header.sample_rate != decoder_session->sample_rate) { flac__utils_printf(stderr, 1, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate); - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + if(!decoder_session->continue_through_decode_errors) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } /* * limit the number of samples to accept based on --until */ FLAC__ASSERT(!decoder_session->skip_specification->is_relative); + /* if we never got the total_samples from the metadata, the skip and until specs would never have been canonicalized, so protect against that: */ + if(decoder_session->skip_specification->is_relative) { + if(decoder_session->skip_specification->value.samples == 0) /* special case for when no --skip was given */ + decoder_session->skip_specification->is_relative = false; /* convert to our meaning of beginning-of-stream */ + else { + flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --skip because the total sample count was not found in the metadata\n", decoder_session->inbasefilename); + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + } + if(decoder_session->until_specification->is_relative) { + if(decoder_session->until_specification->value.samples == 0) /* special case for when no --until was given */ + decoder_session->until_specification->is_relative = false; /* convert to our meaning of end-of-stream */ + else { + flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until because the total sample count was not found in the metadata\n", decoder_session->inbasefilename); + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + } FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0); - FLAC__ASSERT(!decoder_session->until_specification->is_relative); FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0); if(decoder_session->until_specification->value.samples > 0) { const FLAC__uint64 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples; @@ -1044,6 +1075,7 @@ void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata (void)decoder; if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { FLAC__uint64 skip, until; + decoder_session->got_stream_info = true; decoder_session->bps = metadata->data.stream_info.bits_per_sample; decoder_session->channels = metadata->data.stream_info.channels; decoder_session->sample_rate = metadata->data.stream_info.sample_rate; -- 2.7.4