Commit 47d9bbd6 authored by Josh Coalson's avatar Josh Coalson
Browse files

fix up reporting of the current frame to the write callback; also fixes a...

fix up reporting of the current frame to the write callback; also fixes a problem with progress callbacks in the ogg flac file encoder
parent 43d8f85f
......@@ -45,6 +45,10 @@
#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 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.
*/
......@@ -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) {
......
......@@ -35,6 +35,11 @@
#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
......
......@@ -36,6 +36,11 @@
#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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment