multifix: change FLAC__stream_encoder_finish() to also return false if there is an error processing the last frame or updating metadata; fix problem trying to update metadata when encoding to stdout; fix problem with updating metadata if client seek_callback returns UNSUPPORTED
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index ec6a0f5..8cf6235 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -1271,10 +1271,10 @@
init_status = init_stream_internal_(
encoder,
- is_ogg? file_read_callback_ : 0,
+ encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_ : 0,
file_write_callback_,
- file_seek_callback_,
- file_tell_callback_,
+ encoder->private_->file == stdout? 0 : file_seek_callback_,
+ encoder->private_->file == stdout? 0 : file_tell_callback_,
/*metadata_callback=*/0,
client_data,
is_ogg
@@ -1366,7 +1366,7 @@
FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
{
- FLAC__bool verify_mismatch = false;
+ FLAC__bool error = false;
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
@@ -1379,28 +1379,37 @@
if(encoder->private_->current_sample_number != 0) {
const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number;
encoder->protected_->blocksize = encoder->private_->current_sample_number;
- if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true) && encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
- verify_mismatch = true;
+ if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true))
+ error = true;
}
}
FLAC__MD5Final(encoder->private_->streaminfo.data.stream_info.md5sum, &encoder->private_->md5context);
- if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) {
- if(encoder->private_->seek_callback) {
+ if(!encoder->private_->is_being_deleted) {
+ if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK) {
+ if(encoder->private_->seek_callback) {
#if FLAC__HAS_OGG
- if(encoder->private_->is_ogg)
- update_ogg_metadata_(encoder);
- else
+ if(encoder->private_->is_ogg)
+ update_ogg_metadata_(encoder);
+ else
#endif
- update_metadata_(encoder);
- }
- if(encoder->private_->metadata_callback)
- encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data);
- }
+ update_metadata_(encoder);
- if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder))
- verify_mismatch = true;
+ /* check if an error occurred while updating metadata */
+ if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
+ error = true;
+ }
+ if(encoder->private_->metadata_callback)
+ 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(!error)
+ encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
+ error = true;
+ }
+ }
if(0 != encoder->private_->file) {
if(encoder->private_->file != stdout)
@@ -1416,13 +1425,10 @@
free_(encoder);
set_defaults_(encoder);
- /* 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
+ if(!error)
encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
- return !verify_mismatch;
+ return !error;
}
FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value)
@@ -2913,6 +2919,13 @@
ogg_page page;
FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
+ FLAC__ASSERT(0 != encoder->private_->seek_callback);
+
+ /* Pre-check that client supports seeking, since we don't want the
+ * ogg_helper code to ever have to deal with this condition.
+ */
+ if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED)
+ return;
/* All this is based on intimate knowledge of the stream header
* layout, but a change to the header format that would break this