1/* 2** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com> 3** Copyright (C) 2018 Arthur Taylor <art@ified.ca> 4** 5** This program is free software ; you can redistribute it and/or modify 6** it under the terms of the GNU Lesser General Public License as published by 7** the Free Software Foundation ; either version 2.1 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY ; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU Lesser General Public License for more details. 14** 15** You should have received a copy of the GNU Lesser General Public License 16** along with this program ; if not, write to the Free Software 17** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18*/ 19 20#ifndef SF_SRC_OGG_H 21#define SF_SRC_OGG_H 22 23enum 24{ OGG_ANNODEX = 300, 25 OGG_ANXDATA, 26 OGG_FLAC, 27 OGG_FLAC0, 28 OGG_PCM, 29 OGG_SPEEX, 30 OGG_VORBIS, 31 OGG_OPUS, 32} ; 33 34typedef struct 35{ /* Sync and verify incoming physical bitstream */ 36 ogg_sync_state osync ; 37 /* Take physical pages, weld into a logical stream of packets */ 38 ogg_stream_state ostream ; 39 /* One Ogg bitstream page. Codec packets are inside */ 40 ogg_page opage ; 41 /* One raw packet of data for decode */ 42 ogg_packet opacket ; 43 44 /* Unpacked packets. 255 is max there can ever be in one page. */ 45 ogg_packet pkt [255] ; 46 /* How many packets */ 47 int pkt_len ; 48 /* Current packet */ 49 int pkt_indx ; 50 51 int eos ; 52 int codec ; 53} OGG_PRIVATE ; 54 55 56#define readint(buf, base) (((buf [base + 3] << 24) & 0xff000000) | \ 57 ((buf [base + 2] <<16) & 0xff0000) | \ 58 ((buf [base + 1] << 8) & 0xff00) | \ 59 (buf [base] & 0xff)) 60/*----------------------------------------------------------------------------------------------- 61** Inline functions. 62*/ 63 64/* 65** LibOgg documentation is noted as being bad by it's author. 66** Add some useful utility inline functions for introspecting Ogg pages. 67*/ 68 69/* ogg_page_segments returns how many segments are in this page. */ 70static inline int 71ogg_page_segments (ogg_page *pg) 72{ return (int) (pg->header [26]) ; } 73 74/* ogg_page_continues returns true if this page ends in a continued packet. */ 75static inline int 76ogg_page_continues (ogg_page *pg) 77{ return pg->header [27 + pg->header [26] - 1] == 255 ; 78} 79 80/*----------------------------------------------------------------------------------------------- 81** Exported functions. 82*/ 83 84/* 85** ogg_read_first_page loads the first Ogg page found in the file, and sets the 86** OGG_PRIVATE serialno to match the logical stream of the page. Data is read 87** without seeking backwards, loading any data present from psf->header into 88** the ogg_sync state first, so that this function works with pipes. 89*/ 90int ogg_read_first_page (SF_PRIVATE *, OGG_PRIVATE *) ; 91 92/* 93** Write the whole Ogg page out. Convenience function as the ogg_page struct 94** splits header and body data into separate buffers. 95*/ 96int ogg_write_page (SF_PRIVATE *, ogg_page *) ; 97 98/* 99** Wrapper around psf_ftell() that returns the current offset in the file after 100** the most recent page that has been returned by ogg_sync_pageout(). 101*/ 102sf_count_t ogg_sync_ftell (SF_PRIVATE *) ; 103 104/* 105** Wrapper around psf_fseek() that on success resets the ogg_sync_state struct 106** so that it doesn't get corrupted. 107*/ 108sf_count_t ogg_sync_fseek (SF_PRIVATE *, sf_count_t offset, int whence) ; 109 110/* 111** Get the next page from the physical bitstream, reading in data as necessary. 112** Pays no attention to Ogg BOS/EOS markers or stream serial numbers. 113** The page is buffered in the ogg_sync_state struct, (replacing any other 114** buffered there) and also returned in *og. readmax sets a boundary for how 115** many bytes more may be read from the file, use already buffered only, or 116** unlimited reading in the case of a positive, zero or negative argument 117** respectively. If a pointer to a sf_count_t is passed in offset, then it will 118** be incremented by how many bytes were skipped to find the next page header. 119** (Useful for seeking, normally zero.) Returns the page size in bytes on 120** success, 0 on out-of-data (be it end of file or readmax reached) and -1 on 121** error with psf->error set appropriately. 122*/ 123int ogg_sync_next_page (SF_PRIVATE * psf, ogg_page *og, sf_count_t readmax, sf_count_t *offset) ; 124 125/* 126** Load the last page of a stream before the provided file offset. Searches the 127** physical bitstream, and selects a page of the passed serialno. The page 128** found is loaded in the sync buffer and exposed in odata->opage, and not 129** loaded into the ogg_stream_state. If found, the granulepos is returned in 130** *gp_out. Returns the file offset *before* the last page on success, or -1 on 131** error, setting psf->error as appropriate. 132*/ 133sf_count_t ogg_sync_last_page_before (SF_PRIVATE *psf, OGG_PRIVATE *odata, uint64_t *gp_out, sf_count_t offset, int32_t serialno) ; 134 135/* 136** Load the next page from the virtual bitstream, reading data as necessary. 137** Reads in pages from the physical bitstream, skipping pages until one of the 138** virtual bitstream of interest is found, and then feeds it into the 139** ogg_stream_state of odata->ostream, where it is buffered. Heeds EOS markers. 140** Returns 1 on success, 0 on end of stream, and -1 on fatal error. 141*/ 142int ogg_stream_next_page (SF_PRIVATE * psf, OGG_PRIVATE *odata) ; 143 144/* 145** Loads the next page using ogg_stream_next_page() and unpacks all packets 146** into the array odata->pkt, updating odata->pkt_len and setting 147** odata->pkt_indx to 0. Returns 1 if okay, 2 if okay but a hole was found 148** in the bitstream, 0 if on end of stream, and -1 on fatal error. 149*/ 150int ogg_stream_unpack_page (SF_PRIVATE *psf, OGG_PRIVATE *odata) ; 151 152/* 153** Seek within the Ogg virtual bitstream for a page containing target_gp. 154** Preforms a bisection search. If not found exactly, the best result is 155** returned in *best_gp. Found page is loaded into the virtual bitstream, 156** ready for unpacking. Arguments pcm_start and pcm_end are the highest and 157** lowest granule positions of the file. begin and end are the file offset 158** range to search. gp_rate is an information hint so granule positions can 159** be correlated to playback time, so the search can figure out how close it 160** is, should be granule positions per second. 161*/ 162int ogg_stream_seek_page_search (SF_PRIVATE *psf, OGG_PRIVATE *odata, 163 uint64_t target_gp, 164 uint64_t pcm_start, uint64_t pcm_end, 165 uint64_t *best_gp, 166 sf_count_t begin, sf_count_t end, 167 uint64_t gp_rate) ; 168 169#endif /* SF_SRC_OGG_H */ 170