Skip to content

Commit

Permalink
use ogg_page_granulepos to get number of samples written for Ogg FLAC (
Browse files Browse the repository at this point in the history
…#743)

Co-authored-by: Martijn van Beurden <[email protected]>
  • Loading branch information
ziplantil and ktmf01 authored Sep 26, 2024
1 parent e42f723 commit 9dd1b0a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
9 changes: 5 additions & 4 deletions include/FLAC/stream_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,10 +544,11 @@ typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const F
* 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.
* callback will be \c 0. For the write callback call containing the first
* page body, the \a samples argument is the number of samples contained in
* all newly added complete packets (not pages). This means that in case a
* packet is split over two pages, they are counted in the samples argument
* of the page on which the packet is completed.
*
* \note In general, FLAC__StreamEncoder functions which change the
* state should not be called on the \a encoder while in the callback.
Expand Down
2 changes: 1 addition & 1 deletion src/libFLAC/include/private/ogg_encoder_aspect.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +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__int64 last_page_granule_pos;
} FLAC__OggEncoderAspect;

void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value);
Expand Down
29 changes: 23 additions & 6 deletions src/libFLAC/ogg_encoder_aspect.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +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;
aspect->last_page_granule_pos = 0;

return true;
}
Expand Down Expand Up @@ -197,23 +197,40 @@ FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(F
* 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) {
FLAC__int64 page_granule_pos = ogg_page_granulepos(&aspect->page);
uint32_t samples_on_this_page;
if(page_granule_pos == -1) {
/* a granule position of -1 means no packets finish on this page */
samples_on_this_page = 0;
}
else {
samples_on_this_page = (uint32_t)(page_granule_pos - aspect->last_page_granule_pos);
aspect->last_page_granule_pos = page_granule_pos;
}
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, aspect->samples_in_submit_buffer, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, samples_on_this_page, 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) {
FLAC__int64 page_granule_pos = ogg_page_granulepos(&aspect->page);
uint32_t samples_on_this_page;
if(page_granule_pos == -1) {
/* a granule position of -1 means no packets finish on this page */
samples_on_this_page = 0;
}
else {
samples_on_this_page = (uint32_t)(page_granule_pos - aspect->last_page_granule_pos);
aspect->last_page_granule_pos = page_granule_pos;
}
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, aspect->samples_in_submit_buffer, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, samples_on_this_page, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
aspect->samples_in_submit_buffer = 0;
}
}
}
Expand Down

0 comments on commit 9dd1b0a

Please sign in to comment.