summaryrefslogtreecommitdiff
path: root/apps/codecs/libFLAC/seekable_stream_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libFLAC/seekable_stream_encoder.c')
-rw-r--r--apps/codecs/libFLAC/seekable_stream_encoder.c943
1 files changed, 0 insertions, 943 deletions
diff --git a/apps/codecs/libFLAC/seekable_stream_encoder.c b/apps/codecs/libFLAC/seekable_stream_encoder.c
deleted file mode 100644
index ba4326bdc9..0000000000
--- a/apps/codecs/libFLAC/seekable_stream_encoder.c
+++ /dev/null
@@ -1,943 +0,0 @@
1/* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 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 "global.h" /* for calloc() */
34#include <string.h> /* for memcpy() */
35#include "FLAC/assert.h"
36#include "protected/seekable_stream_encoder.h"
37
38#ifdef max
39#undef max
40#endif
41#define max(a,b) ((a)>(b)?(a):(b))
42
43/***********************************************************************
44 *
45 * Private class method prototypes
46 *
47 ***********************************************************************/
48
49/* unpublished debug routines */
50extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
51extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
52extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
53
54static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
55static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
56static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
57
58/***********************************************************************
59 *
60 * Private class data
61 *
62 ***********************************************************************/
63
64typedef struct FLAC__SeekableStreamEncoderPrivate {
65 FLAC__SeekableStreamEncoderSeekCallback seek_callback;
66 FLAC__SeekableStreamEncoderTellCallback tell_callback;
67 FLAC__SeekableStreamEncoderWriteCallback write_callback;
68 void *client_data;
69 FLAC__StreamEncoder *stream_encoder;
70 FLAC__StreamMetadata_SeekTable *seek_table;
71 /* internal vars (all the above are class settings) */
72 unsigned first_seekpoint_to_check;
73 FLAC__uint64 samples_written;
74} FLAC__SeekableStreamEncoderPrivate;
75
76/***********************************************************************
77 *
78 * Public static class data
79 *
80 ***********************************************************************/
81
82FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
83 "FLAC__SEEKABLE_STREAM_ENCODER_OK",
84 "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
85 "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
86 "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
87 "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
88 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
89 "FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
90 "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
91 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
92 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
93 "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
94};
95
96FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
97 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
98 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
99};
100
101FLAC_API const char * const FLAC__SeekableStreamEncoderTellStatusString[] = {
102 "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK",
103 "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR"
104};
105
106
107/***********************************************************************
108 *
109 * Class constructor/destructor
110 *
111 ***********************************************************************/
112
113FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
114{
115 FLAC__SeekableStreamEncoder *encoder;
116
117 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
118
119 encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
120 if(encoder == 0) {
121 return 0;
122 }
123
124 encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
125 if(encoder->protected_ == 0) {
126 free(encoder);
127 return 0;
128 }
129
130 encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
131 if(encoder->private_ == 0) {
132 free(encoder->protected_);
133 free(encoder);
134 return 0;
135 }
136
137 encoder->private_->stream_encoder = FLAC__stream_encoder_new();
138 if(0 == encoder->private_->stream_encoder) {
139 free(encoder->private_);
140 free(encoder->protected_);
141 free(encoder);
142 return 0;
143 }
144
145 set_defaults_(encoder);
146
147 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
148
149 return encoder;
150}
151
152FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
153{
154 FLAC__ASSERT(0 != encoder);
155 FLAC__ASSERT(0 != encoder->protected_);
156 FLAC__ASSERT(0 != encoder->private_);
157 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
158
159 (void)FLAC__seekable_stream_encoder_finish(encoder);
160
161 FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
162
163 free(encoder->private_);
164 free(encoder->protected_);
165 free(encoder);
166}
167
168
169/***********************************************************************
170 *
171 * Public class methods
172 *
173 ***********************************************************************/
174
175FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
176{
177 FLAC__ASSERT(0 != encoder);
178
179 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
180 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
181
182 if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
183 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
184
185 if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
186 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
187
188 /*
189 * These must be done before we init the stream encoder because that
190 * calls the write_callback, which uses these values.
191 */
192 encoder->private_->first_seekpoint_to_check = 0;
193 encoder->private_->samples_written = 0;
194 encoder->protected_->streaminfo_offset = 0;
195 encoder->protected_->seektable_offset = 0;
196 encoder->protected_->audio_offset = 0;
197
198 FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
199 FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
200 FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
201
202 if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
203 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
204
205 /*
206 * Initializing the stream encoder writes all the metadata, so we
207 * save the stream offset now.
208 */
209 if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
210 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
211
212 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
213}
214
215FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
216{
217 FLAC__ASSERT(0 != encoder);
218 FLAC__ASSERT(0 != encoder->private_);
219 FLAC__ASSERT(0 != encoder->protected_);
220
221 if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
222 return;
223
224 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
225
226 FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
227
228 set_defaults_(encoder);
229
230 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
231}
232
233FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
234{
235 FLAC__ASSERT(0 != encoder);
236 FLAC__ASSERT(0 != encoder->private_);
237 FLAC__ASSERT(0 != encoder->protected_);
238 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
239 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
240 return false;
241 return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
242}
243
244FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
245{
246 FLAC__ASSERT(0 != encoder);
247 FLAC__ASSERT(0 != encoder->private_);
248 FLAC__ASSERT(0 != encoder->protected_);
249 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
250 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
251 return false;
252 return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
253}
254
255FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
256{
257 FLAC__ASSERT(0 != encoder);
258 FLAC__ASSERT(0 != encoder->private_);
259 FLAC__ASSERT(0 != encoder->protected_);
260 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
261 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
262 return false;
263 return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
264}
265
266FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
267{
268 FLAC__ASSERT(0 != encoder);
269 FLAC__ASSERT(0 != encoder->private_);
270 FLAC__ASSERT(0 != encoder->protected_);
271 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
272 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
273 return false;
274 return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
275}
276
277FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
278{
279 FLAC__ASSERT(0 != encoder);
280 FLAC__ASSERT(0 != encoder->private_);
281 FLAC__ASSERT(0 != encoder->protected_);
282 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
283 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
284 return false;
285 return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
286}
287
288FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
289{
290 FLAC__ASSERT(0 != encoder);
291 FLAC__ASSERT(0 != encoder->private_);
292 FLAC__ASSERT(0 != encoder->protected_);
293 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
294 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
295 return false;
296 return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
297}
298
299FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
300{
301 FLAC__ASSERT(0 != encoder);
302 FLAC__ASSERT(0 != encoder->private_);
303 FLAC__ASSERT(0 != encoder->protected_);
304 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
305 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
306 return false;
307 return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
308}
309
310FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
311{
312 FLAC__ASSERT(0 != encoder);
313 FLAC__ASSERT(0 != encoder->private_);
314 FLAC__ASSERT(0 != encoder->protected_);
315 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
316 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
317 return false;
318 return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
319}
320
321FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
322{
323 FLAC__ASSERT(0 != encoder);
324 FLAC__ASSERT(0 != encoder->private_);
325 FLAC__ASSERT(0 != encoder->protected_);
326 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
327 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
328 return false;
329 return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
330}
331
332FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
333{
334 FLAC__ASSERT(0 != encoder);
335 FLAC__ASSERT(0 != encoder->private_);
336 FLAC__ASSERT(0 != encoder->protected_);
337 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
338 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
339 return false;
340 return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
341}
342
343FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
344{
345 FLAC__ASSERT(0 != encoder);
346 FLAC__ASSERT(0 != encoder->private_);
347 FLAC__ASSERT(0 != encoder->protected_);
348 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
349 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
350 return false;
351 return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
352}
353
354FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
355{
356 FLAC__ASSERT(0 != encoder);
357 FLAC__ASSERT(0 != encoder->private_);
358 FLAC__ASSERT(0 != encoder->protected_);
359 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
360 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
361 return false;
362 return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
363}
364
365FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
366{
367 FLAC__ASSERT(0 != encoder);
368 FLAC__ASSERT(0 != encoder->private_);
369 FLAC__ASSERT(0 != encoder->protected_);
370 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
371 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
372 return false;
373 return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
374}
375
376FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
377{
378 FLAC__ASSERT(0 != encoder);
379 FLAC__ASSERT(0 != encoder->private_);
380 FLAC__ASSERT(0 != encoder->protected_);
381 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
382 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
383 return false;
384 return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
385}
386
387FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
388{
389 FLAC__ASSERT(0 != encoder);
390 FLAC__ASSERT(0 != encoder->private_);
391 FLAC__ASSERT(0 != encoder->protected_);
392 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
393 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
394 return false;
395 return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
396}
397
398FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
399{
400 FLAC__ASSERT(0 != encoder);
401 FLAC__ASSERT(0 != encoder->private_);
402 FLAC__ASSERT(0 != encoder->protected_);
403 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
404 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
405 return false;
406 return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
407}
408
409FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
410{
411 FLAC__ASSERT(0 != encoder);
412 FLAC__ASSERT(0 != encoder->private_);
413 FLAC__ASSERT(0 != encoder->protected_);
414 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
415 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
416 return false;
417 return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
418}
419
420FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
421{
422 FLAC__ASSERT(0 != encoder);
423 FLAC__ASSERT(0 != encoder->private_);
424 FLAC__ASSERT(0 != encoder->protected_);
425 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
426 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
427 return false;
428 if(0 != metadata && num_blocks > 0) {
429 unsigned i;
430 for(i = 0; i < num_blocks; i++) {
431 if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
432 encoder->private_->seek_table = &metadata[i]->data.seek_table;
433 break; /* take only the first one */
434 }
435 }
436 }
437 return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
438}
439
440FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
441{
442 FLAC__ASSERT(0 != encoder);
443 FLAC__ASSERT(0 != encoder->private_);
444 FLAC__ASSERT(0 != encoder->protected_);
445 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
446 return false;
447 encoder->private_->seek_callback = value;
448 return true;
449}
450
451FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_tell_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderTellCallback value)
452{
453 FLAC__ASSERT(0 != encoder);
454 FLAC__ASSERT(0 != encoder->private_);
455 FLAC__ASSERT(0 != encoder->protected_);
456 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
457 return false;
458 encoder->private_->tell_callback = value;
459 return true;
460}
461
462FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
463{
464 FLAC__ASSERT(0 != encoder);
465 FLAC__ASSERT(0 != encoder->private_);
466 FLAC__ASSERT(0 != encoder->protected_);
467 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
468 return false;
469 encoder->private_->write_callback = value;
470 return true;
471}
472
473FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
474{
475 FLAC__ASSERT(0 != encoder);
476 FLAC__ASSERT(0 != encoder->private_);
477 FLAC__ASSERT(0 != encoder->protected_);
478 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
479 return false;
480 encoder->private_->client_data = value;
481 return true;
482}
483
484/*
485 * These three functions are not static, but not publically exposed in
486 * include/FLAC/ either. They are used by the test suite.
487 */
488FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
489{
490 FLAC__ASSERT(0 != encoder);
491 FLAC__ASSERT(0 != encoder->private_);
492 FLAC__ASSERT(0 != encoder->protected_);
493 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
494 return false;
495 return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
496}
497
498FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
499{
500 FLAC__ASSERT(0 != encoder);
501 FLAC__ASSERT(0 != encoder->private_);
502 FLAC__ASSERT(0 != encoder->protected_);
503 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
504 return false;
505 return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
506}
507
508FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
509{
510 FLAC__ASSERT(0 != encoder);
511 FLAC__ASSERT(0 != encoder->private_);
512 FLAC__ASSERT(0 != encoder->protected_);
513 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
514 return false;
515 return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
516}
517
518FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
519{
520 FLAC__ASSERT(0 != encoder);
521 FLAC__ASSERT(0 != encoder->protected_);
522 return encoder->protected_->state;
523}
524
525FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
526{
527 FLAC__ASSERT(0 != encoder);
528 FLAC__ASSERT(0 != encoder->private_);
529 return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
530}
531
532FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
533{
534 FLAC__ASSERT(0 != encoder);
535 FLAC__ASSERT(0 != encoder->private_);
536 return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
537}
538
539FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder)
540{
541 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR)
542 return FLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
543 else
544 return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->stream_encoder);
545}
546
547FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
548{
549 FLAC__ASSERT(0 != encoder);
550 FLAC__ASSERT(0 != encoder->private_);
551 FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
552}
553
554FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
555{
556 FLAC__ASSERT(0 != encoder);
557 FLAC__ASSERT(0 != encoder->private_);
558 return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
559}
560
561FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
562{
563 FLAC__ASSERT(0 != encoder);
564 FLAC__ASSERT(0 != encoder->private_);
565 return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
566}
567
568FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
569{
570 FLAC__ASSERT(0 != encoder);
571 FLAC__ASSERT(0 != encoder->private_);
572 return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
573}
574
575FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
576{
577 FLAC__ASSERT(0 != encoder);
578 FLAC__ASSERT(0 != encoder->private_);
579 return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
580}
581
582FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
583{
584 FLAC__ASSERT(0 != encoder);
585 FLAC__ASSERT(0 != encoder->private_);
586 return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
587}
588
589FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
590{
591 FLAC__ASSERT(0 != encoder);
592 FLAC__ASSERT(0 != encoder->private_);
593 return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
594}
595
596FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
597{
598 FLAC__ASSERT(0 != encoder);
599 FLAC__ASSERT(0 != encoder->private_);
600 return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
601}
602
603FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
604{
605 FLAC__ASSERT(0 != encoder);
606 FLAC__ASSERT(0 != encoder->private_);
607 return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
608}
609
610FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
611{
612 FLAC__ASSERT(0 != encoder);
613 FLAC__ASSERT(0 != encoder->private_);
614 return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
615}
616
617FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
618{
619 FLAC__ASSERT(0 != encoder);
620 FLAC__ASSERT(0 != encoder->private_);
621 return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
622}
623
624FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
625{
626 FLAC__ASSERT(0 != encoder);
627 FLAC__ASSERT(0 != encoder->private_);
628 return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
629}
630
631FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
632{
633 FLAC__ASSERT(0 != encoder);
634 FLAC__ASSERT(0 != encoder->private_);
635 return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
636}
637
638FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
639{
640 FLAC__ASSERT(0 != encoder);
641 FLAC__ASSERT(0 != encoder->private_);
642 return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
643}
644
645FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
646{
647 FLAC__ASSERT(0 != encoder);
648 FLAC__ASSERT(0 != encoder->private_);
649 return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
650}
651
652FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
653{
654 FLAC__ASSERT(0 != encoder);
655 FLAC__ASSERT(0 != encoder->private_);
656 return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
657}
658
659FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
660{
661 FLAC__ASSERT(0 != encoder);
662 FLAC__ASSERT(0 != encoder->private_);
663 return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
664}
665
666FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
667{
668 FLAC__ASSERT(0 != encoder);
669 FLAC__ASSERT(0 != encoder->private_);
670 return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
671}
672
673FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
674{
675 FLAC__ASSERT(0 != encoder);
676 FLAC__ASSERT(0 != encoder->private_);
677 if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
678 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
679 return false;
680 }
681 else
682 return true;
683}
684
685/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
686FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
687{
688 FLAC__ASSERT(0 != encoder);
689 FLAC__ASSERT(0 != encoder->private_);
690 if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
691 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
692 return false;
693 }
694 else
695 return true;
696}
697
698/***********************************************************************
699 *
700 * Private class methods
701 *
702 ***********************************************************************/
703
704void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
705{
706 FLAC__ASSERT(0 != encoder);
707 FLAC__ASSERT(0 != encoder->private_);
708 FLAC__ASSERT(0 != encoder->protected_);
709
710 encoder->private_->seek_callback = 0;
711 encoder->private_->tell_callback = 0;
712 encoder->private_->write_callback = 0;
713 encoder->private_->client_data = 0;
714
715 encoder->private_->seek_table = 0;
716}
717
718FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
719{
720 FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
721 FLAC__StreamEncoderWriteStatus status;
722 FLAC__uint64 output_position;
723
724 (void)unused; /* silence compiler warning about unused parameter */
725 FLAC__ASSERT(encoder->private_->stream_encoder == unused);
726
727 if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
728 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
729
730 /*
731 * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
732 */
733 if(samples == 0) {
734 FLAC__MetadataType type = (buffer[0] & 0x7f);
735 if(type == FLAC__METADATA_TYPE_STREAMINFO)
736 encoder->protected_->streaminfo_offset = output_position;
737 else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
738 encoder->protected_->seektable_offset = output_position;
739 }
740
741 /*
742 * Mark the current seek point if hit (if audio_offset == 0 that
743 * means we're still writing metadata and haven't hit the first
744 * frame yet)
745 */
746 if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
747 const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
748 const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
749 const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
750 FLAC__uint64 test_sample;
751 unsigned i;
752 for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
753 test_sample = encoder->private_->seek_table->points[i].sample_number;
754 if(test_sample > frame_last_sample) {
755 break;
756 }
757 else if(test_sample >= frame_first_sample) {
758 encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
759 encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
760 encoder->private_->seek_table->points[i].frame_samples = blocksize;
761 encoder->private_->first_seekpoint_to_check++;
762 /* DO NOT: "break;" and here's why:
763 * The seektable template may contain more than one target
764 * sample for any given frame; we will keep looping, generating
765 * duplicate seekpoints for them, and we'll clean it up later,
766 * just before writing the seektable back to the metadata.
767 */
768 }
769 else {
770 encoder->private_->first_seekpoint_to_check++;
771 }
772 }
773 }
774
775 status = encoder->private_->write_callback(encoder, buffer, bytes, samples, current_frame, encoder->private_->client_data);
776
777 if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
778 encoder->private_->samples_written += samples;
779 }
780 else
781 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
782
783 return status;
784}
785
786void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
787{
788 FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
789 FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
790 const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
791 const unsigned min_framesize = metadata->data.stream_info.min_framesize;
792 const unsigned max_framesize = metadata->data.stream_info.max_framesize;
793 const unsigned bps = metadata->data.stream_info.bits_per_sample;
794
795 FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
796
797 /* We get called by the stream encoder when the encoding process
798 * has finished so that we can update the STREAMINFO and SEEKTABLE
799 * blocks.
800 */
801
802 (void)unused; /* silence compiler warning about unused parameter */
803 FLAC__ASSERT(encoder->private_->stream_encoder == unused);
804
805 /*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
806
807 /* All this is based on intimate knowledge of the stream header
808 * layout, but a change to the header format that would break this
809 * would also break all streams encoded in the previous format.
810 */
811
812 /*
813 * Write MD5 signature
814 */
815 {
816 const unsigned md5_offset =
817 FLAC__STREAM_METADATA_HEADER_LENGTH +
818 (
819 FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
820 FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
821 FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
822 FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
823 FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
824 FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
825 FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
826 FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
827 ) / 8;
828
829 if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
830 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
831 return;
832 }
833 if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
834 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
835 return;
836 }
837 }
838
839 /*
840 * Write total samples
841 */
842 {
843 const unsigned total_samples_byte_offset =
844 FLAC__STREAM_METADATA_HEADER_LENGTH +
845 (
846 FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
847 FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
848 FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
849 FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
850 FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
851 FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
852 FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
853 - 4
854 ) / 8;
855
856 b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
857 b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
858 b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
859 b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
860 b[4] = (FLAC__byte)(samples & 0xFF);
861 if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
862 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
863 return;
864 }
865 if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
866 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
867 return;
868 }
869 }
870
871 /*
872 * Write min/max framesize
873 */
874 {
875 const unsigned min_framesize_offset =
876 FLAC__STREAM_METADATA_HEADER_LENGTH +
877 (
878 FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
879 FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
880 ) / 8;
881
882 b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
883 b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
884 b[2] = (FLAC__byte)(min_framesize & 0xFF);
885 b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
886 b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
887 b[5] = (FLAC__byte)(max_framesize & 0xFF);
888 if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
889 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
890 return;
891 }
892 if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
893 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
894 return;
895 }
896 }
897
898 /*
899 * Write seektable
900 */
901 if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
902 unsigned i;
903
904 FLAC__format_seektable_sort(encoder->private_->seek_table);
905
906 FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
907
908 if(encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
909 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
910 return;
911 }
912
913 for(i = 0; i < encoder->private_->seek_table->num_points; i++) {
914 FLAC__uint64 xx;
915 unsigned x;
916 xx = encoder->private_->seek_table->points[i].sample_number;
917 b[7] = (FLAC__byte)xx; xx >>= 8;
918 b[6] = (FLAC__byte)xx; xx >>= 8;
919 b[5] = (FLAC__byte)xx; xx >>= 8;
920 b[4] = (FLAC__byte)xx; xx >>= 8;
921 b[3] = (FLAC__byte)xx; xx >>= 8;
922 b[2] = (FLAC__byte)xx; xx >>= 8;
923 b[1] = (FLAC__byte)xx; xx >>= 8;
924 b[0] = (FLAC__byte)xx; xx >>= 8;
925 xx = encoder->private_->seek_table->points[i].stream_offset;
926 b[15] = (FLAC__byte)xx; xx >>= 8;
927 b[14] = (FLAC__byte)xx; xx >>= 8;
928 b[13] = (FLAC__byte)xx; xx >>= 8;
929 b[12] = (FLAC__byte)xx; xx >>= 8;
930 b[11] = (FLAC__byte)xx; xx >>= 8;
931 b[10] = (FLAC__byte)xx; xx >>= 8;
932 b[9] = (FLAC__byte)xx; xx >>= 8;
933 b[8] = (FLAC__byte)xx; xx >>= 8;
934 x = encoder->private_->seek_table->points[i].frame_samples;
935 b[17] = (FLAC__byte)x; x >>= 8;
936 b[16] = (FLAC__byte)x; x >>= 8;
937 if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
938 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
939 return;
940 }
941 }
942 }
943}