mirror of https://github.com/xiph/flac
don't just pass 0 for samples in Ogg/FLAC callback
This is a fix for https://github.com/xiph/flac/issues/661
This commit is contained in:
parent
8e6498d44d
commit
1880f21066
|
@ -538,11 +538,16 @@ typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const F
|
|||
* callback is being called to write metadata.
|
||||
*
|
||||
* \note
|
||||
* Unlike when writing to native FLAC, when writing to Ogg FLAC the
|
||||
* write callback will be called twice when writing each audio
|
||||
* frame; once for the page header, and once for the page body.
|
||||
* When writing the page header, the \a samples argument to the
|
||||
* write callback will be \c 0.
|
||||
* Unlike when writing to native FLAC, when writing to Ogg FLAC the write
|
||||
* callback will be called at least twice when writing each audio frame; once
|
||||
* for the page header and once for the page body, possibly repeating this
|
||||
* pair of calls several times in a batch with the same value of
|
||||
* \a current_frame. When writing the page header, as well as in all but the
|
||||
* first page body write of the batch, the \a samples argument to the write
|
||||
* callback will be \c 0. The full number of samples of the batch will be
|
||||
* passed in the first page body write. Furthermore, it is possible that a few
|
||||
* of these samples are retained in an internal Ogg encoding buffer and not
|
||||
* actually encoded until the next batch.
|
||||
*
|
||||
* \note In general, FLAC__StreamEncoder functions which change the
|
||||
* state should not be called on the \a encoder while in the callback.
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct FLAC__OggEncoderAspect {
|
|||
FLAC__bool seen_magic; /* true if we've seen the fLaC magic in the write callback yet */
|
||||
FLAC__bool is_first_packet;
|
||||
FLAC__uint64 samples_written;
|
||||
uint32_t samples_in_submit_buffer;
|
||||
} FLAC__OggEncoderAspect;
|
||||
|
||||
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value);
|
||||
|
|
|
@ -57,6 +57,7 @@ FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect)
|
|||
aspect->seen_magic = false;
|
||||
aspect->is_first_packet = true;
|
||||
aspect->samples_written = 0;
|
||||
aspect->samples_in_submit_buffer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -192,21 +193,27 @@ FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(F
|
|||
if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
/*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */
|
||||
/* For a batch of write_callback calls associated with the same current_frame, pass the number of samples in the
|
||||
* first non-metadata page body call, and then set to zero in case there are more iterations of the while loop (so
|
||||
* as not to give the impression of more samples being processed).
|
||||
*/
|
||||
aspect->samples_in_submit_buffer += samples;
|
||||
if(is_metadata) {
|
||||
while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) {
|
||||
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, aspect->samples_in_submit_buffer, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
aspect->samples_in_submit_buffer = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) {
|
||||
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, aspect->samples_in_submit_buffer, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
aspect->samples_in_submit_buffer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue