1
/* libOggFLAC - Free Lossless Audio Codec + Ogg library
2
* Copyright (C) 2002,2003,2004,2005 Josh Coalson
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
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.
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.
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.
33
#include <stdlib.h> /* for calloc() */
34
#include <string.h> /* for memcpy() */
35
#include "FLAC/assert.h"
36
#include "OggFLAC/seekable_stream_encoder.h"
37
#include "protected/seekable_stream_encoder.h"
38
#include "private/ogg_helper.h"
43
#define max(a,b) ((a)>(b)?(a):(b))
45
/***********************************************************************
47
* Private class method prototypes
49
***********************************************************************/
51
/* unpublished debug routines */
52
extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
53
extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
54
extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
56
static void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder);
57
static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
58
static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
61
/***********************************************************************
65
***********************************************************************/
67
typedef struct OggFLAC__SeekableStreamEncoderPrivate {
68
OggFLAC__SeekableStreamEncoderReadCallback read_callback;
69
OggFLAC__SeekableStreamEncoderSeekCallback seek_callback;
70
OggFLAC__SeekableStreamEncoderTellCallback tell_callback;
71
OggFLAC__SeekableStreamEncoderWriteCallback write_callback;
73
FLAC__StreamEncoder *FLAC_stream_encoder;
74
FLAC__StreamMetadata_SeekTable *seek_table;
75
/* internal vars (all the above are class settings) */
76
unsigned first_seekpoint_to_check;
77
FLAC__uint64 samples_written;
78
} OggFLAC__SeekableStreamEncoderPrivate;
81
/***********************************************************************
83
* Public static class data
85
***********************************************************************/
87
OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderStateString[] = {
88
"OggFLAC__SEEKABLE_STREAM_ENCODER_OK",
89
"OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR",
90
"OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
91
"OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
92
"OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
93
"OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
94
"OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
95
"OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
96
"OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
97
"OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
98
"OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
99
"OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
100
"OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
103
OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderReadStatusString[] = {
104
"OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE",
105
"OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
106
"OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT"
110
/***********************************************************************
112
* Class constructor/destructor
115
OggFLAC_API OggFLAC__SeekableStreamEncoder *OggFLAC__seekable_stream_encoder_new()
117
OggFLAC__SeekableStreamEncoder *encoder;
119
encoder = (OggFLAC__SeekableStreamEncoder*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoder));
124
encoder->protected_ = (OggFLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderProtected));
125
if(encoder->protected_ == 0) {
130
encoder->private_ = (OggFLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderPrivate));
131
if(encoder->private_ == 0) {
132
free(encoder->protected_);
137
encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
138
if(0 == encoder->private_->FLAC_stream_encoder) {
139
free(encoder->private_);
140
free(encoder->protected_);
145
set_defaults_(encoder);
147
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
152
OggFLAC_API void OggFLAC__seekable_stream_encoder_delete(OggFLAC__SeekableStreamEncoder *encoder)
154
FLAC__ASSERT(0 != encoder);
155
FLAC__ASSERT(0 != encoder->protected_);
156
FLAC__ASSERT(0 != encoder->private_);
157
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
159
(void)OggFLAC__seekable_stream_encoder_finish(encoder);
161
FLAC__stream_encoder_delete(encoder->private_->FLAC_stream_encoder);
163
free(encoder->private_);
164
free(encoder->protected_);
169
/***********************************************************************
171
* Public class methods
173
***********************************************************************/
175
OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_init(OggFLAC__SeekableStreamEncoder *encoder)
177
FLAC__ASSERT(0 != encoder);
179
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
180
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
182
if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
183
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
185
if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect))
186
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
188
if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
189
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
192
* These must be done before we init the stream encoder because that
193
* calls the write_callback, which uses these values.
195
encoder->private_->first_seekpoint_to_check = 0;
196
encoder->private_->samples_written = 0;
197
encoder->protected_->streaminfo_offset = 0;
198
encoder->protected_->seektable_offset = 0;
199
encoder->protected_->audio_offset = 0;
201
FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
202
FLAC__stream_encoder_set_metadata_callback(encoder->private_->FLAC_stream_encoder, metadata_callback_);
203
FLAC__stream_encoder_set_client_data(encoder->private_->FLAC_stream_encoder, encoder);
205
if(FLAC__stream_encoder_init(encoder->private_->FLAC_stream_encoder) != FLAC__STREAM_ENCODER_OK)
206
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
209
* Initializing the stream encoder writes all the metadata, so we
210
* save the stream offset now.
212
if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
213
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
215
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OK;
218
OggFLAC_API void OggFLAC__seekable_stream_encoder_finish(OggFLAC__SeekableStreamEncoder *encoder)
220
FLAC__ASSERT(0 != encoder);
221
FLAC__ASSERT(0 != encoder->private_);
222
FLAC__ASSERT(0 != encoder->protected_);
224
if(encoder->protected_->state == OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
227
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
229
FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
231
OggFLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
233
set_defaults_(encoder);
235
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
238
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_serial_number(OggFLAC__SeekableStreamEncoder *encoder, long value)
240
FLAC__ASSERT(0 != encoder);
241
FLAC__ASSERT(0 != encoder->private_);
242
FLAC__ASSERT(0 != encoder->protected_);
243
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
244
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
246
OggFLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
250
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_verify(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
252
FLAC__ASSERT(0 != encoder);
253
FLAC__ASSERT(0 != encoder->private_);
254
FLAC__ASSERT(0 != encoder->protected_);
255
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
256
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
258
return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
261
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_streamable_subset(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
263
FLAC__ASSERT(0 != encoder);
264
FLAC__ASSERT(0 != encoder->private_);
265
FLAC__ASSERT(0 != encoder->protected_);
266
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
267
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
269
return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
272
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
274
FLAC__ASSERT(0 != encoder);
275
FLAC__ASSERT(0 != encoder->private_);
276
FLAC__ASSERT(0 != encoder->protected_);
277
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
278
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
280
return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
283
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
285
FLAC__ASSERT(0 != encoder);
286
FLAC__ASSERT(0 != encoder->private_);
287
FLAC__ASSERT(0 != encoder->protected_);
288
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
289
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
291
return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
294
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_channels(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
296
FLAC__ASSERT(0 != encoder);
297
FLAC__ASSERT(0 != encoder->private_);
298
FLAC__ASSERT(0 != encoder->protected_);
299
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
300
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
302
return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
305
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_bits_per_sample(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
307
FLAC__ASSERT(0 != encoder);
308
FLAC__ASSERT(0 != encoder->private_);
309
FLAC__ASSERT(0 != encoder->protected_);
310
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
311
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
313
return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
316
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_sample_rate(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
318
FLAC__ASSERT(0 != encoder);
319
FLAC__ASSERT(0 != encoder->private_);
320
FLAC__ASSERT(0 != encoder->protected_);
321
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
322
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
324
return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
327
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
329
FLAC__ASSERT(0 != encoder);
330
FLAC__ASSERT(0 != encoder->private_);
331
FLAC__ASSERT(0 != encoder->protected_);
332
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
333
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
335
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
338
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
340
FLAC__ASSERT(0 != encoder);
341
FLAC__ASSERT(0 != encoder->private_);
342
FLAC__ASSERT(0 != encoder->protected_);
343
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
344
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
346
return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
349
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
351
FLAC__ASSERT(0 != encoder);
352
FLAC__ASSERT(0 != encoder->private_);
353
FLAC__ASSERT(0 != encoder->protected_);
354
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
355
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
357
return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
360
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
362
FLAC__ASSERT(0 != encoder);
363
FLAC__ASSERT(0 != encoder->private_);
364
FLAC__ASSERT(0 != encoder->protected_);
365
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
366
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
368
return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
371
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_escape_coding(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
373
FLAC__ASSERT(0 != encoder);
374
FLAC__ASSERT(0 != encoder->private_);
375
FLAC__ASSERT(0 != encoder->protected_);
376
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
377
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
379
return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
382
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
384
FLAC__ASSERT(0 != encoder);
385
FLAC__ASSERT(0 != encoder->private_);
386
FLAC__ASSERT(0 != encoder->protected_);
387
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
388
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
390
return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
393
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
395
FLAC__ASSERT(0 != encoder);
396
FLAC__ASSERT(0 != encoder->private_);
397
FLAC__ASSERT(0 != encoder->protected_);
398
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
399
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
401
return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
404
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
406
FLAC__ASSERT(0 != encoder);
407
FLAC__ASSERT(0 != encoder->private_);
408
FLAC__ASSERT(0 != encoder->protected_);
409
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
410
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
412
return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
415
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
417
FLAC__ASSERT(0 != encoder);
418
FLAC__ASSERT(0 != encoder->private_);
419
FLAC__ASSERT(0 != encoder->protected_);
420
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
421
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
423
return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
426
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_total_samples_estimate(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
428
FLAC__ASSERT(0 != encoder);
429
FLAC__ASSERT(0 != encoder->private_);
430
FLAC__ASSERT(0 != encoder->protected_);
431
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
432
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
434
return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
437
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_metadata(OggFLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
439
FLAC__ASSERT(0 != encoder);
440
FLAC__ASSERT(0 != encoder->private_);
441
FLAC__ASSERT(0 != encoder->protected_);
442
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
443
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
445
/* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
446
if(0 != metadata && num_blocks > 1) {
448
for(i = 1; i < num_blocks; i++) {
449
if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
450
FLAC__StreamMetadata *vc = metadata[i];
452
metadata[i] = metadata[i-1];
458
if(0 != metadata && num_blocks > 0) {
460
for(i = 0; i < num_blocks; i++) {
461
/* keep track of any SEEKTABLE block */
462
if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
463
encoder->private_->seek_table = &metadata[i]->data.seek_table;
464
break; /* take only the first one */
468
if(!OggFLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
470
return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
473
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_read_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderReadCallback value)
475
FLAC__ASSERT(0 != encoder);
476
FLAC__ASSERT(0 != encoder->private_);
477
FLAC__ASSERT(0 != encoder->protected_);
478
FLAC__ASSERT(0 != value);
479
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
481
encoder->private_->read_callback = value;
485
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_seek_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderSeekCallback value)
487
FLAC__ASSERT(0 != encoder);
488
FLAC__ASSERT(0 != encoder->private_);
489
FLAC__ASSERT(0 != encoder->protected_);
490
FLAC__ASSERT(0 != value);
491
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
493
encoder->private_->seek_callback = value;
497
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_tell_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderTellCallback value)
499
FLAC__ASSERT(0 != encoder);
500
FLAC__ASSERT(0 != encoder->private_);
501
FLAC__ASSERT(0 != encoder->protected_);
502
FLAC__ASSERT(0 != value);
503
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
505
encoder->private_->tell_callback = value;
509
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_write_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderWriteCallback value)
511
FLAC__ASSERT(0 != encoder);
512
FLAC__ASSERT(0 != encoder->private_);
513
FLAC__ASSERT(0 != encoder->protected_);
514
FLAC__ASSERT(0 != value);
515
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
517
encoder->private_->write_callback = value;
521
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_client_data(OggFLAC__SeekableStreamEncoder *encoder, void *value)
523
FLAC__ASSERT(0 != encoder);
524
FLAC__ASSERT(0 != encoder->private_);
525
FLAC__ASSERT(0 != encoder->protected_);
526
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
528
encoder->private_->client_data = value;
533
* These three functions are not static, but not publically exposed in
534
* include/FLAC/ either. They are used by the test suite.
536
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
538
FLAC__ASSERT(0 != encoder);
539
FLAC__ASSERT(0 != encoder->private_);
540
FLAC__ASSERT(0 != encoder->protected_);
541
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
543
return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->FLAC_stream_encoder, value);
546
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
548
FLAC__ASSERT(0 != encoder);
549
FLAC__ASSERT(0 != encoder->private_);
550
FLAC__ASSERT(0 != encoder->protected_);
551
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
553
return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->FLAC_stream_encoder, value);
556
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
558
FLAC__ASSERT(0 != encoder);
559
FLAC__ASSERT(0 != encoder->private_);
560
FLAC__ASSERT(0 != encoder->protected_);
561
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
563
return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->FLAC_stream_encoder, value);
566
OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_get_state(const OggFLAC__SeekableStreamEncoder *encoder)
568
FLAC__ASSERT(0 != encoder);
569
FLAC__ASSERT(0 != encoder->private_);
570
FLAC__ASSERT(0 != encoder->protected_);
571
return encoder->protected_->state;
574
OggFLAC_API FLAC__StreamEncoderState OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
576
FLAC__ASSERT(0 != encoder);
577
FLAC__ASSERT(0 != encoder->private_);
578
FLAC__ASSERT(0 != encoder->protected_);
579
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
580
return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
583
OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_encoder_get_verify_decoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
585
FLAC__ASSERT(0 != encoder);
586
FLAC__ASSERT(0 != encoder->private_);
587
FLAC__ASSERT(0 != encoder->protected_);
588
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
589
return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
592
OggFLAC_API const char *OggFLAC__seekable_stream_encoder_get_resolved_state_string(const OggFLAC__SeekableStreamEncoder *encoder)
594
FLAC__ASSERT(0 != encoder);
595
FLAC__ASSERT(0 != encoder->private_);
596
FLAC__ASSERT(0 != encoder->protected_);
597
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
598
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR)
599
return OggFLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
601
return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->FLAC_stream_encoder);
604
OggFLAC_API void OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
606
FLAC__ASSERT(0 != encoder);
607
FLAC__ASSERT(0 != encoder->private_);
608
FLAC__ASSERT(0 != encoder->protected_);
609
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
610
FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->FLAC_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
613
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_verify(const OggFLAC__SeekableStreamEncoder *encoder)
615
FLAC__ASSERT(0 != encoder);
616
FLAC__ASSERT(0 != encoder->private_);
617
FLAC__ASSERT(0 != encoder->protected_);
618
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
619
return FLAC__stream_encoder_get_verify(encoder->private_->FLAC_stream_encoder);
622
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_streamable_subset(const OggFLAC__SeekableStreamEncoder *encoder)
624
FLAC__ASSERT(0 != encoder);
625
FLAC__ASSERT(0 != encoder->private_);
626
FLAC__ASSERT(0 != encoder->protected_);
627
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
628
return FLAC__stream_encoder_get_streamable_subset(encoder->private_->FLAC_stream_encoder);
631
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
633
FLAC__ASSERT(0 != encoder);
634
FLAC__ASSERT(0 != encoder->private_);
635
FLAC__ASSERT(0 != encoder->protected_);
636
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
637
return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
640
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
642
FLAC__ASSERT(0 != encoder);
643
FLAC__ASSERT(0 != encoder->private_);
644
FLAC__ASSERT(0 != encoder->protected_);
645
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
646
return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
649
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_channels(const OggFLAC__SeekableStreamEncoder *encoder)
651
FLAC__ASSERT(0 != encoder);
652
FLAC__ASSERT(0 != encoder->private_);
653
FLAC__ASSERT(0 != encoder->protected_);
654
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
655
return FLAC__stream_encoder_get_channels(encoder->private_->FLAC_stream_encoder);
658
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_bits_per_sample(const OggFLAC__SeekableStreamEncoder *encoder)
660
FLAC__ASSERT(0 != encoder);
661
FLAC__ASSERT(0 != encoder->private_);
662
FLAC__ASSERT(0 != encoder->protected_);
663
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
664
return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->FLAC_stream_encoder);
667
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_sample_rate(const OggFLAC__SeekableStreamEncoder *encoder)
669
FLAC__ASSERT(0 != encoder);
670
FLAC__ASSERT(0 != encoder->private_);
671
FLAC__ASSERT(0 != encoder->protected_);
672
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
673
return FLAC__stream_encoder_get_sample_rate(encoder->private_->FLAC_stream_encoder);
676
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_blocksize(const OggFLAC__SeekableStreamEncoder *encoder)
678
FLAC__ASSERT(0 != encoder);
679
FLAC__ASSERT(0 != encoder->private_);
680
FLAC__ASSERT(0 != encoder->protected_);
681
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
682
return FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
685
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_lpc_order(const OggFLAC__SeekableStreamEncoder *encoder)
687
FLAC__ASSERT(0 != encoder);
688
FLAC__ASSERT(0 != encoder->private_);
689
FLAC__ASSERT(0 != encoder->protected_);
690
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
691
return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->FLAC_stream_encoder);
694
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(const OggFLAC__SeekableStreamEncoder *encoder)
696
FLAC__ASSERT(0 != encoder);
697
FLAC__ASSERT(0 != encoder->private_);
698
FLAC__ASSERT(0 != encoder->protected_);
699
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
700
return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder);
703
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__SeekableStreamEncoder *encoder)
705
FLAC__ASSERT(0 != encoder);
706
FLAC__ASSERT(0 != encoder->private_);
707
FLAC__ASSERT(0 != encoder->protected_);
708
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
709
return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder);
712
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_escape_coding(const OggFLAC__SeekableStreamEncoder *encoder)
714
FLAC__ASSERT(0 != encoder);
715
FLAC__ASSERT(0 != encoder->private_);
716
FLAC__ASSERT(0 != encoder->protected_);
717
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
718
return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->FLAC_stream_encoder);
721
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const OggFLAC__SeekableStreamEncoder *encoder)
723
FLAC__ASSERT(0 != encoder);
724
FLAC__ASSERT(0 != encoder->private_);
725
FLAC__ASSERT(0 != encoder->protected_);
726
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
727
return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder);
730
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
732
FLAC__ASSERT(0 != encoder);
733
FLAC__ASSERT(0 != encoder->private_);
734
FLAC__ASSERT(0 != encoder->protected_);
735
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
736
return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->FLAC_stream_encoder);
739
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
741
FLAC__ASSERT(0 != encoder);
742
FLAC__ASSERT(0 != encoder->private_);
743
FLAC__ASSERT(0 != encoder->protected_);
744
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
745
return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->FLAC_stream_encoder);
748
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const OggFLAC__SeekableStreamEncoder *encoder)
750
FLAC__ASSERT(0 != encoder);
751
FLAC__ASSERT(0 != encoder->private_);
752
FLAC__ASSERT(0 != encoder->protected_);
753
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
754
return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder);
757
OggFLAC_API FLAC__uint64 OggFLAC__seekable_stream_encoder_get_total_samples_estimate(const OggFLAC__SeekableStreamEncoder *encoder)
759
FLAC__ASSERT(0 != encoder);
760
FLAC__ASSERT(0 != encoder->private_);
761
FLAC__ASSERT(0 != encoder->protected_);
762
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
763
return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
766
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
768
FLAC__ASSERT(0 != encoder);
769
FLAC__ASSERT(0 != encoder->private_);
770
FLAC__ASSERT(0 != encoder->protected_);
771
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
772
if(!FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
773
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
780
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process_interleaved(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
782
FLAC__ASSERT(0 != encoder);
783
FLAC__ASSERT(0 != encoder->private_);
784
FLAC__ASSERT(0 != encoder->protected_);
785
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
786
if(!FLAC__stream_encoder_process_interleaved(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
787
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
794
/***********************************************************************
796
* Private class methods
798
***********************************************************************/
800
void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder)
802
FLAC__ASSERT(0 != encoder);
803
FLAC__ASSERT(0 != encoder->private_);
804
FLAC__ASSERT(0 != encoder->protected_);
806
encoder->private_->seek_callback = 0;
807
encoder->private_->tell_callback = 0;
808
encoder->private_->write_callback = 0;
809
encoder->private_->client_data = 0;
811
encoder->private_->seek_table = 0;
813
OggFLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
816
FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
818
OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
819
FLAC__StreamEncoderWriteStatus status;
820
FLAC__uint64 output_position;
822
(void)unused; /* silence compiler warning about unused parameter */
823
FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
825
if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
826
return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
829
* Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
832
FLAC__MetadataType type = (buffer[0] & 0x7f);
833
if(type == FLAC__METADATA_TYPE_STREAMINFO)
834
encoder->protected_->streaminfo_offset = output_position;
835
else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
836
encoder->protected_->seektable_offset = output_position;
840
* Mark the current seek point if hit (if audio_offset == 0 that
841
* means we're still writing metadata and haven't hit the first
844
if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
845
const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
846
const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
847
const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
848
FLAC__uint64 test_sample;
850
for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
851
test_sample = encoder->private_->seek_table->points[i].sample_number;
852
if(test_sample > frame_last_sample) {
855
else if(test_sample >= frame_first_sample) {
856
encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
857
encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
858
encoder->private_->seek_table->points[i].frame_samples = blocksize;
859
encoder->private_->first_seekpoint_to_check++;
860
/* DO NOT: "break;" and here's why:
861
* The seektable template may contain more than one target
862
* sample for any given frame; we will keep looping, generating
863
* duplicate seekpoints for them, and we'll clean it up later,
864
* just before writing the seektable back to the metadata.
868
encoder->private_->first_seekpoint_to_check++;
873
status = OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder), buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
875
if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
876
encoder->private_->samples_written += samples;
879
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
884
void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
886
OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
887
FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
888
const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
889
const unsigned min_framesize = metadata->data.stream_info.min_framesize;
890
const unsigned max_framesize = metadata->data.stream_info.max_framesize;
893
FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
895
/* We get called by the stream encoder when the encoding process
896
* has finished so that we can update the STREAMINFO and SEEKTABLE
900
(void)unused; /* silence compiler warning about unused parameter */
901
FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
903
/*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
905
/* All this is based on intimate knowledge of the stream header
906
* layout, but a change to the header format that would break this
907
* would also break all streams encoded in the previous format.
911
* Write STREAMINFO stats
913
simple_ogg_page__init(&page);
914
if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
915
simple_ogg_page__clear(&page);
916
return; /* state already set */
922
const unsigned md5_offset =
923
FLAC__STREAM_METADATA_HEADER_LENGTH +
925
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
926
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
927
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
928
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
929
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
930
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
931
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
932
FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
935
if(md5_offset + 16 > (unsigned)page.body_len) {
936
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
937
simple_ogg_page__clear(&page);
940
memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
946
const unsigned total_samples_byte_offset =
947
FLAC__STREAM_METADATA_HEADER_LENGTH +
949
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
950
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
951
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
952
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
953
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
954
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
955
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
959
if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
960
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
961
simple_ogg_page__clear(&page);
964
b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
965
b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
966
b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
967
b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
968
b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
969
b[4] = (FLAC__byte)(samples & 0xFF);
970
memcpy(page.body + total_samples_byte_offset, b, 5);
976
const unsigned min_framesize_offset =
977
FLAC__STREAM_METADATA_HEADER_LENGTH +
979
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
980
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
983
if(min_framesize_offset + 6 > (unsigned)page.body_len) {
984
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
985
simple_ogg_page__clear(&page);
988
b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
989
b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
990
b[2] = (FLAC__byte)(min_framesize & 0xFF);
991
b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
992
b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
993
b[5] = (FLAC__byte)(max_framesize & 0xFF);
994
memcpy(page.body + min_framesize_offset, b, 6);
996
if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
997
simple_ogg_page__clear(&page);
998
return; /* state already set */
1000
simple_ogg_page__clear(&page);
1005
if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
1009
FLAC__format_seektable_sort(encoder->private_->seek_table);
1011
FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
1013
simple_ogg_page__init(&page);
1014
if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
1015
simple_ogg_page__clear(&page);
1016
return; /* state already set */
1019
if(FLAC__STREAM_METADATA_HEADER_LENGTH + (18*encoder->private_->seek_table->num_points) > (unsigned)page.body_len) {
1020
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
1021
simple_ogg_page__clear(&page);
1025
for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
1028
xx = encoder->private_->seek_table->points[i].sample_number;
1029
b[7] = (FLAC__byte)xx; xx >>= 8;
1030
b[6] = (FLAC__byte)xx; xx >>= 8;
1031
b[5] = (FLAC__byte)xx; xx >>= 8;
1032
b[4] = (FLAC__byte)xx; xx >>= 8;
1033
b[3] = (FLAC__byte)xx; xx >>= 8;
1034
b[2] = (FLAC__byte)xx; xx >>= 8;
1035
b[1] = (FLAC__byte)xx; xx >>= 8;
1036
b[0] = (FLAC__byte)xx; xx >>= 8;
1037
xx = encoder->private_->seek_table->points[i].stream_offset;
1038
b[15] = (FLAC__byte)xx; xx >>= 8;
1039
b[14] = (FLAC__byte)xx; xx >>= 8;
1040
b[13] = (FLAC__byte)xx; xx >>= 8;
1041
b[12] = (FLAC__byte)xx; xx >>= 8;
1042
b[11] = (FLAC__byte)xx; xx >>= 8;
1043
b[10] = (FLAC__byte)xx; xx >>= 8;
1044
b[9] = (FLAC__byte)xx; xx >>= 8;
1045
b[8] = (FLAC__byte)xx; xx >>= 8;
1046
x = encoder->private_->seek_table->points[i].frame_samples;
1047
b[17] = (FLAC__byte)x; x >>= 8;
1048
b[16] = (FLAC__byte)x; x >>= 8;
1049
if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
1050
encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
1051
simple_ogg_page__clear(&page);
1057
if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
1058
simple_ogg_page__clear(&page);
1059
return; /* state already set */
1061
simple_ogg_page__clear(&page);