On 05/28/2010 04:38 PM, Olivier Guilyardi wrote:
> Hi,
> 
> I am working on an application which records directly into a FLAC file. For 
> this
> purpose I'm using the FLAC stream encoder interface.
> 
> It works fine, but if my application is killed during encoding, the metadata 
> is
> not being updated since the file isn't closed properly by calling
> FLAC__stream_encoder_finish().
> 
> Thus when opening the file afterwards for playback, it is possible to decode
> audio data but the FLAC__StreamMetadata.data.stream_info.total_samples field 
> is
> equals to zero.
> 
> This is a true problem because it looks like data loss to the user, especially
> if he/she's been recording for hours...
> 
> So I'm looking for a way to update the metadata periodically during encoding,
> before calling FLAC__stream_encoder_finish().
> 
> Is this possible?

For the records, I ended up with adding FLAC__stream_encoder_flush(), as shown
in the attached diff.

It's certainly not perfect, for instance it won't work for the OGG container.

But it apparently works for me.

--
  Olivier
--- src/libFLAC/stream_encoder.c        (.../vendor/flac/1.2.1) (revision 482)
+++ src/libFLAC/stream_encoder.c        (.../trunk/lib/flac)    (revision 482)
@@ -1398,6 +1398,28 @@
 #endif
 }
 
+FLAC_API FLAC__bool FLAC__stream_encoder_flush(FLAC__StreamEncoder *encoder) {
+       FLAC__bool error = false;
+    FLAC__uint64 offset;
+
+       if(!encoder->private_->tell_callback 
+            || encoder->private_->tell_callback(encoder, &offset, 
encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) {
+        return false;
+    }
+
+    update_metadata_(encoder);
+
+    /* check if an error occurred while updating metadata */
+    if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
+        error = true;
+   
+    if(!encoder->private_->seek_callback 
+            || encoder->private_->seek_callback(encoder, offset, 
encoder->private_->client_data) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK)
+        error = true;
+
+    return !error;
+}
+
 FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder 
*encoder, FLAC__bool value)
 {
        FLAC__ASSERT(0 != encoder);
--- include/FLAC/stream_encoder.h       (.../vendor/flac/1.2.1) (revision 482)
+++ include/FLAC/stream_encoder.h       (.../trunk/lib/flac)    (revision 482)
@@ -1700,6 +1700,8 @@
  */
 FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder);
 
+FLAC_API FLAC__bool FLAC__stream_encoder_flush(FLAC__StreamEncoder *encoder);
+
 /** Submit data for encoding.
  *  This version allows you to supply the input data via an array of
  *  pointers, each pointer pointing to an array of \a samples samples
_______________________________________________
Flac-dev mailing list
[email protected]
http://lists.xiph.org/mailman/listinfo/flac-dev

Reply via email to