fix up reporting of the current frame to the write callback; also fixes a problem...
authorJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 31 Dec 2003 05:35:48 +0000 (05:35 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Wed, 31 Dec 2003 05:35:48 +0000 (05:35 +0000)
src/flac/encode.c
src/libFLAC/file_encoder.c
src/libOggFLAC/file_encoder.c

index d7e573b..4b08be0 100644 (file)
 #undef min
 #endif
 #define min(x,y) ((x)<(y)?(x):(y))
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
 
 /* this MUST be >= 588 so that sector aligning can take place with one read */
 #define CHUNK_OF_SAMPLES 2048
@@ -73,9 +77,8 @@ typedef struct {
        unsigned stats_mask;
 
        /*
-        * We use flac.stream for encoding native FLAC to stdout
-        * We use flac.file for encoding native FLAC to a regular file
-        * We use ogg.stream for encoding Ogg FLAC to either stdout or a regular file
+        * We use *.stream for encoding to stdout
+        * We use *.file for encoding to a regular file
         */
        union {
                union {
@@ -1801,7 +1804,7 @@ FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__
        encoder_session->bytes_written += bytes;
        /*
         * With Ogg FLAC we don't get one write callback per frame and
-        * we don't have good number for 'samples', so we estimate based
+        * we don't have good number for 'samples', so we estimate based
         * on the frame number and the knowledge that all blocks (except
         * the last) are the same size.
         */
@@ -1825,8 +1828,16 @@ void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder,
 
 void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
 {
+       EncoderSession *encoder_session = (EncoderSession*)client_data;
+
        (void)encoder;
 
+       /*
+        * With Ogg FLAC we don't get a value for 'samples_written', so we
+        * estimate based on the frames written and the knowledge that all
+        * blocks (except the last) are the same size.
+        */
+       samples_written = frames_written * encoder_session->blocksize;
        flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
 }
 
@@ -1912,7 +1923,7 @@ void print_stats(const EncoderSession *encoder_session)
        const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * progress);
 #else
        const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
-       const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * progress);
+       const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * max(1.0, progress));
 #endif
 
        if(samples_written == encoder_session->total_samples_to_encode) {
index 266b690..63b80a8 100644 (file)
 #include "FLAC/assert.h"
 #include "protected/file_encoder.h"
 
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
+
 /***********************************************************************
  *
  * Private class method prototypes
@@ -63,6 +68,7 @@ typedef struct FLAC__FileEncoderPrivate {
        char *filename;
        FLAC__uint64 bytes_written;
        FLAC__uint64 samples_written;
+       FLAC__uint64 frames_written;
        unsigned total_frames_estimate;
        FLAC__SeekableStreamEncoder *seekable_stream_encoder;
        FILE *file;
@@ -172,6 +178,7 @@ FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encod
 
        encoder->private_->bytes_written = 0;
        encoder->private_->samples_written = 0;
+       encoder->private_->frames_written = 0;
 
        FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
        FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
@@ -755,8 +762,13 @@ FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder
        if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
                file_encoder->private_->bytes_written += bytes;
                file_encoder->private_->samples_written += samples;
+               /* we keep a high watermark on the number of frames written because
+                * when the encoder goes back to write metadata, 'current_frame'
+                * will drop back to 0.
+                */
+               file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
                if(0 != file_encoder->private_->progress_callback && samples > 0)
-                       file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, current_frame+1, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
+                       file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
                return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
        }
        else
index da465d2..6a01b65 100644 (file)
 #include "OggFLAC/seekable_stream_encoder.h"
 #include "protected/file_encoder.h"
 
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
+
 /***********************************************************************
  *
  * Private class method prototypes
@@ -64,6 +69,7 @@ typedef struct OggFLAC__FileEncoderPrivate {
        char *filename;
        FLAC__uint64 bytes_written;
        FLAC__uint64 samples_written;
+       FLAC__uint64 frames_written;
        unsigned total_frames_estimate;
        OggFLAC__SeekableStreamEncoder *seekable_stream_encoder;
        FILE *file;
@@ -173,6 +179,7 @@ OggFLAC_API OggFLAC__FileEncoderState OggFLAC__file_encoder_init(OggFLAC__FileEn
 
        encoder->private_->bytes_written = 0;
        encoder->private_->samples_written = 0;
+       encoder->private_->frames_written = 0;
 
        OggFLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
        OggFLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
@@ -767,15 +774,25 @@ FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEnco
 {
        OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
 
-       (void)encoder, (void)samples, (void)current_frame;
+       (void)encoder;
 
        FLAC__ASSERT(0 != file_encoder);
 
        if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
                file_encoder->private_->bytes_written += bytes;
                file_encoder->private_->samples_written += samples;
-               if(0 != file_encoder->private_->progress_callback && samples > 0)
-                       file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, current_frame+1, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
+               /* we keep a high watermark on the number of frames written because
+                * when the encoder goes back to write metadata, 'current_frame'
+                * will drop back to 0.
+                */
+               file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
+               /*@@@@@@ We would like to add an '&& samples > 0' to the if clause
+                * here but currently because of the nature of Ogg writing 'samples'
+                * is always 0 (see ogg_encoder_aspect.c).  The downside is extra
+                * progress callbacks.
+                */
+               if(0 != file_encoder->private_->progress_callback)
+                       file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
                return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
        }
        else