1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 *
9 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: stdio-based convenience library for opening/seeking/decoding
14 last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $
15
16 ********************************************************************/
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "internal.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <limits.h>
26 #include <string.h>
27 #include <math.h>
28
29 #include "opusfile.h"
30
31 /*This implementation is largely based off of libvorbisfile.
32 All of the Ogg bits work roughly the same, though I have made some
33 "improvements" that have not been folded back there, yet.*/
34
35 /*A 'chained bitstream' is an Ogg Opus bitstream that contains more than one
36 logical bitstream arranged end to end (the only form of Ogg multiplexing
37 supported by this library.
38 Grouping (parallel multiplexing) is not supported, except to the extent that
39 if there are multiple logical Ogg streams in a single link of the chain, we
40 will ignore all but the first Opus stream we find.*/
41
42 /*An Ogg Opus file can be played beginning to end (streamed) without worrying
43 ahead of time about chaining (see opusdec from the opus-tools package).
44 If we have the whole file, however, and want random access
45 (seeking/scrubbing) or desire to know the total length/time of a file, we
46 need to account for the possibility of chaining.*/
47
48 /*We can handle things a number of ways.
49 We can determine the entire bitstream structure right off the bat, or find
50 pieces on demand.
51 This library determines and caches structure for the entire bitstream, but
52 builds a virtual decoder on the fly when moving between links in the chain.*/
53
54 /*There are also different ways to implement seeking.
55 Enough information exists in an Ogg bitstream to seek to sample-granularity
56 positions in the output.
57 Or, one can seek by picking some portion of the stream roughly in the desired
58 area if we only want coarse navigation through the stream.
59 We implement and expose both strategies.*/
60
61 /*The maximum number of bytes in a page (including the page headers).*/
62 #define OP_PAGE_SIZE_MAX (65307)
63 /*The default amount to seek backwards per step when trying to find the
64 previous page.
65 This must be at least as large as the maximum size of a page.*/
66 #define OP_CHUNK_SIZE (65536)
67 /*The maximum amount to seek backwards per step when trying to find the
68 previous page.*/
69 #define OP_CHUNK_SIZE_MAX (1024*(opus_int32)1024)
70 /*A smaller read size is needed for low-rate streaming.*/
71 #define OP_READ_SIZE (2048)
72
op_test(OpusHead * _head,const unsigned char * _initial_data,size_t _initial_bytes)73 int op_test(OpusHead *_head,
74 const unsigned char *_initial_data,size_t _initial_bytes){
75 ogg_sync_state oy;
76 char *data;
77 int err;
78 /*The first page of a normal Opus file will be at most 57 bytes (27 Ogg
79 page header bytes + 1 lacing value + 21 Opus header bytes + 8 channel
80 mapping bytes).
81 It will be at least 47 bytes (27 Ogg page header bytes + 1 lacing value +
82 19 Opus header bytes using channel mapping family 0).
83 If we don't have at least that much data, give up now.*/
84 if(_initial_bytes<47)return OP_FALSE;
85 /*Only proceed if we start with the magic OggS string.
86 This is to prevent us spending a lot of time allocating memory and looking
87 for Ogg pages in non-Ogg files.*/
88 if(memcmp(_initial_data,"OggS",4)!=0)return OP_ENOTFORMAT;
89 ogg_sync_init(&oy);
90 data=ogg_sync_buffer(&oy,_initial_bytes);
91 if(data!=NULL){
92 ogg_stream_state os;
93 ogg_page og;
94 int ret;
95 memcpy(data,_initial_data,_initial_bytes);
96 ogg_sync_wrote(&oy,_initial_bytes);
97 ogg_stream_init(&os,-1);
98 err=OP_FALSE;
99 do{
100 ogg_packet op;
101 ret=ogg_sync_pageout(&oy,&og);
102 /*Ignore holes.*/
103 if(ret<0)continue;
104 /*Stop if we run out of data.*/
105 if(!ret)break;
106 ogg_stream_reset_serialno(&os,ogg_page_serialno(&og));
107 ogg_stream_pagein(&os,&og);
108 /*Only process the first packet on this page (if it's a BOS packet,
109 it's required to be the only one).*/
110 if(ogg_stream_packetout(&os,&op)==1){
111 if(op.b_o_s){
112 ret=opus_head_parse(_head,op.packet,op.bytes);
113 /*If this didn't look like Opus, keep going.*/
114 if(ret==OP_ENOTFORMAT)continue;
115 /*Otherwise we're done, one way or another.*/
116 err=ret;
117 }
118 /*We finished parsing the headers.
119 There is no Opus to be found.*/
120 else err=OP_ENOTFORMAT;
121 }
122 }
123 while(err==OP_FALSE);
124 ogg_stream_clear(&os);
125 }
126 else err=OP_EFAULT;
127 ogg_sync_clear(&oy);
128 return err;
129 }
130
131 /*Many, many internal helpers.
132 The intention is not to be confusing.
133 Rampant duplication and monolithic function implementation (though we do have
134 some large, omnibus functions still) would be harder to understand anyway.
135 The high level functions are last.
136 Begin grokking near the end of the file if you prefer to read things
137 top-down.*/
138
139 /*The read/seek functions track absolute position within the stream.*/
140
141 /*Read a little more data from the file/pipe into the ogg_sync framer.
142 _nbytes: The maximum number of bytes to read.
143 Return: A positive number of bytes read on success, 0 on end-of-file, or a
144 negative value on failure.*/
op_get_data(OggOpusFile * _of,int _nbytes)145 static int op_get_data(OggOpusFile *_of,int _nbytes){
146 unsigned char *buffer;
147 int nbytes;
148 OP_ASSERT(_nbytes>0);
149 buffer=(unsigned char *)ogg_sync_buffer(&_of->oy,_nbytes);
150 nbytes=(int)(*_of->callbacks.read)(_of->source,buffer,_nbytes);
151 OP_ASSERT(nbytes<=_nbytes);
152 if(OP_LIKELY(nbytes>0))ogg_sync_wrote(&_of->oy,nbytes);
153 return nbytes;
154 }
155
156 /*Save a tiny smidge of verbosity to make the code more readable.*/
op_seek_helper(OggOpusFile * _of,opus_int64 _offset)157 static int op_seek_helper(OggOpusFile *_of,opus_int64 _offset){
158 if(_offset==_of->offset)return 0;
159 if(_of->callbacks.seek==NULL
160 ||(*_of->callbacks.seek)(_of->source,_offset,SEEK_SET)){
161 return OP_EREAD;
162 }
163 _of->offset=_offset;
164 ogg_sync_reset(&_of->oy);
165 return 0;
166 }
167
168 /*Get the current position indicator of the underlying source.
169 This should be the same as the value reported by tell().*/
op_position(const OggOpusFile * _of)170 static opus_int64 op_position(const OggOpusFile *_of){
171 /*The current position indicator is _not_ simply offset.
172 We may also have unprocessed, buffered data in the sync state.*/
173 return _of->offset+_of->oy.fill-_of->oy.returned;
174 }
175
176 /*From the head of the stream, get the next page.
177 _boundary specifies if the function is allowed to fetch more data from the
178 stream (and how much) or only use internally buffered data.
179 _boundary: -1: Unbounded search.
180 0: Read no additional data.
181 Use only cached data.
182 n: Search for the start of a new page up to file position n.
183 Return: n>=0: Found a page at absolute offset n.
184 OP_FALSE: Hit the _boundary limit.
185 OP_EREAD: An underlying read operation failed.
186 OP_BADLINK: We hit end-of-file before reaching _boundary.*/
op_get_next_page(OggOpusFile * _of,ogg_page * _og,opus_int64 _boundary)187 static opus_int64 op_get_next_page(OggOpusFile *_of,ogg_page *_og,
188 opus_int64 _boundary){
189 while(_boundary<=0||_of->offset<_boundary){
190 int more;
191 more=ogg_sync_pageseek(&_of->oy,_og);
192 /*Skipped (-more) bytes.*/
193 if(OP_UNLIKELY(more<0))_of->offset-=more;
194 else if(more==0){
195 int read_nbytes;
196 int ret;
197 /*Send more paramedics.*/
198 if(!_boundary)return OP_FALSE;
199 if(_boundary<0)read_nbytes=OP_READ_SIZE;
200 else{
201 opus_int64 position;
202 position=op_position(_of);
203 if(position>=_boundary)return OP_FALSE;
204 read_nbytes=(int)OP_MIN(_boundary-position,OP_READ_SIZE);
205 }
206 ret=op_get_data(_of,read_nbytes);
207 if(OP_UNLIKELY(ret<0))return OP_EREAD;
208 if(OP_UNLIKELY(ret==0)){
209 /*Only fail cleanly on EOF if we didn't have a known boundary.
210 Otherwise, we should have been able to reach that boundary, and this
211 is a fatal error.*/
212 return OP_UNLIKELY(_boundary<0)?OP_FALSE:OP_EBADLINK;
213 }
214 }
215 else{
216 /*Got a page.
217 Return the page start offset and advance the internal offset past the
218 page end.*/
219 opus_int64 page_offset;
220 page_offset=_of->offset;
221 _of->offset+=more;
222 OP_ASSERT(page_offset>=0);
223 return page_offset;
224 }
225 }
226 return OP_FALSE;
227 }
228
op_add_serialno(const ogg_page * _og,ogg_uint32_t ** _serialnos,int * _nserialnos,int * _cserialnos)229 static int op_add_serialno(const ogg_page *_og,
230 ogg_uint32_t **_serialnos,int *_nserialnos,int *_cserialnos){
231 ogg_uint32_t *serialnos;
232 int nserialnos;
233 int cserialnos;
234 ogg_uint32_t s;
235 s=ogg_page_serialno(_og);
236 serialnos=*_serialnos;
237 nserialnos=*_nserialnos;
238 cserialnos=*_cserialnos;
239 if(OP_UNLIKELY(nserialnos>=cserialnos)){
240 if(OP_UNLIKELY(cserialnos>INT_MAX/(int)sizeof(*serialnos)-1>>1)){
241 return OP_EFAULT;
242 }
243 cserialnos=2*cserialnos+1;
244 OP_ASSERT(nserialnos<cserialnos);
245 serialnos=(ogg_uint32_t *)_ogg_realloc(serialnos,
246 sizeof(*serialnos)*cserialnos);
247 if(OP_UNLIKELY(serialnos==NULL))return OP_EFAULT;
248 }
249 serialnos[nserialnos++]=s;
250 *_serialnos=serialnos;
251 *_nserialnos=nserialnos;
252 *_cserialnos=cserialnos;
253 return 0;
254 }
255
256 /*Returns nonzero if found.*/
op_lookup_serialno(ogg_uint32_t _s,const ogg_uint32_t * _serialnos,int _nserialnos)257 static int op_lookup_serialno(ogg_uint32_t _s,
258 const ogg_uint32_t *_serialnos,int _nserialnos){
259 int i;
260 for(i=0;i<_nserialnos&&_serialnos[i]!=_s;i++);
261 return i<_nserialnos;
262 }
263
op_lookup_page_serialno(const ogg_page * _og,const ogg_uint32_t * _serialnos,int _nserialnos)264 static int op_lookup_page_serialno(const ogg_page *_og,
265 const ogg_uint32_t *_serialnos,int _nserialnos){
266 return op_lookup_serialno(ogg_page_serialno(_og),_serialnos,_nserialnos);
267 }
268
269 typedef struct OpusSeekRecord OpusSeekRecord;
270
271 /*We use this to remember the pages we found while enumerating the links of a
272 chained stream.
273 We keep track of the starting and ending offsets, as well as the point we
274 started searching from, so we know where to bisect.
275 We also keep the serial number, so we can tell if the page belonged to the
276 current link or not, as well as the granule position, to aid in estimating
277 the start of the link.*/
278 struct OpusSeekRecord{
279 /*The earliest byte we know of such that reading forward from it causes
280 capture to be regained at this page.*/
281 opus_int64 search_start;
282 /*The offset of this page.*/
283 opus_int64 offset;
284 /*The size of this page.*/
285 opus_int32 size;
286 /*The serial number of this page.*/
287 ogg_uint32_t serialno;
288 /*The granule position of this page.*/
289 ogg_int64_t gp;
290 };
291
292 /*Find the last page beginning before _offset with a valid granule position.
293 There is no '_boundary' parameter as it will always have to read more data.
294 This is much dirtier than the above, as Ogg doesn't have any backward search
295 linkage.
296 This search prefers pages of the specified serial number.
297 If a page of the specified serial number is spotted during the
298 seek-back-and-read-forward, it will return the info of last page of the
299 matching serial number, instead of the very last page, unless the very last
300 page belongs to a different link than preferred serial number.
301 If no page of the specified serial number is seen, it will return the info of
302 the last page.
303 [out] _sr: Returns information about the page that was found on success.
304 _offset: The _offset before which to find a page.
305 Any page returned will consist of data entirely before _offset.
306 _serialno: The preferred serial number.
307 If a page with this serial number is found, it will be returned
308 even if another page in the same link is found closer to
309 _offset.
310 This is purely opportunistic: there is no guarantee such a page
311 will be found if it exists.
312 _serialnos: The list of serial numbers in the link that contains the
313 preferred serial number.
314 _nserialnos: The number of serial numbers in the current link.
315 Return: 0 on success, or a negative value on failure.
316 OP_EREAD: Failed to read more data (error or EOF).
317 OP_EBADLINK: We couldn't find a page even after seeking back to the
318 start of the stream.*/
op_get_prev_page_serial(OggOpusFile * _of,OpusSeekRecord * _sr,opus_int64 _offset,ogg_uint32_t _serialno,const ogg_uint32_t * _serialnos,int _nserialnos)319 static int op_get_prev_page_serial(OggOpusFile *_of,OpusSeekRecord *_sr,
320 opus_int64 _offset,ogg_uint32_t _serialno,
321 const ogg_uint32_t *_serialnos,int _nserialnos){
322 OpusSeekRecord preferred_sr;
323 ogg_page og;
324 opus_int64 begin;
325 opus_int64 end;
326 opus_int64 original_end;
327 opus_int32 chunk_size;
328 int preferred_found;
329 original_end=end=begin=_offset;
330 preferred_found=0;
331 _offset=-1;
332 chunk_size=OP_CHUNK_SIZE;
333 do{
334 opus_int64 search_start;
335 int ret;
336 OP_ASSERT(chunk_size>=OP_PAGE_SIZE_MAX);
337 begin=OP_MAX(begin-chunk_size,0);
338 ret=op_seek_helper(_of,begin);
339 if(OP_UNLIKELY(ret<0))return ret;
340 search_start=begin;
341 while(_of->offset<end){
342 opus_int64 llret;
343 ogg_uint32_t serialno;
344 llret=op_get_next_page(_of,&og,end);
345 if(OP_UNLIKELY(llret<OP_FALSE))return (int)llret;
346 else if(llret==OP_FALSE)break;
347 serialno=ogg_page_serialno(&og);
348 /*Save the information for this page.
349 We're not interested in the page itself... just the serial number, byte
350 offset, page size, and granule position.*/
351 _sr->search_start=search_start;
352 _sr->offset=_offset=llret;
353 _sr->serialno=serialno;
354 OP_ASSERT(_of->offset-_offset>=0);
355 OP_ASSERT(_of->offset-_offset<=OP_PAGE_SIZE_MAX);
356 _sr->size=(opus_int32)(_of->offset-_offset);
357 _sr->gp=ogg_page_granulepos(&og);
358 /*If this page is from the stream we're looking for, remember it.*/
359 if(serialno==_serialno){
360 preferred_found=1;
361 *&preferred_sr=*_sr;
362 }
363 if(!op_lookup_serialno(serialno,_serialnos,_nserialnos)){
364 /*We fell off the end of the link, which means we seeked back too far
365 and shouldn't have been looking in that link to begin with.
366 If we found the preferred serial number, forget that we saw it.*/
367 preferred_found=0;
368 }
369 search_start=llret+1;
370 }
371 /*We started from the beginning of the stream and found nothing.
372 This should be impossible unless the contents of the source changed out
373 from under us after we read from it.*/
374 if(OP_UNLIKELY(!begin)&&OP_UNLIKELY(_offset<0))return OP_EBADLINK;
375 /*Bump up the chunk size.
376 This is mildly helpful when seeks are very expensive (http).*/
377 chunk_size=OP_MIN(2*chunk_size,OP_CHUNK_SIZE_MAX);
378 /*Avoid quadratic complexity if we hit an invalid patch of the file.*/
379 end=OP_MIN(begin+OP_PAGE_SIZE_MAX-1,original_end);
380 }
381 while(_offset<0);
382 if(preferred_found)*_sr=*&preferred_sr;
383 return 0;
384 }
385
386 /*Find the last page beginning before _offset with the given serial number and
387 a valid granule position.
388 Unlike the above search, this continues until it finds such a page, but does
389 not stray outside the current link.
390 We could implement it (inefficiently) by calling op_get_prev_page_serial()
391 repeatedly until it returned a page that had both our preferred serial
392 number and a valid granule position, but doing it with a separate function
393 allows us to avoid repeatedly re-scanning valid pages from other streams as
394 we seek-back-and-read-forward.
395 [out] _gp: Returns the granule position of the page that was found on
396 success.
397 _offset: The _offset before which to find a page.
398 Any page returned will consist of data entirely before _offset.
399 _serialno: The target serial number.
400 _serialnos: The list of serial numbers in the link that contains the
401 preferred serial number.
402 _nserialnos: The number of serial numbers in the current link.
403 Return: The offset of the page on success, or a negative value on failure.
404 OP_EREAD: Failed to read more data (error or EOF).
405 OP_EBADLINK: We couldn't find a page even after seeking back past the
406 beginning of the link.*/
op_get_last_page(OggOpusFile * _of,ogg_int64_t * _gp,opus_int64 _offset,ogg_uint32_t _serialno,const ogg_uint32_t * _serialnos,int _nserialnos)407 static opus_int64 op_get_last_page(OggOpusFile *_of,ogg_int64_t *_gp,
408 opus_int64 _offset,ogg_uint32_t _serialno,
409 const ogg_uint32_t *_serialnos,int _nserialnos){
410 ogg_page og;
411 ogg_int64_t gp;
412 opus_int64 begin;
413 opus_int64 end;
414 opus_int64 original_end;
415 opus_int32 chunk_size;
416 /*The target serial number must belong to the current link.*/
417 OP_ASSERT(op_lookup_serialno(_serialno,_serialnos,_nserialnos));
418 original_end=end=begin=_offset;
419 _offset=-1;
420 /*We shouldn't have to initialize gp, but gcc is too dumb to figure out that
421 ret>=0 implies we entered the if(page_gp!=-1) block at least once.*/
422 gp=-1;
423 chunk_size=OP_CHUNK_SIZE;
424 do{
425 int left_link;
426 int ret;
427 OP_ASSERT(chunk_size>=OP_PAGE_SIZE_MAX);
428 begin=OP_MAX(begin-chunk_size,0);
429 ret=op_seek_helper(_of,begin);
430 if(OP_UNLIKELY(ret<0))return ret;
431 left_link=0;
432 while(_of->offset<end){
433 opus_int64 llret;
434 ogg_uint32_t serialno;
435 llret=op_get_next_page(_of,&og,end);
436 if(OP_UNLIKELY(llret<OP_FALSE))return llret;
437 else if(llret==OP_FALSE)break;
438 serialno=ogg_page_serialno(&og);
439 if(serialno==_serialno){
440 ogg_int64_t page_gp;
441 /*The page is from the right stream...*/
442 page_gp=ogg_page_granulepos(&og);
443 if(page_gp!=-1){
444 /*And has a valid granule position.
445 Let's remember it.*/
446 _offset=llret;
447 gp=page_gp;
448 }
449 }
450 else if(OP_UNLIKELY(!op_lookup_serialno(serialno,
451 _serialnos,_nserialnos))){
452 /*We fell off the start of the link, which means we don't need to keep
453 seeking any farther back.*/
454 left_link=1;
455 }
456 }
457 /*We started from at or before the beginning of the link and found nothing.
458 This should be impossible unless the contents of the source changed out
459 from under us after we read from it.*/
460 if((OP_UNLIKELY(left_link)||OP_UNLIKELY(!begin))&&OP_UNLIKELY(_offset<0)){
461 return OP_EBADLINK;
462 }
463 /*Bump up the chunk size.
464 This is mildly helpful when seeks are very expensive (http).*/
465 chunk_size=OP_MIN(2*chunk_size,OP_CHUNK_SIZE_MAX);
466 /*Avoid quadratic complexity if we hit an invalid patch of the file.*/
467 end=OP_MIN(begin+OP_PAGE_SIZE_MAX-1,original_end);
468 }
469 while(_offset<0);
470 *_gp=gp;
471 return _offset;
472 }
473
474 /*Uses the local ogg_stream storage in _of.
475 This is important for non-streaming input sources.*/
op_fetch_headers_impl(OggOpusFile * _of,OpusHead * _head,OpusTags * _tags,ogg_uint32_t ** _serialnos,int * _nserialnos,int * _cserialnos,ogg_page * _og)476 static int op_fetch_headers_impl(OggOpusFile *_of,OpusHead *_head,
477 OpusTags *_tags,ogg_uint32_t **_serialnos,int *_nserialnos,
478 int *_cserialnos,ogg_page *_og){
479 ogg_packet op;
480 int ret;
481 if(_serialnos!=NULL)*_nserialnos=0;
482 /*Extract the serialnos of all BOS pages plus the first set of Opus headers
483 we see in the link.*/
484 while(ogg_page_bos(_og)){
485 if(_serialnos!=NULL){
486 if(OP_UNLIKELY(op_lookup_page_serialno(_og,*_serialnos,*_nserialnos))){
487 /*A dupe serialnumber in an initial header packet set==invalid stream.*/
488 return OP_EBADHEADER;
489 }
490 ret=op_add_serialno(_og,_serialnos,_nserialnos,_cserialnos);
491 if(OP_UNLIKELY(ret<0))return ret;
492 }
493 if(_of->ready_state<OP_STREAMSET){
494 /*We don't have an Opus stream in this link yet, so begin prospective
495 stream setup.
496 We need a stream to get packets.*/
497 ogg_stream_reset_serialno(&_of->os,ogg_page_serialno(_og));
498 ogg_stream_pagein(&_of->os,_og);
499 if(OP_LIKELY(ogg_stream_packetout(&_of->os,&op)>0)){
500 ret=opus_head_parse(_head,op.packet,op.bytes);
501 /*Found a valid Opus header.
502 Continue setup.*/
503 if(OP_LIKELY(ret>=0))_of->ready_state=OP_STREAMSET;
504 /*If it's just a stream type we don't recognize, ignore it.
505 Everything else is fatal.*/
506 else if(ret!=OP_ENOTFORMAT)return ret;
507 }
508 /*TODO: Should a BOS page with no packets be an error?*/
509 }
510 /*Get the next page.
511 No need to clamp the boundary offset against _of->end, as all errors
512 become OP_ENOTFORMAT or OP_EBADHEADER.*/
513 if(OP_UNLIKELY(op_get_next_page(_of,_og,
514 OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){
515 return _of->ready_state<OP_STREAMSET?OP_ENOTFORMAT:OP_EBADHEADER;
516 }
517 }
518 if(OP_UNLIKELY(_of->ready_state!=OP_STREAMSET))return OP_ENOTFORMAT;
519 /*If the first non-header page belonged to our Opus stream, submit it.*/
520 if(_of->os.serialno==ogg_page_serialno(_og))ogg_stream_pagein(&_of->os,_og);
521 /*Loop getting packets.*/
522 for(;;){
523 switch(ogg_stream_packetout(&_of->os,&op)){
524 case 0:{
525 /*Loop getting pages.*/
526 for(;;){
527 /*No need to clamp the boundary offset against _of->end, as all
528 errors become OP_EBADHEADER.*/
529 if(OP_UNLIKELY(op_get_next_page(_of,_og,
530 OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){
531 return OP_EBADHEADER;
532 }
533 /*If this page belongs to the correct stream, go parse it.*/
534 if(_of->os.serialno==ogg_page_serialno(_og)){
535 ogg_stream_pagein(&_of->os,_og);
536 break;
537 }
538 /*If the link ends before we see the Opus comment header, abort.*/
539 if(OP_UNLIKELY(ogg_page_bos(_og)))return OP_EBADHEADER;
540 /*Otherwise, keep looking.*/
541 }
542 }break;
543 /*We shouldn't get a hole in the headers!*/
544 case -1:return OP_EBADHEADER;
545 default:{
546 /*Got a packet.
547 It should be the comment header.*/
548 ret=opus_tags_parse(_tags,op.packet,op.bytes);
549 if(OP_UNLIKELY(ret<0))return ret;
550 /*Make sure the page terminated at the end of the comment header.
551 If there is another packet on the page, or part of a packet, then
552 reject the stream.
553 Otherwise seekable sources won't be able to seek back to the start
554 properly.*/
555 ret=ogg_stream_packetout(&_of->os,&op);
556 if(OP_UNLIKELY(ret!=0)
557 ||OP_UNLIKELY(_og->header[_og->header_len-1]==255)){
558 /*If we fail, the caller assumes our tags are uninitialized.*/
559 opus_tags_clear(_tags);
560 return OP_EBADHEADER;
561 }
562 return 0;
563 }
564 }
565 }
566 }
567
op_fetch_headers(OggOpusFile * _of,OpusHead * _head,OpusTags * _tags,ogg_uint32_t ** _serialnos,int * _nserialnos,int * _cserialnos,ogg_page * _og)568 static int op_fetch_headers(OggOpusFile *_of,OpusHead *_head,
569 OpusTags *_tags,ogg_uint32_t **_serialnos,int *_nserialnos,
570 int *_cserialnos,ogg_page *_og){
571 ogg_page og;
572 int ret;
573 if(!_og){
574 /*No need to clamp the boundary offset against _of->end, as all errors
575 become OP_ENOTFORMAT.*/
576 if(OP_UNLIKELY(op_get_next_page(_of,&og,
577 OP_ADV_OFFSET(_of->offset,OP_CHUNK_SIZE))<0)){
578 return OP_ENOTFORMAT;
579 }
580 _og=&og;
581 }
582 _of->ready_state=OP_OPENED;
583 ret=op_fetch_headers_impl(_of,_head,_tags,_serialnos,_nserialnos,
584 _cserialnos,_og);
585 /*Revert back from OP_STREAMSET to OP_OPENED on failure, to prevent
586 double-free of the tags in an unseekable stream.*/
587 if(OP_UNLIKELY(ret<0))_of->ready_state=OP_OPENED;
588 return ret;
589 }
590
591 /*Granule position manipulation routines.
592 A granule position is defined to be an unsigned 64-bit integer, with the
593 special value -1 in two's complement indicating an unset or invalid granule
594 position.
595 We are not guaranteed to have an unsigned 64-bit type, so we construct the
596 following routines that
597 a) Properly order negative numbers as larger than positive numbers, and
598 b) Check for underflow or overflow past the special -1 value.
599 This lets us operate on the full, valid range of granule positions in a
600 consistent and safe manner.
601 This full range is organized into distinct regions:
602 [ -1 (invalid) ][ 0 ... OP_INT64_MAX ][ OP_INT64_MIN ... -2 ][-1 (invalid) ]
603
604 No one should actually use granule positions so large that they're negative,
605 even if they are technically valid, as very little software handles them
606 correctly (including most of Xiph.Org's).
607 This library also refuses to support durations so large they won't fit in a
608 signed 64-bit integer (to avoid exposing this mess to the application, and
609 to simplify a good deal of internal arithmetic), so the only way to use them
610 successfully is if pcm_start is very large.
611 This means there isn't anything you can do with negative granule positions
612 that you couldn't have done with purely non-negative ones.
613 The main purpose of these routines is to allow us to think very explicitly
614 about the possible failure cases of all granule position manipulations.*/
615
616 /*Safely adds a small signed integer to a valid (not -1) granule position.
617 The result can use the full 64-bit range of values (both positive and
618 negative), but will fail on overflow (wrapping past -1; wrapping past
619 OP_INT64_MAX is explicitly okay).
620 [out] _dst_gp: The resulting granule position.
621 Only modified on success.
622 _src_gp: The granule position to add to.
623 This must not be -1.
624 _delta: The amount to add.
625 This is allowed to be up to 32 bits to support the maximum
626 duration of a single Ogg page (255 packets * 120 ms per
627 packet == 1,468,800 samples at 48 kHz).
628 Return: 0 on success, or OP_EINVAL if the result would wrap around past -1.*/
op_granpos_add(ogg_int64_t * _dst_gp,ogg_int64_t _src_gp,opus_int32 _delta)629 static int op_granpos_add(ogg_int64_t *_dst_gp,ogg_int64_t _src_gp,
630 opus_int32 _delta){
631 /*The code below handles this case correctly, but there's no reason we
632 should ever be called with these values, so make sure we aren't.*/
633 OP_ASSERT(_src_gp!=-1);
634 if(_delta>0){
635 /*Adding this amount to the granule position would overflow its 64-bit
636 range.*/
637 if(OP_UNLIKELY(_src_gp<0)&&OP_UNLIKELY(_src_gp>=-1-_delta))return OP_EINVAL;
638 if(OP_UNLIKELY(_src_gp>OP_INT64_MAX-_delta)){
639 /*Adding this amount to the granule position would overflow the positive
640 half of its 64-bit range.
641 Since signed overflow is undefined in C, do it in a way the compiler
642 isn't allowed to screw up.*/
643 _delta-=(opus_int32)(OP_INT64_MAX-_src_gp)+1;
644 _src_gp=OP_INT64_MIN;
645 }
646 }
647 else if(_delta<0){
648 /*Subtracting this amount from the granule position would underflow its
649 64-bit range.*/
650 if(_src_gp>=0&&OP_UNLIKELY(_src_gp<-_delta))return OP_EINVAL;
651 if(OP_UNLIKELY(_src_gp<OP_INT64_MIN-_delta)){
652 /*Subtracting this amount from the granule position would underflow the
653 negative half of its 64-bit range.
654 Since signed underflow is undefined in C, do it in a way the compiler
655 isn't allowed to screw up.*/
656 _delta+=(opus_int32)(_src_gp-OP_INT64_MIN)+1;
657 _src_gp=OP_INT64_MAX;
658 }
659 }
660 *_dst_gp=_src_gp+_delta;
661 return 0;
662 }
663
664 /*Safely computes the difference between two granule positions.
665 The difference must fit in a signed 64-bit integer, or the function fails.
666 It correctly handles the case where the granule position has wrapped around
667 from positive values to negative ones.
668 [out] _delta: The difference between the granule positions.
669 Only modified on success.
670 _gp_a: The granule position to subtract from.
671 This must not be -1.
672 _gp_b: The granule position to subtract.
673 This must not be -1.
674 Return: 0 on success, or OP_EINVAL if the result would not fit in a signed
675 64-bit integer.*/
op_granpos_diff(ogg_int64_t * _delta,ogg_int64_t _gp_a,ogg_int64_t _gp_b)676 static int op_granpos_diff(ogg_int64_t *_delta,
677 ogg_int64_t _gp_a,ogg_int64_t _gp_b){
678 int gp_a_negative;
679 int gp_b_negative;
680 /*The code below handles these cases correctly, but there's no reason we
681 should ever be called with these values, so make sure we aren't.*/
682 OP_ASSERT(_gp_a!=-1);
683 OP_ASSERT(_gp_b!=-1);
684 gp_a_negative=OP_UNLIKELY(_gp_a<0);
685 gp_b_negative=OP_UNLIKELY(_gp_b<0);
686 if(OP_UNLIKELY(gp_a_negative^gp_b_negative)){
687 ogg_int64_t da;
688 ogg_int64_t db;
689 if(gp_a_negative){
690 /*_gp_a has wrapped to a negative value but _gp_b hasn't: the difference
691 should be positive.*/
692 /*Step 1: Handle wrapping.*/
693 /*_gp_a < 0 => da < 0.*/
694 da=(OP_INT64_MIN-_gp_a)-1;
695 /*_gp_b >= 0 => db >= 0.*/
696 db=OP_INT64_MAX-_gp_b;
697 /*Step 2: Check for overflow.*/
698 if(OP_UNLIKELY(OP_INT64_MAX+da<db))return OP_EINVAL;
699 *_delta=db-da;
700 }
701 else{
702 /*_gp_b has wrapped to a negative value but _gp_a hasn't: the difference
703 should be negative.*/
704 /*Step 1: Handle wrapping.*/
705 /*_gp_a >= 0 => da <= 0*/
706 da=_gp_a+OP_INT64_MIN;
707 /*_gp_b < 0 => db <= 0*/
708 db=OP_INT64_MIN-_gp_b;
709 /*Step 2: Check for overflow.*/
710 if(OP_UNLIKELY(da<OP_INT64_MIN-db))return OP_EINVAL;
711 *_delta=da+db;
712 }
713 }
714 else *_delta=_gp_a-_gp_b;
715 return 0;
716 }
717
op_granpos_cmp(ogg_int64_t _gp_a,ogg_int64_t _gp_b)718 static int op_granpos_cmp(ogg_int64_t _gp_a,ogg_int64_t _gp_b){
719 /*The invalid granule position -1 should behave like NaN: neither greater
720 than nor less than any other granule position, nor equal to any other
721 granule position, including itself.
722 However, that means there isn't anything we could sensibly return from this
723 function for it.*/
724 OP_ASSERT(_gp_a!=-1);
725 OP_ASSERT(_gp_b!=-1);
726 /*Handle the wrapping cases.*/
727 if(OP_UNLIKELY(_gp_a<0)){
728 if(_gp_b>=0)return 1;
729 /*Else fall through.*/
730 }
731 else if(OP_UNLIKELY(_gp_b<0))return -1;
732 /*No wrapping case.*/
733 return (_gp_a>_gp_b)-(_gp_b>_gp_a);
734 }
735
736 /*Returns the duration of the packet (in samples at 48 kHz), or a negative
737 value on error.*/
op_get_packet_duration(const unsigned char * _data,int _len)738 static int op_get_packet_duration(const unsigned char *_data,int _len){
739 int nframes;
740 int frame_size;
741 int nsamples;
742 nframes=opus_packet_get_nb_frames(_data,_len);
743 if(OP_UNLIKELY(nframes<0))return OP_EBADPACKET;
744 frame_size=opus_packet_get_samples_per_frame(_data,48000);
745 nsamples=nframes*frame_size;
746 if(OP_UNLIKELY(nsamples>120*48))return OP_EBADPACKET;
747 return nsamples;
748 }
749
750 /*This function more properly belongs in info.c, but we define it here to allow
751 the static granule position manipulation functions to remain static.*/
opus_granule_sample(const OpusHead * _head,ogg_int64_t _gp)752 ogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp){
753 opus_int32 pre_skip;
754 pre_skip=_head->pre_skip;
755 if(_gp!=-1&&op_granpos_add(&_gp,_gp,-pre_skip))_gp=-1;
756 return _gp;
757 }
758
759 /*Grab all the packets currently in the stream state, and compute their
760 durations.
761 _of->op_count is set to the number of packets collected.
762 [out] _durations: Returns the durations of the individual packets.
763 Return: The total duration of all packets, or OP_HOLE if there was a hole.*/
op_collect_audio_packets(OggOpusFile * _of,int _durations[255])764 static opus_int32 op_collect_audio_packets(OggOpusFile *_of,
765 int _durations[255]){
766 opus_int32 total_duration;
767 int op_count;
768 /*Count the durations of all packets in the page.*/
769 op_count=0;
770 total_duration=0;
771 for(;;){
772 int ret;
773 /*This takes advantage of undocumented libogg behavior that returned
774 ogg_packet buffers are valid at least until the next page is
775 submitted.
776 Relying on this is not too terrible, as _none_ of the Ogg memory
777 ownership/lifetime rules are well-documented.
778 But I can read its code and know this will work.*/
779 ret=ogg_stream_packetout(&_of->os,_of->op+op_count);
780 if(!ret)break;
781 if(OP_UNLIKELY(ret<0)){
782 /*We shouldn't get holes in the middle of pages.*/
783 OP_ASSERT(op_count==0);
784 /*Set the return value and break out of the loop.
785 We want to make sure op_count gets set to 0, because we've ingested a
786 page, so any previously loaded packets are now invalid.*/
787 total_duration=OP_HOLE;
788 break;
789 }
790 /*Unless libogg is broken, we can't get more than 255 packets from a
791 single page.*/
792 OP_ASSERT(op_count<255);
793 _durations[op_count]=op_get_packet_duration(_of->op[op_count].packet,
794 _of->op[op_count].bytes);
795 if(OP_LIKELY(_durations[op_count]>0)){
796 /*With at most 255 packets on a page, this can't overflow.*/
797 total_duration+=_durations[op_count++];
798 }
799 /*Ignore packets with an invalid TOC sequence.*/
800 else if(op_count>0){
801 /*But save the granule position, if there was one.*/
802 _of->op[op_count-1].granulepos=_of->op[op_count].granulepos;
803 }
804 }
805 _of->op_pos=0;
806 _of->op_count=op_count;
807 return total_duration;
808 }
809
810 /*Starting from current cursor position, get the initial PCM offset of the next
811 page.
812 This also validates the granule position on the first page with a completed
813 audio data packet, as required by the spec.
814 If this link is completely empty (no pages with completed packets), then this
815 function sets pcm_start=pcm_end=0 and returns the BOS page of the next link
816 (if any).
817 In the seekable case, we initialize pcm_end=-1 before calling this function,
818 so that later we can detect that the link was empty before calling
819 op_find_final_pcm_offset().
820 [inout] _link: The link for which to find pcm_start.
821 [out] _og: Returns the BOS page of the next link if this link was empty.
822 In the unseekable case, we can then feed this to
823 op_fetch_headers() to start the next link.
824 The caller may pass NULL (e.g., for seekable streams), in
825 which case this page will be discarded.
826 Return: 0 on success, 1 if there is a buffered BOS page available, or a
827 negative value on unrecoverable error.*/
op_find_initial_pcm_offset(OggOpusFile * _of,OggOpusLink * _link,ogg_page * _og)828 static int op_find_initial_pcm_offset(OggOpusFile *_of,
829 OggOpusLink *_link,ogg_page *_og){
830 ogg_page og;
831 opus_int64 page_offset;
832 ogg_int64_t pcm_start;
833 ogg_int64_t prev_packet_gp;
834 ogg_int64_t cur_page_gp;
835 ogg_uint32_t serialno;
836 opus_int32 total_duration;
837 int durations[255];
838 int cur_page_eos;
839 int op_count;
840 int pi;
841 if(_og==NULL)_og=&og;
842 serialno=_of->os.serialno;
843 op_count=0;
844 /*We shouldn't have to initialize total_duration, but gcc is too dumb to
845 figure out that op_count>0 implies we've been through the whole loop at
846 least once.*/
847 total_duration=0;
848 do{
849 page_offset=op_get_next_page(_of,_og,_of->end);
850 /*We should get a page unless the file is truncated or mangled.
851 Otherwise there are no audio data packets in the whole logical stream.*/
852 if(OP_UNLIKELY(page_offset<0)){
853 /*Fail if there was a read error.*/
854 if(page_offset<OP_FALSE)return (int)page_offset;
855 /*Fail if the pre-skip is non-zero, since it's asking us to skip more
856 samples than exist.*/
857 if(_link->head.pre_skip>0)return OP_EBADTIMESTAMP;
858 /*Set pcm_end and end_offset so we can skip the call to
859 op_find_final_pcm_offset().*/
860 _link->pcm_start=_link->pcm_end=0;
861 _link->end_offset=_link->data_offset;
862 return 0;
863 }
864 /*Similarly, if we hit the next link in the chain, we've gone too far.*/
865 if(OP_UNLIKELY(ogg_page_bos(_og))){
866 if(_link->head.pre_skip>0)return OP_EBADTIMESTAMP;
867 /*Set pcm_end and end_offset so we can skip the call to
868 op_find_final_pcm_offset().*/
869 _link->pcm_end=_link->pcm_start=0;
870 _link->end_offset=_link->data_offset;
871 /*Tell the caller we've got a buffered page for them.*/
872 return 1;
873 }
874 /*Ignore pages from other streams (not strictly necessary, because of the
875 checks in ogg_stream_pagein(), but saves some work).*/
876 if(serialno!=(ogg_uint32_t)ogg_page_serialno(_og))continue;
877 ogg_stream_pagein(&_of->os,_og);
878 /*Bitrate tracking: add the header's bytes here.
879 The body bytes are counted when we consume the packets.*/
880 _of->bytes_tracked+=_og->header_len;
881 /*Count the durations of all packets in the page.*/
882 do total_duration=op_collect_audio_packets(_of,durations);
883 /*Ignore holes.*/
884 while(OP_UNLIKELY(total_duration<0));
885 op_count=_of->op_count;
886 }
887 while(op_count<=0);
888 /*We found the first page with a completed audio data packet: actually look
889 at the granule position.
890 RFC 3533 says, "A special value of -1 (in two's complement) indicates that
891 no packets finish on this page," which does not say that a granule
892 position that is NOT -1 indicates that some packets DO finish on that page
893 (even though this was the intention, libogg itself violated this intention
894 for years before we fixed it).
895 The Ogg Opus specification only imposes its start-time requirements
896 on the granule position of the first page with completed packets,
897 so we ignore any set granule positions until then.*/
898 cur_page_gp=_of->op[op_count-1].granulepos;
899 /*But getting a packet without a valid granule position on the page is not
900 okay.*/
901 if(cur_page_gp==-1)return OP_EBADTIMESTAMP;
902 cur_page_eos=_of->op[op_count-1].e_o_s;
903 if(OP_LIKELY(!cur_page_eos)){
904 /*The EOS flag wasn't set.
905 Work backwards from the provided granule position to get the starting PCM
906 offset.*/
907 if(OP_UNLIKELY(op_granpos_add(&pcm_start,cur_page_gp,-total_duration)<0)){
908 /*The starting granule position MUST not be smaller than the amount of
909 audio on the first page with completed packets.*/
910 return OP_EBADTIMESTAMP;
911 }
912 }
913 else{
914 /*The first page with completed packets was also the last.*/
915 if(OP_LIKELY(op_granpos_add(&pcm_start,cur_page_gp,-total_duration)<0)){
916 /*If there's less audio on the page than indicated by the granule
917 position, then we're doing end-trimming, and the starting PCM offset
918 is zero by spec mandate.*/
919 pcm_start=0;
920 /*However, the end-trimming MUST not ask us to trim more samples than
921 exist after applying the pre-skip.*/
922 if(OP_UNLIKELY(op_granpos_cmp(cur_page_gp,_link->head.pre_skip)<0)){
923 return OP_EBADTIMESTAMP;
924 }
925 }
926 }
927 /*Timestamp the individual packets.*/
928 prev_packet_gp=pcm_start;
929 for(pi=0;pi<op_count;pi++){
930 if(cur_page_eos){
931 ogg_int64_t diff;
932 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,cur_page_gp,prev_packet_gp));
933 diff=durations[pi]-diff;
934 /*If we have samples to trim...*/
935 if(diff>0){
936 /*If we trimmed the entire packet, stop (the spec says encoders
937 shouldn't do this, but we support it anyway).*/
938 if(OP_UNLIKELY(diff>durations[pi]))break;
939 _of->op[pi].granulepos=prev_packet_gp=cur_page_gp;
940 /*Move the EOS flag to this packet, if necessary, so we'll trim the
941 samples.*/
942 _of->op[pi].e_o_s=1;
943 continue;
944 }
945 }
946 /*Update the granule position as normal.*/
947 OP_ALWAYS_TRUE(!op_granpos_add(&_of->op[pi].granulepos,
948 prev_packet_gp,durations[pi]));
949 prev_packet_gp=_of->op[pi].granulepos;
950 }
951 /*Update the packet count after end-trimming.*/
952 _of->op_count=pi;
953 _of->cur_discard_count=_link->head.pre_skip;
954 _of->prev_packet_gp=_link->pcm_start=pcm_start;
955 _of->prev_page_offset=page_offset;
956 return 0;
957 }
958
959 /*Starting from current cursor position, get the final PCM offset of the
960 previous page.
961 This also validates the duration of the link, which, while not strictly
962 required by the spec, we need to ensure duration calculations don't
963 overflow.
964 This is only done for seekable sources.
965 We must validate that op_find_initial_pcm_offset() succeeded for this link
966 before calling this function, otherwise it will scan the entire stream
967 backwards until it reaches the start, and then fail.*/
op_find_final_pcm_offset(OggOpusFile * _of,const ogg_uint32_t * _serialnos,int _nserialnos,OggOpusLink * _link,opus_int64 _offset,ogg_uint32_t _end_serialno,ogg_int64_t _end_gp,ogg_int64_t * _total_duration)968 static int op_find_final_pcm_offset(OggOpusFile *_of,
969 const ogg_uint32_t *_serialnos,int _nserialnos,OggOpusLink *_link,
970 opus_int64 _offset,ogg_uint32_t _end_serialno,ogg_int64_t _end_gp,
971 ogg_int64_t *_total_duration){
972 ogg_int64_t total_duration;
973 ogg_int64_t duration;
974 ogg_uint32_t cur_serialno;
975 /*For the time being, fetch end PCM offset the simple way.*/
976 cur_serialno=_link->serialno;
977 if(_end_serialno!=cur_serialno||_end_gp==-1){
978 _offset=op_get_last_page(_of,&_end_gp,_offset,
979 cur_serialno,_serialnos,_nserialnos);
980 if(OP_UNLIKELY(_offset<0))return (int)_offset;
981 }
982 /*At worst we should have found the first page with completed packets.*/
983 if(OP_UNLIKELY(_offset<_link->data_offset))return OP_EBADLINK;
984 /*This implementation requires that the difference between the first and last
985 granule positions in each link be representable in a signed, 64-bit
986 number, and that each link also have at least as many samples as the
987 pre-skip requires.*/
988 if(OP_UNLIKELY(op_granpos_diff(&duration,_end_gp,_link->pcm_start)<0)
989 ||OP_UNLIKELY(duration<_link->head.pre_skip)){
990 return OP_EBADTIMESTAMP;
991 }
992 /*We also require that the total duration be representable in a signed,
993 64-bit number.*/
994 duration-=_link->head.pre_skip;
995 total_duration=*_total_duration;
996 if(OP_UNLIKELY(OP_INT64_MAX-duration<total_duration))return OP_EBADTIMESTAMP;
997 *_total_duration=total_duration+duration;
998 _link->pcm_end=_end_gp;
999 _link->end_offset=_offset;
1000 return 0;
1001 }
1002
1003 /*Rescale the number _x from the range [0,_from] to [0,_to].
1004 _from and _to must be positive.*/
op_rescale64(opus_int64 _x,opus_int64 _from,opus_int64 _to)1005 static opus_int64 op_rescale64(opus_int64 _x,opus_int64 _from,opus_int64 _to){
1006 opus_int64 frac;
1007 opus_int64 ret;
1008 int i;
1009 if(_x>=_from)return _to;
1010 if(_x<=0)return 0;
1011 frac=0;
1012 for(i=0;i<63;i++){
1013 frac<<=1;
1014 OP_ASSERT(_x<=_from);
1015 if(_x>=_from>>1){
1016 _x-=_from-_x;
1017 frac|=1;
1018 }
1019 else _x<<=1;
1020 }
1021 ret=0;
1022 for(i=0;i<63;i++){
1023 if(frac&1)ret=(ret&_to&1)+(ret>>1)+(_to>>1);
1024 else ret>>=1;
1025 frac>>=1;
1026 }
1027 return ret;
1028 }
1029
1030 /*The minimum granule position spacing allowed for making predictions.
1031 This corresponds to about 1 second of audio at 48 kHz for both Opus and
1032 Vorbis, or one keyframe interval in Theora with the default keyframe spacing
1033 of 256.*/
1034 #define OP_GP_SPACING_MIN (48000)
1035
1036 /*Try to estimate the location of the next link using the current seek
1037 records, assuming the initial granule position of any streams we've found is
1038 0.*/
op_predict_link_start(const OpusSeekRecord * _sr,int _nsr,opus_int64 _searched,opus_int64 _end_searched,opus_int32 _bias)1039 static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr,
1040 opus_int64 _searched,opus_int64 _end_searched,opus_int32 _bias){
1041 opus_int64 bisect;
1042 int sri;
1043 int srj;
1044 /*Require that we be at least OP_CHUNK_SIZE from the end.
1045 We don't require that we be at least OP_CHUNK_SIZE from the beginning,
1046 because if we are we'll just scan forward without seeking.*/
1047 _end_searched-=OP_CHUNK_SIZE;
1048 if(_searched>=_end_searched)return -1;
1049 bisect=_end_searched;
1050 for(sri=0;sri<_nsr;sri++){
1051 ogg_int64_t gp1;
1052 ogg_int64_t gp2_min;
1053 ogg_uint32_t serialno1;
1054 opus_int64 offset1;
1055 /*If the granule position is negative, either it's invalid or we'd cause
1056 overflow.*/
1057 gp1=_sr[sri].gp;
1058 if(gp1<0)continue;
1059 /*We require some minimum distance between granule positions to make an
1060 estimate.
1061 We don't actually know what granule position scheme is being used,
1062 because we have no idea what kind of stream these came from.
1063 Therefore we require a minimum spacing between them, with the
1064 expectation that while bitrates and granule position increments might
1065 vary locally in quite complex ways, they are globally smooth.*/
1066 if(OP_UNLIKELY(op_granpos_add(&gp2_min,gp1,OP_GP_SPACING_MIN)<0)){
1067 /*No granule position would satisfy us.*/
1068 continue;
1069 }
1070 offset1=_sr[sri].offset;
1071 serialno1=_sr[sri].serialno;
1072 for(srj=sri;srj-->0;){
1073 ogg_int64_t gp2;
1074 opus_int64 offset2;
1075 opus_int64 num;
1076 ogg_int64_t den;
1077 ogg_int64_t ipart;
1078 gp2=_sr[srj].gp;
1079 if(gp2<gp2_min)continue;
1080 /*Oh, and also make sure these came from the same stream.*/
1081 if(_sr[srj].serialno!=serialno1)continue;
1082 offset2=_sr[srj].offset;
1083 /*For once, we can subtract with impunity.*/
1084 den=gp2-gp1;
1085 ipart=gp2/den;
1086 num=offset2-offset1;
1087 OP_ASSERT(num>0);
1088 if(ipart>0&&(offset2-_searched)/ipart<num)continue;
1089 offset2-=ipart*num;
1090 gp2-=ipart*den;
1091 offset2-=op_rescale64(gp2,den,num)-_bias;
1092 if(offset2<_searched)continue;
1093 bisect=OP_MIN(bisect,offset2);
1094 break;
1095 }
1096 }
1097 return bisect>=_end_searched?-1:bisect;
1098 }
1099
1100 /*Finds each bitstream link, one at a time, using a bisection search.
1101 This has to begin by knowing the offset of the first link's initial page.*/
op_bisect_forward_serialno(OggOpusFile * _of,opus_int64 _searched,OpusSeekRecord * _sr,int _csr,ogg_uint32_t ** _serialnos,int * _nserialnos,int * _cserialnos)1102 static int op_bisect_forward_serialno(OggOpusFile *_of,
1103 opus_int64 _searched,OpusSeekRecord *_sr,int _csr,
1104 ogg_uint32_t **_serialnos,int *_nserialnos,int *_cserialnos){
1105 ogg_page og;
1106 OggOpusLink *links;
1107 int nlinks;
1108 int clinks;
1109 ogg_uint32_t *serialnos;
1110 int nserialnos;
1111 ogg_int64_t total_duration;
1112 int nsr;
1113 int ret;
1114 links=_of->links;
1115 nlinks=clinks=_of->nlinks;
1116 total_duration=0;
1117 /*We start with one seek record, for the last page in the file.
1118 We build up a list of records for places we seek to during link
1119 enumeration.
1120 This list is kept sorted in reverse order.
1121 We only care about seek locations that were _not_ in the current link,
1122 therefore we can add them one at a time to the end of the list as we
1123 improve the lower bound on the location where the next link starts.*/
1124 nsr=1;
1125 for(;;){
1126 opus_int64 end_searched;
1127 opus_int64 bisect;
1128 opus_int64 next;
1129 opus_int64 last;
1130 ogg_int64_t end_offset;
1131 ogg_int64_t end_gp;
1132 int sri;
1133 serialnos=*_serialnos;
1134 nserialnos=*_nserialnos;
1135 if(OP_UNLIKELY(nlinks>=clinks)){
1136 if(OP_UNLIKELY(clinks>INT_MAX-1>>1))return OP_EFAULT;
1137 clinks=2*clinks+1;
1138 OP_ASSERT(nlinks<clinks);
1139 links=(OggOpusLink *)_ogg_realloc(links,sizeof(*links)*clinks);
1140 if(OP_UNLIKELY(links==NULL))return OP_EFAULT;
1141 _of->links=links;
1142 }
1143 /*Invariants:
1144 We have the headers and serial numbers for the link beginning at 'begin'.
1145 We have the offset and granule position of the last page in the file
1146 (potentially not a page we care about).*/
1147 /*Scan the seek records we already have to save us some bisection.*/
1148 for(sri=0;sri<nsr;sri++){
1149 if(op_lookup_serialno(_sr[sri].serialno,serialnos,nserialnos))break;
1150 }
1151 /*Is the last page in our current list of serial numbers?*/
1152 if(sri<=0)break;
1153 /*Last page wasn't found.
1154 We have at least one more link.*/
1155 last=-1;
1156 end_searched=_sr[sri-1].search_start;
1157 next=_sr[sri-1].offset;
1158 end_gp=-1;
1159 if(sri<nsr){
1160 _searched=_sr[sri].offset+_sr[sri].size;
1161 if(_sr[sri].serialno==links[nlinks-1].serialno){
1162 end_gp=_sr[sri].gp;
1163 end_offset=_sr[sri].offset;
1164 }
1165 }
1166 nsr=sri;
1167 bisect=-1;
1168 /*If we've already found the end of at least one link, try to pick the
1169 first bisection point at twice the average link size.
1170 This is a good choice for files with lots of links that are all about the
1171 same size.*/
1172 if(nlinks>1){
1173 opus_int64 last_offset;
1174 opus_int64 avg_link_size;
1175 opus_int64 upper_limit;
1176 last_offset=links[nlinks-1].offset;
1177 avg_link_size=last_offset/(nlinks-1);
1178 upper_limit=end_searched-OP_CHUNK_SIZE-avg_link_size;
1179 if(OP_LIKELY(last_offset>_searched-avg_link_size)
1180 &&OP_LIKELY(last_offset<upper_limit)){
1181 bisect=last_offset+avg_link_size;
1182 if(OP_LIKELY(bisect<upper_limit))bisect+=avg_link_size;
1183 }
1184 }
1185 /*We guard against garbage separating the last and first pages of two
1186 links below.*/
1187 while(_searched<end_searched){
1188 opus_int32 next_bias;
1189 /*If we don't have a better estimate, use simple bisection.*/
1190 if(bisect==-1)bisect=_searched+(end_searched-_searched>>1);
1191 /*If we're within OP_CHUNK_SIZE of the start, scan forward.*/
1192 if(bisect-_searched<OP_CHUNK_SIZE)bisect=_searched;
1193 /*Otherwise we're skipping data.
1194 Forget the end page, if we saw one, as we might miss a later one.*/
1195 else end_gp=-1;
1196 ret=op_seek_helper(_of,bisect);
1197 if(OP_UNLIKELY(ret<0))return ret;
1198 last=op_get_next_page(_of,&og,_sr[nsr-1].offset);
1199 if(OP_UNLIKELY(last<OP_FALSE))return (int)last;
1200 next_bias=0;
1201 if(last==OP_FALSE)end_searched=bisect;
1202 else{
1203 ogg_uint32_t serialno;
1204 ogg_int64_t gp;
1205 serialno=ogg_page_serialno(&og);
1206 gp=ogg_page_granulepos(&og);
1207 if(!op_lookup_serialno(serialno,serialnos,nserialnos)){
1208 end_searched=bisect;
1209 next=last;
1210 /*In reality we should always have enough room, but be paranoid.*/
1211 if(OP_LIKELY(nsr<_csr)){
1212 _sr[nsr].search_start=bisect;
1213 _sr[nsr].offset=last;
1214 OP_ASSERT(_of->offset-last>=0);
1215 OP_ASSERT(_of->offset-last<=OP_PAGE_SIZE_MAX);
1216 _sr[nsr].size=(opus_int32)(_of->offset-last);
1217 _sr[nsr].serialno=serialno;
1218 _sr[nsr].gp=gp;
1219 nsr++;
1220 }
1221 }
1222 else{
1223 _searched=_of->offset;
1224 next_bias=OP_CHUNK_SIZE;
1225 if(serialno==links[nlinks-1].serialno){
1226 /*This page was from the stream we want, remember it.
1227 If it's the last such page in the link, we won't have to go back
1228 looking for it later.*/
1229 end_gp=gp;
1230 end_offset=last;
1231 }
1232 }
1233 }
1234 bisect=op_predict_link_start(_sr,nsr,_searched,end_searched,next_bias);
1235 }
1236 /*Bisection point found.
1237 Get the final granule position of the previous link, assuming
1238 op_find_initial_pcm_offset() didn't already determine the link was
1239 empty.*/
1240 if(OP_LIKELY(links[nlinks-1].pcm_end==-1)){
1241 if(end_gp==-1){
1242 /*If we don't know where the end page is, we'll have to seek back and
1243 look for it, starting from the end of the link.*/
1244 end_offset=next;
1245 /*Also forget the last page we read.
1246 It won't be available after the seek.*/
1247 last=-1;
1248 }
1249 ret=op_find_final_pcm_offset(_of,serialnos,nserialnos,
1250 links+nlinks-1,end_offset,links[nlinks-1].serialno,end_gp,
1251 &total_duration);
1252 if(OP_UNLIKELY(ret<0))return ret;
1253 }
1254 if(last!=next){
1255 /*The last page we read was not the first page the next link.
1256 Move the cursor position to the offset of that first page.
1257 This only performs an actual seek if the first page of the next link
1258 does not start at the end of the last page from the current Opus
1259 stream with a valid granule position.*/
1260 ret=op_seek_helper(_of,next);
1261 if(OP_UNLIKELY(ret<0))return ret;
1262 }
1263 ret=op_fetch_headers(_of,&links[nlinks].head,&links[nlinks].tags,
1264 _serialnos,_nserialnos,_cserialnos,last!=next?NULL:&og);
1265 if(OP_UNLIKELY(ret<0))return ret;
1266 links[nlinks].offset=next;
1267 links[nlinks].data_offset=_of->offset;
1268 links[nlinks].serialno=_of->os.serialno;
1269 links[nlinks].pcm_end=-1;
1270 /*This might consume a page from the next link, however the next bisection
1271 always starts with a seek.*/
1272 ret=op_find_initial_pcm_offset(_of,links+nlinks,NULL);
1273 if(OP_UNLIKELY(ret<0))return ret;
1274 _searched=_of->offset;
1275 /*Mark the current link count so it can be cleaned up on error.*/
1276 _of->nlinks=++nlinks;
1277 }
1278 /*Last page is in the starting serialno list, so we've reached the last link.
1279 Now find the last granule position for it (if we didn't the first time we
1280 looked at the end of the stream, and if op_find_initial_pcm_offset()
1281 didn't already determine the link was empty).*/
1282 if(OP_LIKELY(links[nlinks-1].pcm_end==-1)){
1283 ret=op_find_final_pcm_offset(_of,serialnos,nserialnos,
1284 links+nlinks-1,_sr[0].offset,_sr[0].serialno,_sr[0].gp,&total_duration);
1285 if(OP_UNLIKELY(ret<0))return ret;
1286 }
1287 /*Trim back the links array if necessary.*/
1288 links=(OggOpusLink *)_ogg_realloc(links,sizeof(*links)*nlinks);
1289 if(OP_LIKELY(links!=NULL))_of->links=links;
1290 /*We also don't need these anymore.*/
1291 _ogg_free(*_serialnos);
1292 *_serialnos=NULL;
1293 *_cserialnos=*_nserialnos=0;
1294 return 0;
1295 }
1296
op_update_gain(OggOpusFile * _of)1297 static void op_update_gain(OggOpusFile *_of){
1298 OpusHead *head;
1299 opus_int32 gain_q8;
1300 int li;
1301 /*If decode isn't ready, then we'll apply the gain when we initialize the
1302 decoder.*/
1303 if(_of->ready_state<OP_INITSET)return;
1304 gain_q8=_of->gain_offset_q8;
1305 li=_of->seekable?_of->cur_link:0;
1306 head=&_of->links[li].head;
1307 /*We don't have to worry about overflow here because the header gain and
1308 track gain must lie in the range [-32768,32767], and the user-supplied
1309 offset has been pre-clamped to [-98302,98303].*/
1310 switch(_of->gain_type){
1311 case OP_ALBUM_GAIN:{
1312 int album_gain_q8;
1313 album_gain_q8=0;
1314 opus_tags_get_album_gain(&_of->links[li].tags,&album_gain_q8);
1315 gain_q8+=album_gain_q8;
1316 gain_q8+=head->output_gain;
1317 }break;
1318 case OP_TRACK_GAIN:{
1319 int track_gain_q8;
1320 track_gain_q8=0;
1321 opus_tags_get_track_gain(&_of->links[li].tags,&track_gain_q8);
1322 gain_q8+=track_gain_q8;
1323 gain_q8+=head->output_gain;
1324 }break;
1325 case OP_HEADER_GAIN:gain_q8+=head->output_gain;break;
1326 case OP_ABSOLUTE_GAIN:break;
1327 default:OP_ASSERT(0);
1328 }
1329 gain_q8=OP_CLAMP(-32768,gain_q8,32767);
1330 OP_ASSERT(_of->od!=NULL);
1331 #if defined(OPUS_SET_GAIN)
1332 opus_multistream_decoder_ctl(_of->od,OPUS_SET_GAIN(gain_q8));
1333 #else
1334 /*A fallback that works with both float and fixed-point is a bunch of work,
1335 so just force people to use a sufficiently new version.
1336 This is deployed well enough at this point that this shouldn't be a burden.*/
1337 # error "libopus 1.0.1 or later required"
1338 #endif
1339 }
1340
op_make_decode_ready(OggOpusFile * _of)1341 static int op_make_decode_ready(OggOpusFile *_of){
1342 const OpusHead *head;
1343 int li;
1344 int stream_count;
1345 int coupled_count;
1346 int channel_count;
1347 if(_of->ready_state>OP_STREAMSET)return 0;
1348 if(OP_UNLIKELY(_of->ready_state<OP_STREAMSET))return OP_EFAULT;
1349 li=_of->seekable?_of->cur_link:0;
1350 head=&_of->links[li].head;
1351 stream_count=head->stream_count;
1352 coupled_count=head->coupled_count;
1353 channel_count=head->channel_count;
1354 /*Check to see if the current decoder is compatible with the current link.*/
1355 if(_of->od!=NULL&&_of->od_stream_count==stream_count
1356 &&_of->od_coupled_count==coupled_count&&_of->od_channel_count==channel_count
1357 &&memcmp(_of->od_mapping,head->mapping,
1358 sizeof(*head->mapping)*channel_count)==0){
1359 opus_multistream_decoder_ctl(_of->od,OPUS_RESET_STATE);
1360 }
1361 else{
1362 int err;
1363 opus_multistream_decoder_destroy(_of->od);
1364 _of->od=opus_multistream_decoder_create(48000,channel_count,
1365 stream_count,coupled_count,head->mapping,&err);
1366 if(_of->od==NULL)return OP_EFAULT;
1367 _of->od_stream_count=stream_count;
1368 _of->od_coupled_count=coupled_count;
1369 _of->od_channel_count=channel_count;
1370 memcpy(_of->od_mapping,head->mapping,sizeof(*head->mapping)*channel_count);
1371 }
1372 _of->ready_state=OP_INITSET;
1373 _of->bytes_tracked=0;
1374 _of->samples_tracked=0;
1375 #if !defined(OP_FIXED_POINT)
1376 _of->state_channel_count=0;
1377 /*Use the serial number for the PRNG seed to get repeatable output for
1378 straight play-throughs.*/
1379 _of->dither_seed=_of->links[li].serialno;
1380 #endif
1381 op_update_gain(_of);
1382 return 0;
1383 }
1384
op_open_seekable2_impl(OggOpusFile * _of)1385 static int op_open_seekable2_impl(OggOpusFile *_of){
1386 /*64 seek records should be enough for anybody.
1387 Actually, with a bisection search in a 63-bit range down to OP_CHUNK_SIZE
1388 granularity, much more than enough.*/
1389 OpusSeekRecord sr[64];
1390 opus_int64 data_offset;
1391 int ret;
1392 /*We can seek, so set out learning all about this file.*/
1393 (*_of->callbacks.seek)(_of->source,0,SEEK_END);
1394 _of->offset=_of->end=(*_of->callbacks.tell)(_of->source);
1395 if(OP_UNLIKELY(_of->end<0))return OP_EREAD;
1396 data_offset=_of->links[0].data_offset;
1397 if(OP_UNLIKELY(_of->end<data_offset))return OP_EBADLINK;
1398 /*Get the offset of the last page of the physical bitstream, or, if we're
1399 lucky, the last Opus page of the first link, as most Ogg Opus files will
1400 contain a single logical bitstream.*/
1401 ret=op_get_prev_page_serial(_of,sr,_of->end,
1402 _of->links[0].serialno,_of->serialnos,_of->nserialnos);
1403 if(OP_UNLIKELY(ret<0))return ret;
1404 /*If there's any trailing junk, forget about it.*/
1405 _of->end=sr[0].offset+sr[0].size;
1406 if(OP_UNLIKELY(_of->end<data_offset))return OP_EBADLINK;
1407 /*Now enumerate the bitstream structure.*/
1408 return op_bisect_forward_serialno(_of,data_offset,sr,sizeof(sr)/sizeof(*sr),
1409 &_of->serialnos,&_of->nserialnos,&_of->cserialnos);
1410 }
1411
op_open_seekable2(OggOpusFile * _of)1412 static int op_open_seekable2(OggOpusFile *_of){
1413 ogg_sync_state oy_start;
1414 ogg_stream_state os_start;
1415 ogg_packet *op_start;
1416 opus_int64 prev_page_offset;
1417 opus_int64 start_offset;
1418 int start_op_count;
1419 int ret;
1420 /*We're partially open and have a first link header state in storage in _of.
1421 Save off that stream state so we can come back to it.
1422 It would be simpler to just dump all this state and seek back to
1423 links[0].data_offset when we're done.
1424 But we do the extra work to allow us to seek back to _exactly_ the same
1425 stream position we're at now.
1426 This allows, e.g., the HTTP backend to continue reading from the original
1427 connection (if it's still available), instead of opening a new one.
1428 This means we can open and start playing a normal Opus file with a single
1429 link and reasonable packet sizes using only two HTTP requests.*/
1430 start_op_count=_of->op_count;
1431 /*This is a bit too large to put on the stack unconditionally.*/
1432 op_start=(ogg_packet *)_ogg_malloc(sizeof(*op_start)*start_op_count);
1433 if(op_start==NULL)return OP_EFAULT;
1434 *&oy_start=_of->oy;
1435 *&os_start=_of->os;
1436 prev_page_offset=_of->prev_page_offset;
1437 start_offset=_of->offset;
1438 memcpy(op_start,_of->op,sizeof(*op_start)*start_op_count);
1439 OP_ASSERT((*_of->callbacks.tell)(_of->source)==op_position(_of));
1440 ogg_sync_init(&_of->oy);
1441 ogg_stream_init(&_of->os,-1);
1442 ret=op_open_seekable2_impl(_of);
1443 /*Restore the old stream state.*/
1444 ogg_stream_clear(&_of->os);
1445 ogg_sync_clear(&_of->oy);
1446 *&_of->oy=*&oy_start;
1447 *&_of->os=*&os_start;
1448 _of->offset=start_offset;
1449 _of->op_count=start_op_count;
1450 memcpy(_of->op,op_start,sizeof(*_of->op)*start_op_count);
1451 _ogg_free(op_start);
1452 _of->prev_packet_gp=_of->links[0].pcm_start;
1453 _of->prev_page_offset=prev_page_offset;
1454 _of->cur_discard_count=_of->links[0].head.pre_skip;
1455 if(OP_UNLIKELY(ret<0))return ret;
1456 /*And restore the position indicator.*/
1457 ret=(*_of->callbacks.seek)(_of->source,op_position(_of),SEEK_SET);
1458 return OP_UNLIKELY(ret<0)?OP_EREAD:0;
1459 }
1460
1461 /*Clear out the current logical bitstream decoder.*/
op_decode_clear(OggOpusFile * _of)1462 static void op_decode_clear(OggOpusFile *_of){
1463 /*We don't actually free the decoder.
1464 We might be able to re-use it for the next link.*/
1465 _of->op_count=0;
1466 _of->od_buffer_size=0;
1467 _of->prev_packet_gp=-1;
1468 _of->prev_page_offset=-1;
1469 if(!_of->seekable){
1470 OP_ASSERT(_of->ready_state>=OP_INITSET);
1471 opus_tags_clear(&_of->links[0].tags);
1472 }
1473 _of->ready_state=OP_OPENED;
1474 }
1475
op_clear(OggOpusFile * _of)1476 static void op_clear(OggOpusFile *_of){
1477 OggOpusLink *links;
1478 _ogg_free(_of->od_buffer);
1479 if(_of->od!=NULL)opus_multistream_decoder_destroy(_of->od);
1480 links=_of->links;
1481 if(!_of->seekable){
1482 if(_of->ready_state>OP_OPENED||_of->ready_state==OP_PARTOPEN){
1483 opus_tags_clear(&links[0].tags);
1484 }
1485 }
1486 else if(OP_LIKELY(links!=NULL)){
1487 int nlinks;
1488 int link;
1489 nlinks=_of->nlinks;
1490 for(link=0;link<nlinks;link++)opus_tags_clear(&links[link].tags);
1491 }
1492 _ogg_free(links);
1493 _ogg_free(_of->serialnos);
1494 ogg_stream_clear(&_of->os);
1495 ogg_sync_clear(&_of->oy);
1496 if(_of->callbacks.close!=NULL)(*_of->callbacks.close)(_of->source);
1497 }
1498
op_open1(OggOpusFile * _of,void * _source,const OpusFileCallbacks * _cb,const unsigned char * _initial_data,size_t _initial_bytes)1499 static int op_open1(OggOpusFile *_of,
1500 void *_source,const OpusFileCallbacks *_cb,
1501 const unsigned char *_initial_data,size_t _initial_bytes){
1502 ogg_page og;
1503 ogg_page *pog;
1504 int seekable;
1505 int ret;
1506 memset(_of,0,sizeof(*_of));
1507 _of->end=-1;
1508 _of->source=_source;
1509 *&_of->callbacks=*_cb;
1510 /*At a minimum, we need to be able to read data.*/
1511 if(OP_UNLIKELY(_of->callbacks.read==NULL))return OP_EREAD;
1512 /*Initialize the framing state.*/
1513 ogg_sync_init(&_of->oy);
1514 /*Perhaps some data was previously read into a buffer for testing against
1515 other stream types.
1516 Allow initialization from this previously read data (especially as we may
1517 be reading from a non-seekable stream).
1518 This requires copying it into a buffer allocated by ogg_sync_buffer() and
1519 doesn't support seeking, so this is not a good mechanism to use for
1520 decoding entire files from RAM.*/
1521 if(_initial_bytes>0){
1522 char *buffer;
1523 buffer=ogg_sync_buffer(&_of->oy,_initial_bytes);
1524 memcpy(buffer,_initial_data,_initial_bytes*sizeof(*buffer));
1525 ogg_sync_wrote(&_of->oy,_initial_bytes);
1526 }
1527 /*Can we seek?
1528 Stevens suggests the seek test is portable.*/
1529 seekable=_cb->seek!=NULL&&(*_cb->seek)(_source,0,SEEK_CUR)!=-1;
1530 /*If seek is implemented, tell must also be implemented.*/
1531 if(seekable){
1532 opus_int64 pos;
1533 if(OP_UNLIKELY(_of->callbacks.tell==NULL))return OP_EINVAL;
1534 pos=(*_of->callbacks.tell)(_of->source);
1535 /*If the current position is not equal to the initial bytes consumed,
1536 absolute seeking will not work.*/
1537 if(OP_UNLIKELY(pos!=(opus_int64)_initial_bytes))return OP_EINVAL;
1538 }
1539 _of->seekable=seekable;
1540 /*Don't seek yet.
1541 Set up a 'single' (current) logical bitstream entry for partial open.*/
1542 _of->links=(OggOpusLink *)_ogg_malloc(sizeof(*_of->links));
1543 /*The serialno gets filled in later by op_fetch_headers().*/
1544 ogg_stream_init(&_of->os,-1);
1545 pog=NULL;
1546 for(;;){
1547 /*Fetch all BOS pages, store the Opus header and all seen serial numbers,
1548 and load subsequent Opus setup headers.*/
1549 ret=op_fetch_headers(_of,&_of->links[0].head,&_of->links[0].tags,
1550 &_of->serialnos,&_of->nserialnos,&_of->cserialnos,pog);
1551 if(OP_UNLIKELY(ret<0))break;
1552 _of->nlinks=1;
1553 _of->links[0].offset=0;
1554 _of->links[0].data_offset=_of->offset;
1555 _of->links[0].pcm_end=-1;
1556 _of->links[0].serialno=_of->os.serialno;
1557 /*Fetch the initial PCM offset.*/
1558 ret=op_find_initial_pcm_offset(_of,_of->links,&og);
1559 if(seekable||OP_LIKELY(ret<=0))break;
1560 /*This link was empty, but we already have the BOS page for the next one in
1561 og.
1562 We can't seek, so start processing the next link right now.*/
1563 opus_tags_clear(&_of->links[0].tags);
1564 _of->nlinks=0;
1565 if(!seekable)_of->cur_link++;
1566 pog=&og;
1567 }
1568 if(OP_LIKELY(ret>=0))_of->ready_state=OP_PARTOPEN;
1569 return ret;
1570 }
1571
op_open2(OggOpusFile * _of)1572 static int op_open2(OggOpusFile *_of){
1573 int ret;
1574 OP_ASSERT(_of->ready_state==OP_PARTOPEN);
1575 if(_of->seekable){
1576 _of->ready_state=OP_OPENED;
1577 ret=op_open_seekable2(_of);
1578 }
1579 else ret=0;
1580 if(OP_LIKELY(ret>=0)){
1581 /*We have buffered packets from op_find_initial_pcm_offset().
1582 Move to OP_INITSET so we can use them.*/
1583 _of->ready_state=OP_STREAMSET;
1584 ret=op_make_decode_ready(_of);
1585 if(OP_LIKELY(ret>=0))return 0;
1586 }
1587 /*Don't auto-close the stream on failure.*/
1588 _of->callbacks.close=NULL;
1589 op_clear(_of);
1590 return ret;
1591 }
1592
op_test_callbacks(void * _source,const OpusFileCallbacks * _cb,const unsigned char * _initial_data,size_t _initial_bytes,int * _error)1593 OggOpusFile *op_test_callbacks(void *_source,const OpusFileCallbacks *_cb,
1594 const unsigned char *_initial_data,size_t _initial_bytes,int *_error){
1595 OggOpusFile *of;
1596 int ret;
1597 of=(OggOpusFile *)_ogg_malloc(sizeof(*of));
1598 ret=OP_EFAULT;
1599 if(OP_LIKELY(of!=NULL)){
1600 ret=op_open1(of,_source,_cb,_initial_data,_initial_bytes);
1601 if(OP_LIKELY(ret>=0)){
1602 if(_error!=NULL)*_error=0;
1603 return of;
1604 }
1605 /*Don't auto-close the stream on failure.*/
1606 of->callbacks.close=NULL;
1607 op_clear(of);
1608 _ogg_free(of);
1609 }
1610 if(_error!=NULL)*_error=ret;
1611 return NULL;
1612 }
1613
op_open_callbacks(void * _source,const OpusFileCallbacks * _cb,const unsigned char * _initial_data,size_t _initial_bytes,int * _error)1614 OggOpusFile *op_open_callbacks(void *_source,const OpusFileCallbacks *_cb,
1615 const unsigned char *_initial_data,size_t _initial_bytes,int *_error){
1616 OggOpusFile *of;
1617 of=op_test_callbacks(_source,_cb,_initial_data,_initial_bytes,_error);
1618 if(OP_LIKELY(of!=NULL)){
1619 int ret;
1620 ret=op_open2(of);
1621 if(OP_LIKELY(ret>=0))return of;
1622 if(_error!=NULL)*_error=ret;
1623 _ogg_free(of);
1624 }
1625 return NULL;
1626 }
1627
1628 /*Convenience routine to clean up from failure for the open functions that
1629 create their own streams.*/
op_open_close_on_failure(void * _source,const OpusFileCallbacks * _cb,int * _error)1630 static OggOpusFile *op_open_close_on_failure(void *_source,
1631 const OpusFileCallbacks *_cb,int *_error){
1632 OggOpusFile *of;
1633 if(OP_UNLIKELY(_source==NULL)){
1634 if(_error!=NULL)*_error=OP_EFAULT;
1635 return NULL;
1636 }
1637 of=op_open_callbacks(_source,_cb,NULL,0,_error);
1638 if(OP_UNLIKELY(of==NULL))(*_cb->close)(_source);
1639 return of;
1640 }
1641
op_open_file(const char * _path,int * _error)1642 OggOpusFile *op_open_file(const char *_path,int *_error){
1643 OpusFileCallbacks cb;
1644 return op_open_close_on_failure(op_fopen(&cb,_path,"rb"),&cb,_error);
1645 }
1646
op_open_memory(const unsigned char * _data,size_t _size,int * _error)1647 OggOpusFile *op_open_memory(const unsigned char *_data,size_t _size,
1648 int *_error){
1649 OpusFileCallbacks cb;
1650 return op_open_close_on_failure(op_mem_stream_create(&cb,_data,_size),&cb,
1651 _error);
1652 }
1653
1654 /*Convenience routine to clean up from failure for the open functions that
1655 create their own streams.*/
op_test_close_on_failure(void * _source,const OpusFileCallbacks * _cb,int * _error)1656 static OggOpusFile *op_test_close_on_failure(void *_source,
1657 const OpusFileCallbacks *_cb,int *_error){
1658 OggOpusFile *of;
1659 if(OP_UNLIKELY(_source==NULL)){
1660 if(_error!=NULL)*_error=OP_EFAULT;
1661 return NULL;
1662 }
1663 of=op_test_callbacks(_source,_cb,NULL,0,_error);
1664 if(OP_UNLIKELY(of==NULL))(*_cb->close)(_source);
1665 return of;
1666 }
1667
op_test_file(const char * _path,int * _error)1668 OggOpusFile *op_test_file(const char *_path,int *_error){
1669 OpusFileCallbacks cb;
1670 return op_test_close_on_failure(op_fopen(&cb,_path,"rb"),&cb,_error);
1671 }
1672
op_test_memory(const unsigned char * _data,size_t _size,int * _error)1673 OggOpusFile *op_test_memory(const unsigned char *_data,size_t _size,
1674 int *_error){
1675 OpusFileCallbacks cb;
1676 return op_test_close_on_failure(op_mem_stream_create(&cb,_data,_size),&cb,
1677 _error);
1678 }
1679
op_test_open(OggOpusFile * _of)1680 int op_test_open(OggOpusFile *_of){
1681 int ret;
1682 if(OP_UNLIKELY(_of->ready_state!=OP_PARTOPEN))return OP_EINVAL;
1683 ret=op_open2(_of);
1684 /*op_open2() will clear this structure on failure.
1685 Reset its contents to prevent double-frees in op_free().*/
1686 if(OP_UNLIKELY(ret<0))memset(_of,0,sizeof(*_of));
1687 return ret;
1688 }
1689
op_free(OggOpusFile * _of)1690 void op_free(OggOpusFile *_of){
1691 if(OP_LIKELY(_of!=NULL)){
1692 op_clear(_of);
1693 _ogg_free(_of);
1694 }
1695 }
1696
op_seekable(const OggOpusFile * _of)1697 int op_seekable(const OggOpusFile *_of){
1698 return _of->seekable;
1699 }
1700
op_link_count(const OggOpusFile * _of)1701 int op_link_count(const OggOpusFile *_of){
1702 return _of->nlinks;
1703 }
1704
op_serialno(const OggOpusFile * _of,int _li)1705 ogg_uint32_t op_serialno(const OggOpusFile *_of,int _li){
1706 if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1;
1707 if(!_of->seekable)_li=0;
1708 return _of->links[_li<0?_of->cur_link:_li].serialno;
1709 }
1710
op_channel_count(const OggOpusFile * _of,int _li)1711 int op_channel_count(const OggOpusFile *_of,int _li){
1712 return op_head(_of,_li)->channel_count;
1713 }
1714
op_raw_total(const OggOpusFile * _of,int _li)1715 opus_int64 op_raw_total(const OggOpusFile *_of,int _li){
1716 if(OP_UNLIKELY(_of->ready_state<OP_OPENED)
1717 ||OP_UNLIKELY(!_of->seekable)
1718 ||OP_UNLIKELY(_li>=_of->nlinks)){
1719 return OP_EINVAL;
1720 }
1721 if(_li<0)return _of->end-_of->links[0].offset;
1722 return (_li+1>=_of->nlinks?_of->end:_of->links[_li+1].offset)
1723 -_of->links[_li].offset;
1724 }
1725
op_pcm_total(const OggOpusFile * _of,int _li)1726 ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li){
1727 OggOpusLink *links;
1728 ogg_int64_t diff;
1729 int nlinks;
1730 nlinks=_of->nlinks;
1731 if(OP_UNLIKELY(_of->ready_state<OP_OPENED)
1732 ||OP_UNLIKELY(!_of->seekable)
1733 ||OP_UNLIKELY(_li>=nlinks)){
1734 return OP_EINVAL;
1735 }
1736 links=_of->links;
1737 /*We verify that the granule position differences are larger than the
1738 pre-skip and that the total duration does not overflow during link
1739 enumeration, so we don't have to check here.*/
1740 if(_li<0){
1741 ogg_int64_t pcm_total;
1742 int li;
1743 pcm_total=0;
1744 for(li=0;li<nlinks;li++){
1745 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,
1746 links[li].pcm_end,links[li].pcm_start));
1747 pcm_total+=diff-links[li].head.pre_skip;
1748 }
1749 return pcm_total;
1750 }
1751 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,
1752 links[_li].pcm_end,links[_li].pcm_start));
1753 return diff-links[_li].head.pre_skip;
1754 }
1755
op_head(const OggOpusFile * _of,int _li)1756 const OpusHead *op_head(const OggOpusFile *_of,int _li){
1757 if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1;
1758 if(!_of->seekable)_li=0;
1759 return &_of->links[_li<0?_of->cur_link:_li].head;
1760 }
1761
op_tags(const OggOpusFile * _of,int _li)1762 const OpusTags *op_tags(const OggOpusFile *_of,int _li){
1763 if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1;
1764 if(!_of->seekable){
1765 if(_of->ready_state<OP_STREAMSET&&_of->ready_state!=OP_PARTOPEN){
1766 return NULL;
1767 }
1768 _li=0;
1769 }
1770 else if(_li<0)_li=_of->ready_state>=OP_STREAMSET?_of->cur_link:0;
1771 return &_of->links[_li].tags;
1772 }
1773
op_current_link(const OggOpusFile * _of)1774 int op_current_link(const OggOpusFile *_of){
1775 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
1776 return _of->cur_link;
1777 }
1778
1779 /*Compute an average bitrate given a byte and sample count.
1780 Return: The bitrate in bits per second.*/
op_calc_bitrate(opus_int64 _bytes,ogg_int64_t _samples)1781 static opus_int32 op_calc_bitrate(opus_int64 _bytes,ogg_int64_t _samples){
1782 /*These rates are absurd, but let's handle them anyway.*/
1783 if(OP_UNLIKELY(_bytes>(OP_INT64_MAX-(_samples>>1))/(48000*8))){
1784 ogg_int64_t den;
1785 if(OP_UNLIKELY(_bytes/(OP_INT32_MAX/(48000*8))>=_samples)){
1786 return OP_INT32_MAX;
1787 }
1788 den=_samples/(48000*8);
1789 return (opus_int32)((_bytes+(den>>1))/den);
1790 }
1791 if(OP_UNLIKELY(_samples<=0))return OP_INT32_MAX;
1792 /*This can't actually overflow in normal operation: even with a pre-skip of
1793 545 2.5 ms frames with 8 streams running at 1282*8+1 bytes per packet
1794 (1275 byte frames + Opus framing overhead + Ogg lacing values), that all
1795 produce a single sample of decoded output, we still don't top 45 Mbps.
1796 The only way to get bitrates larger than that is with excessive Opus
1797 padding, more encoded streams than output channels, or lots and lots of
1798 Ogg pages with no packets on them.*/
1799 return (opus_int32)OP_MIN((_bytes*48000*8+(_samples>>1))/_samples,
1800 OP_INT32_MAX);
1801 }
1802
op_bitrate(const OggOpusFile * _of,int _li)1803 opus_int32 op_bitrate(const OggOpusFile *_of,int _li){
1804 if(OP_UNLIKELY(_of->ready_state<OP_OPENED)||OP_UNLIKELY(!_of->seekable)
1805 ||OP_UNLIKELY(_li>=_of->nlinks)){
1806 return OP_EINVAL;
1807 }
1808 return op_calc_bitrate(op_raw_total(_of,_li),op_pcm_total(_of,_li));
1809 }
1810
op_bitrate_instant(OggOpusFile * _of)1811 opus_int32 op_bitrate_instant(OggOpusFile *_of){
1812 ogg_int64_t samples_tracked;
1813 opus_int32 ret;
1814 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
1815 samples_tracked=_of->samples_tracked;
1816 if(OP_UNLIKELY(samples_tracked==0))return OP_FALSE;
1817 ret=op_calc_bitrate(_of->bytes_tracked,samples_tracked);
1818 _of->bytes_tracked=0;
1819 _of->samples_tracked=0;
1820 return ret;
1821 }
1822
1823 /*Fetch and process a page.
1824 This handles the case where we're at a bitstream boundary and dumps the
1825 decoding machine.
1826 If the decoding machine is unloaded, it loads it.
1827 It also keeps prev_packet_gp up to date (seek and read both use this).
1828 Return: <0) Error, OP_HOLE (lost packet), or OP_EOF.
1829 0) Got at least one audio data packet.*/
op_fetch_and_process_page(OggOpusFile * _of,ogg_page * _og,opus_int64 _page_offset,int _spanp,int _ignore_holes)1830 static int op_fetch_and_process_page(OggOpusFile *_of,
1831 ogg_page *_og,opus_int64 _page_offset,int _spanp,int _ignore_holes){
1832 OggOpusLink *links;
1833 ogg_uint32_t cur_serialno;
1834 int seekable;
1835 int cur_link;
1836 int ret;
1837 /*We shouldn't get here if we have unprocessed packets.*/
1838 OP_ASSERT(_of->ready_state<OP_INITSET||_of->op_pos>=_of->op_count);
1839 seekable=_of->seekable;
1840 links=_of->links;
1841 cur_link=seekable?_of->cur_link:0;
1842 cur_serialno=links[cur_link].serialno;
1843 /*Handle one page.*/
1844 for(;;){
1845 ogg_page og;
1846 OP_ASSERT(_of->ready_state>=OP_OPENED);
1847 /*If we were given a page to use, use it.*/
1848 if(_og!=NULL){
1849 *&og=*_og;
1850 _og=NULL;
1851 }
1852 /*Keep reading until we get a page with the correct serialno.*/
1853 else _page_offset=op_get_next_page(_of,&og,_of->end);
1854 /*EOF: Leave uninitialized.*/
1855 if(_page_offset<0)return _page_offset<OP_FALSE?(int)_page_offset:OP_EOF;
1856 if(OP_LIKELY(_of->ready_state>=OP_STREAMSET)
1857 &&cur_serialno!=(ogg_uint32_t)ogg_page_serialno(&og)){
1858 /*Two possibilities:
1859 1) Another stream is multiplexed into this logical section, or*/
1860 if(OP_LIKELY(!ogg_page_bos(&og)))continue;
1861 /* 2) Our decoding just traversed a bitstream boundary.*/
1862 if(!_spanp)return OP_EOF;
1863 if(OP_LIKELY(_of->ready_state>=OP_INITSET))op_decode_clear(_of);
1864 }
1865 /*Bitrate tracking: add the header's bytes here.
1866 The body bytes are counted when we consume the packets.*/
1867 else _of->bytes_tracked+=og.header_len;
1868 /*Do we need to load a new machine before submitting the page?
1869 This is different in the seekable and non-seekable cases.
1870 In the seekable case, we already have all the header information loaded
1871 and cached.
1872 We just initialize the machine with it and continue on our merry way.
1873 In the non-seekable (streaming) case, we'll only be at a boundary if we
1874 just left the previous logical bitstream, and we're now nominally at the
1875 header of the next bitstream.*/
1876 if(OP_UNLIKELY(_of->ready_state<OP_STREAMSET)){
1877 if(seekable){
1878 ogg_uint32_t serialno;
1879 int nlinks;
1880 int li;
1881 serialno=ogg_page_serialno(&og);
1882 /*Match the serialno to bitstream section.
1883 We use this rather than offset positions to avoid problems near
1884 logical bitstream boundaries.*/
1885 nlinks=_of->nlinks;
1886 for(li=0;li<nlinks&&links[li].serialno!=serialno;li++);
1887 /*Not a desired Opus bitstream section.
1888 Keep trying.*/
1889 if(li>=nlinks)continue;
1890 cur_serialno=serialno;
1891 _of->cur_link=cur_link=li;
1892 ogg_stream_reset_serialno(&_of->os,serialno);
1893 _of->ready_state=OP_STREAMSET;
1894 /*If we're at the start of this link, initialize the granule position
1895 and pre-skip tracking.*/
1896 if(_page_offset<=links[cur_link].data_offset){
1897 _of->prev_packet_gp=links[cur_link].pcm_start;
1898 _of->prev_page_offset=-1;
1899 _of->cur_discard_count=links[cur_link].head.pre_skip;
1900 /*Ignore a hole at the start of a new link (this is common for
1901 streams joined in the middle) or after seeking.*/
1902 _ignore_holes=1;
1903 }
1904 }
1905 else{
1906 do{
1907 /*We're streaming.
1908 Fetch the two header packets, build the info struct.*/
1909 ret=op_fetch_headers(_of,&links[0].head,&links[0].tags,
1910 NULL,NULL,NULL,&og);
1911 if(OP_UNLIKELY(ret<0))return ret;
1912 /*op_find_initial_pcm_offset() will suppress any initial hole for us,
1913 so no need to set _ignore_holes.*/
1914 ret=op_find_initial_pcm_offset(_of,links,&og);
1915 if(OP_UNLIKELY(ret<0))return ret;
1916 _of->links[0].serialno=cur_serialno=_of->os.serialno;
1917 _of->cur_link++;
1918 }
1919 /*If the link was empty, keep going, because we already have the
1920 BOS page of the next one in og.*/
1921 while(OP_UNLIKELY(ret>0));
1922 /*If we didn't get any packets out of op_find_initial_pcm_offset(),
1923 keep going (this is possible if end-trimming trimmed them all).*/
1924 if(_of->op_count<=0)continue;
1925 /*Otherwise, we're done.
1926 TODO: This resets bytes_tracked, which misses the header bytes
1927 already processed by op_find_initial_pcm_offset().*/
1928 ret=op_make_decode_ready(_of);
1929 if(OP_UNLIKELY(ret<0))return ret;
1930 return 0;
1931 }
1932 }
1933 /*The buffered page is the data we want, and we're ready for it.
1934 Add it to the stream state.*/
1935 if(OP_UNLIKELY(_of->ready_state==OP_STREAMSET)){
1936 ret=op_make_decode_ready(_of);
1937 if(OP_UNLIKELY(ret<0))return ret;
1938 }
1939 /*Extract all the packets from the current page.*/
1940 ogg_stream_pagein(&_of->os,&og);
1941 if(OP_LIKELY(_of->ready_state>=OP_INITSET)){
1942 opus_int32 total_duration;
1943 int durations[255];
1944 int op_count;
1945 total_duration=op_collect_audio_packets(_of,durations);
1946 if(OP_UNLIKELY(total_duration<0)){
1947 /*Drain the packets from the page anyway.*/
1948 total_duration=op_collect_audio_packets(_of,durations);
1949 OP_ASSERT(total_duration>=0);
1950 /*Report holes to the caller.*/
1951 if(!_ignore_holes)return OP_HOLE;
1952 }
1953 op_count=_of->op_count;
1954 /*If we found at least one audio data packet, compute per-packet granule
1955 positions for them.*/
1956 if(op_count>0){
1957 ogg_int64_t diff;
1958 ogg_int64_t prev_packet_gp;
1959 ogg_int64_t cur_packet_gp;
1960 ogg_int64_t cur_page_gp;
1961 int cur_page_eos;
1962 int pi;
1963 cur_page_gp=_of->op[op_count-1].granulepos;
1964 cur_page_eos=_of->op[op_count-1].e_o_s;
1965 prev_packet_gp=_of->prev_packet_gp;
1966 if(OP_UNLIKELY(prev_packet_gp==-1)){
1967 opus_int32 cur_discard_count;
1968 /*This is the first call after a raw seek.
1969 Try to reconstruct prev_packet_gp from scratch.*/
1970 OP_ASSERT(seekable);
1971 if(OP_UNLIKELY(cur_page_eos)){
1972 /*If the first page we hit after our seek was the EOS page, and
1973 we didn't start from data_offset or before, we don't have
1974 enough information to do end-trimming.
1975 Proceed to the next link, rather than risk playing back some
1976 samples that shouldn't have been played.*/
1977 _of->op_count=0;
1978 continue;
1979 }
1980 /*By default discard 80 ms of data after a seek, unless we seek
1981 into the pre-skip region.*/
1982 cur_discard_count=80*48;
1983 cur_page_gp=_of->op[op_count-1].granulepos;
1984 /*Try to initialize prev_packet_gp.
1985 If the current page had packets but didn't have a granule
1986 position, or the granule position it had was too small (both
1987 illegal), just use the starting granule position for the link.*/
1988 prev_packet_gp=links[cur_link].pcm_start;
1989 if(OP_LIKELY(cur_page_gp!=-1)){
1990 op_granpos_add(&prev_packet_gp,cur_page_gp,-total_duration);
1991 }
1992 if(OP_LIKELY(!op_granpos_diff(&diff,
1993 prev_packet_gp,links[cur_link].pcm_start))){
1994 opus_int32 pre_skip;
1995 /*If we start at the beginning of the pre-skip region, or we're
1996 at least 80 ms from the end of the pre-skip region, we discard
1997 to the end of the pre-skip region.
1998 Otherwise, we still use the 80 ms default, which will discard
1999 past the end of the pre-skip region.*/
2000 pre_skip=links[cur_link].head.pre_skip;
2001 if(diff>=0&&diff<=OP_MAX(0,pre_skip-80*48)){
2002 cur_discard_count=pre_skip-(int)diff;
2003 }
2004 }
2005 _of->cur_discard_count=cur_discard_count;
2006 }
2007 if(OP_UNLIKELY(cur_page_gp==-1)){
2008 /*This page had completed packets but didn't have a valid granule
2009 position.
2010 This is illegal, but we'll try to handle it by continuing to count
2011 forwards from the previous page.*/
2012 if(op_granpos_add(&cur_page_gp,prev_packet_gp,total_duration)<0){
2013 /*The timestamp for this page overflowed.*/
2014 cur_page_gp=links[cur_link].pcm_end;
2015 }
2016 }
2017 /*If we hit the last page, handle end-trimming.*/
2018 if(OP_UNLIKELY(cur_page_eos)
2019 &&OP_LIKELY(!op_granpos_diff(&diff,cur_page_gp,prev_packet_gp))
2020 &&OP_LIKELY(diff<total_duration)){
2021 cur_packet_gp=prev_packet_gp;
2022 for(pi=0;pi<op_count;pi++){
2023 diff=durations[pi]-diff;
2024 /*If we have samples to trim...*/
2025 if(diff>0){
2026 /*If we trimmed the entire packet, stop (the spec says encoders
2027 shouldn't do this, but we support it anyway).*/
2028 if(OP_UNLIKELY(diff>durations[pi]))break;
2029 cur_packet_gp=cur_page_gp;
2030 /*Move the EOS flag to this packet, if necessary, so we'll trim
2031 the samples during decode.*/
2032 _of->op[pi].e_o_s=1;
2033 }
2034 else{
2035 /*Update the granule position as normal.*/
2036 OP_ALWAYS_TRUE(!op_granpos_add(&cur_packet_gp,
2037 cur_packet_gp,durations[pi]));
2038 }
2039 _of->op[pi].granulepos=cur_packet_gp;
2040 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,cur_page_gp,cur_packet_gp));
2041 }
2042 }
2043 else{
2044 /*Propagate timestamps to earlier packets.
2045 op_granpos_add(&prev_packet_gp,prev_packet_gp,total_duration)
2046 should succeed and give prev_packet_gp==cur_page_gp.
2047 But we don't bother to check that, as there isn't much we can do
2048 if it's not true, and it actually will not be true on the first
2049 page after a seek, if there was a continued packet.
2050 The only thing we guarantee is that the start and end granule
2051 positions of the packets are valid, and that they are monotonic
2052 within a page.
2053 They might be completely out of range for this link (we'll check
2054 that elsewhere), or non-monotonic between pages.*/
2055 if(OP_UNLIKELY(op_granpos_add(&prev_packet_gp,
2056 cur_page_gp,-total_duration)<0)){
2057 /*The starting timestamp for the first packet on this page
2058 underflowed.
2059 This is illegal, but we ignore it.*/
2060 prev_packet_gp=0;
2061 }
2062 for(pi=0;pi<op_count;pi++){
2063 if(OP_UNLIKELY(op_granpos_add(&cur_packet_gp,
2064 cur_page_gp,-total_duration)<0)){
2065 /*The start timestamp for this packet underflowed.
2066 This is illegal, but we ignore it.*/
2067 cur_packet_gp=0;
2068 }
2069 total_duration-=durations[pi];
2070 OP_ASSERT(total_duration>=0);
2071 OP_ALWAYS_TRUE(!op_granpos_add(&cur_packet_gp,
2072 cur_packet_gp,durations[pi]));
2073 _of->op[pi].granulepos=cur_packet_gp;
2074 }
2075 OP_ASSERT(total_duration==0);
2076 }
2077 _of->prev_packet_gp=prev_packet_gp;
2078 _of->prev_page_offset=_page_offset;
2079 _of->op_count=pi;
2080 /*If end-trimming didn't trim all the packets, we're done.*/
2081 if(OP_LIKELY(pi>0))return 0;
2082 }
2083 }
2084 }
2085 }
2086
op_raw_seek(OggOpusFile * _of,opus_int64 _pos)2087 int op_raw_seek(OggOpusFile *_of,opus_int64 _pos){
2088 int ret;
2089 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
2090 /*Don't dump the decoder state if we can't seek.*/
2091 if(OP_UNLIKELY(!_of->seekable))return OP_ENOSEEK;
2092 if(OP_UNLIKELY(_pos<0)||OP_UNLIKELY(_pos>_of->end))return OP_EINVAL;
2093 /*Clear out any buffered, decoded data.*/
2094 op_decode_clear(_of);
2095 _of->bytes_tracked=0;
2096 _of->samples_tracked=0;
2097 ret=op_seek_helper(_of,_pos);
2098 if(OP_UNLIKELY(ret<0))return OP_EREAD;
2099 ret=op_fetch_and_process_page(_of,NULL,-1,1,1);
2100 /*If we hit EOF, op_fetch_and_process_page() leaves us uninitialized.
2101 Instead, jump to the end.*/
2102 if(ret==OP_EOF){
2103 int cur_link;
2104 op_decode_clear(_of);
2105 cur_link=_of->nlinks-1;
2106 _of->cur_link=cur_link;
2107 _of->prev_packet_gp=_of->links[cur_link].pcm_end;
2108 _of->cur_discard_count=0;
2109 ret=0;
2110 }
2111 return ret;
2112 }
2113
2114 /*Convert a PCM offset relative to the start of the whole stream to a granule
2115 position in an individual link.*/
op_get_granulepos(const OggOpusFile * _of,ogg_int64_t _pcm_offset,int * _li)2116 static ogg_int64_t op_get_granulepos(const OggOpusFile *_of,
2117 ogg_int64_t _pcm_offset,int *_li){
2118 const OggOpusLink *links;
2119 ogg_int64_t duration;
2120 int nlinks;
2121 int li;
2122 OP_ASSERT(_pcm_offset>=0);
2123 nlinks=_of->nlinks;
2124 links=_of->links;
2125 for(li=0;OP_LIKELY(li<nlinks);li++){
2126 ogg_int64_t pcm_start;
2127 opus_int32 pre_skip;
2128 pcm_start=links[li].pcm_start;
2129 pre_skip=links[li].head.pre_skip;
2130 OP_ALWAYS_TRUE(!op_granpos_diff(&duration,links[li].pcm_end,pcm_start));
2131 duration-=pre_skip;
2132 if(_pcm_offset<duration){
2133 _pcm_offset+=pre_skip;
2134 if(OP_UNLIKELY(pcm_start>OP_INT64_MAX-_pcm_offset)){
2135 /*Adding this amount to the granule position would overflow the positive
2136 half of its 64-bit range.
2137 Since signed overflow is undefined in C, do it in a way the compiler
2138 isn't allowed to screw up.*/
2139 _pcm_offset-=OP_INT64_MAX-pcm_start+1;
2140 pcm_start=OP_INT64_MIN;
2141 }
2142 pcm_start+=_pcm_offset;
2143 *_li=li;
2144 return pcm_start;
2145 }
2146 _pcm_offset-=duration;
2147 }
2148 return -1;
2149 }
2150
2151 /*A small helper to determine if an Ogg page contains data that continues onto
2152 a subsequent page.*/
op_page_continues(const ogg_page * _og)2153 static int op_page_continues(const ogg_page *_og){
2154 int nlacing;
2155 OP_ASSERT(_og->header_len>=27);
2156 nlacing=_og->header[26];
2157 OP_ASSERT(_og->header_len>=27+nlacing);
2158 /*This also correctly handles the (unlikely) case of nlacing==0, because
2159 0!=255.*/
2160 return _og->header[27+nlacing-1]==255;
2161 }
2162
2163 /*A small helper to buffer the continued packet data from a page.*/
op_buffer_continued_data(OggOpusFile * _of,ogg_page * _og)2164 static void op_buffer_continued_data(OggOpusFile *_of,ogg_page *_og){
2165 ogg_packet op;
2166 ogg_stream_pagein(&_of->os,_og);
2167 /*Drain any packets that did end on this page (and ignore holes).
2168 We only care about the continued packet data.*/
2169 while(ogg_stream_packetout(&_of->os,&op));
2170 }
2171
2172 /*This controls how close the target has to be to use the current stream
2173 position to subdivide the initial range.
2174 Two minutes seems to be a good default.*/
2175 #define OP_CUR_TIME_THRESH (120*48*(opus_int32)1000)
2176
2177 /*Note: The OP_SMALL_FOOTPRINT #define doesn't (currently) save much code size,
2178 but it's meant to serve as documentation for portions of the seeking
2179 algorithm that are purely optional, to aid others learning from/porting this
2180 code to other contexts.*/
2181 /*#define OP_SMALL_FOOTPRINT (1)*/
2182
2183 /*Search within link _li for the page with the highest granule position
2184 preceding (or equal to) _target_gp.
2185 There is a danger here: missing pages or incorrect frame number information
2186 in the bitstream could make our task impossible.
2187 Account for that (and report it as an error condition).*/
op_pcm_seek_page(OggOpusFile * _of,ogg_int64_t _target_gp,int _li)2188 static int op_pcm_seek_page(OggOpusFile *_of,
2189 ogg_int64_t _target_gp,int _li){
2190 const OggOpusLink *link;
2191 ogg_page og;
2192 ogg_int64_t pcm_pre_skip;
2193 ogg_int64_t pcm_start;
2194 ogg_int64_t pcm_end;
2195 ogg_int64_t best_gp;
2196 ogg_int64_t diff;
2197 ogg_uint32_t serialno;
2198 opus_int32 pre_skip;
2199 opus_int64 begin;
2200 opus_int64 end;
2201 opus_int64 boundary;
2202 opus_int64 best;
2203 opus_int64 best_start;
2204 opus_int64 page_offset;
2205 opus_int64 d0;
2206 opus_int64 d1;
2207 opus_int64 d2;
2208 int force_bisect;
2209 int buffering;
2210 int ret;
2211 _of->bytes_tracked=0;
2212 _of->samples_tracked=0;
2213 link=_of->links+_li;
2214 best_gp=pcm_start=link->pcm_start;
2215 pcm_end=link->pcm_end;
2216 serialno=link->serialno;
2217 best=best_start=begin=link->data_offset;
2218 page_offset=-1;
2219 buffering=0;
2220 /*We discard the first 80 ms of data after a seek, so seek back that much
2221 farther.
2222 If we can't, simply seek to the beginning of the link.*/
2223 if(OP_UNLIKELY(op_granpos_add(&_target_gp,_target_gp,-80*48)<0)
2224 ||OP_UNLIKELY(op_granpos_cmp(_target_gp,pcm_start)<0)){
2225 _target_gp=pcm_start;
2226 }
2227 /*Special case seeking to the start of the link.*/
2228 pre_skip=link->head.pre_skip;
2229 OP_ALWAYS_TRUE(!op_granpos_add(&pcm_pre_skip,pcm_start,pre_skip));
2230 if(op_granpos_cmp(_target_gp,pcm_pre_skip)<0)end=boundary=begin;
2231 else{
2232 end=boundary=link->end_offset;
2233 #if !defined(OP_SMALL_FOOTPRINT)
2234 /*If we were decoding from this link, we can narrow the range a bit.*/
2235 if(_li==_of->cur_link&&_of->ready_state>=OP_INITSET){
2236 opus_int64 offset;
2237 int op_count;
2238 op_count=_of->op_count;
2239 /*The only way the offset can be invalid _and_ we can fail the granule
2240 position checks below is if someone changed the contents of the last
2241 page since we read it.
2242 We'd be within our rights to just return OP_EBADLINK in that case, but
2243 we'll simply ignore the current position instead.*/
2244 offset=_of->offset;
2245 if(op_count>0&&OP_LIKELY(offset<=end)){
2246 ogg_int64_t gp;
2247 /*Make sure the timestamp is valid.
2248 The granule position might be -1 if we collected the packets from a
2249 page without a granule position after reporting a hole.*/
2250 gp=_of->op[op_count-1].granulepos;
2251 if(OP_LIKELY(gp!=-1)&&OP_LIKELY(op_granpos_cmp(pcm_start,gp)<0)
2252 &&OP_LIKELY(op_granpos_cmp(pcm_end,gp)>0)){
2253 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,gp,_target_gp));
2254 /*We only actually use the current time if either
2255 a) We can cut off at least half the range, or
2256 b) We're seeking sufficiently close to the current position that
2257 it's likely to be informative.
2258 Otherwise it appears using the whole link range to estimate the
2259 first seek location gives better results, on average.*/
2260 if(diff<0){
2261 OP_ASSERT(offset>=begin);
2262 if(offset-begin>=end-begin>>1||diff>-OP_CUR_TIME_THRESH){
2263 best=begin=offset;
2264 best_gp=pcm_start=gp;
2265 /*If we have buffered data from a continued packet, remember the
2266 offset of the previous page's start, so that if we do wind up
2267 having to seek back here later, we can prime the stream with
2268 the continued packet data.
2269 With no continued packet, we remember the end of the page.*/
2270 best_start=_of->os.body_returned<_of->os.body_fill?
2271 _of->prev_page_offset:best;
2272 /*If there's completed packets and data in the stream state,
2273 prev_page_offset should always be set.*/
2274 OP_ASSERT(best_start>=0);
2275 /*Buffer any continued packet data starting from here.*/
2276 buffering=1;
2277 }
2278 }
2279 else{
2280 ogg_int64_t prev_page_gp;
2281 /*We might get lucky and already have the packet with the target
2282 buffered.
2283 Worth checking.
2284 For very small files (with all of the data in a single page,
2285 generally 1 second or less), we can loop them continuously
2286 without seeking at all.*/
2287 OP_ALWAYS_TRUE(!op_granpos_add(&prev_page_gp,_of->op[0].granulepos,
2288 -op_get_packet_duration(_of->op[0].packet,_of->op[0].bytes)));
2289 if(op_granpos_cmp(prev_page_gp,_target_gp)<=0){
2290 /*Don't call op_decode_clear(), because it will dump our
2291 packets.*/
2292 _of->op_pos=0;
2293 _of->od_buffer_size=0;
2294 _of->prev_packet_gp=prev_page_gp;
2295 /*_of->prev_page_offset already points to the right place.*/
2296 _of->ready_state=OP_STREAMSET;
2297 return op_make_decode_ready(_of);
2298 }
2299 /*No such luck.
2300 Check if we can cut off at least half the range, though.*/
2301 if(offset-begin<=end-begin>>1||diff<OP_CUR_TIME_THRESH){
2302 /*We really want the page start here, but this will do.*/
2303 end=boundary=offset;
2304 pcm_end=gp;
2305 }
2306 }
2307 }
2308 }
2309 }
2310 #endif
2311 }
2312 /*This code was originally based on the "new search algorithm by HB (Nicholas
2313 Vinen)" from libvorbisfile.
2314 It has been modified substantially since.*/
2315 op_decode_clear(_of);
2316 if(!buffering)ogg_stream_reset_serialno(&_of->os,serialno);
2317 _of->cur_link=_li;
2318 _of->ready_state=OP_STREAMSET;
2319 /*Initialize the interval size history.*/
2320 d2=d1=d0=end-begin;
2321 force_bisect=0;
2322 while(begin<end){
2323 opus_int64 bisect;
2324 opus_int64 next_boundary;
2325 opus_int32 chunk_size;
2326 if(end-begin<OP_CHUNK_SIZE)bisect=begin;
2327 else{
2328 /*Update the interval size history.*/
2329 d0=d1>>1;
2330 d1=d2>>1;
2331 d2=end-begin>>1;
2332 if(force_bisect)bisect=begin+(end-begin>>1);
2333 else{
2334 ogg_int64_t diff2;
2335 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,_target_gp,pcm_start));
2336 OP_ALWAYS_TRUE(!op_granpos_diff(&diff2,pcm_end,pcm_start));
2337 /*Take a (pretty decent) guess.*/
2338 bisect=begin+op_rescale64(diff,diff2,end-begin)-OP_CHUNK_SIZE;
2339 }
2340 if(bisect-OP_CHUNK_SIZE<begin)bisect=begin;
2341 force_bisect=0;
2342 }
2343 if(bisect!=_of->offset){
2344 /*Discard any buffered continued packet data.*/
2345 if(buffering)ogg_stream_reset(&_of->os);
2346 buffering=0;
2347 page_offset=-1;
2348 ret=op_seek_helper(_of,bisect);
2349 if(OP_UNLIKELY(ret<0))return ret;
2350 }
2351 chunk_size=OP_CHUNK_SIZE;
2352 next_boundary=boundary;
2353 /*Now scan forward and figure out where we landed.
2354 In the ideal case, we will see a page with a granule position at or
2355 before our target, followed by a page with a granule position after our
2356 target (or the end of the search interval).
2357 Then we can just drop out and will have all of the data we need with no
2358 additional seeking.
2359 If we landed too far before, or after, we'll break out and do another
2360 bisection.*/
2361 while(begin<end){
2362 page_offset=op_get_next_page(_of,&og,boundary);
2363 if(page_offset<0){
2364 if(page_offset<OP_FALSE)return (int)page_offset;
2365 /*There are no more pages in our interval from our stream with a valid
2366 timestamp that start at position bisect or later.*/
2367 /*If we scanned the whole interval, we're done.*/
2368 if(bisect<=begin+1)end=begin;
2369 else{
2370 /*Otherwise, back up one chunk.
2371 First, discard any data from a continued packet.*/
2372 if(buffering)ogg_stream_reset(&_of->os);
2373 buffering=0;
2374 bisect=OP_MAX(bisect-chunk_size,begin);
2375 ret=op_seek_helper(_of,bisect);
2376 if(OP_UNLIKELY(ret<0))return ret;
2377 /*Bump up the chunk size.*/
2378 chunk_size=OP_MIN(2*chunk_size,OP_CHUNK_SIZE_MAX);
2379 /*If we did find a page from another stream or without a timestamp,
2380 don't read past it.*/
2381 boundary=next_boundary;
2382 }
2383 }
2384 else{
2385 ogg_int64_t gp;
2386 int has_packets;
2387 /*Save the offset of the first page we found after the seek, regardless
2388 of the stream it came from or whether or not it has a timestamp.*/
2389 next_boundary=OP_MIN(page_offset,next_boundary);
2390 if(serialno!=(ogg_uint32_t)ogg_page_serialno(&og))continue;
2391 has_packets=ogg_page_packets(&og)>0;
2392 /*Force the gp to -1 (as it should be per spec) if no packets end on
2393 this page.
2394 Otherwise we might get confused when we try to pull out a packet
2395 with that timestamp and can't find it.*/
2396 gp=has_packets?ogg_page_granulepos(&og):-1;
2397 if(gp==-1){
2398 if(buffering){
2399 if(OP_LIKELY(!has_packets))ogg_stream_pagein(&_of->os,&og);
2400 else{
2401 /*If packets did end on this page, but we still didn't have a
2402 valid granule position (in violation of the spec!), stop
2403 buffering continued packet data.
2404 Otherwise we might continue past the packet we actually
2405 wanted.*/
2406 ogg_stream_reset(&_of->os);
2407 buffering=0;
2408 }
2409 }
2410 continue;
2411 }
2412 if(op_granpos_cmp(gp,_target_gp)<0){
2413 /*We found a page that ends before our target.
2414 Advance to the raw offset of the next page.*/
2415 begin=_of->offset;
2416 if(OP_UNLIKELY(op_granpos_cmp(pcm_start,gp)>0)
2417 ||OP_UNLIKELY(op_granpos_cmp(pcm_end,gp)<0)){
2418 /*Don't let pcm_start get out of range!
2419 That could happen with an invalid timestamp.*/
2420 break;
2421 }
2422 /*Save the byte offset of the end of the page with this granule
2423 position.*/
2424 best=best_start=begin;
2425 /*Buffer any data from a continued packet, if necessary.
2426 This avoids the need to seek back here if the next timestamp we
2427 encounter while scanning forward lies after our target.*/
2428 if(buffering)ogg_stream_reset(&_of->os);
2429 if(op_page_continues(&og)){
2430 op_buffer_continued_data(_of,&og);
2431 /*If we have a continued packet, remember the offset of this
2432 page's start, so that if we do wind up having to seek back here
2433 later, we can prime the stream with the continued packet data.
2434 With no continued packet, we remember the end of the page.*/
2435 best_start=page_offset;
2436 }
2437 /*Then force buffering on, so that if a packet starts (but does not
2438 end) on the next page, we still avoid the extra seek back.*/
2439 buffering=1;
2440 best_gp=pcm_start=gp;
2441 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,_target_gp,pcm_start));
2442 /*If we're more than a second away from our target, break out and
2443 do another bisection.*/
2444 if(diff>48000)break;
2445 /*Otherwise, keep scanning forward (do NOT use begin+1).*/
2446 bisect=begin;
2447 }
2448 else{
2449 /*We found a page that ends after our target.*/
2450 /*If we scanned the whole interval before we found it, we're done.*/
2451 if(bisect<=begin+1)end=begin;
2452 else{
2453 end=bisect;
2454 /*In later iterations, don't read past the first page we found.*/
2455 boundary=next_boundary;
2456 /*If we're not making much progress shrinking the interval size,
2457 start forcing straight bisection to limit the worst case.*/
2458 force_bisect=end-begin>d0*2;
2459 /*Don't let pcm_end get out of range!
2460 That could happen with an invalid timestamp.*/
2461 if(OP_LIKELY(op_granpos_cmp(pcm_end,gp)>0)
2462 &&OP_LIKELY(op_granpos_cmp(pcm_start,gp)<=0)){
2463 pcm_end=gp;
2464 }
2465 break;
2466 }
2467 }
2468 }
2469 }
2470 }
2471 /*Found our page.*/
2472 OP_ASSERT(op_granpos_cmp(best_gp,pcm_start)>=0);
2473 /*Seek, if necessary.
2474 If we were buffering data from a continued packet, we should be able to
2475 continue to scan forward to get the rest of the data (even if
2476 page_offset==-1).
2477 Otherwise, we need to seek back to best_start.*/
2478 if(!buffering){
2479 if(best_start!=page_offset){
2480 page_offset=-1;
2481 ret=op_seek_helper(_of,best_start);
2482 if(OP_UNLIKELY(ret<0))return ret;
2483 }
2484 if(best_start<best){
2485 /*Retrieve the page at best_start, if we do not already have it.*/
2486 if(page_offset<0){
2487 page_offset=op_get_next_page(_of,&og,link->end_offset);
2488 if(OP_UNLIKELY(page_offset<OP_FALSE))return (int)page_offset;
2489 if(OP_UNLIKELY(page_offset!=best_start))return OP_EBADLINK;
2490 }
2491 op_buffer_continued_data(_of,&og);
2492 page_offset=-1;
2493 }
2494 }
2495 /*Update prev_packet_gp to allow per-packet granule position assignment.*/
2496 _of->prev_packet_gp=best_gp;
2497 _of->prev_page_offset=best_start;
2498 ret=op_fetch_and_process_page(_of,page_offset<0?NULL:&og,page_offset,0,1);
2499 if(OP_UNLIKELY(ret<0))return OP_EBADLINK;
2500 /*Verify result.*/
2501 if(OP_UNLIKELY(op_granpos_cmp(_of->prev_packet_gp,_target_gp)>0)){
2502 return OP_EBADLINK;
2503 }
2504 /*Our caller will set cur_discard_count to handle pre-roll.*/
2505 return 0;
2506 }
2507
op_pcm_seek(OggOpusFile * _of,ogg_int64_t _pcm_offset)2508 int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset){
2509 const OggOpusLink *link;
2510 ogg_int64_t pcm_start;
2511 ogg_int64_t target_gp;
2512 ogg_int64_t prev_packet_gp;
2513 ogg_int64_t skip;
2514 ogg_int64_t diff;
2515 int op_count;
2516 int op_pos;
2517 int ret;
2518 int li;
2519 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
2520 if(OP_UNLIKELY(!_of->seekable))return OP_ENOSEEK;
2521 if(OP_UNLIKELY(_pcm_offset<0))return OP_EINVAL;
2522 target_gp=op_get_granulepos(_of,_pcm_offset,&li);
2523 if(OP_UNLIKELY(target_gp==-1))return OP_EINVAL;
2524 link=_of->links+li;
2525 pcm_start=link->pcm_start;
2526 OP_ALWAYS_TRUE(!op_granpos_diff(&_pcm_offset,target_gp,pcm_start));
2527 #if !defined(OP_SMALL_FOOTPRINT)
2528 /*For small (90 ms or less) forward seeks within the same link, just decode
2529 forward.
2530 This also optimizes the case of seeking to the current position.*/
2531 if(li==_of->cur_link&&_of->ready_state>=OP_INITSET){
2532 ogg_int64_t gp;
2533 gp=_of->prev_packet_gp;
2534 if(OP_LIKELY(gp!=-1)){
2535 int nbuffered;
2536 nbuffered=OP_MAX(_of->od_buffer_size-_of->od_buffer_pos,0);
2537 OP_ALWAYS_TRUE(!op_granpos_add(&gp,gp,-nbuffered));
2538 /*We do _not_ add cur_discard_count to gp.
2539 Otherwise the total amount to discard could grow without bound, and it
2540 would be better just to do a full seek.*/
2541 if(OP_LIKELY(!op_granpos_diff(&diff,gp,pcm_start))){
2542 ogg_int64_t discard_count;
2543 discard_count=_pcm_offset-diff;
2544 /*We use a threshold of 90 ms instead of 80, since 80 ms is the
2545 _minimum_ we would have discarded after a full seek.
2546 Assuming 20 ms frames (the default), we'd discard 90 ms on average.*/
2547 if(discard_count>=0&&OP_UNLIKELY(discard_count<90*48)){
2548 _of->cur_discard_count=(opus_int32)discard_count;
2549 return 0;
2550 }
2551 }
2552 }
2553 }
2554 #endif
2555 ret=op_pcm_seek_page(_of,target_gp,li);
2556 if(OP_UNLIKELY(ret<0))return ret;
2557 /*Now skip samples until we actually get to our target.*/
2558 /*Figure out where we should skip to.*/
2559 if(_pcm_offset<=link->head.pre_skip)skip=0;
2560 else skip=OP_MAX(_pcm_offset-80*48,0);
2561 OP_ASSERT(_pcm_offset-skip>=0);
2562 OP_ASSERT(_pcm_offset-skip<OP_INT32_MAX-120*48);
2563 /*Skip packets until we find one with samples past our skip target.*/
2564 for(;;){
2565 op_count=_of->op_count;
2566 prev_packet_gp=_of->prev_packet_gp;
2567 for(op_pos=_of->op_pos;op_pos<op_count;op_pos++){
2568 ogg_int64_t cur_packet_gp;
2569 cur_packet_gp=_of->op[op_pos].granulepos;
2570 if(OP_LIKELY(!op_granpos_diff(&diff,cur_packet_gp,pcm_start))
2571 &&diff>skip){
2572 break;
2573 }
2574 prev_packet_gp=cur_packet_gp;
2575 }
2576 _of->prev_packet_gp=prev_packet_gp;
2577 _of->op_pos=op_pos;
2578 if(op_pos<op_count)break;
2579 /*We skipped all the packets on this page.
2580 Fetch another.*/
2581 ret=op_fetch_and_process_page(_of,NULL,-1,0,1);
2582 if(OP_UNLIKELY(ret<0))return OP_EBADLINK;
2583 }
2584 OP_ALWAYS_TRUE(!op_granpos_diff(&diff,prev_packet_gp,pcm_start));
2585 /*We skipped too far.
2586 Either the timestamps were illegal or there was a hole in the data.*/
2587 if(diff>skip)return OP_EBADLINK;
2588 OP_ASSERT(_pcm_offset-diff<OP_INT32_MAX);
2589 /*TODO: If there are further holes/illegal timestamps, we still won't decode
2590 to the correct sample.
2591 However, at least op_pcm_tell() will report the correct value immediately
2592 after returning.*/
2593 _of->cur_discard_count=(opus_int32)(_pcm_offset-diff);
2594 return 0;
2595 }
2596
op_raw_tell(const OggOpusFile * _of)2597 opus_int64 op_raw_tell(const OggOpusFile *_of){
2598 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
2599 return _of->offset;
2600 }
2601
2602 /*Convert a granule position from a given link to a PCM offset relative to the
2603 start of the whole stream.
2604 For unseekable sources, this gets reset to 0 at the beginning of each link.*/
op_get_pcm_offset(const OggOpusFile * _of,ogg_int64_t _gp,int _li)2605 static ogg_int64_t op_get_pcm_offset(const OggOpusFile *_of,
2606 ogg_int64_t _gp,int _li){
2607 const OggOpusLink *links;
2608 ogg_int64_t pcm_offset;
2609 ogg_int64_t delta;
2610 int li;
2611 links=_of->links;
2612 pcm_offset=0;
2613 OP_ASSERT(_li<_of->nlinks);
2614 for(li=0;li<_li;li++){
2615 OP_ALWAYS_TRUE(!op_granpos_diff(&delta,
2616 links[li].pcm_end,links[li].pcm_start));
2617 delta-=links[li].head.pre_skip;
2618 pcm_offset+=delta;
2619 }
2620 OP_ASSERT(_li>=0);
2621 if(_of->seekable&&OP_UNLIKELY(op_granpos_cmp(_gp,links[_li].pcm_end)>0)){
2622 _gp=links[_li].pcm_end;
2623 }
2624 if(OP_LIKELY(op_granpos_cmp(_gp,links[_li].pcm_start)>0)){
2625 if(OP_UNLIKELY(op_granpos_diff(&delta,_gp,links[_li].pcm_start)<0)){
2626 /*This means an unseekable stream claimed to have a page from more than
2627 2 billion days after we joined.*/
2628 OP_ASSERT(!_of->seekable);
2629 return OP_INT64_MAX;
2630 }
2631 if(delta<links[_li].head.pre_skip)delta=0;
2632 else delta-=links[_li].head.pre_skip;
2633 /*In the seekable case, _gp was limited by pcm_end.
2634 In the unseekable case, pcm_offset should be 0.*/
2635 OP_ASSERT(pcm_offset<=OP_INT64_MAX-delta);
2636 pcm_offset+=delta;
2637 }
2638 return pcm_offset;
2639 }
2640
op_pcm_tell(const OggOpusFile * _of)2641 ogg_int64_t op_pcm_tell(const OggOpusFile *_of){
2642 ogg_int64_t gp;
2643 int nbuffered;
2644 int li;
2645 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
2646 gp=_of->prev_packet_gp;
2647 if(gp==-1)return 0;
2648 nbuffered=OP_MAX(_of->od_buffer_size-_of->od_buffer_pos,0);
2649 OP_ALWAYS_TRUE(!op_granpos_add(&gp,gp,-nbuffered));
2650 li=_of->seekable?_of->cur_link:0;
2651 if(op_granpos_add(&gp,gp,_of->cur_discard_count)<0){
2652 gp=_of->links[li].pcm_end;
2653 }
2654 return op_get_pcm_offset(_of,gp,li);
2655 }
2656
op_set_decode_callback(OggOpusFile * _of,op_decode_cb_func _decode_cb,void * _ctx)2657 void op_set_decode_callback(OggOpusFile *_of,
2658 op_decode_cb_func _decode_cb,void *_ctx){
2659 _of->decode_cb=_decode_cb;
2660 _of->decode_cb_ctx=_ctx;
2661 }
2662
op_set_gain_offset(OggOpusFile * _of,int _gain_type,opus_int32 _gain_offset_q8)2663 int op_set_gain_offset(OggOpusFile *_of,
2664 int _gain_type,opus_int32 _gain_offset_q8){
2665 if(_gain_type!=OP_HEADER_GAIN&&_gain_type!=OP_ALBUM_GAIN
2666 &&_gain_type!=OP_TRACK_GAIN&&_gain_type!=OP_ABSOLUTE_GAIN){
2667 return OP_EINVAL;
2668 }
2669 _of->gain_type=_gain_type;
2670 /*The sum of header gain and track gain lies in the range [-65536,65534].
2671 These bounds allow the offset to set the final value to anywhere in the
2672 range [-32768,32767], which is what we'll clamp it to before applying.*/
2673 _of->gain_offset_q8=OP_CLAMP(-98302,_gain_offset_q8,98303);
2674 op_update_gain(_of);
2675 return 0;
2676 }
2677
op_set_dither_enabled(OggOpusFile * _of,int _enabled)2678 void op_set_dither_enabled(OggOpusFile *_of,int _enabled){
2679 #if !defined(OP_FIXED_POINT)
2680 _of->dither_disabled=!_enabled;
2681 if(!_enabled)_of->dither_mute=65;
2682 #endif
2683 }
2684
2685 /*Allocate the decoder scratch buffer.
2686 This is done lazily, since if the user provides large enough buffers, we'll
2687 never need it.*/
op_init_buffer(OggOpusFile * _of)2688 static int op_init_buffer(OggOpusFile *_of){
2689 int nchannels_max;
2690 if(_of->seekable){
2691 const OggOpusLink *links;
2692 int nlinks;
2693 int li;
2694 links=_of->links;
2695 nlinks=_of->nlinks;
2696 nchannels_max=1;
2697 for(li=0;li<nlinks;li++){
2698 nchannels_max=OP_MAX(nchannels_max,links[li].head.channel_count);
2699 }
2700 }
2701 else nchannels_max=OP_NCHANNELS_MAX;
2702 _of->od_buffer=(op_sample *)_ogg_malloc(
2703 sizeof(*_of->od_buffer)*nchannels_max*120*48);
2704 if(_of->od_buffer==NULL)return OP_EFAULT;
2705 return 0;
2706 }
2707
2708 /*Decode a single packet into the target buffer.*/
op_decode(OggOpusFile * _of,op_sample * _pcm,const ogg_packet * _op,int _nsamples,int _nchannels)2709 static int op_decode(OggOpusFile *_of,op_sample *_pcm,
2710 const ogg_packet *_op,int _nsamples,int _nchannels){
2711 int ret;
2712 /*First we try using the application-provided decode callback.*/
2713 if(_of->decode_cb!=NULL){
2714 #if defined(OP_FIXED_POINT)
2715 ret=(*_of->decode_cb)(_of->decode_cb_ctx,_of->od,_pcm,_op,
2716 _nsamples,_nchannels,OP_DEC_FORMAT_SHORT,_of->cur_link);
2717 #else
2718 ret=(*_of->decode_cb)(_of->decode_cb_ctx,_of->od,_pcm,_op,
2719 _nsamples,_nchannels,OP_DEC_FORMAT_FLOAT,_of->cur_link);
2720 #endif
2721 }
2722 else ret=OP_DEC_USE_DEFAULT;
2723 /*If the application didn't want to handle decoding, do it ourselves.*/
2724 if(ret==OP_DEC_USE_DEFAULT){
2725 #if defined(OP_FIXED_POINT)
2726 ret=opus_multistream_decode(_of->od,
2727 _op->packet,_op->bytes,_pcm,_nsamples,0);
2728 #else
2729 ret=opus_multistream_decode_float(_of->od,
2730 _op->packet,_op->bytes,_pcm,_nsamples,0);
2731 #endif
2732 OP_ASSERT(ret<0||ret==_nsamples);
2733 }
2734 /*If the application returned a positive value other than 0 or
2735 OP_DEC_USE_DEFAULT, fail.*/
2736 else if(OP_UNLIKELY(ret>0))return OP_EBADPACKET;
2737 if(OP_UNLIKELY(ret<0))return OP_EBADPACKET;
2738 return ret;
2739 }
2740
2741 /*Read more samples from the stream, using the same API as op_read() or
2742 op_read_float().*/
op_read_native(OggOpusFile * _of,op_sample * _pcm,int _buf_size,int * _li)2743 static int op_read_native(OggOpusFile *_of,
2744 op_sample *_pcm,int _buf_size,int *_li){
2745 if(OP_UNLIKELY(_of->ready_state<OP_OPENED))return OP_EINVAL;
2746 for(;;){
2747 int ret;
2748 if(OP_LIKELY(_of->ready_state>=OP_INITSET)){
2749 int nchannels;
2750 int od_buffer_pos;
2751 int nsamples;
2752 int op_pos;
2753 nchannels=_of->links[_of->seekable?_of->cur_link:0].head.channel_count;
2754 od_buffer_pos=_of->od_buffer_pos;
2755 nsamples=_of->od_buffer_size-od_buffer_pos;
2756 /*If we have buffered samples, return them.*/
2757 if(nsamples>0){
2758 if(nsamples*nchannels>_buf_size)nsamples=_buf_size/nchannels;
2759 memcpy(_pcm,_of->od_buffer+nchannels*od_buffer_pos,
2760 sizeof(*_pcm)*nchannels*nsamples);
2761 od_buffer_pos+=nsamples;
2762 _of->od_buffer_pos=od_buffer_pos;
2763 if(_li!=NULL)*_li=_of->cur_link;
2764 return nsamples;
2765 }
2766 /*If we have buffered packets, decode one.*/
2767 op_pos=_of->op_pos;
2768 if(OP_LIKELY(op_pos<_of->op_count)){
2769 const ogg_packet *pop;
2770 ogg_int64_t diff;
2771 opus_int32 cur_discard_count;
2772 int duration;
2773 int trimmed_duration;
2774 pop=_of->op+op_pos++;
2775 _of->op_pos=op_pos;
2776 cur_discard_count=_of->cur_discard_count;
2777 duration=op_get_packet_duration(pop->packet,pop->bytes);
2778 /*We don't buffer packets with an invalid TOC sequence.*/
2779 OP_ASSERT(duration>0);
2780 trimmed_duration=duration;
2781 /*Perform end-trimming.*/
2782 if(OP_UNLIKELY(pop->e_o_s)){
2783 if(OP_UNLIKELY(op_granpos_cmp(pop->granulepos,
2784 _of->prev_packet_gp)<=0)){
2785 trimmed_duration=0;
2786 }
2787 else if(OP_LIKELY(!op_granpos_diff(&diff,
2788 pop->granulepos,_of->prev_packet_gp))){
2789 trimmed_duration=(int)OP_MIN(diff,trimmed_duration);
2790 }
2791 }
2792 _of->prev_packet_gp=pop->granulepos;
2793 if(OP_UNLIKELY(duration*nchannels>_buf_size)){
2794 op_sample *buf;
2795 /*If the user's buffer is too small, decode into a scratch buffer.*/
2796 buf=_of->od_buffer;
2797 if(OP_UNLIKELY(buf==NULL)){
2798 ret=op_init_buffer(_of);
2799 if(OP_UNLIKELY(ret<0))return ret;
2800 buf=_of->od_buffer;
2801 }
2802 ret=op_decode(_of,buf,pop,duration,nchannels);
2803 if(OP_UNLIKELY(ret<0))return ret;
2804 /*Perform pre-skip/pre-roll.*/
2805 od_buffer_pos=(int)OP_MIN(trimmed_duration,cur_discard_count);
2806 cur_discard_count-=od_buffer_pos;
2807 _of->cur_discard_count=cur_discard_count;
2808 _of->od_buffer_pos=od_buffer_pos;
2809 _of->od_buffer_size=trimmed_duration;
2810 /*Update bitrate tracking based on the actual samples we used from
2811 what was decoded.*/
2812 _of->bytes_tracked+=pop->bytes;
2813 _of->samples_tracked+=trimmed_duration-od_buffer_pos;
2814 }
2815 else{
2816 /*Otherwise decode directly into the user's buffer.*/
2817 ret=op_decode(_of,_pcm,pop,duration,nchannels);
2818 if(OP_UNLIKELY(ret<0))return ret;
2819 if(OP_LIKELY(trimmed_duration>0)){
2820 /*Perform pre-skip/pre-roll.*/
2821 od_buffer_pos=(int)OP_MIN(trimmed_duration,cur_discard_count);
2822 cur_discard_count-=od_buffer_pos;
2823 _of->cur_discard_count=cur_discard_count;
2824 trimmed_duration-=od_buffer_pos;
2825 if(OP_LIKELY(trimmed_duration>0)
2826 &&OP_UNLIKELY(od_buffer_pos>0)){
2827 memmove(_pcm,_pcm+od_buffer_pos*nchannels,
2828 sizeof(*_pcm)*trimmed_duration*nchannels);
2829 }
2830 /*Update bitrate tracking based on the actual samples we used from
2831 what was decoded.*/
2832 _of->bytes_tracked+=pop->bytes;
2833 _of->samples_tracked+=trimmed_duration;
2834 if(OP_LIKELY(trimmed_duration>0)){
2835 if(_li!=NULL)*_li=_of->cur_link;
2836 return trimmed_duration;
2837 }
2838 }
2839 }
2840 /*Don't grab another page yet.
2841 This one might have more packets, or might have buffered data now.*/
2842 continue;
2843 }
2844 }
2845 /*Suck in another page.*/
2846 ret=op_fetch_and_process_page(_of,NULL,-1,1,0);
2847 if(OP_UNLIKELY(ret==OP_EOF)){
2848 if(_li!=NULL)*_li=_of->cur_link;
2849 return 0;
2850 }
2851 if(OP_UNLIKELY(ret<0))return ret;
2852 }
2853 }
2854
2855 /*A generic filter to apply to the decoded audio data.
2856 _src is non-const because we will destructively modify the contents of the
2857 source buffer that we consume in some cases.*/
2858 typedef int (*op_read_filter_func)(OggOpusFile *_of,void *_dst,int _dst_sz,
2859 op_sample *_src,int _nsamples,int _nchannels);
2860
2861 /*Decode some samples and then apply a custom filter to them.
2862 This is used to convert to different output formats.*/
op_filter_read_native(OggOpusFile * _of,void * _dst,int _dst_sz,op_read_filter_func _filter,int * _li)2863 static int op_filter_read_native(OggOpusFile *_of,void *_dst,int _dst_sz,
2864 op_read_filter_func _filter,int *_li){
2865 int ret;
2866 /*Ensure we have some decoded samples in our buffer.*/
2867 ret=op_read_native(_of,NULL,0,_li);
2868 /*Now apply the filter to them.*/
2869 if(OP_LIKELY(ret>=0)&&OP_LIKELY(_of->ready_state>=OP_INITSET)){
2870 int od_buffer_pos;
2871 od_buffer_pos=_of->od_buffer_pos;
2872 ret=_of->od_buffer_size-od_buffer_pos;
2873 if(OP_LIKELY(ret>0)){
2874 int nchannels;
2875 nchannels=_of->links[_of->seekable?_of->cur_link:0].head.channel_count;
2876 ret=(*_filter)(_of,_dst,_dst_sz,
2877 _of->od_buffer+nchannels*od_buffer_pos,ret,nchannels);
2878 OP_ASSERT(ret>=0);
2879 OP_ASSERT(ret<=_of->od_buffer_size-od_buffer_pos);
2880 od_buffer_pos+=ret;
2881 _of->od_buffer_pos=od_buffer_pos;
2882 }
2883 }
2884 return ret;
2885 }
2886
2887 #if !defined(OP_FIXED_POINT)||!defined(OP_DISABLE_FLOAT_API)
2888
2889 /*Matrices for downmixing from the supported channel counts to stereo.
2890 The matrices with 5 or more channels are normalized to a total volume of 2.0,
2891 since most mixes sound too quiet if normalized to 1.0 (as there is generally
2892 little volume in the side/rear channels).*/
2893 static const float OP_STEREO_DOWNMIX[OP_NCHANNELS_MAX-2][OP_NCHANNELS_MAX][2]={
2894 /*3.0*/
2895 {
2896 {0.5858F,0.0F},{0.4142F,0.4142F},{0.0F,0.5858F}
2897 },
2898 /*quadrophonic*/
2899 {
2900 {0.4226F,0.0F},{0.0F,0.4226F},{0.366F,0.2114F},{0.2114F,0.336F}
2901 },
2902 /*5.0*/
2903 {
2904 {0.651F,0.0F},{0.46F,0.46F},{0.0F,0.651F},{0.5636F,0.3254F},
2905 {0.3254F,0.5636F}
2906 },
2907 /*5.1*/
2908 {
2909 {0.529F,0.0F},{0.3741F,0.3741F},{0.0F,0.529F},{0.4582F,0.2645F},
2910 {0.2645F,0.4582F},{0.3741F,0.3741F}
2911 },
2912 /*6.1*/
2913 {
2914 {0.4553F,0.0F},{0.322F,0.322F},{0.0F,0.4553F},{0.3943F,0.2277F},
2915 {0.2277F,0.3943F},{0.2788F,0.2788F},{0.322F,0.322F}
2916 },
2917 /*7.1*/
2918 {
2919 {0.3886F,0.0F},{0.2748F,0.2748F},{0.0F,0.3886F},{0.3366F,0.1943F},
2920 {0.1943F,0.3366F},{0.3366F,0.1943F},{0.1943F,0.3366F},{0.2748F,0.2748F}
2921 }
2922 };
2923
2924 #endif
2925
2926 #if defined(OP_FIXED_POINT)
2927
2928 /*Matrices for downmixing from the supported channel counts to stereo.
2929 The matrices with 5 or more channels are normalized to a total volume of 2.0,
2930 since most mixes sound too quiet if normalized to 1.0 (as there is generally
2931 little volume in the side/rear channels).
2932 Hence we keep the coefficients in Q14, so the downmix values won't overflow a
2933 32-bit number.*/
2934 static const opus_int16 OP_STEREO_DOWNMIX_Q14
2935 [OP_NCHANNELS_MAX-2][OP_NCHANNELS_MAX][2]={
2936 /*3.0*/
2937 {
2938 {9598,0},{6786,6786},{0,9598}
2939 },
2940 /*quadrophonic*/
2941 {
2942 {6924,0},{0,6924},{5996,3464},{3464,5996}
2943 },
2944 /*5.0*/
2945 {
2946 {10666,0},{7537,7537},{0,10666},{9234,5331},{5331,9234}
2947 },
2948 /*5.1*/
2949 {
2950 {8668,0},{6129,6129},{0,8668},{7507,4335},{4335,7507},{6129,6129}
2951 },
2952 /*6.1*/
2953 {
2954 {7459,0},{5275,5275},{0,7459},{6460,3731},{3731,6460},{4568,4568},
2955 {5275,5275}
2956 },
2957 /*7.1*/
2958 {
2959 {6368,0},{4502,4502},{0,6368},{5515,3183},{3183,5515},{5515,3183},
2960 {3183,5515},{4502,4502}
2961 }
2962 };
2963
op_read(OggOpusFile * _of,opus_int16 * _pcm,int _buf_size,int * _li)2964 int op_read(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size,int *_li){
2965 return op_read_native(_of,_pcm,_buf_size,_li);
2966 }
2967
op_stereo_filter(OggOpusFile * _of,void * _dst,int _dst_sz,op_sample * _src,int _nsamples,int _nchannels)2968 static int op_stereo_filter(OggOpusFile *_of,void *_dst,int _dst_sz,
2969 op_sample *_src,int _nsamples,int _nchannels){
2970 (void)_of;
2971 _nsamples=OP_MIN(_nsamples,_dst_sz>>1);
2972 if(_nchannels==2)memcpy(_dst,_src,_nsamples*2*sizeof(*_src));
2973 else{
2974 opus_int16 *dst;
2975 int i;
2976 dst=(opus_int16 *)_dst;
2977 if(_nchannels==1){
2978 for(i=0;i<_nsamples;i++)dst[2*i+0]=dst[2*i+1]=_src[i];
2979 }
2980 else{
2981 for(i=0;i<_nsamples;i++){
2982 opus_int32 l;
2983 opus_int32 r;
2984 int ci;
2985 l=r=0;
2986 for(ci=0;ci<_nchannels;ci++){
2987 opus_int32 s;
2988 s=_src[_nchannels*i+ci];
2989 l+=OP_STEREO_DOWNMIX_Q14[_nchannels-3][ci][0]*s;
2990 r+=OP_STEREO_DOWNMIX_Q14[_nchannels-3][ci][1]*s;
2991 }
2992 /*TODO: For 5 or more channels, we should do soft clipping here.*/
2993 dst[2*i+0]=(opus_int16)OP_CLAMP(-32768,l+8192>>14,32767);
2994 dst[2*i+1]=(opus_int16)OP_CLAMP(-32768,r+8192>>14,32767);
2995 }
2996 }
2997 }
2998 return _nsamples;
2999 }
3000
op_read_stereo(OggOpusFile * _of,opus_int16 * _pcm,int _buf_size)3001 int op_read_stereo(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size){
3002 return op_filter_read_native(_of,_pcm,_buf_size,op_stereo_filter,NULL);
3003 }
3004
3005 # if !defined(OP_DISABLE_FLOAT_API)
3006
op_short2float_filter(OggOpusFile * _of,void * _dst,int _dst_sz,op_sample * _src,int _nsamples,int _nchannels)3007 static int op_short2float_filter(OggOpusFile *_of,void *_dst,int _dst_sz,
3008 op_sample *_src,int _nsamples,int _nchannels){
3009 float *dst;
3010 int i;
3011 (void)_of;
3012 dst=(float *)_dst;
3013 if(OP_UNLIKELY(_nsamples*_nchannels>_dst_sz))_nsamples=_dst_sz/_nchannels;
3014 _dst_sz=_nsamples*_nchannels;
3015 for(i=0;i<_dst_sz;i++)dst[i]=(1.0F/32768)*_src[i];
3016 return _nsamples;
3017 }
3018
op_read_float(OggOpusFile * _of,float * _pcm,int _buf_size,int * _li)3019 int op_read_float(OggOpusFile *_of,float *_pcm,int _buf_size,int *_li){
3020 return op_filter_read_native(_of,_pcm,_buf_size,op_short2float_filter,_li);
3021 }
3022
op_short2float_stereo_filter(OggOpusFile * _of,void * _dst,int _dst_sz,op_sample * _src,int _nsamples,int _nchannels)3023 static int op_short2float_stereo_filter(OggOpusFile *_of,
3024 void *_dst,int _dst_sz,op_sample *_src,int _nsamples,int _nchannels){
3025 float *dst;
3026 int i;
3027 dst=(float *)_dst;
3028 _nsamples=OP_MIN(_nsamples,_dst_sz>>1);
3029 if(_nchannels==1){
3030 _nsamples=op_short2float_filter(_of,dst,_nsamples,_src,_nsamples,1);
3031 for(i=_nsamples;i-->0;)dst[2*i+0]=dst[2*i+1]=dst[i];
3032 }
3033 else if(_nchannels<5){
3034 /*For 3 or 4 channels, we can downmix in fixed point without risk of
3035 clipping.*/
3036 if(_nchannels>2){
3037 _nsamples=op_stereo_filter(_of,_src,_nsamples*2,
3038 _src,_nsamples,_nchannels);
3039 }
3040 return op_short2float_filter(_of,dst,_dst_sz,_src,_nsamples,2);
3041 }
3042 else{
3043 /*For 5 or more channels, we convert to floats and then downmix (so that we
3044 don't risk clipping).*/
3045 for(i=0;i<_nsamples;i++){
3046 float l;
3047 float r;
3048 int ci;
3049 l=r=0;
3050 for(ci=0;ci<_nchannels;ci++){
3051 float s;
3052 s=(1.0F/32768)*_src[_nchannels*i+ci];
3053 l+=OP_STEREO_DOWNMIX[_nchannels-3][ci][0]*s;
3054 r+=OP_STEREO_DOWNMIX[_nchannels-3][ci][1]*s;
3055 }
3056 dst[2*i+0]=l;
3057 dst[2*i+1]=r;
3058 }
3059 }
3060 return _nsamples;
3061 }
3062
op_read_float_stereo(OggOpusFile * _of,float * _pcm,int _buf_size)3063 int op_read_float_stereo(OggOpusFile *_of,float *_pcm,int _buf_size){
3064 return op_filter_read_native(_of,_pcm,_buf_size,
3065 op_short2float_stereo_filter,NULL);
3066 }
3067
3068 # endif
3069
3070 #else
3071
3072 # if defined(OP_HAVE_LRINTF)
3073 # include <math.h>
3074 # define op_float2int(_x) (lrintf(_x))
3075 # else
3076 # define op_float2int(_x) ((int)((_x)+((_x)<0?-0.5F:0.5F)))
3077 # endif
3078
3079 /*The dithering code here is adapted from opusdec, part of opus-tools.
3080 It was originally written by Greg Maxwell.*/
3081
op_rand(opus_uint32 _seed)3082 static opus_uint32 op_rand(opus_uint32 _seed){
3083 return _seed*96314165+907633515&0xFFFFFFFFU;
3084 }
3085
3086 /*This implements 16-bit quantization with full triangular dither and IIR noise
3087 shaping.
3088 The noise shaping filters were designed by Sebastian Gesemann, and are based
3089 on the LAME ATH curves with flattening to limit their peak gain to 20 dB.
3090 Everyone else's noise shaping filters are mildly crazy.
3091 The 48 kHz version of this filter is just a warped version of the 44.1 kHz
3092 filter and probably could be improved by shifting the HF shelf up in
3093 frequency a little bit, since 48 kHz has a bit more room and being more
3094 conservative against bat-ears is probably more important than more noise
3095 suppression.
3096 This process can increase the peak level of the signal (in theory by the peak
3097 error of 1.5 +20 dB, though that is unobservably rare).
3098 To avoid clipping, the signal is attenuated by a couple thousandths of a dB.
3099 Initially, the approach taken here was to only attenuate by the 99.9th
3100 percentile, making clipping rare but not impossible (like SoX), but the
3101 limited gain of the filter means that the worst case was only two
3102 thousandths of a dB more, so this just uses the worst case.
3103 The attenuation is probably also helpful to prevent clipping in the DAC
3104 reconstruction filters or downstream resampling, in any case.*/
3105
3106 # define OP_GAIN (32753.0F)
3107
3108 # define OP_PRNG_GAIN (1.0F/0xFFFFFFFF)
3109
3110 /*48 kHz noise shaping filter, sd=2.34.*/
3111
3112 static const float OP_FCOEF_B[4]={
3113 2.2374F,-0.7339F,-0.1251F,-0.6033F
3114 };
3115
3116 static const float OP_FCOEF_A[4]={
3117 0.9030F,0.0116F,-0.5853F,-0.2571F
3118 };
3119
op_float2short_filter(OggOpusFile * _of,void * _dst,int _dst_sz,float * _src,int _nsamples,int _nchannels)3120 static int op_float2short_filter(OggOpusFile *_of,void *_dst,int _dst_sz,
3121 float *_src,int _nsamples,int _nchannels){
3122 opus_int16 *dst;
3123 int ci;
3124 int i;
3125 dst=(opus_int16 *)_dst;
3126 if(OP_UNLIKELY(_nsamples*_nchannels>_dst_sz))_nsamples=_dst_sz/_nchannels;
3127 # if defined(OP_SOFT_CLIP)
3128 if(_of->state_channel_count!=_nchannels){
3129 for(ci=0;ci<_nchannels;ci++)_of->clip_state[ci]=0;
3130 }
3131 opus_pcm_soft_clip(_src,_nsamples,_nchannels,_of->clip_state);
3132 # endif
3133 if(_of->dither_disabled){
3134 for(i=0;i<_nchannels*_nsamples;i++){
3135 dst[i]=op_float2int(OP_CLAMP(-32768,32768.0F*_src[i],32767));
3136 }
3137 }
3138 else{
3139 opus_uint32 seed;
3140 int mute;
3141 seed=_of->dither_seed;
3142 mute=_of->dither_mute;
3143 if(_of->state_channel_count!=_nchannels)mute=65;
3144 /*In order to avoid replacing digital silence with quiet dither noise, we
3145 mute if the output has been silent for a while.*/
3146 if(mute>64)memset(_of->dither_a,0,sizeof(*_of->dither_a)*4*_nchannels);
3147 for(i=0;i<_nsamples;i++){
3148 int silent;
3149 silent=1;
3150 for(ci=0;ci<_nchannels;ci++){
3151 float r;
3152 float s;
3153 float err;
3154 int si;
3155 int j;
3156 s=_src[_nchannels*i+ci];
3157 silent&=s==0;
3158 s*=OP_GAIN;
3159 err=0;
3160 for(j=0;j<4;j++){
3161 err+=OP_FCOEF_B[j]*_of->dither_b[ci*4+j]
3162 -OP_FCOEF_A[j]*_of->dither_a[ci*4+j];
3163 }
3164 for(j=3;j-->0;)_of->dither_a[ci*4+j+1]=_of->dither_a[ci*4+j];
3165 for(j=3;j-->0;)_of->dither_b[ci*4+j+1]=_of->dither_b[ci*4+j];
3166 _of->dither_a[ci*4]=err;
3167 s-=err;
3168 if(mute>16)r=0;
3169 else{
3170 seed=op_rand(seed);
3171 r=seed*OP_PRNG_GAIN;
3172 seed=op_rand(seed);
3173 r-=seed*OP_PRNG_GAIN;
3174 }
3175 /*Clamp in float out of paranoia that the input will be > 96 dBFS and
3176 wrap if the integer is clamped.*/
3177 si=op_float2int(OP_CLAMP(-32768,s+r,32767));
3178 dst[_nchannels*i+ci]=(opus_int16)si;
3179 /*Including clipping in the noise shaping is generally disastrous: the
3180 futile effort to restore the clipped energy results in more clipping.
3181 However, small amounts---at the level which could normally be created
3182 by dither and rounding---are harmless and can even reduce clipping
3183 somewhat due to the clipping sometimes reducing the dither + rounding
3184 error.*/
3185 _of->dither_b[ci*4]=mute>16?0:OP_CLAMP(-1.5F,si-s,1.5F);
3186 }
3187 mute++;
3188 if(!silent)mute=0;
3189 }
3190 _of->dither_mute=OP_MIN(mute,65);
3191 _of->dither_seed=seed;
3192 }
3193 _of->state_channel_count=_nchannels;
3194 return _nsamples;
3195 }
3196
op_read(OggOpusFile * _of,opus_int16 * _pcm,int _buf_size,int * _li)3197 int op_read(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size,int *_li){
3198 return op_filter_read_native(_of,_pcm,_buf_size,op_float2short_filter,_li);
3199 }
3200
op_read_float(OggOpusFile * _of,float * _pcm,int _buf_size,int * _li)3201 int op_read_float(OggOpusFile *_of,float *_pcm,int _buf_size,int *_li){
3202 _of->state_channel_count=0;
3203 return op_read_native(_of,_pcm,_buf_size,_li);
3204 }
3205
op_stereo_filter(OggOpusFile * _of,void * _dst,int _dst_sz,op_sample * _src,int _nsamples,int _nchannels)3206 static int op_stereo_filter(OggOpusFile *_of,void *_dst,int _dst_sz,
3207 op_sample *_src,int _nsamples,int _nchannels){
3208 (void)_of;
3209 _nsamples=OP_MIN(_nsamples,_dst_sz>>1);
3210 if(_nchannels==2)memcpy(_dst,_src,_nsamples*2*sizeof(*_src));
3211 else{
3212 float *dst;
3213 int i;
3214 dst=(float *)_dst;
3215 if(_nchannels==1){
3216 for(i=0;i<_nsamples;i++)dst[2*i+0]=dst[2*i+1]=_src[i];
3217 }
3218 else{
3219 for(i=0;i<_nsamples;i++){
3220 float l;
3221 float r;
3222 int ci;
3223 l=r=0;
3224 for(ci=0;ci<_nchannels;ci++){
3225 l+=OP_STEREO_DOWNMIX[_nchannels-3][ci][0]*_src[_nchannels*i+ci];
3226 r+=OP_STEREO_DOWNMIX[_nchannels-3][ci][1]*_src[_nchannels*i+ci];
3227 }
3228 dst[2*i+0]=l;
3229 dst[2*i+1]=r;
3230 }
3231 }
3232 }
3233 return _nsamples;
3234 }
3235
op_float2short_stereo_filter(OggOpusFile * _of,void * _dst,int _dst_sz,op_sample * _src,int _nsamples,int _nchannels)3236 static int op_float2short_stereo_filter(OggOpusFile *_of,
3237 void *_dst,int _dst_sz,op_sample *_src,int _nsamples,int _nchannels){
3238 opus_int16 *dst;
3239 dst=(opus_int16 *)_dst;
3240 if(_nchannels==1){
3241 int i;
3242 _nsamples=op_float2short_filter(_of,dst,_dst_sz>>1,_src,_nsamples,1);
3243 for(i=_nsamples;i-->0;)dst[2*i+0]=dst[2*i+1]=dst[i];
3244 }
3245 else{
3246 if(_nchannels>2){
3247 _nsamples=OP_MIN(_nsamples,_dst_sz>>1);
3248 _nsamples=op_stereo_filter(_of,_src,_nsamples*2,
3249 _src,_nsamples,_nchannels);
3250 }
3251 _nsamples=op_float2short_filter(_of,dst,_dst_sz,_src,_nsamples,2);
3252 }
3253 return _nsamples;
3254 }
3255
op_read_stereo(OggOpusFile * _of,opus_int16 * _pcm,int _buf_size)3256 int op_read_stereo(OggOpusFile *_of,opus_int16 *_pcm,int _buf_size){
3257 return op_filter_read_native(_of,_pcm,_buf_size,
3258 op_float2short_stereo_filter,NULL);
3259 }
3260
op_read_float_stereo(OggOpusFile * _of,float * _pcm,int _buf_size)3261 int op_read_float_stereo(OggOpusFile *_of,float *_pcm,int _buf_size){
3262 _of->state_channel_count=0;
3263 return op_filter_read_native(_of,_pcm,_buf_size,op_stereo_filter,NULL);
3264 }
3265
3266 #endif
3267