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