* the encoder may need to change the \a is_last flag inside them, and
* in some cases update seek point offsets. Otherwise, the encoder will
* not modify or free the blocks. It is up to the caller to free the
- * metadata blocks after encoding.
+ * metadata blocks after encoding finishes.
*
* \note
- * The encoder stores only the \a metadata pointer; the passed-in array
- * must survive at least until after FLAC__stream_encoder_init_*() returns.
- * Do not modify the array or free the blocks until then.
+ * The encoder stores only copies of the pointers in the \a metadata array;
+ * the metadata blocks themselves must survive at least until after
+ * FLAC__stream_encoder_finish() returns. Do not free the blocks until then.
*
* \note
* The STREAMINFO block is always written and no STREAMINFO block may
FLAC__ASSERT(0 != encoder->protected_);
if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- encoder->protected_->metadata = metadata;
- encoder->protected_->num_metadata_blocks = num_blocks;
+ if(0 == metadata)
+ num_blocks = 0;
+ if(0 == num_blocks)
+ metadata = 0;
+ /* realloc() does not do exactly what we want so... */
+ if(encoder->protected_->metadata) {
+ free(encoder->protected_->metadata);
+ encoder->protected_->metadata = 0;
+ encoder->protected_->num_metadata_blocks = 0;
+ }
+ if(num_blocks) {
+ FLAC__StreamMetadata **m;
+ if(0 == (m = (FLAC__StreamMetadata**)malloc(sizeof(m[0]) * num_blocks)))
+ return false;
+ memcpy(m, metadata, sizeof(m[0]) * num_blocks);
+ encoder->protected_->metadata = m;
+ encoder->protected_->num_metadata_blocks = num_blocks;
+ }
#if FLAC__HAS_OGG
if(!FLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
return false;
unsigned i, channel;
FLAC__ASSERT(0 != encoder);
+ if(encoder->protected_->metadata) {
+ free(encoder->protected_->metadata);
+ encoder->protected_->metadata = 0;
+ encoder->protected_->num_metadata_blocks = 0;
+ }
for(i = 0; i < encoder->protected_->channels; i++) {
if(0 != encoder->private_->integer_signal_unaligned[i]) {
free(encoder->private_->integer_signal_unaligned[i]);