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.
|
* callback is being called to write metadata.
|
||||||
*
|
*
|
||||||
* \note
|
* \note
|
||||||
* Unlike when writing to native FLAC, when writing to Ogg FLAC the
|
* Unlike when writing to native FLAC, when writing to Ogg FLAC the write
|
||||||
* write callback will be called twice when writing each audio
|
* callback will be called at least twice when writing each audio frame; once
|
||||||
* frame; once for the page header, and once for the page body.
|
* for the page header and once for the page body, possibly repeating this
|
||||||
* When writing the page header, the \a samples argument to the
|
* pair of calls several times in a batch with the same value of
|
||||||
* write callback will be \c 0.
|
* \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
|
* \note In general, FLAC__StreamEncoder functions which change the
|
||||||
* state should not be called on the \a encoder while in the callback.
|
* 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 seen_magic; /* true if we've seen the fLaC magic in the write callback yet */
|
||||||
FLAC__bool is_first_packet;
|
FLAC__bool is_first_packet;
|
||||||
FLAC__uint64 samples_written;
|
FLAC__uint64 samples_written;
|
||||||
|
uint32_t samples_in_submit_buffer;
|
||||||
} FLAC__OggEncoderAspect;
|
} FLAC__OggEncoderAspect;
|
||||||
|
|
||||||
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value);
|
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->seen_magic = false;
|
||||||
aspect->is_first_packet = true;
|
aspect->is_first_packet = true;
|
||||||
aspect->samples_written = 0;
|
aspect->samples_written = 0;
|
||||||
|
aspect->samples_in_submit_buffer = 0;
|
||||||
|
|
||||||
return true;
|
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)
|
if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0)
|
||||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
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) {
|
if(is_metadata) {
|
||||||
while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) {
|
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)
|
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;
|
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;
|
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||||
|
aspect->samples_in_submit_buffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) {
|
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)
|
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;
|
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;
|
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||||
|
aspect->samples_in_submit_buffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue