xref: /third_party/libsnd/src/ogg.h (revision b815c7f3)
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