From 16f2ff3d3a6951588cd7a4ba1b33832a07b8652b Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 22 Dec 2018 18:04:28 +0100 Subject: [PATCH] ogg: Detect missing ogg pages. If pages of an ogg file were cut out, for example with a command like para_afh -r 'afh -b 100 -f foo.ogg' the ogg audio format handler still reports the duration of the full file. This commit makes it detect this case and adjust the duration accordingly. This affects all audio formats which employ the ogg container format. --- ogg_afh_common.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/ogg_afh_common.c b/ogg_afh_common.c index 62cde3d4..4fc37952 100644 --- a/ogg_afh_common.c +++ b/ogg_afh_common.c @@ -124,8 +124,9 @@ int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi, 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 = 0, granule_skip = 0, num_frames = 0; + int64_t prev_granule = 0; ogg_sync_init(&oss); ret = -E_OGG_SYNC; @@ -145,8 +146,16 @@ int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi, 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); + + granule = ogg_page_granulepos(&op); + 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) @@ -163,7 +172,7 @@ int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi, 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++; -- 2.30.2