ogg_sync_state oss;
ogg_page op;
char *buf;
- int ret, i, j, frames_per_chunk, ct_size;
- long long unsigned num_frames = 0;
+ int ret, i, j, frames_per_chunk, ct_size, prev_pageno = 0;
+ long long unsigned granule_skip = 0, num_frames = 0;
+ int64_t granule = 0, prev_granule = 0;
ogg_sync_init(&oss);
ret = -E_OGG_SYNC;
oss.returned = 0;
oss.fill = numbytes;
/* count ogg pages and get duration of the file */
- for (i = 0; ogg_sync_pageseek(&oss, &op) > 0; i++)
- num_frames = ogg_page_granulepos(&op);
+ for (i = 0; ogg_sync_pageseek(&oss, &op) > 0; i++) {
+ int this_pageno = ogg_page_pageno(&op);
+ int64_t this_granule = ogg_page_granulepos(&op);
+ if (this_granule >= 0)
+ granule = this_granule;
+ if (i > 0 && this_pageno != prev_pageno + 1) /* hole */
+ granule_skip += granule - prev_granule;
+ prev_pageno = this_pageno;
+ prev_granule = granule;
+ }
+ num_frames = granule - granule_skip;
PARA_INFO_LOG("%d pages, %llu frames\n", i, num_frames);
ret = -E_OGG_EMPTY;
if (i == 0)
afhi->seconds_total = num_frames / afhi->frequency;
/* use roughly one page per chunk */
frames_per_chunk = num_frames / i;
- PARA_INFO_LOG("%" PRIu32 "seconds, %d frames/chunk\n",
+ PARA_INFO_LOG("%" PRIu32 " seconds, %d frames/chunk\n",
afhi->seconds_total, frames_per_chunk);
ct_size = 250;
afhi->chunk_table = para_malloc(ct_size * sizeof(uint32_t));
oss.returned = afhi->header_len;
oss.fill = numbytes;
for (j = 1; ogg_sync_pageseek(&oss, &op) > 0; /* nothing */) {
- int granule = ogg_page_granulepos(&op);
+ granule = ogg_page_granulepos(&op);
while (granule >= (j + 1) * frames_per_chunk) {
j++;