summaryrefslogtreecommitdiff
path: root/apps/codecs/libFLAC/seekable_stream_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libFLAC/seekable_stream_decoder.c')
-rw-r--r--apps/codecs/libFLAC/seekable_stream_decoder.c1111
1 files changed, 1111 insertions, 0 deletions
diff --git a/apps/codecs/libFLAC/seekable_stream_decoder.c b/apps/codecs/libFLAC/seekable_stream_decoder.c
new file mode 100644
index 0000000000..2c899f20b3
--- /dev/null
+++ b/apps/codecs/libFLAC/seekable_stream_decoder.c
@@ -0,0 +1,1111 @@
1/* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <stdio.h>
33#include <stdlib.h> /* for calloc() */
34#include <string.h> /* for memcpy()/memcmp() */
35#include "FLAC/assert.h"
36#include "protected/seekable_stream_decoder.h"
37#include "protected/stream_decoder.h"
38#include "private/float.h" /* for FLAC__double */
39#include "private/md5.h"
40
41/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
42#ifdef _MSC_VER
43#define FLAC__U64L(x) x
44#else
45#define FLAC__U64L(x) x##LLU
46#endif
47
48/***********************************************************************
49 *
50 * Private class method prototypes
51 *
52 ***********************************************************************/
53
54static void set_defaults_(FLAC__SeekableStreamDecoder *decoder);
55static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
56static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
57static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
58static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
59static FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
60
61/***********************************************************************
62 *
63 * Private class data
64 *
65 ***********************************************************************/
66
67typedef struct FLAC__SeekableStreamDecoderPrivate {
68 FLAC__SeekableStreamDecoderReadCallback read_callback;
69 FLAC__SeekableStreamDecoderSeekCallback seek_callback;
70 FLAC__SeekableStreamDecoderTellCallback tell_callback;
71 FLAC__SeekableStreamDecoderLengthCallback length_callback;
72 FLAC__SeekableStreamDecoderEofCallback eof_callback;
73 FLAC__SeekableStreamDecoderWriteCallback write_callback;
74 FLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
75 FLAC__SeekableStreamDecoderErrorCallback error_callback;
76 void *client_data;
77 FLAC__StreamDecoder *stream_decoder;
78 FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */
79 struct FLAC__MD5Context md5context;
80 FLAC__byte stored_md5sum[16]; /* this is what is stored in the metadata */
81 FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
82 /* the rest of these are only used for seeking: */
83 FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */
84 const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
85 /* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */
86 FLAC__bool ignore_stream_info_block;
87 FLAC__bool ignore_seek_table_block;
88 FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
89 FLAC__uint64 target_sample;
90} FLAC__SeekableStreamDecoderPrivate;
91
92/***********************************************************************
93 *
94 * Public static class data
95 *
96 ***********************************************************************/
97
98FLAC_API const char * const FLAC__SeekableStreamDecoderStateString[] = {
99 "FLAC__SEEKABLE_STREAM_DECODER_OK",
100 "FLAC__SEEKABLE_STREAM_DECODER_SEEKING",
101 "FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
102 "FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
103 "FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR",
104 "FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
105 "FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR",
106 "FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
107 "FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
108 "FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
109};
110
111FLAC_API const char * const FLAC__SeekableStreamDecoderReadStatusString[] = {
112 "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK",
113 "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR"
114};
115
116FLAC_API const char * const FLAC__SeekableStreamDecoderSeekStatusString[] = {
117 "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK",
118 "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR"
119};
120
121FLAC_API const char * const FLAC__SeekableStreamDecoderTellStatusString[] = {
122 "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK",
123 "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR"
124};
125
126FLAC_API const char * const FLAC__SeekableStreamDecoderLengthStatusString[] = {
127 "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK",
128 "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR"
129};
130
131
132/***********************************************************************
133 *
134 * Class constructor/destructor
135 *
136 ***********************************************************************/
137
138FLAC_API FLAC__SeekableStreamDecoder *FLAC__seekable_stream_decoder_new()
139{
140 FLAC__SeekableStreamDecoder *decoder;
141
142 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
143
144 decoder = (FLAC__SeekableStreamDecoder*)calloc(1, sizeof(FLAC__SeekableStreamDecoder));
145 if(decoder == 0) {
146 return 0;
147 }
148
149 decoder->protected_ = (FLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamDecoderProtected));
150 if(decoder->protected_ == 0) {
151 free(decoder);
152 return 0;
153 }
154
155 decoder->private_ = (FLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamDecoderPrivate));
156 if(decoder->private_ == 0) {
157 free(decoder->protected_);
158 free(decoder);
159 return 0;
160 }
161
162 decoder->private_->stream_decoder = FLAC__stream_decoder_new();
163 if(0 == decoder->private_->stream_decoder) {
164 free(decoder->private_);
165 free(decoder->protected_);
166 free(decoder);
167 return 0;
168 }
169
170 set_defaults_(decoder);
171
172 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
173
174 return decoder;
175}
176
177FLAC_API void FLAC__seekable_stream_decoder_delete(FLAC__SeekableStreamDecoder *decoder)
178{
179 FLAC__ASSERT(0 != decoder);
180 FLAC__ASSERT(0 != decoder->protected_);
181 FLAC__ASSERT(0 != decoder->private_);
182 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
183
184 (void)FLAC__seekable_stream_decoder_finish(decoder);
185
186 FLAC__stream_decoder_delete(decoder->private_->stream_decoder);
187
188 free(decoder->private_);
189 free(decoder->protected_);
190 free(decoder);
191}
192
193/***********************************************************************
194 *
195 * Public class methods
196 *
197 ***********************************************************************/
198
199FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_init(FLAC__SeekableStreamDecoder *decoder)
200{
201 FLAC__ASSERT(0 != decoder);
202
203 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
204 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
205
206 if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
207 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
208
209 if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
210 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
211
212 decoder->private_->seek_table = 0;
213
214 decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
215
216 /* We initialize the FLAC__MD5Context even though we may never use it. This
217 * is because md5 checking may be turned on to start and then turned off if
218 * a seek occurs. So we always init the context here and finalize it in
219 * FLAC__seekable_stream_decoder_finish() to make sure things are always
220 * cleaned up properly.
221 */
222 FLAC__MD5Init(&decoder->private_->md5context);
223
224 FLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
225 FLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
226 FLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
227 FLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
228 FLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);
229
230 /* We always want to see these blocks. Whether or not we pass them up
231 * through the metadata callback will be determined by flags set in our
232 * implementation of ..._set_metadata_respond/ignore...()
233 */
234 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
235 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
236
237 if(FLAC__stream_decoder_init(decoder->private_->stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
238 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
239
240 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
241}
242
243FLAC_API FLAC__bool FLAC__seekable_stream_decoder_finish(FLAC__SeekableStreamDecoder *decoder)
244{
245 FLAC__bool md5_failed = false;
246
247 FLAC__ASSERT(0 != decoder);
248 FLAC__ASSERT(0 != decoder->private_);
249 FLAC__ASSERT(0 != decoder->protected_);
250
251 if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
252 return true;
253
254 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
255
256 /* see the comment in FLAC__seekable_stream_decoder_init() as to why we
257 * always call FLAC__MD5Final()
258 */
259 FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
260
261 FLAC__stream_decoder_finish(decoder->private_->stream_decoder);
262
263 if(decoder->private_->do_md5_checking) {
264 if(memcmp(decoder->private_->stored_md5sum, decoder->private_->computed_md5sum, 16))
265 md5_failed = true;
266 }
267
268 set_defaults_(decoder);
269
270 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
271
272 return !md5_failed;
273}
274
275FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_md5_checking(FLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
276{
277 FLAC__ASSERT(0 != decoder);
278 FLAC__ASSERT(0 != decoder->protected_);
279 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
280 return false;
281 decoder->protected_->md5_checking = value;
282 return true;
283}
284
285FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_read_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderReadCallback value)
286{
287 FLAC__ASSERT(0 != decoder);
288 FLAC__ASSERT(0 != decoder->private_);
289 FLAC__ASSERT(0 != decoder->protected_);
290 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
291 return false;
292 decoder->private_->read_callback = value;
293 return true;
294}
295
296FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_seek_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderSeekCallback value)
297{
298 FLAC__ASSERT(0 != decoder);
299 FLAC__ASSERT(0 != decoder->private_);
300 FLAC__ASSERT(0 != decoder->protected_);
301 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
302 return false;
303 decoder->private_->seek_callback = value;
304 return true;
305}
306
307FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_tell_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderTellCallback value)
308{
309 FLAC__ASSERT(0 != decoder);
310 FLAC__ASSERT(0 != decoder->private_);
311 FLAC__ASSERT(0 != decoder->protected_);
312 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
313 return false;
314 decoder->private_->tell_callback = value;
315 return true;
316}
317
318FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_length_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderLengthCallback value)
319{
320 FLAC__ASSERT(0 != decoder);
321 FLAC__ASSERT(0 != decoder->private_);
322 FLAC__ASSERT(0 != decoder->protected_);
323 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
324 return false;
325 decoder->private_->length_callback = value;
326 return true;
327}
328
329FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderEofCallback value)
330{
331 FLAC__ASSERT(0 != decoder);
332 FLAC__ASSERT(0 != decoder->private_);
333 FLAC__ASSERT(0 != decoder->protected_);
334 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
335 return false;
336 decoder->private_->eof_callback = value;
337 return true;
338}
339
340FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderWriteCallback value)
341{
342 FLAC__ASSERT(0 != decoder);
343 FLAC__ASSERT(0 != decoder->private_);
344 FLAC__ASSERT(0 != decoder->protected_);
345 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
346 return false;
347 decoder->private_->write_callback = value;
348 return true;
349}
350
351FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderMetadataCallback value)
352{
353 FLAC__ASSERT(0 != decoder);
354 FLAC__ASSERT(0 != decoder->private_);
355 FLAC__ASSERT(0 != decoder->protected_);
356 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
357 return false;
358 decoder->private_->metadata_callback = value;
359 return true;
360}
361
362FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_error_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderErrorCallback value)
363{
364 FLAC__ASSERT(0 != decoder);
365 FLAC__ASSERT(0 != decoder->private_);
366 FLAC__ASSERT(0 != decoder->protected_);
367 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
368 return false;
369 decoder->private_->error_callback = value;
370 return true;
371}
372
373FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_client_data(FLAC__SeekableStreamDecoder *decoder, void *value)
374{
375 FLAC__ASSERT(0 != decoder);
376 FLAC__ASSERT(0 != decoder->private_);
377 FLAC__ASSERT(0 != decoder->protected_);
378 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
379 return false;
380 decoder->private_->client_data = value;
381 return true;
382}
383
384FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
385{
386 FLAC__ASSERT(0 != decoder);
387 FLAC__ASSERT(0 != decoder->private_);
388 FLAC__ASSERT(0 != decoder->protected_);
389 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
390 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
391 return false;
392 if(type == FLAC__METADATA_TYPE_STREAMINFO)
393 decoder->private_->ignore_stream_info_block = false;
394 else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
395 decoder->private_->ignore_seek_table_block = false;
396 return FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
397}
398
399FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
400{
401 FLAC__ASSERT(0 != decoder);
402 FLAC__ASSERT(0 != decoder->private_);
403 FLAC__ASSERT(0 != decoder->protected_);
404 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
405 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
406 return false;
407 return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id);
408}
409
410FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_all(FLAC__SeekableStreamDecoder *decoder)
411{
412 FLAC__ASSERT(0 != decoder);
413 FLAC__ASSERT(0 != decoder->private_);
414 FLAC__ASSERT(0 != decoder->protected_);
415 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
416 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
417 return false;
418 decoder->private_->ignore_stream_info_block = false;
419 decoder->private_->ignore_seek_table_block = false;
420 return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder);
421}
422
423FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
424{
425 FLAC__ASSERT(0 != decoder);
426 FLAC__ASSERT(0 != decoder->private_);
427 FLAC__ASSERT(0 != decoder->protected_);
428 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
429 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
430 return false;
431 if(type == FLAC__METADATA_TYPE_STREAMINFO) {
432 decoder->private_->ignore_stream_info_block = true;
433 return true;
434 }
435 else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
436 decoder->private_->ignore_seek_table_block = true;
437 return true;
438 }
439 else
440 return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
441}
442
443FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
444{
445 FLAC__ASSERT(0 != decoder);
446 FLAC__ASSERT(0 != decoder->private_);
447 FLAC__ASSERT(0 != decoder->protected_);
448 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
449 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
450 return false;
451 return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
452}
453
454FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder)
455{
456 FLAC__ASSERT(0 != decoder);
457 FLAC__ASSERT(0 != decoder->private_);
458 FLAC__ASSERT(0 != decoder->protected_);
459 FLAC__ASSERT(0 != decoder->private_->stream_decoder);
460 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
461 return false;
462 decoder->private_->ignore_stream_info_block = true;
463 decoder->private_->ignore_seek_table_block = true;
464 return
465 FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
466 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
467 FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
468}
469
470FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_get_state(const FLAC__SeekableStreamDecoder *decoder)
471{
472 FLAC__ASSERT(0 != decoder);
473 FLAC__ASSERT(0 != decoder->protected_);
474 return decoder->protected_->state;
475}
476
477FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder)
478{
479 FLAC__ASSERT(0 != decoder);
480 FLAC__ASSERT(0 != decoder->private_);
481 return FLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
482}
483
484FLAC_API const char *FLAC__seekable_stream_decoder_get_resolved_state_string(const FLAC__SeekableStreamDecoder *decoder)
485{
486 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
487 return FLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
488 else
489 return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
490}
491
492FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_md5_checking(const FLAC__SeekableStreamDecoder *decoder)
493{
494 FLAC__ASSERT(0 != decoder);
495 FLAC__ASSERT(0 != decoder->protected_);
496 return decoder->protected_->md5_checking;
497}
498
499FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder)
500{
501 FLAC__ASSERT(0 != decoder);
502 FLAC__ASSERT(0 != decoder->private_);
503 return FLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
504}
505
506FLAC_API FLAC__ChannelAssignment FLAC__seekable_stream_decoder_get_channel_assignment(const FLAC__SeekableStreamDecoder *decoder)
507{
508 FLAC__ASSERT(0 != decoder);
509 FLAC__ASSERT(0 != decoder->private_);
510 return FLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
511}
512
513FLAC_API unsigned FLAC__seekable_stream_decoder_get_bits_per_sample(const FLAC__SeekableStreamDecoder *decoder)
514{
515 FLAC__ASSERT(0 != decoder);
516 FLAC__ASSERT(0 != decoder->private_);
517 return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
518}
519
520FLAC_API unsigned FLAC__seekable_stream_decoder_get_sample_rate(const FLAC__SeekableStreamDecoder *decoder)
521{
522 FLAC__ASSERT(0 != decoder);
523 FLAC__ASSERT(0 != decoder->private_);
524 return FLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
525}
526
527FLAC_API unsigned FLAC__seekable_stream_decoder_get_blocksize(const FLAC__SeekableStreamDecoder *decoder)
528{
529 FLAC__ASSERT(0 != decoder);
530 FLAC__ASSERT(0 != decoder->private_);
531 return FLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
532}
533
534FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_decode_position(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
535{
536 FLAC__ASSERT(0 != decoder);
537 FLAC__ASSERT(0 != decoder->private_);
538 FLAC__ASSERT(0 != position);
539
540 if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK)
541 return false;
542 FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder));
543 *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
544 return true;
545}
546
547FLAC_API FLAC__bool FLAC__seekable_stream_decoder_flush(FLAC__SeekableStreamDecoder *decoder)
548{
549 FLAC__ASSERT(0 != decoder);
550 FLAC__ASSERT(0 != decoder->private_);
551 FLAC__ASSERT(0 != decoder->protected_);
552
553 decoder->private_->do_md5_checking = false;
554
555 if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
556 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
557 return false;
558 }
559
560 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
561
562 return true;
563}
564
565FLAC_API FLAC__bool FLAC__seekable_stream_decoder_reset(FLAC__SeekableStreamDecoder *decoder)
566{
567 FLAC__ASSERT(0 != decoder);
568 FLAC__ASSERT(0 != decoder->private_);
569 FLAC__ASSERT(0 != decoder->protected_);
570
571 if(!FLAC__seekable_stream_decoder_flush(decoder)) {
572 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
573 return false;
574 }
575
576 if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
577 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
578 return false;
579 }
580
581 decoder->private_->seek_table = 0;
582
583 decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
584
585 /* We initialize the FLAC__MD5Context even though we may never use it. This
586 * is because md5 checking may be turned on to start and then turned off if
587 * a seek occurs. So we always init the context here and finalize it in
588 * FLAC__seekable_stream_decoder_finish() to make sure things are always
589 * cleaned up properly.
590 */
591 FLAC__MD5Init(&decoder->private_->md5context);
592
593 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
594
595 return true;
596}
597
598FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder)
599{
600 FLAC__bool ret;
601 FLAC__ASSERT(0 != decoder);
602
603 if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
604 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
605
606 if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
607 return true;
608
609 FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
610
611 ret = FLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
612 if(!ret)
613 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
614
615 return ret;
616}
617
618FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder)
619{
620 FLAC__bool ret;
621 FLAC__ASSERT(0 != decoder);
622
623 if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
624 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
625
626 if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
627 return true;
628
629 FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
630
631 ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
632 if(!ret)
633 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
634
635 return ret;
636}
637
638FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_stream(FLAC__SeekableStreamDecoder *decoder)
639{
640 FLAC__bool ret;
641 FLAC__ASSERT(0 != decoder);
642
643 if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
644 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
645
646 if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
647 return true;
648
649 FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
650
651 ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
652 if(!ret)
653 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
654
655 return ret;
656}
657
658FLAC_API FLAC__bool FLAC__seekable_stream_decoder_skip_single_frame(FLAC__SeekableStreamDecoder *decoder)
659{
660 FLAC__bool ret;
661 FLAC__ASSERT(0 != decoder);
662
663 if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM)
664 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
665
666 if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
667 return true;
668
669 FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK);
670
671 ret = FLAC__stream_decoder_skip_single_frame(decoder->private_->stream_decoder);
672 if(!ret)
673 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
674
675 return ret;
676}
677
678FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
679{
680 FLAC__uint64 length;
681
682 FLAC__ASSERT(0 != decoder);
683 FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
684
685 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEKING;
686
687 /* turn off md5 checking if a seek is attempted */
688 decoder->private_->do_md5_checking = false;
689
690 if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
691 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
692 return false;
693 }
694 /* get the file length */
695 if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
696 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
697 return false;
698 }
699 /* rewind */
700 if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
701 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
702 return false;
703 }
704 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
705 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
706 return false;
707 }
708 if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
709 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
710 return false;
711 }
712
713 return seek_to_absolute_sample_(decoder, length, sample);
714}
715
716/***********************************************************************
717 *
718 * Private class methods
719 *
720 ***********************************************************************/
721
722void set_defaults_(FLAC__SeekableStreamDecoder *decoder)
723{
724 decoder->private_->read_callback = 0;
725 decoder->private_->seek_callback = 0;
726 decoder->private_->tell_callback = 0;
727 decoder->private_->length_callback = 0;
728 decoder->private_->eof_callback = 0;
729 decoder->private_->write_callback = 0;
730 decoder->private_->metadata_callback = 0;
731 decoder->private_->error_callback = 0;
732 decoder->private_->client_data = 0;
733 /* WATCHOUT: these should match the default behavior of FLAC__StreamDecoder */
734 decoder->private_->ignore_stream_info_block = false;
735 decoder->private_->ignore_seek_table_block = true;
736
737 decoder->protected_->md5_checking = false;
738}
739
740FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
741{
742 FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
743 (void)decoder;
744 if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
745 *bytes = 0;
746#if 0
747 /*@@@@@@ verify that this is not needed */
748 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
749#endif
750 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
751 }
752 else if(*bytes > 0) {
753 if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) {
754 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
755 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
756 }
757 if(*bytes == 0) {
758 if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
759#if 0
760 /*@@@@@@ verify that this is not needed */
761 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
762#endif
763 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
764 }
765 else
766 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
767 }
768 else {
769 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
770 }
771 }
772 else
773 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
774}
775
776FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
777{
778 FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
779 (void)decoder;
780
781 if(seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
782 FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
783 FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
784 FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
785
786 FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
787
788 seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
789 if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
790 unsigned delta = (unsigned)(target_sample - this_frame_sample);
791 /* kick out of seek mode */
792 seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK;
793 /* shift out the samples before target_sample */
794 if(delta > 0) {
795 unsigned channel;
796 const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
797 for(channel = 0; channel < frame->header.channels; channel++)
798 newbuffer[channel] = buffer[channel] + delta;
799 seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
800 seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
801 /* write the relevant samples */
802 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
803 }
804 else {
805 /* write the relevant samples */
806 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
807 }
808 }
809 else {
810 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
811 }
812 }
813 else {
814 if(seekable_stream_decoder->private_->do_md5_checking) {
815 if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
816 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
817 }
818 return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
819 }
820}
821
822void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
823{
824 FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
825 (void)decoder;
826
827 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
828 seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
829 /* save the MD5 signature for comparison later */
830 memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16);
831 if(0 == memcmp(seekable_stream_decoder->private_->stored_md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
832 seekable_stream_decoder->private_->do_md5_checking = false;
833 }
834 else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
835 seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
836 }
837
838 if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
839 FLAC__bool ignore_block = false;
840 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
841 ignore_block = true;
842 else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
843 ignore_block = true;
844 if(!ignore_block)
845 seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
846 }
847}
848
849void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
850{
851 FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data;
852 (void)decoder;
853
854 if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING)
855 seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
856}
857
858FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
859{
860 FLAC__uint64 first_frame_offset, lower_bound, upper_bound;
861 FLAC__int64 pos = -1, last_pos = -1;
862 int i, lower_seek_point = -1, upper_seek_point = -1;
863 unsigned approx_bytes_per_frame;
864 FLAC__uint64 last_frame_sample = FLAC__U64L(0xffffffffffffffff);
865 FLAC__bool needs_seek;
866 const FLAC__uint64 total_samples = decoder->private_->stream_info.total_samples;
867 const unsigned min_blocksize = decoder->private_->stream_info.min_blocksize;
868 const unsigned max_blocksize = decoder->private_->stream_info.max_blocksize;
869 const unsigned max_framesize = decoder->private_->stream_info.max_framesize;
870 const unsigned channels = FLAC__seekable_stream_decoder_get_channels(decoder);
871 const unsigned bps = FLAC__seekable_stream_decoder_get_bits_per_sample(decoder);
872
873 /* we are just guessing here, but we want to guess high, not low */
874 if(max_framesize > 0) {
875 approx_bytes_per_frame = max_framesize;
876 }
877 /*
878 * Check if it's a known fixed-blocksize stream. Note that though
879 * the spec doesn't allow zeroes in the STREAMINFO block, we may
880 * never get a STREAMINFO block when decoding so the value of
881 * min_blocksize might be zero.
882 */
883 else if(min_blocksize == max_blocksize && min_blocksize > 0) {
884 /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */
885 approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64;
886 }
887 else
888 approx_bytes_per_frame = 4608 * channels * bps/8 + 64;
889
890 /*
891 * The decode position is currently at the first frame since we
892 * rewound and processed metadata.
893 */
894 if(!FLAC__seekable_stream_decoder_get_decode_position(decoder, &first_frame_offset)) {
895 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
896 return false;
897 }
898
899 /*
900 * First, we set an upper and lower bound on where in the
901 * stream we will search. For now we assume the worst case
902 * scenario, which is our best guess at the beginning of
903 * the first and last frames.
904 */
905 lower_bound = first_frame_offset;
906
907 /* calc the upper_bound, beyond which we never want to seek */
908 if(max_framesize > 0)
909 upper_bound = stream_length - (max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */
910 else
911 upper_bound = stream_length - ((channels * bps * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2);
912
913 /*
914 * Now we refine the bounds if we have a seektable with
915 * suitable points. Note that according to the spec they
916 * must be ordered by ascending sample number.
917 */
918 if(0 != decoder->private_->seek_table) {
919 /* find the closest seek point <= target_sample, if it exists */
920 for(i = (int)decoder->private_->seek_table->num_points - 1; i >= 0; i--) {
921 if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number <= target_sample)
922 break;
923 }
924 if(i >= 0) { /* i.e. we found a suitable seek point... */
925 lower_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
926 lower_seek_point = i;
927 }
928
929 /* find the closest seek point > target_sample, if it exists */
930 for(i = 0; i < (int)decoder->private_->seek_table->num_points; i++) {
931 if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number > target_sample)
932 break;
933 }
934 if(i < (int)decoder->private_->seek_table->num_points) { /* i.e. we found a suitable seek point... */
935 upper_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset;
936 upper_seek_point = i;
937 }
938 }
939
940 /*
941 * Now guess at where within those bounds our target
942 * sample will be.
943 */
944 if(lower_seek_point >= 0) {
945 /* first see if our sample is within a few frames of the lower seekpoint */
946 if(decoder->private_->seek_table->points[lower_seek_point].sample_number <= target_sample && target_sample < decoder->private_->seek_table->points[lower_seek_point].sample_number + (decoder->private_->seek_table->points[lower_seek_point].frame_samples * 4)) {
947 pos = (FLAC__int64)lower_bound;
948 }
949 else if(upper_seek_point >= 0) {
950 const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number;
951 const FLAC__uint64 range_samples = decoder->private_->seek_table->points[upper_seek_point].sample_number - decoder->private_->seek_table->points[lower_seek_point].sample_number;
952 const FLAC__uint64 range_bytes = (upper_bound>lower_bound? upper_bound - lower_bound - 1 : 0);
953#ifndef FLAC__INTEGER_ONLY_LIBRARY
954#if defined _MSC_VER || defined __MINGW32__
955 /* with MSVC you have to spoon feed it the casting */
956 pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_offset / (FLAC__double)(FLAC__int64)range_samples) * (FLAC__double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame;
957#else
958 pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)target_offset / (FLAC__double)range_samples) * (FLAC__double)range_bytes) - approx_bytes_per_frame;
959#endif
960#else
961 /* a little less accurate: */
962 if (range_bytes <= 0xffffffff)
963 pos = (FLAC__int64)lower_bound + (FLAC__int64)((target_offset * range_bytes) / range_samples) - approx_bytes_per_frame;
964 else /* @@@ WATCHOUT, ~2TB limit */
965 pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_offset>>8) * (range_bytes>>8)) / (range_samples>>16)) - approx_bytes_per_frame;
966#endif
967 }
968 }
969
970 /*
971 * If there's no seek table, we need to use the metadata (if we
972 * have it) and the filelength to estimate the position of the
973 * frame with the correct sample.
974 */
975 if(pos < 0 && total_samples > 0) {
976 /*
977 * For max accuracy we should be using
978 * (stream_length-first_frame_offset-1) in the divisor, but the
979 * difference is trivial and (stream_length-first_frame_offset)
980 * has no chance of underflow.
981 */
982#ifndef FLAC__INTEGER_ONLY_LIBRARY
983#if defined _MSC_VER || defined __MINGW32__
984 /* with VC++ you have to spoon feed it the casting */
985 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_sample / (FLAC__double)(FLAC__int64)total_samples) * (FLAC__double)(FLAC__int64)(stream_length-first_frame_offset)) - approx_bytes_per_frame;
986#else
987 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)target_sample / (FLAC__double)total_samples) * (FLAC__double)(stream_length-first_frame_offset)) - approx_bytes_per_frame;
988#endif
989#else
990 /* a little less accurate: */
991 if (stream_length < 0xffffffff)
992 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((target_sample * (stream_length-first_frame_offset)) / total_samples) - approx_bytes_per_frame;
993 else /* @@@ WATCHOUT, ~2TB limit */
994 pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((target_sample>>8) * ((stream_length-first_frame_offset)>>8)) / (total_samples>>16)) - approx_bytes_per_frame;
995#endif
996 }
997
998 /*
999 * If there's no seek table and total_samples is unknown, we
1000 * don't even bother trying to figure out a target, we just use
1001 * our current position.
1002 */
1003 if(pos < 0) {
1004 FLAC__uint64 upos;
1005 if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
1006 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1007 return false;
1008 }
1009 pos = (FLAC__int64)upos;
1010 needs_seek = false;
1011 }
1012 else
1013 needs_seek = true;
1014
1015 /* clip the position to the bounds, lower bound takes precedence */
1016 if(pos >= (FLAC__int64)upper_bound) {
1017 pos = (FLAC__int64)upper_bound-1;
1018 needs_seek = true;
1019 }
1020 if(pos < (FLAC__int64)lower_bound) {
1021 pos = (FLAC__int64)lower_bound;
1022 needs_seek = true;
1023 }
1024
1025 decoder->private_->target_sample = target_sample;
1026 while(1) {
1027 if(needs_seek) {
1028 if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
1029 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1030 return false;
1031 }
1032 if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
1033 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
1034 return false;
1035 }
1036 }
1037 /* Now we need to get a frame. It is possible for our seek
1038 * to land in the middle of audio data that looks exactly like
1039 * a frame header from a future version of an encoder. When
1040 * that happens, FLAC__stream_decoder_process_single() will
1041 * return false and the state will be
1042 * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. But there is a
1043 * remote possibility that it is properly synced at such a
1044 * "future-codec frame", so to make sure, we wait to see
1045 * several "unparseable" errors in a row before bailing out.
1046 */
1047 {
1048 unsigned unparseable_count;
1049 FLAC__bool got_a_frame = false;
1050 for (unparseable_count = 0; !got_a_frame && unparseable_count < 10; unparseable_count++) {
1051 if(FLAC__stream_decoder_process_single(decoder->private_->stream_decoder))
1052 got_a_frame = true;
1053 else if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_UNPARSEABLE_STREAM)
1054 /* try again. we don't want to flush the decoder since that clears the bitbuffer */
1055 decoder->private_->stream_decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
1056 else /* it's a real error */
1057 break;
1058 }
1059 if (!got_a_frame) {
1060 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1061 return false;
1062 }
1063 }
1064 /* our write callback will change the state when it gets to the target frame */
1065 /* actually, we could have got_a_frame if our decoder is at FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM so we need to check for that also */
1066 if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
1067 break;
1068 }
1069 else { /* we need to narrow the search */
1070 const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
1071 FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
1072 if(this_frame_sample == last_frame_sample && pos < last_pos) {
1073 /* our last move backwards wasn't big enough, double it */
1074 pos -= (last_pos - pos);
1075 needs_seek = true;
1076 }
1077 else {
1078 if(target_sample < this_frame_sample) {
1079 last_pos = pos;
1080 approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64;
1081 pos -= approx_bytes_per_frame;
1082 needs_seek = true;
1083 }
1084 else { /* target_sample >= this_frame_sample + this frame's blocksize */
1085 FLAC__uint64 upos;
1086 if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) {
1087 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1088 return false;
1089 }
1090 last_pos = pos;
1091 pos = (FLAC__int64)upos;
1092 pos -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
1093 needs_seek = false;
1094 /*
1095 * if we haven't hit the target frame yet and our position hasn't changed,
1096 * it means we're at the end of the stream and the seek target does not exist.
1097 */
1098 if(last_pos == pos) {
1099 decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
1100 return false;
1101 }
1102 }
1103 }
1104 if(pos < (FLAC__int64)lower_bound)
1105 pos = (FLAC__int64)lower_bound;
1106 last_frame_sample = this_frame_sample;
1107 }
1108 }
1109
1110 return true;
1111}