diff --git a/doc/html/changelog.html b/doc/html/changelog.html
index 647cb94e..977000c9 100644
--- a/doc/html/changelog.html
+++ b/doc/html/changelog.html
@@ -185,6 +185,7 @@
Added FLAC__metadata_object_cuesheet_calculate_cddb_id()
Added FLAC__metadata_get_cuesheet()
Added FLAC__metadata_get_picture()
+ Changed FLAC__stream_encoder_finish() now returns a FLAC__bool to signal a verify failure.
Changed FLAC__StreamDecoderState: removed state FLAC__STREAM_DECODER_UNPARSEABLE_STREAM
Changed FLAC__StreamDecoderErrorStatus: new error code FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
The above two changes mean that when the decoder encounters what it thinks are unparseable frames from a future decoder, instead of returning a fatal error with the FLAC__STREAM_DECODER_UNPARSEABLE_STREAM state, it just calls the error callback with FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM and leaves the behavior up to the application.
@@ -199,6 +200,8 @@
Added FLAC::Metadata::CueSheet::calculate_cddb_id()
Added FLAC::Metadata::get_cuesheet()
Added FLAC::Metadata::get_picture()
+ Changed FLAC::Decoder::Stream::finish() now returns a bool to signal an MD5 failure like FLAC__stream_decoder_finish() does.
+ Changed FLAC::Encoder::Stream::finish() now returns a bool to signal a verify failure.
diff --git a/include/FLAC++/encoder.h b/include/FLAC++/encoder.h
index a14ba1ff..67f2a135 100644
--- a/include/FLAC++/encoder.h
+++ b/include/FLAC++/encoder.h
@@ -172,7 +172,7 @@ namespace FLAC {
virtual ::FLAC__StreamEncoderInitStatus init(); ///< See FLAC__stream_encoder_init_stream()
virtual ::FLAC__StreamEncoderInitStatus init_ogg(); ///< See FLAC__stream_encoder_init_ogg_stream()
- virtual void finish(); ///< See FLAC__stream_encoder_finish()
+ virtual bool finish(); ///< See FLAC__stream_encoder_finish()
virtual bool process(const FLAC__int32 * const buffer[], unsigned samples); ///< See FLAC__stream_encoder_process()
virtual bool process_interleaved(const FLAC__int32 buffer[], unsigned samples); ///< See FLAC__stream_encoder_process_interleaved()
diff --git a/include/FLAC/stream_encoder.h b/include/FLAC/stream_encoder.h
index eb0b193d..e69540b3 100644
--- a/include/FLAC/stream_encoder.h
+++ b/include/FLAC/stream_encoder.h
@@ -1683,8 +1683,12 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(FLAC__
* \param encoder An uninitialized encoder instance.
* \assert
* \code encoder != NULL \endcode
+ * \retval FLAC__bool
+ * \c false if verify mode is set (see FLAC__stream_encoder_set_verify())
+ * and there was a verify mismatch (in which case the state will be
+ * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR), else \c true.
*/
-FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder);
+FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder);
/** Submit data for encoding.
* This version allows you to supply the input data via an array of
diff --git a/src/flac/encode.c b/src/flac/encode.c
index 5d7fd816..6a09d7fb 100644
--- a/src/flac/encode.c
+++ b/src/flac/encode.c
@@ -1581,7 +1581,7 @@ int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_a
if(e->encoder) {
fse_state = FLAC__stream_encoder_get_state(e->encoder);
- FLAC__stream_encoder_finish(e->encoder);
+ ret = FLAC__stream_encoder_finish(e->encoder)? 0 : 1;
}
if(e->total_samples_to_encode > 0) {
@@ -1589,7 +1589,10 @@ int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_a
flac__utils_printf(stderr, 2, "\n");
}
- if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
+ if(
+ fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA ||
+ FLAC__stream_encoder_get_state(e->encoder) == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA
+ ) {
print_verify_error(e);
ret = 1;
}
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index 0a27caee..5b7f3374 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -612,7 +612,7 @@ FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder)
encoder->private_->is_being_deleted = true;
- FLAC__stream_encoder_finish(encoder);
+ (void)FLAC__stream_encoder_finish(encoder);
if(0 != encoder->private_->verify.decoder)
FLAC__stream_decoder_delete(encoder->private_->verify.decoder);
@@ -1350,19 +1350,22 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(
return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/true);
}
-FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
+FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
{
+ FLAC__bool verify_mismatch = false;
+
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED)
- return;
+ return true;
if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) {
if(encoder->private_->current_sample_number != 0) {
encoder->protected_->blocksize = encoder->private_->current_sample_number;
- process_frame_(encoder, /*is_fractional_block=*/true);
+ if(!process_frame_(encoder, /*is_fractional_block=*/true) && encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
+ verify_mismatch = true;
}
}
@@ -1381,8 +1384,8 @@ FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data);
}
- if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder)
- FLAC__stream_decoder_finish(encoder->private_->verify.decoder);
+ if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder))
+ verify_mismatch = true;
if(0 != encoder->private_->file) {
if(encoder->private_->file != stdout)
@@ -1398,7 +1401,13 @@ FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
free_(encoder);
set_defaults_(encoder);
- encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
+ /* change the state to uninitialized unless there was a verify mismatch */
+ if(verify_mismatch)
+ encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
+ else
+ encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
+
+ return !verify_mismatch;
}
FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value)
diff --git a/src/test_libFLAC++/encoders.cpp b/src/test_libFLAC++/encoders.cpp
index 14364988..acb1ec37 100644
--- a/src/test_libFLAC++/encoders.cpp
+++ b/src/test_libFLAC++/encoders.cpp
@@ -473,7 +473,11 @@ static bool test_stream_encoder(Layer layer, bool is_ogg)
printf("OK\n");
printf("testing finish()... ");
- encoder->finish();
+ if(!encoder->finish()) {
+ FLAC::Encoder::Stream::State state = encoder->get_state();
+ printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
+ return false;
+ }
printf("OK\n");
printf("freeing encoder instance... ");
diff --git a/src/test_libFLAC/encoders.c b/src/test_libFLAC/encoders.c
index ea945b0d..e498c3ef 100644
--- a/src/test_libFLAC/encoders.c
+++ b/src/test_libFLAC/encoders.c
@@ -443,7 +443,8 @@ static FLAC__bool test_stream_encoder(Layer layer, FLAC__bool is_ogg)
printf("OK\n");
printf("testing FLAC__stream_encoder_finish()... ");
- FLAC__stream_encoder_finish(encoder);
+ if(!FLAC__stream_encoder_finish(encoder))
+ return die_s_("returned false", encoder);
printf("OK\n");
printf("testing FLAC__stream_encoder_delete()... ");