]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
ogg: Detect missing ogg pages.
authorAndre Noll <maan@tuebingen.mpg.de>
Sat, 22 Dec 2018 17:04:28 +0000 (18:04 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 24 Feb 2019 13:23:57 +0000 (14:23 +0100)
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

index 62cde3d465ab7c86a23d6c539b8a2b447d465f78..4fc37952a61fcb92a8a6a9c74978b501525716bd 100644 (file)
@@ -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++;