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