#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
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 {
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 a 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.
*/
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);
}
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) {
#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
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;
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_);
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
#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
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;
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_);
{
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