/src/flac/src/libFLAC/stream_encoder.c
Line | Count | Source |
1 | | /* libFLAC - Free Lossless Audio Codec library |
2 | | * Copyright (C) 2000-2009 Josh Coalson |
3 | | * Copyright (C) 2011-2025 Xiph.Org Foundation |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * - Redistributions of source code must retain the above copyright |
10 | | * notice, this list of conditions and the following disclaimer. |
11 | | * |
12 | | * - Redistributions in binary form must reproduce the above copyright |
13 | | * notice, this list of conditions and the following disclaimer in the |
14 | | * documentation and/or other materials provided with the distribution. |
15 | | * |
16 | | * - Neither the name of the Xiph.org Foundation nor the names of its |
17 | | * contributors may be used to endorse or promote products derived from |
18 | | * this software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
24 | | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | | */ |
32 | | |
33 | | #ifdef HAVE_CONFIG_H |
34 | | # include <config.h> |
35 | | #endif |
36 | | |
37 | | #include <limits.h> |
38 | | #include <stdio.h> |
39 | | #include <stdlib.h> /* for malloc() */ |
40 | | #include <string.h> /* for memcpy() */ |
41 | | #include <sys/types.h> /* for off_t */ |
42 | | #ifdef _WIN32 |
43 | | #include <windows.h> /* for GetFileType() */ |
44 | | #include <io.h> /* for _get_osfhandle() */ |
45 | | #endif |
46 | | #include "share/compat.h" |
47 | | #include "share/compat_threads.h" |
48 | | #include "FLAC/assert.h" |
49 | | #include "FLAC/stream_decoder.h" |
50 | | #include "protected/stream_encoder.h" |
51 | | #include "private/bitwriter.h" |
52 | | #include "private/bitmath.h" |
53 | | #include "private/crc.h" |
54 | | #include "private/cpu.h" |
55 | | #include "private/fixed.h" |
56 | | #include "private/format.h" |
57 | | #include "private/lpc.h" |
58 | | #include "private/md5.h" |
59 | | #include "private/memory.h" |
60 | | #include "private/macros.h" |
61 | | #if FLAC__HAS_OGG |
62 | | #include "private/ogg_helper.h" |
63 | | #include "private/ogg_mapping.h" |
64 | | #endif |
65 | | #include "private/stream_encoder.h" |
66 | | #include "private/stream_encoder_framing.h" |
67 | | #include "private/window.h" |
68 | | #include "share/alloc.h" |
69 | | #include "share/private.h" |
70 | | |
71 | | |
72 | | /* Exact Rice codeword length calculation is off by default. The simple |
73 | | * (and fast) estimation (of how many bits a residual value will be |
74 | | * encoded with) in this encoder is very good, almost always yielding |
75 | | * compression within 0.1% of exact calculation. |
76 | | */ |
77 | | #undef EXACT_RICE_BITS_CALCULATION |
78 | | /* Rice parameter searching is off by default. The simple (and fast) |
79 | | * parameter estimation in this encoder is very good, almost always |
80 | | * yielding compression within 0.1% of the optimal parameters. |
81 | | */ |
82 | | #undef ENABLE_RICE_PARAMETER_SEARCH |
83 | | |
84 | | #ifdef local_abs64 |
85 | | #undef local_abs64 |
86 | | #endif |
87 | 6.29M | #define local_abs64(x) ((uint64_t)((x)<0? -(x) : (x))) |
88 | | |
89 | | |
90 | | typedef struct { |
91 | | FLAC__int32 *data[FLAC__MAX_CHANNELS]; |
92 | | uint32_t size; /* of each data[] in samples */ |
93 | | uint32_t tail; |
94 | | } verify_input_fifo; |
95 | | |
96 | | typedef struct { |
97 | | const FLAC__byte *data; |
98 | | uint32_t capacity; |
99 | | uint32_t bytes; |
100 | | } verify_output; |
101 | | |
102 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
103 | | typedef struct { |
104 | | uint32_t a, b, c; |
105 | | FLAC__ApodizationSpecification * current_apodization; |
106 | | double autoc_root[FLAC__MAX_LPC_ORDER+1]; |
107 | | double autoc[FLAC__MAX_LPC_ORDER+1]; |
108 | | } apply_apodization_state_struct; |
109 | | #endif |
110 | | |
111 | | typedef enum { |
112 | | ENCODER_IN_MAGIC = 0, |
113 | | ENCODER_IN_METADATA = 1, |
114 | | ENCODER_IN_AUDIO = 2 |
115 | | } EncoderStateHint; |
116 | | |
117 | | static const struct CompressionLevels { |
118 | | FLAC__bool do_mid_side_stereo; |
119 | | FLAC__bool loose_mid_side_stereo; |
120 | | uint32_t max_lpc_order; |
121 | | uint32_t qlp_coeff_precision; |
122 | | FLAC__bool do_qlp_coeff_prec_search; |
123 | | FLAC__bool do_escape_coding; |
124 | | FLAC__bool do_exhaustive_model_search; |
125 | | uint32_t min_residual_partition_order; |
126 | | uint32_t max_residual_partition_order; |
127 | | uint32_t rice_parameter_search_dist; |
128 | | const char *apodization; |
129 | | } compression_levels_[] = { |
130 | | { false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, |
131 | | { true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, |
132 | | { true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, |
133 | | { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, |
134 | | { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, |
135 | | { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" }, |
136 | | { true , false, 8, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" }, |
137 | | { true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" }, |
138 | | { true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(3)" } |
139 | | /* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */ |
140 | | }; |
141 | | |
142 | | /*********************************************************************** |
143 | | * |
144 | | * Thread-private data |
145 | | * |
146 | | ***********************************************************************/ |
147 | | |
148 | | |
149 | | typedef struct FLAC__StreamEncoderThreadTask { |
150 | | FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */ |
151 | | FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */ |
152 | | FLAC__int64 *integer_signal_33bit_side; /* 33-bit side for 32-bit stereo decorrelation */ |
153 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
154 | | FLAC__real *windowed_signal; /* the integer_signal[] * current window[] */ |
155 | | #endif |
156 | | uint32_t subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */ |
157 | | uint32_t subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */ |
158 | | FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */ |
159 | | FLAC__int32 *residual_workspace_mid_side[2][2]; |
160 | | FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2]; |
161 | | FLAC__Subframe subframe_workspace_mid_side[2][2]; |
162 | | FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2]; |
163 | | FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2]; |
164 | | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2]; |
165 | | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2]; |
166 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2]; |
167 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2]; |
168 | | uint32_t best_subframe[FLAC__MAX_CHANNELS]; /* index (0 or 1) into 2nd dimension of the above workspaces */ |
169 | | uint32_t best_subframe_mid_side[2]; |
170 | | uint32_t best_subframe_bits[FLAC__MAX_CHANNELS]; /* size in bits of the best subframe for each channel */ |
171 | | uint32_t best_subframe_bits_mid_side[2]; |
172 | | FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ |
173 | | uint32_t *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ |
174 | | FLAC__BitWriter *frame; /* the current frame being worked on */ |
175 | | uint32_t current_frame_number; |
176 | | /* unaligned (original) pointers to allocated data */ |
177 | | FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS]; |
178 | | FLAC__int32 *integer_signal_mid_side_unaligned[2]; |
179 | | FLAC__int64 *integer_signal_33bit_side_unaligned; |
180 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
181 | | FLAC__real *windowed_signal_unaligned; |
182 | | #endif |
183 | | FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2]; |
184 | | FLAC__int32 *residual_workspace_mid_side_unaligned[2][2]; |
185 | | FLAC__uint64 *abs_residual_partition_sums_unaligned; |
186 | | uint32_t *raw_bits_per_partition_unaligned; |
187 | | /* |
188 | | * These fields have been moved here from private function local |
189 | | * declarations merely to save stack space during encoding. |
190 | | */ |
191 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
192 | | FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */ |
193 | | #endif |
194 | | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */ |
195 | | FLAC__bool disable_constant_subframes; |
196 | | #ifdef FLAC__USE_THREADS |
197 | | FLAC__mtx_t mutex_this_task; /* To lock whole threadtask */ |
198 | | FLAC__cnd_t cond_task_done; |
199 | | FLAC__bool task_done; |
200 | | FLAC__bool returnvalue; |
201 | | #endif |
202 | | } FLAC__StreamEncoderThreadTask; |
203 | | |
204 | | /*********************************************************************** |
205 | | * |
206 | | * Private class method prototypes |
207 | | * |
208 | | ***********************************************************************/ |
209 | | |
210 | | static void set_defaults_(FLAC__StreamEncoder *encoder); |
211 | | static void free_(FLAC__StreamEncoder *encoder); |
212 | | static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize); |
213 | | static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderThreadTask *threadtask, uint32_t samples, FLAC__bool is_last_block); |
214 | | static FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, FLAC__bool is_last_block); |
215 | | static void update_metadata_(const FLAC__StreamEncoder *encoder); |
216 | | #if FLAC__HAS_OGG |
217 | | static void update_ogg_metadata_(FLAC__StreamEncoder *encoder); |
218 | | #endif |
219 | | static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block); |
220 | | #ifdef FLAC__USE_THREADS |
221 | | FLAC__thread_return_type process_frame_thread_(void * encoder); |
222 | | #endif |
223 | | FLAC__bool process_frame_thread_inner_(FLAC__StreamEncoder * encoder, FLAC__StreamEncoderThreadTask *threadtask); |
224 | | static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderThreadTask *threadtask); |
225 | | |
226 | | static FLAC__bool process_subframe_( |
227 | | FLAC__StreamEncoder *encoder, |
228 | | FLAC__StreamEncoderThreadTask *threadtask, |
229 | | uint32_t min_partition_order, |
230 | | uint32_t max_partition_order, |
231 | | const FLAC__FrameHeader *frame_header, |
232 | | uint32_t subframe_bps, |
233 | | const void *integer_signal, |
234 | | FLAC__Subframe *subframe[2], |
235 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], |
236 | | FLAC__int32 *residual[2], |
237 | | uint32_t *best_subframe, |
238 | | uint32_t *best_bits |
239 | | ); |
240 | | |
241 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
242 | | static FLAC__bool apply_apodization_( |
243 | | FLAC__StreamEncoder *encoder, |
244 | | FLAC__StreamEncoderThreadTask *threadtask, |
245 | | apply_apodization_state_struct *apply_apodization_state, |
246 | | uint32_t blocksize, |
247 | | double *lpc_error, |
248 | | uint32_t *max_lpc_order_this_apodization, |
249 | | uint32_t subframe_bps, |
250 | | const void *integer_signal, |
251 | | uint32_t *guess_lpc_order |
252 | | ); |
253 | | #endif |
254 | | |
255 | | static FLAC__bool add_subframe_( |
256 | | FLAC__StreamEncoder *encoder, |
257 | | uint32_t blocksize, |
258 | | uint32_t subframe_bps, |
259 | | const FLAC__Subframe *subframe, |
260 | | FLAC__BitWriter *frame |
261 | | ); |
262 | | |
263 | | static uint32_t evaluate_constant_subframe_( |
264 | | FLAC__StreamEncoder *encoder, |
265 | | const FLAC__int64 signal, |
266 | | uint32_t blocksize, |
267 | | uint32_t subframe_bps, |
268 | | FLAC__Subframe *subframe |
269 | | ); |
270 | | |
271 | | static uint32_t evaluate_fixed_subframe_( |
272 | | FLAC__StreamEncoder *encoder, |
273 | | FLAC__StreamEncoderThreadTask *threadtask, |
274 | | const void *signal, |
275 | | FLAC__int32 residual[], |
276 | | FLAC__uint64 abs_residual_partition_sums[], |
277 | | uint32_t raw_bits_per_partition[], |
278 | | uint32_t blocksize, |
279 | | uint32_t subframe_bps, |
280 | | uint32_t order, |
281 | | uint32_t rice_parameter_limit, |
282 | | uint32_t min_partition_order, |
283 | | uint32_t max_partition_order, |
284 | | FLAC__bool do_escape_coding, |
285 | | uint32_t rice_parameter_search_dist, |
286 | | FLAC__Subframe *subframe, |
287 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents |
288 | | ); |
289 | | |
290 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
291 | | static uint32_t evaluate_lpc_subframe_( |
292 | | FLAC__StreamEncoder *encoder, |
293 | | FLAC__StreamEncoderThreadTask *threadtask, |
294 | | const void *signal, |
295 | | FLAC__int32 residual[], |
296 | | FLAC__uint64 abs_residual_partition_sums[], |
297 | | uint32_t raw_bits_per_partition[], |
298 | | const FLAC__real lp_coeff[], |
299 | | uint32_t blocksize, |
300 | | uint32_t subframe_bps, |
301 | | uint32_t order, |
302 | | uint32_t qlp_coeff_precision, |
303 | | uint32_t rice_parameter_limit, |
304 | | uint32_t min_partition_order, |
305 | | uint32_t max_partition_order, |
306 | | FLAC__bool do_escape_coding, |
307 | | uint32_t rice_parameter_search_dist, |
308 | | FLAC__Subframe *subframe, |
309 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents |
310 | | ); |
311 | | #endif |
312 | | |
313 | | static uint32_t evaluate_verbatim_subframe_( |
314 | | FLAC__StreamEncoder *encoder, |
315 | | const void *signal, |
316 | | uint32_t blocksize, |
317 | | uint32_t subframe_bps, |
318 | | FLAC__Subframe *subframe |
319 | | ); |
320 | | |
321 | | static uint32_t find_best_partition_order_( |
322 | | struct FLAC__StreamEncoderPrivate *private_, |
323 | | FLAC__StreamEncoderThreadTask *threadtask, |
324 | | const FLAC__int32 residual[], |
325 | | FLAC__uint64 abs_residual_partition_sums[], |
326 | | uint32_t raw_bits_per_partition[], |
327 | | uint32_t residual_samples, |
328 | | uint32_t predictor_order, |
329 | | uint32_t rice_parameter_limit, |
330 | | uint32_t min_partition_order, |
331 | | uint32_t max_partition_order, |
332 | | uint32_t bps, |
333 | | FLAC__bool do_escape_coding, |
334 | | uint32_t rice_parameter_search_dist, |
335 | | FLAC__EntropyCodingMethod *best_ecm |
336 | | ); |
337 | | |
338 | | static void precompute_partition_info_sums_( |
339 | | const FLAC__int32 residual[], |
340 | | FLAC__uint64 abs_residual_partition_sums[], |
341 | | uint32_t residual_samples, |
342 | | uint32_t predictor_order, |
343 | | uint32_t min_partition_order, |
344 | | uint32_t max_partition_order, |
345 | | uint32_t bps |
346 | | ); |
347 | | |
348 | | static void precompute_partition_info_escapes_( |
349 | | const FLAC__int32 residual[], |
350 | | uint32_t raw_bits_per_partition[], |
351 | | uint32_t residual_samples, |
352 | | uint32_t predictor_order, |
353 | | uint32_t min_partition_order, |
354 | | uint32_t max_partition_order |
355 | | ); |
356 | | |
357 | | static FLAC__bool set_partitioned_rice_( |
358 | | #ifdef EXACT_RICE_BITS_CALCULATION |
359 | | const FLAC__int32 residual[], |
360 | | #endif |
361 | | const FLAC__uint64 abs_residual_partition_sums[], |
362 | | const uint32_t raw_bits_per_partition[], |
363 | | const uint32_t residual_samples, |
364 | | const uint32_t predictor_order, |
365 | | const uint32_t rice_parameter_limit, |
366 | | const uint32_t rice_parameter_search_dist, |
367 | | const uint32_t partition_order, |
368 | | const FLAC__bool search_for_escapes, |
369 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, |
370 | | uint32_t *bits |
371 | | ); |
372 | | |
373 | | static uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples); |
374 | | static uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples); |
375 | | |
376 | | /* verify-related routines: */ |
377 | | static void append_to_verify_fifo_( |
378 | | verify_input_fifo *fifo, |
379 | | const FLAC__int32 * const input[], |
380 | | uint32_t input_offset, |
381 | | uint32_t channels, |
382 | | uint32_t wide_samples |
383 | | ); |
384 | | |
385 | | static void append_to_verify_fifo_interleaved_( |
386 | | verify_input_fifo *fifo, |
387 | | const FLAC__int32 input[], |
388 | | uint32_t input_offset, |
389 | | uint32_t channels, |
390 | | uint32_t wide_samples |
391 | | ); |
392 | | |
393 | | static FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); |
394 | | static FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); |
395 | | static void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); |
396 | | static void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); |
397 | | |
398 | | static FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); |
399 | | static FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); |
400 | | static FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); |
401 | | static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data); |
402 | | static FILE *get_binary_stdout_(void); |
403 | | |
404 | | |
405 | | /*********************************************************************** |
406 | | * |
407 | | * Private class data |
408 | | * |
409 | | ***********************************************************************/ |
410 | | |
411 | | typedef struct FLAC__StreamEncoderPrivate { |
412 | | FLAC__StreamEncoderThreadTask * threadtask[FLAC__STREAM_ENCODER_MAX_THREADTASKS]; |
413 | | #ifdef FLAC__USE_THREADS |
414 | | FLAC__thrd_t thread[FLAC__STREAM_ENCODER_MAX_THREADS]; |
415 | | #endif |
416 | | uint32_t input_capacity; /* current size (in samples) of the signal and residual buffers */ |
417 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
418 | | FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */ |
419 | | FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS]; |
420 | | #endif |
421 | | FLAC__StreamMetadata streaminfo; /* scratchpad for STREAMINFO as it is built */ |
422 | | FLAC__StreamMetadata_SeekTable *seek_table; /* pointer into encoder->protected_->metadata_ where the seek table is */ |
423 | | uint32_t current_sample_number; |
424 | | uint32_t current_frame_number; |
425 | | FLAC__MD5Context md5context; |
426 | | FLAC__CPUInfo cpuinfo; |
427 | | void (*local_precompute_partition_info_sums)(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], uint32_t residual_samples, uint32_t predictor_order, uint32_t min_partition_order, uint32_t max_partition_order, uint32_t bps); |
428 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
429 | | uint32_t (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
430 | | uint32_t (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
431 | | uint32_t (*local_fixed_compute_best_predictor_limit_residual)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
432 | | #else |
433 | | uint32_t (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
434 | | uint32_t (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
435 | | uint32_t (*local_fixed_compute_best_predictor_limit_residual)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); |
436 | | #endif |
437 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
438 | | void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); |
439 | | void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); |
440 | | void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); |
441 | | void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); |
442 | | #endif |
443 | | FLAC__bool disable_mmx; |
444 | | FLAC__bool disable_sse2; |
445 | | FLAC__bool disable_ssse3; |
446 | | FLAC__bool disable_sse41; |
447 | | FLAC__bool disable_sse42; |
448 | | FLAC__bool disable_avx2; |
449 | | FLAC__bool disable_fma; |
450 | | FLAC__bool disable_constant_subframes; |
451 | | FLAC__bool disable_fixed_subframes; |
452 | | FLAC__bool disable_verbatim_subframes; |
453 | | FLAC__bool is_ogg; |
454 | | FLAC__StreamEncoderReadCallback read_callback; /* currently only needed for Ogg FLAC */ |
455 | | FLAC__StreamEncoderSeekCallback seek_callback; |
456 | | FLAC__StreamEncoderTellCallback tell_callback; |
457 | | FLAC__StreamEncoderWriteCallback write_callback; |
458 | | FLAC__StreamEncoderMetadataCallback metadata_callback; |
459 | | FLAC__StreamEncoderProgressCallback progress_callback; |
460 | | void *client_data; |
461 | | uint32_t first_seekpoint_to_check; |
462 | | FILE *file; /* only used when encoding to a file */ |
463 | | FLAC__uint64 bytes_written; |
464 | | FLAC__uint64 samples_written; |
465 | | uint32_t frames_written; |
466 | | uint32_t total_frames_estimate; |
467 | | /* |
468 | | * The data for the verify section |
469 | | */ |
470 | | struct { |
471 | | FLAC__StreamDecoder *decoder; |
472 | | EncoderStateHint state_hint; |
473 | | FLAC__bool needs_magic_hack; |
474 | | verify_input_fifo input_fifo; |
475 | | verify_output output; |
476 | | struct { |
477 | | FLAC__uint64 absolute_sample; |
478 | | uint32_t frame_number; |
479 | | uint32_t channel; |
480 | | uint32_t sample; |
481 | | FLAC__int32 expected; |
482 | | FLAC__int32 got; |
483 | | } error_stats; |
484 | | } verify; |
485 | | FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */ |
486 | | uint32_t num_threadtasks; |
487 | | #ifdef FLAC__USE_THREADS |
488 | | uint32_t num_created_threads; |
489 | | uint32_t next_thread; /* This is the next thread that needs start, or needs to finish and be restarted */ |
490 | | uint32_t num_started_threadtasks; |
491 | | uint32_t num_available_threadtasks; /* Number of threadtasks that are available to work on */ |
492 | | uint32_t num_running_threads; |
493 | | uint32_t next_threadtask; /* Next threadtask that is available to work on */ |
494 | | FLAC__mtx_t mutex_md5_fifo; |
495 | | FLAC__mtx_t mutex_work_queue; /* To lock work related variables in this struct */ |
496 | | FLAC__cnd_t cond_md5_emptied; /* To signal to main thread that MD5 queue has been emptied */ |
497 | | FLAC__cnd_t cond_work_available; /* To signal to threads that work is available */ |
498 | | FLAC__cnd_t cond_wake_up_thread; /* To signal that one sleeping thread can wake up */ |
499 | | FLAC__bool md5_active; |
500 | | FLAC__bool finish_work_threads; |
501 | | int32_t overcommitted_indicator; |
502 | | verify_input_fifo md5_fifo; |
503 | | #endif |
504 | | } FLAC__StreamEncoderPrivate; |
505 | | |
506 | | /*********************************************************************** |
507 | | * |
508 | | * Public static class data |
509 | | * |
510 | | ***********************************************************************/ |
511 | | |
512 | | FLAC_API const char * const FLAC__StreamEncoderStateString[] = { |
513 | | "FLAC__STREAM_ENCODER_OK", |
514 | | "FLAC__STREAM_ENCODER_UNINITIALIZED", |
515 | | "FLAC__STREAM_ENCODER_OGG_ERROR", |
516 | | "FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR", |
517 | | "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA", |
518 | | "FLAC__STREAM_ENCODER_CLIENT_ERROR", |
519 | | "FLAC__STREAM_ENCODER_IO_ERROR", |
520 | | "FLAC__STREAM_ENCODER_FRAMING_ERROR", |
521 | | "FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR" |
522 | | }; |
523 | | |
524 | | FLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = { |
525 | | "FLAC__STREAM_ENCODER_INIT_STATUS_OK", |
526 | | "FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR", |
527 | | "FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER", |
528 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS", |
529 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS", |
530 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE", |
531 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE", |
532 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE", |
533 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER", |
534 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION", |
535 | | "FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER", |
536 | | "FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE", |
537 | | "FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA", |
538 | | "FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED" |
539 | | }; |
540 | | |
541 | | FLAC_API const char * const FLAC__StreamEncoderReadStatusString[] = { |
542 | | "FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE", |
543 | | "FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM", |
544 | | "FLAC__STREAM_ENCODER_READ_STATUS_ABORT", |
545 | | "FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED" |
546 | | }; |
547 | | |
548 | | FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = { |
549 | | "FLAC__STREAM_ENCODER_WRITE_STATUS_OK", |
550 | | "FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR" |
551 | | }; |
552 | | |
553 | | FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[] = { |
554 | | "FLAC__STREAM_ENCODER_SEEK_STATUS_OK", |
555 | | "FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR", |
556 | | "FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED" |
557 | | }; |
558 | | |
559 | | FLAC_API const char * const FLAC__StreamEncoderTellStatusString[] = { |
560 | | "FLAC__STREAM_ENCODER_TELL_STATUS_OK", |
561 | | "FLAC__STREAM_ENCODER_TELL_STATUS_ERROR", |
562 | | "FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED" |
563 | | }; |
564 | | |
565 | | /* Number of samples that will be overread to watch for end of stream. By |
566 | | * 'overread', we mean that the FLAC__stream_encoder_process*() calls will |
567 | | * always try to read blocksize+1 samples before encoding a block, so that |
568 | | * even if the stream has a total sample count that is an integral multiple |
569 | | * of the blocksize, we will still notice when we are encoding the last |
570 | | * block. This is needed, for example, to correctly set the end-of-stream |
571 | | * marker in Ogg FLAC. |
572 | | * |
573 | | * WATCHOUT: some parts of the code assert that OVERREAD_ == 1 and there's |
574 | | * not really any reason to change it. |
575 | | */ |
576 | | static const uint32_t OVERREAD_ = 1; |
577 | | |
578 | | /*********************************************************************** |
579 | | * |
580 | | * Class constructor/destructor |
581 | | * |
582 | | */ |
583 | | FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) |
584 | 12.0k | { |
585 | 12.0k | FLAC__StreamEncoder *encoder; |
586 | 12.0k | uint32_t i; |
587 | | |
588 | 12.0k | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ |
589 | | |
590 | 12.0k | encoder = safe_calloc_(1, sizeof(FLAC__StreamEncoder)); |
591 | 12.0k | if(encoder == 0) { |
592 | 0 | return 0; |
593 | 0 | } |
594 | | |
595 | 12.0k | encoder->protected_ = safe_calloc_(1, sizeof(FLAC__StreamEncoderProtected)); |
596 | 12.0k | if(encoder->protected_ == 0) { |
597 | 0 | free(encoder); |
598 | 0 | return 0; |
599 | 0 | } |
600 | | |
601 | 12.0k | encoder->private_ = safe_calloc_(1, sizeof(FLAC__StreamEncoderPrivate)); |
602 | 12.0k | if(encoder->private_ == 0) { |
603 | 0 | free(encoder->protected_); |
604 | 0 | free(encoder); |
605 | 0 | return 0; |
606 | 0 | } |
607 | | |
608 | 12.0k | encoder->private_->threadtask[0] = safe_calloc_(1, sizeof(FLAC__StreamEncoderThreadTask)); |
609 | 12.0k | if(encoder->private_->threadtask[0] == 0) { |
610 | 0 | free(encoder->private_); |
611 | 0 | free(encoder->protected_); |
612 | 0 | free(encoder); |
613 | 0 | return 0; |
614 | 0 | } |
615 | | |
616 | 12.0k | encoder->private_->threadtask[0]->frame = FLAC__bitwriter_new(); |
617 | 12.0k | if(encoder->private_->threadtask[0]->frame == 0) { |
618 | 0 | free(encoder->private_->threadtask[0]); |
619 | 0 | free(encoder->private_); |
620 | 0 | free(encoder->protected_); |
621 | 0 | free(encoder); |
622 | 0 | return 0; |
623 | 0 | } |
624 | | |
625 | 12.0k | encoder->private_->file = 0; |
626 | | |
627 | 12.0k | encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; |
628 | | |
629 | 12.0k | set_defaults_(encoder); |
630 | | |
631 | 12.0k | encoder->private_->is_being_deleted = false; |
632 | | |
633 | 108k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
634 | 96.6k | encoder->private_->threadtask[0]->subframe_workspace_ptr[i][0] = &encoder->private_->threadtask[0]->subframe_workspace[i][0]; |
635 | 96.6k | encoder->private_->threadtask[0]->subframe_workspace_ptr[i][1] = &encoder->private_->threadtask[0]->subframe_workspace[i][1]; |
636 | 96.6k | } |
637 | 36.2k | for(i = 0; i < 2; i++) { |
638 | 24.1k | encoder->private_->threadtask[0]->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->threadtask[0]->subframe_workspace_mid_side[i][0]; |
639 | 24.1k | encoder->private_->threadtask[0]->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->threadtask[0]->subframe_workspace_mid_side[i][1]; |
640 | 24.1k | } |
641 | 108k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
642 | 96.6k | encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][0]; |
643 | 96.6k | encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][1]; |
644 | 96.6k | } |
645 | 36.2k | for(i = 0; i < 2; i++) { |
646 | 24.1k | encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][0]; |
647 | 24.1k | encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][1]; |
648 | 24.1k | } |
649 | | |
650 | 108k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
651 | 96.6k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][0]); |
652 | 96.6k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][1]); |
653 | 96.6k | } |
654 | 36.2k | for(i = 0; i < 2; i++) { |
655 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][0]); |
656 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][1]); |
657 | 24.1k | } |
658 | 36.2k | for(i = 0; i < 2; i++) |
659 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[0]->partitioned_rice_contents_extra[i]); |
660 | | |
661 | 12.0k | return encoder; |
662 | 12.0k | } |
663 | | |
664 | | FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) |
665 | 12.0k | { |
666 | 12.0k | uint32_t i; |
667 | | |
668 | 12.0k | if (encoder == NULL) |
669 | 0 | return ; |
670 | | |
671 | 12.0k | FLAC__ASSERT(0 != encoder->protected_); |
672 | 12.0k | FLAC__ASSERT(0 != encoder->private_); |
673 | 12.0k | FLAC__ASSERT(0 != encoder->private_->threadtask[0]); |
674 | 12.0k | FLAC__ASSERT(0 != encoder->private_->threadtask[0]->frame); |
675 | | |
676 | 12.0k | encoder->private_->is_being_deleted = true; |
677 | | |
678 | 12.0k | (void)FLAC__stream_encoder_finish(encoder); |
679 | | |
680 | 12.0k | if(0 != encoder->private_->verify.decoder) |
681 | 8.56k | FLAC__stream_decoder_delete(encoder->private_->verify.decoder); |
682 | | |
683 | 108k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
684 | 96.6k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][0]); |
685 | 96.6k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace[i][1]); |
686 | 96.6k | } |
687 | 36.2k | for(i = 0; i < 2; i++) { |
688 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][0]); |
689 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[0]->partitioned_rice_contents_workspace_mid_side[i][1]); |
690 | 24.1k | } |
691 | 36.2k | for(i = 0; i < 2; i++) |
692 | 24.1k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[0]->partitioned_rice_contents_extra[i]); |
693 | | |
694 | 12.0k | FLAC__bitwriter_delete(encoder->private_->threadtask[0]->frame); |
695 | 12.0k | free(encoder->private_->threadtask[0]); |
696 | 12.0k | free(encoder->private_); |
697 | 12.0k | free(encoder->protected_); |
698 | 12.0k | free(encoder); |
699 | 12.0k | } |
700 | | |
701 | | /*********************************************************************** |
702 | | * |
703 | | * Public class methods |
704 | | * |
705 | | ***********************************************************************/ |
706 | | |
707 | | static FLAC__StreamEncoderInitStatus init_stream_internal_( |
708 | | FLAC__StreamEncoder *encoder, |
709 | | FLAC__StreamEncoderReadCallback read_callback, |
710 | | FLAC__StreamEncoderWriteCallback write_callback, |
711 | | FLAC__StreamEncoderSeekCallback seek_callback, |
712 | | FLAC__StreamEncoderTellCallback tell_callback, |
713 | | FLAC__StreamEncoderMetadataCallback metadata_callback, |
714 | | void *client_data, |
715 | | FLAC__bool is_ogg |
716 | | ) |
717 | 10.0k | { |
718 | 10.0k | uint32_t i, t; |
719 | 10.0k | FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment, metadata_picture_has_type1, metadata_picture_has_type2; |
720 | | |
721 | 10.0k | FLAC__ASSERT(0 != encoder); |
722 | | |
723 | 10.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
724 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; |
725 | | |
726 | 10.0k | if(FLAC__HAS_OGG == 0 && is_ogg) |
727 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER; |
728 | | |
729 | 10.0k | if(0 == write_callback || (seek_callback && 0 == tell_callback)) |
730 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS; |
731 | | |
732 | 10.0k | if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS) |
733 | 14 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS; |
734 | | |
735 | 10.0k | if(encoder->protected_->channels != 2) { |
736 | 6.79k | encoder->protected_->do_mid_side_stereo = false; |
737 | 6.79k | encoder->protected_->loose_mid_side_stereo = false; |
738 | 6.79k | } |
739 | 3.20k | else if(!encoder->protected_->do_mid_side_stereo) |
740 | 92 | encoder->protected_->loose_mid_side_stereo = false; |
741 | | |
742 | 10.0k | if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE) |
743 | 6 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE; |
744 | | |
745 | 10.0k | if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate)) |
746 | 28 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE; |
747 | | |
748 | 9.97k | if(encoder->protected_->blocksize == 0) { |
749 | 740 | if(encoder->protected_->max_lpc_order == 0) |
750 | 134 | encoder->protected_->blocksize = 1152; |
751 | 606 | else |
752 | 606 | encoder->protected_->blocksize = 4096; |
753 | 740 | } |
754 | | |
755 | 9.97k | if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE) |
756 | 4 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE; |
757 | | |
758 | 9.96k | if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER) |
759 | 3 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER; |
760 | | |
761 | 9.96k | if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order) |
762 | 1 | return FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER; |
763 | | |
764 | 9.96k | if(encoder->protected_->qlp_coeff_precision == 0) { |
765 | 7.46k | if(encoder->protected_->bits_per_sample < 16) { |
766 | | /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ |
767 | | /* @@@ until then we'll make a guess */ |
768 | 600 | encoder->protected_->qlp_coeff_precision = flac_max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); |
769 | 600 | } |
770 | 6.86k | else if(encoder->protected_->bits_per_sample == 16) { |
771 | 545 | if(encoder->protected_->blocksize <= 192) |
772 | 198 | encoder->protected_->qlp_coeff_precision = 7; |
773 | 347 | else if(encoder->protected_->blocksize <= 384) |
774 | 27 | encoder->protected_->qlp_coeff_precision = 8; |
775 | 320 | else if(encoder->protected_->blocksize <= 576) |
776 | 10 | encoder->protected_->qlp_coeff_precision = 9; |
777 | 310 | else if(encoder->protected_->blocksize <= 1152) |
778 | 27 | encoder->protected_->qlp_coeff_precision = 10; |
779 | 283 | else if(encoder->protected_->blocksize <= 2304) |
780 | 23 | encoder->protected_->qlp_coeff_precision = 11; |
781 | 260 | else if(encoder->protected_->blocksize <= 4608) |
782 | 69 | encoder->protected_->qlp_coeff_precision = 12; |
783 | 191 | else |
784 | 191 | encoder->protected_->qlp_coeff_precision = 13; |
785 | 545 | } |
786 | 6.31k | else { |
787 | 6.31k | if(encoder->protected_->blocksize <= 384) |
788 | 2.20k | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2; |
789 | 4.10k | else if(encoder->protected_->blocksize <= 1152) |
790 | 296 | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1; |
791 | 3.81k | else |
792 | 3.81k | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; |
793 | 6.31k | } |
794 | 7.46k | FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION); |
795 | 7.46k | } |
796 | 2.50k | else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION) |
797 | 50 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION; |
798 | | |
799 | 9.91k | if(encoder->protected_->streamable_subset) { |
800 | 703 | if(!FLAC__format_blocksize_is_subset(encoder->protected_->blocksize, encoder->protected_->sample_rate)) |
801 | 21 | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; |
802 | 682 | if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate)) |
803 | 41 | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; |
804 | 641 | if( |
805 | 641 | encoder->protected_->bits_per_sample != 8 && |
806 | 607 | encoder->protected_->bits_per_sample != 12 && |
807 | 598 | encoder->protected_->bits_per_sample != 16 && |
808 | 507 | encoder->protected_->bits_per_sample != 20 && |
809 | 502 | encoder->protected_->bits_per_sample != 24 && |
810 | 456 | encoder->protected_->bits_per_sample != 32 |
811 | 641 | ) |
812 | 15 | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; |
813 | 626 | if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER) |
814 | 58 | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; |
815 | 568 | if( |
816 | 568 | encoder->protected_->sample_rate <= 48000 && |
817 | 223 | ( |
818 | 223 | encoder->protected_->blocksize > FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ || |
819 | 223 | encoder->protected_->max_lpc_order > FLAC__SUBSET_MAX_LPC_ORDER_48000HZ |
820 | 223 | ) |
821 | 568 | ) { |
822 | 6 | return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; |
823 | 6 | } |
824 | 568 | } |
825 | | |
826 | 9.77k | if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) |
827 | 7.12k | encoder->protected_->max_residual_partition_order = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1; |
828 | 9.77k | if(encoder->protected_->min_residual_partition_order >= encoder->protected_->max_residual_partition_order) |
829 | 8.95k | encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order; |
830 | | |
831 | 9.77k | #if FLAC__HAS_OGG |
832 | | /* drop any seektable for ogg */ |
833 | 9.77k | if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { |
834 | 0 | uint32_t i1; |
835 | 0 | for(i1 = 0; i1 < encoder->protected_->num_metadata_blocks; i1++) { |
836 | 0 | if(0 != encoder->protected_->metadata[i1] && encoder->protected_->metadata[i1]->type == FLAC__METADATA_TYPE_SEEKTABLE) { |
837 | 0 | encoder->protected_->num_metadata_blocks--; |
838 | 0 | for( ; i1 < encoder->protected_->num_metadata_blocks; i1++) |
839 | 0 | encoder->protected_->metadata[i1] = encoder->protected_->metadata[i1+1]; |
840 | 0 | break; |
841 | 0 | } |
842 | 0 | } |
843 | 0 | } |
844 | | /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */ |
845 | 9.77k | if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) { |
846 | 0 | uint32_t i1; |
847 | 0 | for(i1 = 1; i1 < encoder->protected_->num_metadata_blocks; i1++) { |
848 | 0 | if(0 != encoder->protected_->metadata[i1] && encoder->protected_->metadata[i1]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { |
849 | 0 | FLAC__StreamMetadata *vc = encoder->protected_->metadata[i1]; |
850 | 0 | for( ; i1 > 0; i1--) |
851 | 0 | encoder->protected_->metadata[i1] = encoder->protected_->metadata[i1-1]; |
852 | 0 | encoder->protected_->metadata[0] = vc; |
853 | 0 | break; |
854 | 0 | } |
855 | 0 | } |
856 | 0 | } |
857 | 9.77k | #endif |
858 | | /* keep track of any SEEKTABLE block */ |
859 | 9.77k | if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { |
860 | 0 | uint32_t i2; |
861 | 0 | for(i2 = 0; i2 < encoder->protected_->num_metadata_blocks; i2++) { |
862 | 0 | if(0 != encoder->protected_->metadata[i2] && encoder->protected_->metadata[i2]->type == FLAC__METADATA_TYPE_SEEKTABLE) { |
863 | 0 | encoder->private_->seek_table = &encoder->protected_->metadata[i2]->data.seek_table; |
864 | 0 | break; /* take only the first one */ |
865 | 0 | } |
866 | 0 | } |
867 | 0 | } |
868 | | |
869 | | /* validate metadata */ |
870 | 9.77k | if(0 == encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) |
871 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
872 | 9.77k | metadata_has_seektable = false; |
873 | 9.77k | metadata_has_vorbis_comment = false; |
874 | 9.77k | metadata_picture_has_type1 = false; |
875 | 9.77k | metadata_picture_has_type2 = false; |
876 | 9.77k | for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { |
877 | 0 | const FLAC__StreamMetadata *m = encoder->protected_->metadata[i]; |
878 | 0 | if(m->type == FLAC__METADATA_TYPE_STREAMINFO) |
879 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
880 | 0 | else if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) { |
881 | 0 | if(metadata_has_seektable) /* only one is allowed */ |
882 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
883 | 0 | metadata_has_seektable = true; |
884 | 0 | if(!FLAC__format_seektable_is_legal(&m->data.seek_table)) |
885 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
886 | 0 | } |
887 | 0 | else if(m->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { |
888 | 0 | if(metadata_has_vorbis_comment) /* only one is allowed */ |
889 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
890 | 0 | metadata_has_vorbis_comment = true; |
891 | 0 | } |
892 | 0 | else if(m->type == FLAC__METADATA_TYPE_CUESHEET) { |
893 | 0 | if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0)) |
894 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
895 | 0 | } |
896 | 0 | else if(m->type == FLAC__METADATA_TYPE_PICTURE) { |
897 | 0 | if(!FLAC__format_picture_is_legal(&m->data.picture, /*violation=*/0)) |
898 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
899 | 0 | if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) { |
900 | 0 | if(metadata_picture_has_type1) /* there should only be 1 per stream */ |
901 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
902 | 0 | metadata_picture_has_type1 = true; |
903 | | /* standard icon must be 32x32 pixel PNG */ |
904 | 0 | if( |
905 | 0 | m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD && |
906 | 0 | ( |
907 | 0 | (strcmp(m->data.picture.mime_type, "image/png") && strcmp(m->data.picture.mime_type, "-->")) || |
908 | 0 | m->data.picture.width != 32 || |
909 | 0 | m->data.picture.height != 32 |
910 | 0 | ) |
911 | 0 | ) |
912 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
913 | 0 | } |
914 | 0 | else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) { |
915 | 0 | if(metadata_picture_has_type2) /* there should only be 1 per stream */ |
916 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA; |
917 | 0 | metadata_picture_has_type2 = true; |
918 | 0 | } |
919 | 0 | } |
920 | 0 | } |
921 | | |
922 | 9.77k | encoder->private_->input_capacity = 0; |
923 | 9.77k | encoder->private_->current_sample_number = 0; |
924 | 9.77k | encoder->private_->current_frame_number = 0; |
925 | | |
926 | | /* |
927 | | * get the CPU info and set the function pointers |
928 | | */ |
929 | 9.77k | FLAC__cpu_info(&encoder->private_->cpuinfo); |
930 | | /* remove cpu info as requested by |
931 | | * FLAC__stream_encoder_disable_instruction_set */ |
932 | 9.77k | if(encoder->private_->disable_mmx) |
933 | 0 | encoder->private_->cpuinfo.x86.mmx = false; |
934 | 9.77k | if(encoder->private_->disable_sse2) |
935 | 0 | encoder->private_->cpuinfo.x86.sse2 = false; |
936 | 9.77k | if(encoder->private_->disable_ssse3) |
937 | 0 | encoder->private_->cpuinfo.x86.ssse3 = false; |
938 | 9.77k | if(encoder->private_->disable_sse41) |
939 | 0 | encoder->private_->cpuinfo.x86.sse41 = false; |
940 | 9.77k | if(encoder->private_->disable_sse42) |
941 | 0 | encoder->private_->cpuinfo.x86.sse42 = false; |
942 | 9.77k | if(encoder->private_->disable_avx2) |
943 | 0 | encoder->private_->cpuinfo.x86.avx2 = false; |
944 | 9.77k | if(encoder->private_->disable_fma) |
945 | 0 | encoder->private_->cpuinfo.x86.fma = false; |
946 | | /* first default to the non-asm routines */ |
947 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
948 | 9.77k | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; |
949 | 9.77k | #endif |
950 | 9.77k | encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_; |
951 | 9.77k | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; |
952 | 9.77k | encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide; |
953 | 9.77k | encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual; |
954 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
955 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; |
956 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; |
957 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients; |
958 | 9.77k | #endif |
959 | | /* now override with asm where appropriate */ |
960 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
961 | 9.77k | # ifndef FLAC__NO_ASM |
962 | | #if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN |
963 | | #if FLAC__HAS_A64NEONINTRIN |
964 | | if(encoder->protected_->max_lpc_order < 8) |
965 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8; |
966 | | else if(encoder->protected_->max_lpc_order < 10) |
967 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10; |
968 | | else if(encoder->protected_->max_lpc_order < 14) |
969 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14; |
970 | | else |
971 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; |
972 | | #endif |
973 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon; |
974 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon; |
975 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon; |
976 | | #endif /* defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN */ |
977 | | |
978 | 9.77k | if(encoder->private_->cpuinfo.use_asm) { |
979 | | # ifdef FLAC__CPU_IA32 |
980 | | FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); |
981 | | # if FLAC__HAS_X86INTRIN |
982 | | # ifdef FLAC__SSE2_SUPPORTED |
983 | | if (encoder->private_->cpuinfo.x86.sse2) { |
984 | | if(encoder->protected_->max_lpc_order < 8) |
985 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8; |
986 | | else if(encoder->protected_->max_lpc_order < 10) |
987 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10; |
988 | | else if(encoder->protected_->max_lpc_order < 14) |
989 | | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14; |
990 | | |
991 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2; |
992 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; |
993 | | } |
994 | | # endif |
995 | | # ifdef FLAC__SSE4_1_SUPPORTED |
996 | | if (encoder->private_->cpuinfo.x86.sse41) { |
997 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; |
998 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41; |
999 | | } |
1000 | | # endif |
1001 | | # ifdef FLAC__AVX2_SUPPORTED |
1002 | | if (encoder->private_->cpuinfo.x86.avx2) { |
1003 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; |
1004 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; |
1005 | | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; |
1006 | | } |
1007 | | # endif |
1008 | | |
1009 | | # ifdef FLAC__SSE2_SUPPORTED |
1010 | | if (encoder->private_->cpuinfo.x86.sse2) { |
1011 | | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; |
1012 | | } |
1013 | | # endif |
1014 | | # ifdef FLAC__SSSE3_SUPPORTED |
1015 | | if (encoder->private_->cpuinfo.x86.ssse3) { |
1016 | | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; |
1017 | | } |
1018 | | # endif |
1019 | | # ifdef FLAC__SSE4_2_SUPPORTED |
1020 | | if (encoder->private_->cpuinfo.x86.sse42) { |
1021 | | encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_sse42; |
1022 | | } |
1023 | | # endif |
1024 | | # ifdef FLAC__AVX2_SUPPORTED |
1025 | | if (encoder->private_->cpuinfo.x86.avx2) { |
1026 | | encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_avx2; |
1027 | | encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_avx2; |
1028 | | } |
1029 | | # endif |
1030 | | # endif /* FLAC__HAS_X86INTRIN */ |
1031 | | # elif defined FLAC__CPU_X86_64 |
1032 | 9.77k | FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); |
1033 | 9.77k | # if FLAC__HAS_X86INTRIN |
1034 | 9.77k | # ifdef FLAC__SSE2_SUPPORTED |
1035 | 9.77k | if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */ |
1036 | 9.77k | if(encoder->protected_->max_lpc_order < 8) |
1037 | 2.55k | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8; |
1038 | 7.22k | else if(encoder->protected_->max_lpc_order < 10) |
1039 | 455 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10; |
1040 | 6.76k | else if(encoder->protected_->max_lpc_order < 14) |
1041 | 235 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14; |
1042 | | |
1043 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; |
1044 | 9.77k | } |
1045 | 9.77k | # endif |
1046 | 9.77k | # ifdef FLAC__SSE4_1_SUPPORTED |
1047 | 9.77k | if(encoder->private_->cpuinfo.x86.sse41) { |
1048 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; |
1049 | 9.77k | } |
1050 | 9.77k | # endif |
1051 | 9.77k | # ifdef FLAC__AVX2_SUPPORTED |
1052 | 9.77k | if(encoder->private_->cpuinfo.x86.avx2) { |
1053 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; |
1054 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; |
1055 | 9.77k | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; |
1056 | 9.77k | } |
1057 | 9.77k | # endif |
1058 | 9.77k | # ifdef FLAC__FMA_SUPPORTED |
1059 | 9.77k | if(encoder->private_->cpuinfo.x86.fma) { |
1060 | 9.77k | if(encoder->protected_->max_lpc_order < 8) |
1061 | 2.55k | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_8; |
1062 | 7.22k | else if(encoder->protected_->max_lpc_order < 12) |
1063 | 523 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_12; |
1064 | 6.70k | else if(encoder->protected_->max_lpc_order < 16) |
1065 | 2.02k | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_16; |
1066 | 9.77k | } |
1067 | 9.77k | # endif |
1068 | | |
1069 | | |
1070 | 9.77k | # ifdef FLAC__SSE2_SUPPORTED |
1071 | 9.77k | if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */ |
1072 | 9.77k | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; |
1073 | 9.77k | } |
1074 | 9.77k | # endif |
1075 | 9.77k | # ifdef FLAC__SSSE3_SUPPORTED |
1076 | 9.77k | if (encoder->private_->cpuinfo.x86.ssse3) { |
1077 | 9.77k | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; |
1078 | 9.77k | } |
1079 | 9.77k | # endif |
1080 | 9.77k | # ifdef FLAC__SSE4_2_SUPPORTED |
1081 | 9.77k | if (encoder->private_->cpuinfo.x86.sse42) { |
1082 | 9.77k | encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_sse42; |
1083 | 9.77k | } |
1084 | 9.77k | # endif |
1085 | 9.77k | # ifdef FLAC__AVX2_SUPPORTED |
1086 | 9.77k | if (encoder->private_->cpuinfo.x86.avx2) { |
1087 | 9.77k | encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_avx2; |
1088 | 9.77k | encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_avx2; |
1089 | 9.77k | } |
1090 | 9.77k | # endif |
1091 | 9.77k | # endif /* FLAC__HAS_X86INTRIN */ |
1092 | 9.77k | # endif /* FLAC__CPU_... */ |
1093 | 9.77k | } |
1094 | 9.77k | # endif /* !FLAC__NO_ASM */ |
1095 | | |
1096 | 9.77k | #endif /* !FLAC__INTEGER_ONLY_LIBRARY */ |
1097 | 9.77k | #if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN |
1098 | 9.77k | if(encoder->private_->cpuinfo.use_asm) { |
1099 | 9.77k | # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) |
1100 | 9.77k | # ifdef FLAC__SSE2_SUPPORTED |
1101 | 9.77k | if (encoder->private_->cpuinfo.x86.sse2) |
1102 | 9.77k | encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; |
1103 | 9.77k | # endif |
1104 | 9.77k | # ifdef FLAC__SSSE3_SUPPORTED |
1105 | 9.77k | if (encoder->private_->cpuinfo.x86.ssse3) |
1106 | 9.77k | encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; |
1107 | 9.77k | # endif |
1108 | 9.77k | # ifdef FLAC__AVX2_SUPPORTED |
1109 | 9.77k | if (encoder->private_->cpuinfo.x86.avx2) |
1110 | 9.77k | encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; |
1111 | 9.77k | # endif |
1112 | 9.77k | # endif /* FLAC__CPU_... */ |
1113 | 9.77k | } |
1114 | 9.77k | #endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */ |
1115 | | |
1116 | | /* set state to OK; from here on, errors are fatal and we'll override the state then */ |
1117 | 9.77k | encoder->protected_->state = FLAC__STREAM_ENCODER_OK; |
1118 | | |
1119 | 9.77k | #if FLAC__HAS_OGG |
1120 | 9.77k | encoder->private_->is_ogg = is_ogg; |
1121 | 9.77k | if(is_ogg && !FLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect)) { |
1122 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; |
1123 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1124 | 0 | } |
1125 | 9.77k | #endif |
1126 | | |
1127 | 9.77k | encoder->private_->read_callback = read_callback; |
1128 | 9.77k | encoder->private_->write_callback = write_callback; |
1129 | 9.77k | encoder->private_->seek_callback = seek_callback; |
1130 | 9.77k | encoder->private_->tell_callback = tell_callback; |
1131 | 9.77k | encoder->private_->metadata_callback = metadata_callback; |
1132 | 9.77k | encoder->private_->client_data = client_data; |
1133 | | |
1134 | 9.77k | if(encoder->protected_->num_threads > 1) { |
1135 | 852 | #ifdef FLAC__USE_THREADS |
1136 | 852 | encoder->private_->num_threadtasks = encoder->protected_->num_threads * 2 + 2; /* First threadtask is reserved for main thread */ |
1137 | 852 | if(FLAC__mtx_init(&encoder->private_->mutex_md5_fifo, FLAC__mtx_plain) != FLAC__thrd_success) { |
1138 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1139 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1140 | 0 | } |
1141 | 852 | if(FLAC__mtx_init(&encoder->private_->mutex_work_queue, FLAC__mtx_plain) != FLAC__thrd_success) { |
1142 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
1143 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1144 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1145 | 0 | } |
1146 | 852 | if(FLAC__cnd_init(&encoder->private_->cond_md5_emptied) != FLAC__thrd_success) { |
1147 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
1148 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_work_queue); |
1149 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1150 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1151 | 0 | } |
1152 | 852 | if(FLAC__cnd_init(&encoder->private_->cond_work_available) != FLAC__thrd_success) { |
1153 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
1154 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_work_queue); |
1155 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_md5_emptied); |
1156 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1157 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1158 | 0 | } |
1159 | 852 | if(FLAC__cnd_init(&encoder->private_->cond_wake_up_thread) != FLAC__thrd_success) { |
1160 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
1161 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_work_queue); |
1162 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_md5_emptied); |
1163 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_work_available); |
1164 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1165 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1166 | 0 | } |
1167 | 852 | if(encoder->protected_->do_md5) { |
1168 | 852 | encoder->private_->md5_fifo.size = (encoder->protected_->blocksize+OVERREAD_) * (encoder->private_->num_threadtasks + 2); |
1169 | 2.11k | for(i = 0; i < encoder->protected_->channels; i++) { |
1170 | 1.25k | if(0 == (encoder->private_->md5_fifo.data[i] = safe_malloc_mul_2op_p(sizeof(FLAC__int32), /*times*/encoder->private_->md5_fifo.size))) { |
1171 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
1172 | 0 | FLAC__mtx_destroy(&encoder->private_->mutex_work_queue); |
1173 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_md5_emptied); |
1174 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_work_available); |
1175 | 0 | FLAC__cnd_destroy(&encoder->private_->cond_wake_up_thread); |
1176 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1177 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1178 | 0 | } |
1179 | 1.25k | } |
1180 | 852 | } |
1181 | 852 | encoder->private_->md5_fifo.tail = 0; |
1182 | 14.8k | for(t = 1; t < encoder->private_->num_threadtasks; t++) { |
1183 | 13.9k | encoder->private_->threadtask[t] = safe_calloc_(1, sizeof(FLAC__StreamEncoderThreadTask)); |
1184 | 13.9k | if(encoder->private_->threadtask[t] == NULL) { |
1185 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1186 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1187 | 0 | } |
1188 | 13.9k | encoder->private_->threadtask[t]->frame = FLAC__bitwriter_new(); |
1189 | 13.9k | if(encoder->private_->threadtask[t]->frame == NULL) { |
1190 | 0 | free(encoder->private_->threadtask[t]); |
1191 | 0 | encoder->private_->threadtask[t] = 0; |
1192 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1193 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1194 | 0 | } |
1195 | 13.9k | if(FLAC__mtx_init(&encoder->private_->threadtask[t]->mutex_this_task, FLAC__mtx_plain) != FLAC__thrd_success) { |
1196 | 0 | FLAC__bitwriter_delete(encoder->private_->threadtask[t]->frame); |
1197 | 0 | free(encoder->private_->threadtask[t]); |
1198 | 0 | encoder->private_->threadtask[t] = 0; |
1199 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1200 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1201 | 0 | } |
1202 | 13.9k | if(FLAC__cnd_init(&encoder->private_->threadtask[t]->cond_task_done) != FLAC__thrd_success) { |
1203 | 0 | FLAC__mtx_destroy(&encoder->private_->threadtask[t]->mutex_this_task); |
1204 | 0 | FLAC__bitwriter_delete(encoder->private_->threadtask[t]->frame); |
1205 | 0 | free(encoder->private_->threadtask[t]); |
1206 | 0 | encoder->private_->threadtask[t] = 0; |
1207 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1208 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1209 | 0 | } |
1210 | | |
1211 | 125k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
1212 | 111k | encoder->private_->threadtask[t]->subframe_workspace_ptr[i][0] = &encoder->private_->threadtask[t]->subframe_workspace[i][0]; |
1213 | 111k | encoder->private_->threadtask[t]->subframe_workspace_ptr[i][1] = &encoder->private_->threadtask[t]->subframe_workspace[i][1]; |
1214 | 111k | } |
1215 | 41.9k | for(i = 0; i < 2; i++) { |
1216 | 27.9k | encoder->private_->threadtask[t]->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->threadtask[t]->subframe_workspace_mid_side[i][0]; |
1217 | 27.9k | encoder->private_->threadtask[t]->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->threadtask[t]->subframe_workspace_mid_side[i][1]; |
1218 | 27.9k | } |
1219 | 125k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
1220 | 111k | encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][0]; |
1221 | 111k | encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][1]; |
1222 | 111k | } |
1223 | 41.9k | for(i = 0; i < 2; i++) { |
1224 | 27.9k | encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][0]; |
1225 | 27.9k | encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][1]; |
1226 | 27.9k | } |
1227 | | |
1228 | 125k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
1229 | 111k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][0]); |
1230 | 111k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][1]); |
1231 | 111k | } |
1232 | 41.9k | for(i = 0; i < 2; i++) { |
1233 | 27.9k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][0]); |
1234 | 27.9k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][1]); |
1235 | 27.9k | } |
1236 | 41.9k | for(i = 0; i < 2; i++) |
1237 | 27.9k | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->threadtask[t]->partitioned_rice_contents_extra[i]); |
1238 | 13.9k | } |
1239 | | #else |
1240 | | FLAC__ASSERT(0); |
1241 | | #endif |
1242 | 852 | } |
1243 | | |
1244 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
1245 | 32.5k | for(i = 0; i < encoder->protected_->num_apodizations; i++) |
1246 | 22.7k | encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0; |
1247 | 9.77k | #endif |
1248 | 33.5k | for(t = 0; t < encoder->private_->num_threadtasks; t++) { |
1249 | 62.3k | for(i = 0; i < encoder->protected_->channels; i++) { |
1250 | 38.6k | encoder->private_->threadtask[t]->integer_signal_unaligned[i] = encoder->private_->threadtask[t]->integer_signal[i] = 0; |
1251 | 38.6k | } |
1252 | 71.2k | for(i = 0; i < 2; i++) { |
1253 | 47.4k | encoder->private_->threadtask[t]->integer_signal_mid_side_unaligned[i] = encoder->private_->threadtask[t]->integer_signal_mid_side[i] = 0; |
1254 | 47.4k | } |
1255 | 23.7k | encoder->private_->threadtask[t]->integer_signal_33bit_side_unaligned = encoder->private_->threadtask[t]->integer_signal_33bit_side = 0; |
1256 | 23.7k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
1257 | 23.7k | encoder->private_->threadtask[t]->windowed_signal_unaligned = encoder->private_->threadtask[t]->windowed_signal = 0; |
1258 | 23.7k | #endif |
1259 | 62.3k | for(i = 0; i < encoder->protected_->channels; i++) { |
1260 | 38.6k | encoder->private_->threadtask[t]->residual_workspace_unaligned[i][0] = encoder->private_->threadtask[t]->residual_workspace[i][0] = 0; |
1261 | 38.6k | encoder->private_->threadtask[t]->residual_workspace_unaligned[i][1] = encoder->private_->threadtask[t]->residual_workspace[i][1] = 0; |
1262 | 38.6k | encoder->private_->threadtask[t]->best_subframe[i] = 0; |
1263 | 38.6k | } |
1264 | 71.2k | for(i = 0; i < 2; i++) { |
1265 | 47.4k | encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[i][0] = encoder->private_->threadtask[t]->residual_workspace_mid_side[i][0] = 0; |
1266 | 47.4k | encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[i][1] = encoder->private_->threadtask[t]->residual_workspace_mid_side[i][1] = 0; |
1267 | 47.4k | encoder->private_->threadtask[t]->best_subframe_mid_side[i] = 0; |
1268 | 47.4k | } |
1269 | 23.7k | encoder->private_->threadtask[t]->abs_residual_partition_sums_unaligned = encoder->private_->threadtask[t]->abs_residual_partition_sums = 0; |
1270 | 23.7k | encoder->private_->threadtask[t]->raw_bits_per_partition_unaligned = encoder->private_->threadtask[t]->raw_bits_per_partition = 0; |
1271 | 23.7k | } |
1272 | | |
1273 | | |
1274 | 9.77k | if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { |
1275 | | /* the above function sets the state for us in case of an error */ |
1276 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1277 | 0 | } |
1278 | | |
1279 | 33.5k | for(t = 0; t < encoder->private_->num_threadtasks; t++) { |
1280 | 23.7k | if(!FLAC__bitwriter_init(encoder->private_->threadtask[t]->frame)) { |
1281 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1282 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1283 | 0 | } |
1284 | 23.7k | } |
1285 | | |
1286 | | /* |
1287 | | * Set up the verify stuff if necessary |
1288 | | */ |
1289 | 9.77k | if(encoder->protected_->verify) { |
1290 | | /* |
1291 | | * First, set up the fifo which will hold the |
1292 | | * original signal to compare against |
1293 | | */ |
1294 | 8.56k | encoder->private_->verify.input_fifo.size = (encoder->protected_->blocksize+OVERREAD_) * encoder->private_->num_threadtasks; |
1295 | 23.4k | for(i = 0; i < encoder->protected_->channels; i++) { |
1296 | 14.8k | if(0 == (encoder->private_->verify.input_fifo.data[i] = safe_malloc_mul_2op_p(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) { |
1297 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
1298 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1299 | 0 | } |
1300 | 14.8k | } |
1301 | 8.56k | encoder->private_->verify.input_fifo.tail = 0; |
1302 | | |
1303 | | /* |
1304 | | * Now set up a stream decoder for verification |
1305 | | */ |
1306 | 8.56k | if(0 == encoder->private_->verify.decoder) { |
1307 | 8.56k | encoder->private_->verify.decoder = FLAC__stream_decoder_new(); |
1308 | 8.56k | if(0 == encoder->private_->verify.decoder) { |
1309 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; |
1310 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1311 | 0 | } |
1312 | 8.56k | } |
1313 | | |
1314 | 8.56k | if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { |
1315 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; |
1316 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1317 | 0 | } |
1318 | 8.56k | } |
1319 | 9.77k | encoder->private_->verify.error_stats.absolute_sample = 0; |
1320 | 9.77k | encoder->private_->verify.error_stats.frame_number = 0; |
1321 | 9.77k | encoder->private_->verify.error_stats.channel = 0; |
1322 | 9.77k | encoder->private_->verify.error_stats.sample = 0; |
1323 | 9.77k | encoder->private_->verify.error_stats.expected = 0; |
1324 | 9.77k | encoder->private_->verify.error_stats.got = 0; |
1325 | | |
1326 | | /* |
1327 | | * These must be done before we write any metadata, because that |
1328 | | * calls the write_callback, which uses these values. |
1329 | | */ |
1330 | 9.77k | encoder->private_->first_seekpoint_to_check = 0; |
1331 | 9.77k | encoder->private_->samples_written = 0; |
1332 | 9.77k | encoder->protected_->streaminfo_offset = 0; |
1333 | 9.77k | encoder->protected_->seektable_offset = 0; |
1334 | 9.77k | encoder->protected_->audio_offset = 0; |
1335 | | |
1336 | | /* |
1337 | | * write the stream header |
1338 | | */ |
1339 | 9.77k | if(encoder->protected_->verify) |
1340 | 8.56k | encoder->private_->verify.state_hint = ENCODER_IN_MAGIC; |
1341 | 9.77k | if(!FLAC__bitwriter_write_raw_uint32(encoder->private_->threadtask[0]->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) { |
1342 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
1343 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1344 | 0 | } |
1345 | 9.77k | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[0], 0, /*is_last_block=*/false)) { |
1346 | | /* the above function sets the state for us in case of an error */ |
1347 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1348 | 0 | } |
1349 | | |
1350 | | /* |
1351 | | * write the STREAMINFO metadata block |
1352 | | */ |
1353 | 9.77k | if(encoder->protected_->verify) |
1354 | 8.56k | encoder->private_->verify.state_hint = ENCODER_IN_METADATA; |
1355 | 9.77k | encoder->private_->streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO; |
1356 | 9.77k | encoder->private_->streaminfo.is_last = false; /* we will have at a minimum a VORBIS_COMMENT afterwards */ |
1357 | 9.77k | encoder->private_->streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; |
1358 | 9.77k | encoder->private_->streaminfo.data.stream_info.min_blocksize = encoder->protected_->blocksize; /* this encoder uses the same blocksize for the whole stream */ |
1359 | 9.77k | encoder->private_->streaminfo.data.stream_info.max_blocksize = encoder->protected_->blocksize; |
1360 | 9.77k | encoder->private_->streaminfo.data.stream_info.min_framesize = 0; /* we don't know this yet; have to fill it in later */ |
1361 | 9.77k | encoder->private_->streaminfo.data.stream_info.max_framesize = 0; /* we don't know this yet; have to fill it in later */ |
1362 | 9.77k | encoder->private_->streaminfo.data.stream_info.sample_rate = encoder->protected_->sample_rate; |
1363 | 9.77k | encoder->private_->streaminfo.data.stream_info.channels = encoder->protected_->channels; |
1364 | 9.77k | encoder->private_->streaminfo.data.stream_info.bits_per_sample = encoder->protected_->bits_per_sample; |
1365 | 9.77k | encoder->private_->streaminfo.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */ |
1366 | 9.77k | memset(encoder->private_->streaminfo.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */ |
1367 | 9.77k | if(encoder->protected_->do_md5) |
1368 | 9.77k | FLAC__MD5Init(&encoder->private_->md5context); |
1369 | 9.77k | if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->threadtask[0]->frame, true)) { |
1370 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
1371 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1372 | 0 | } |
1373 | 9.77k | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[0], 0, /*is_last_block=*/false)) { |
1374 | | /* the above function sets the state for us in case of an error */ |
1375 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1376 | 0 | } |
1377 | | |
1378 | | /* |
1379 | | * Now that the STREAMINFO block is written, we can init this to an |
1380 | | * absurdly-high value... |
1381 | | */ |
1382 | 9.77k | encoder->private_->streaminfo.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1; |
1383 | | /* ... and clear this to 0 */ |
1384 | 9.77k | encoder->private_->streaminfo.data.stream_info.total_samples = 0; |
1385 | | |
1386 | | /* |
1387 | | * Check to see if the supplied metadata contains a VORBIS_COMMENT; |
1388 | | * if not, we will write an empty one (FLAC__add_metadata_block() |
1389 | | * automatically supplies the vendor string). |
1390 | | * |
1391 | | * WATCHOUT: the Ogg FLAC mapping requires us to write this block after |
1392 | | * the STREAMINFO. (In the case that metadata_has_vorbis_comment is |
1393 | | * true it will have already insured that the metadata list is properly |
1394 | | * ordered.) |
1395 | | */ |
1396 | 9.77k | if(!metadata_has_vorbis_comment) { |
1397 | 9.77k | FLAC__StreamMetadata vorbis_comment; |
1398 | 9.77k | vorbis_comment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT; |
1399 | 9.77k | vorbis_comment.is_last = (encoder->protected_->num_metadata_blocks == 0); |
1400 | 9.77k | vorbis_comment.length = 4 + 4; /* MAGIC NUMBER */ |
1401 | 9.77k | vorbis_comment.data.vorbis_comment.vendor_string.length = 0; |
1402 | 9.77k | vorbis_comment.data.vorbis_comment.vendor_string.entry = 0; |
1403 | 9.77k | vorbis_comment.data.vorbis_comment.num_comments = 0; |
1404 | 9.77k | vorbis_comment.data.vorbis_comment.comments = 0; |
1405 | 9.77k | if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->threadtask[0]->frame, true)) { |
1406 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
1407 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1408 | 0 | } |
1409 | 9.77k | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[0], 0, /*is_last_block=*/false)) { |
1410 | | /* the above function sets the state for us in case of an error */ |
1411 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1412 | 0 | } |
1413 | 9.77k | } |
1414 | | |
1415 | | /* |
1416 | | * write the user's metadata blocks |
1417 | | */ |
1418 | 9.77k | for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { |
1419 | 0 | encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1); |
1420 | 0 | if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->threadtask[0]->frame, true)) { |
1421 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
1422 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1423 | 0 | } |
1424 | 0 | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[0], 0, /*is_last_block=*/false)) { |
1425 | | /* the above function sets the state for us in case of an error */ |
1426 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1427 | 0 | } |
1428 | 0 | } |
1429 | | |
1430 | | /* now that all the metadata is written, we save the stream offset */ |
1431 | 9.77k | if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ |
1432 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
1433 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1434 | 0 | } |
1435 | | |
1436 | 9.77k | if(encoder->protected_->verify) |
1437 | 8.56k | encoder->private_->verify.state_hint = ENCODER_IN_AUDIO; |
1438 | | |
1439 | 9.77k | return FLAC__STREAM_ENCODER_INIT_STATUS_OK; |
1440 | 9.77k | } |
1441 | | |
1442 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream( |
1443 | | FLAC__StreamEncoder *encoder, |
1444 | | FLAC__StreamEncoderWriteCallback write_callback, |
1445 | | FLAC__StreamEncoderSeekCallback seek_callback, |
1446 | | FLAC__StreamEncoderTellCallback tell_callback, |
1447 | | FLAC__StreamEncoderMetadataCallback metadata_callback, |
1448 | | void *client_data |
1449 | | ) |
1450 | 6.83k | { |
1451 | 6.83k | return init_stream_internal_( |
1452 | 6.83k | encoder, |
1453 | 6.83k | /*read_callback=*/0, |
1454 | 6.83k | write_callback, |
1455 | 6.83k | seek_callback, |
1456 | 6.83k | tell_callback, |
1457 | 6.83k | metadata_callback, |
1458 | 6.83k | client_data, |
1459 | 6.83k | /*is_ogg=*/false |
1460 | 6.83k | ); |
1461 | 6.83k | } |
1462 | | |
1463 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream( |
1464 | | FLAC__StreamEncoder *encoder, |
1465 | | FLAC__StreamEncoderReadCallback read_callback, |
1466 | | FLAC__StreamEncoderWriteCallback write_callback, |
1467 | | FLAC__StreamEncoderSeekCallback seek_callback, |
1468 | | FLAC__StreamEncoderTellCallback tell_callback, |
1469 | | FLAC__StreamEncoderMetadataCallback metadata_callback, |
1470 | | void *client_data |
1471 | | ) |
1472 | 3.19k | { |
1473 | 3.19k | return init_stream_internal_( |
1474 | 3.19k | encoder, |
1475 | 3.19k | read_callback, |
1476 | 3.19k | write_callback, |
1477 | 3.19k | seek_callback, |
1478 | 3.19k | tell_callback, |
1479 | 3.19k | metadata_callback, |
1480 | 3.19k | client_data, |
1481 | 3.19k | /*is_ogg=*/true |
1482 | 3.19k | ); |
1483 | 3.19k | } |
1484 | | |
1485 | | static FLAC__StreamEncoderInitStatus init_FILE_internal_( |
1486 | | FLAC__StreamEncoder *encoder, |
1487 | | FILE *file, |
1488 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1489 | | void *client_data, |
1490 | | FLAC__bool is_ogg |
1491 | | ) |
1492 | 0 | { |
1493 | 0 | FLAC__StreamEncoderInitStatus init_status; |
1494 | |
|
1495 | 0 | FLAC__ASSERT(0 != encoder); |
1496 | 0 | FLAC__ASSERT(0 != file); |
1497 | |
|
1498 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1499 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; |
1500 | | |
1501 | | /* double protection */ |
1502 | 0 | if(file == 0) { |
1503 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; |
1504 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1505 | 0 | } |
1506 | | |
1507 | | /* |
1508 | | * To make sure that our file does not go unclosed after an error, we |
1509 | | * must assign the FILE pointer before any further error can occur in |
1510 | | * this routine. |
1511 | | */ |
1512 | 0 | if(file == stdout) |
1513 | 0 | file = get_binary_stdout_(); /* just to be safe */ |
1514 | |
|
1515 | | #ifdef _WIN32 |
1516 | | /* |
1517 | | * Windows can suffer quite badly from disk fragmentation. This can be |
1518 | | * reduced significantly by setting the output buffer size to be 10MB. |
1519 | | */ |
1520 | | if(GetFileType((HANDLE)_get_osfhandle(_fileno(file))) == FILE_TYPE_DISK) |
1521 | | setvbuf(file, NULL, _IOFBF, 10*1024*1024); |
1522 | | #endif |
1523 | 0 | encoder->private_->file = file; |
1524 | |
|
1525 | 0 | encoder->private_->progress_callback = progress_callback; |
1526 | 0 | encoder->private_->bytes_written = 0; |
1527 | 0 | encoder->private_->samples_written = 0; |
1528 | 0 | encoder->private_->frames_written = 0; |
1529 | |
|
1530 | 0 | init_status = init_stream_internal_( |
1531 | 0 | encoder, |
1532 | 0 | encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_ : 0, |
1533 | 0 | file_write_callback_, |
1534 | 0 | encoder->private_->file == stdout? 0 : file_seek_callback_, |
1535 | 0 | encoder->private_->file == stdout? 0 : file_tell_callback_, |
1536 | 0 | /*metadata_callback=*/0, |
1537 | 0 | client_data, |
1538 | 0 | is_ogg |
1539 | 0 | ); |
1540 | 0 | if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { |
1541 | | /* the above function sets the state for us in case of an error */ |
1542 | 0 | return init_status; |
1543 | 0 | } |
1544 | | |
1545 | 0 | { |
1546 | 0 | uint32_t blocksize = FLAC__stream_encoder_get_blocksize(encoder); |
1547 | |
|
1548 | 0 | FLAC__ASSERT(blocksize != 0); |
1549 | 0 | encoder->private_->total_frames_estimate = (uint32_t)((FLAC__stream_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize); |
1550 | 0 | } |
1551 | | |
1552 | 0 | return init_status; |
1553 | 0 | } |
1554 | | |
1555 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE( |
1556 | | FLAC__StreamEncoder *encoder, |
1557 | | FILE *file, |
1558 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1559 | | void *client_data |
1560 | | ) |
1561 | 0 | { |
1562 | 0 | return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/false); |
1563 | 0 | } |
1564 | | |
1565 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE( |
1566 | | FLAC__StreamEncoder *encoder, |
1567 | | FILE *file, |
1568 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1569 | | void *client_data |
1570 | | ) |
1571 | 0 | { |
1572 | 0 | return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/true); |
1573 | 0 | } |
1574 | | |
1575 | | static FLAC__StreamEncoderInitStatus init_file_internal_( |
1576 | | FLAC__StreamEncoder *encoder, |
1577 | | const char *filename, |
1578 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1579 | | void *client_data, |
1580 | | FLAC__bool is_ogg |
1581 | | ) |
1582 | 0 | { |
1583 | 0 | FILE *file; |
1584 | |
|
1585 | 0 | FLAC__ASSERT(0 != encoder); |
1586 | | |
1587 | | /* |
1588 | | * To make sure that our file does not go unclosed after an error, we |
1589 | | * have to do the same entrance checks here that are later performed |
1590 | | * in FLAC__stream_encoder_init_FILE() before the FILE* is assigned. |
1591 | | */ |
1592 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1593 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED; |
1594 | | |
1595 | 0 | file = filename? flac_fopen(filename, "w+b") : stdout; |
1596 | |
|
1597 | 0 | if(file == 0) { |
1598 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR; |
1599 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1600 | 0 | } |
1601 | | |
1602 | 0 | return init_FILE_internal_(encoder, file, progress_callback, client_data, is_ogg); |
1603 | 0 | } |
1604 | | |
1605 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file( |
1606 | | FLAC__StreamEncoder *encoder, |
1607 | | const char *filename, |
1608 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1609 | | void *client_data |
1610 | | ) |
1611 | 0 | { |
1612 | 0 | return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/false); |
1613 | 0 | } |
1614 | | |
1615 | | FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file( |
1616 | | FLAC__StreamEncoder *encoder, |
1617 | | const char *filename, |
1618 | | FLAC__StreamEncoderProgressCallback progress_callback, |
1619 | | void *client_data |
1620 | | ) |
1621 | 0 | { |
1622 | 0 | return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/true); |
1623 | 0 | } |
1624 | | |
1625 | | FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) |
1626 | 36.2k | { |
1627 | 36.2k | FLAC__bool error = false; |
1628 | | |
1629 | 36.2k | if (encoder == NULL) |
1630 | 0 | return false; |
1631 | | |
1632 | 36.2k | FLAC__ASSERT(0 != encoder->private_); |
1633 | 36.2k | FLAC__ASSERT(0 != encoder->protected_); |
1634 | | |
1635 | 36.2k | if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED){ |
1636 | 26.4k | if(encoder->protected_->metadata){ // True in case FLAC__stream_encoder_set_metadata was used but init failed |
1637 | 0 | free(encoder->protected_->metadata); |
1638 | 0 | encoder->protected_->metadata = 0; |
1639 | 0 | encoder->protected_->num_metadata_blocks = 0; |
1640 | 0 | } |
1641 | 26.4k | if(0 != encoder->private_->file) { |
1642 | 0 | if(encoder->private_->file != stdout) |
1643 | 0 | fclose(encoder->private_->file); |
1644 | 0 | encoder->private_->file = 0; |
1645 | 0 | } |
1646 | 26.4k | return true; |
1647 | 26.4k | } |
1648 | | |
1649 | 9.77k | if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) { |
1650 | 9.70k | FLAC__bool ok = true; |
1651 | | /* first finish threads */ |
1652 | 9.70k | if(encoder->protected_->num_threads > 1) { |
1653 | 839 | #ifdef FLAC__USE_THREADS |
1654 | | /* This is quite complicated, so here is an explanation on what is supposed to happen |
1655 | | * |
1656 | | * Thread no.0 and threadtask no.0 are reserved for non-threaded operation, so counting |
1657 | | * here starts at 1, which makes things slightly more complicated. |
1658 | | * |
1659 | | * If the file processed was very short compared to the requested number of threadtasks, |
1660 | | * not all threadtasks have been populated yet. Handling that is easy: threadtask no.1 needs |
1661 | | * to be processed first, monotonically increasing until the last populated threadtask is |
1662 | | * processed. This number is stored in encoder->private_->num_started_threadtasks |
1663 | | * |
1664 | | * If the file is longer, the next due frame chronologically might not be in threadtasks |
1665 | | * number 1, because the threadtasks work like a ringbuffer. To access this, the variable |
1666 | | * twrap starts counting at the next due frame, and the modulo operator (%) is used to |
1667 | | * "wrap" the number with the number of threadtasks. So, if the next due task is 3 |
1668 | | * and 4 tasks are started, twrap increases 3, 4, 5, 6, and t follows with values 3, 4, 1, 2. |
1669 | | */ |
1670 | 839 | uint32_t start, end, t, twrap; |
1671 | 839 | if(encoder->private_->num_started_threadtasks < encoder->private_->num_threadtasks) { |
1672 | 515 | start = 1; |
1673 | 515 | end = encoder->private_->num_started_threadtasks; |
1674 | 515 | } |
1675 | 324 | else { |
1676 | 324 | start = encoder->private_->next_thread; |
1677 | 324 | end = encoder->private_->next_thread + encoder->private_->num_threadtasks - 1; |
1678 | 324 | } |
1679 | 6.67k | for(twrap = start; twrap < end; twrap++) { |
1680 | 5.83k | FLAC__ASSERT(twrap > 0); |
1681 | 5.83k | t = (twrap - 1) % (encoder->private_->num_threadtasks - 1) + 1; |
1682 | | /* Lock mutex, if task isn't done yet, wait for condition */ |
1683 | 5.83k | FLAC__mtx_lock(&encoder->private_->threadtask[t]->mutex_this_task); |
1684 | 5.97k | while(!encoder->private_->threadtask[t]->task_done) |
1685 | 143 | FLAC__cnd_wait(&encoder->private_->threadtask[t]->cond_task_done,&encoder->private_->threadtask[t]->mutex_this_task); |
1686 | | |
1687 | 5.83k | if(!encoder->private_->threadtask[t]->returnvalue) |
1688 | 0 | ok = false; |
1689 | 5.83k | if(ok && !write_bitbuffer_(encoder, encoder->private_->threadtask[t], encoder->protected_->blocksize, 0)) |
1690 | 0 | ok = false; |
1691 | 5.83k | FLAC__mtx_unlock(&encoder->private_->threadtask[t]->mutex_this_task); |
1692 | 5.83k | } |
1693 | | /* Wait for MD5 calculation to finish */ |
1694 | 839 | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
1695 | 840 | while(encoder->private_->md5_active || encoder->private_->md5_fifo.tail > 0) { |
1696 | 1 | FLAC__cnd_wait(&encoder->private_->cond_md5_emptied, &encoder->private_->mutex_work_queue); |
1697 | 1 | } |
1698 | 839 | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
1699 | | #else |
1700 | | FLAC__ASSERT(0); |
1701 | | #endif |
1702 | 839 | } |
1703 | 9.70k | if(ok && encoder->private_->current_sample_number != 0) { |
1704 | 8.88k | encoder->protected_->blocksize = encoder->private_->current_sample_number; |
1705 | 8.88k | if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { |
1706 | | /* the above function sets the state for us in case of an error */ |
1707 | 0 | return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; |
1708 | 0 | } |
1709 | 8.88k | if(!process_frame_(encoder, /*is_last_block=*/true)) |
1710 | 0 | error = true; |
1711 | 8.88k | } |
1712 | 9.70k | } |
1713 | | |
1714 | 9.77k | if(encoder->protected_->num_threads > 1) { |
1715 | 852 | #ifdef FLAC__USE_THREADS |
1716 | | /* Properly finish all threads */ |
1717 | 852 | uint32_t t; |
1718 | 852 | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
1719 | 3.77k | for(t = 1; t < encoder->private_->num_created_threads; t++) |
1720 | 2.92k | encoder->private_->finish_work_threads = true; |
1721 | 852 | FLAC__cnd_broadcast(&encoder->private_->cond_wake_up_thread); |
1722 | 852 | FLAC__cnd_broadcast(&encoder->private_->cond_work_available); |
1723 | 852 | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
1724 | | |
1725 | 3.77k | for(t = 1; t < encoder->private_->num_created_threads; t++) |
1726 | 2.92k | FLAC__thrd_join(encoder->private_->thread[t], NULL); |
1727 | | #else |
1728 | | FLAC__ASSERT(0); |
1729 | | #endif |
1730 | 852 | } |
1731 | | |
1732 | 9.77k | if(encoder->protected_->do_md5) |
1733 | 9.77k | FLAC__MD5Final(encoder->private_->streaminfo.data.stream_info.md5sum, &encoder->private_->md5context); |
1734 | | |
1735 | 9.77k | if(!encoder->private_->is_being_deleted) { |
1736 | 9.77k | if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK) { |
1737 | 9.70k | if(encoder->private_->seek_callback) { |
1738 | 9.70k | #if FLAC__HAS_OGG |
1739 | 9.70k | if(encoder->private_->is_ogg) |
1740 | 3.08k | update_ogg_metadata_(encoder); |
1741 | 6.62k | else |
1742 | 6.62k | #endif |
1743 | 6.62k | update_metadata_(encoder); |
1744 | | |
1745 | | /* check if an error occurred while updating metadata */ |
1746 | 9.70k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) |
1747 | 0 | error = true; |
1748 | 9.70k | } |
1749 | 9.70k | if(encoder->private_->metadata_callback) |
1750 | 9.70k | encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data); |
1751 | 9.70k | } |
1752 | | |
1753 | 9.77k | if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder)) { |
1754 | 0 | if(!error) |
1755 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA; |
1756 | 0 | error = true; |
1757 | 0 | } |
1758 | 9.77k | } |
1759 | | |
1760 | 9.77k | if(0 != encoder->private_->file) { |
1761 | 0 | if(encoder->private_->file != stdout) |
1762 | 0 | fclose(encoder->private_->file); |
1763 | 0 | encoder->private_->file = 0; |
1764 | 0 | } |
1765 | | |
1766 | 9.77k | #if FLAC__HAS_OGG |
1767 | 9.77k | if(encoder->private_->is_ogg) |
1768 | 3.08k | FLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect); |
1769 | 9.77k | #endif |
1770 | | |
1771 | 9.77k | free_(encoder); |
1772 | 9.77k | set_defaults_(encoder); |
1773 | | |
1774 | 9.77k | if(!error) |
1775 | 9.77k | encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; |
1776 | | |
1777 | 9.77k | return !error; |
1778 | 9.77k | } |
1779 | | |
1780 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value) |
1781 | 21.7k | { |
1782 | 21.7k | FLAC__ASSERT(0 != encoder); |
1783 | 21.7k | FLAC__ASSERT(0 != encoder->private_); |
1784 | 21.7k | FLAC__ASSERT(0 != encoder->protected_); |
1785 | 21.7k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1786 | 9.77k | return false; |
1787 | 12.0k | #if FLAC__HAS_OGG |
1788 | | /* can't check encoder->private_->is_ogg since that's not set until init time */ |
1789 | 12.0k | FLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value); |
1790 | 12.0k | return true; |
1791 | | #else |
1792 | | (void)value; |
1793 | | return false; |
1794 | | #endif |
1795 | 21.7k | } |
1796 | | |
1797 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value) |
1798 | 21.7k | { |
1799 | 21.7k | FLAC__ASSERT(0 != encoder); |
1800 | 21.7k | FLAC__ASSERT(0 != encoder->private_); |
1801 | 21.7k | FLAC__ASSERT(0 != encoder->protected_); |
1802 | 21.7k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1803 | 9.77k | return false; |
1804 | 12.0k | #ifndef FLAC__MANDATORY_VERIFY_WHILE_ENCODING |
1805 | 12.0k | encoder->protected_->verify = value; |
1806 | 12.0k | #endif |
1807 | 12.0k | return true; |
1808 | 21.7k | } |
1809 | | |
1810 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value) |
1811 | 21.8k | { |
1812 | 21.8k | FLAC__ASSERT(0 != encoder); |
1813 | 21.8k | FLAC__ASSERT(0 != encoder->private_); |
1814 | 21.8k | FLAC__ASSERT(0 != encoder->protected_); |
1815 | 21.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1816 | 9.77k | return false; |
1817 | 12.0k | encoder->protected_->streamable_subset = value; |
1818 | 12.0k | return true; |
1819 | 21.8k | } |
1820 | | |
1821 | | /* |
1822 | | * The following routine was intended as debug routine and is not in the |
1823 | | * public headers, but SHOULD NOT CHANGE! It is known is is used in |
1824 | | * some non-audio projects needing every last bit of performance. |
1825 | | * See https://github.com/xiph/flac/issues/547 for details. These projects |
1826 | | * provide their own prototype, so changing the signature of this function |
1827 | | * would break building. |
1828 | | */ |
1829 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) |
1830 | 0 | { |
1831 | 0 | FLAC__ASSERT(0 != encoder); |
1832 | 0 | FLAC__ASSERT(0 != encoder->private_); |
1833 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
1834 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1835 | 0 | return false; |
1836 | 0 | encoder->protected_->do_md5 = value; |
1837 | 0 | return true; |
1838 | 0 | } |
1839 | | |
1840 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, uint32_t value) |
1841 | 21.8k | { |
1842 | 21.8k | FLAC__ASSERT(0 != encoder); |
1843 | 21.8k | FLAC__ASSERT(0 != encoder->private_); |
1844 | 21.8k | FLAC__ASSERT(0 != encoder->protected_); |
1845 | 21.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1846 | 9.77k | return false; |
1847 | 12.0k | encoder->protected_->channels = value; |
1848 | 12.0k | return true; |
1849 | 21.8k | } |
1850 | | |
1851 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, uint32_t value) |
1852 | 21.8k | { |
1853 | 21.8k | FLAC__ASSERT(0 != encoder); |
1854 | 21.8k | FLAC__ASSERT(0 != encoder->private_); |
1855 | 21.8k | FLAC__ASSERT(0 != encoder->protected_); |
1856 | 21.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1857 | 9.77k | return false; |
1858 | 12.0k | encoder->protected_->bits_per_sample = value; |
1859 | 12.0k | return true; |
1860 | 21.8k | } |
1861 | | |
1862 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, uint32_t value) |
1863 | 19.8k | { |
1864 | 19.8k | FLAC__ASSERT(0 != encoder); |
1865 | 19.8k | FLAC__ASSERT(0 != encoder->private_); |
1866 | 19.8k | FLAC__ASSERT(0 != encoder->protected_); |
1867 | 19.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1868 | 9.77k | return false; |
1869 | 10.0k | encoder->protected_->sample_rate = value; |
1870 | 10.0k | return true; |
1871 | 19.8k | } |
1872 | | |
1873 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, uint32_t value) |
1874 | 43.6k | { |
1875 | 43.6k | FLAC__bool ok = true; |
1876 | 43.6k | FLAC__ASSERT(0 != encoder); |
1877 | 43.6k | FLAC__ASSERT(0 != encoder->private_); |
1878 | 43.6k | FLAC__ASSERT(0 != encoder->protected_); |
1879 | 43.6k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1880 | 19.5k | return false; |
1881 | 24.0k | if(value >= sizeof(compression_levels_)/sizeof(compression_levels_[0])) |
1882 | 9.81k | value = sizeof(compression_levels_)/sizeof(compression_levels_[0]) - 1; |
1883 | 24.0k | ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo); |
1884 | 24.0k | ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo); |
1885 | 24.0k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
1886 | 24.0k | #if 1 |
1887 | 24.0k | ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization); |
1888 | | #else |
1889 | | /* equivalent to -A tukey(0.5) */ |
1890 | | encoder->protected_->num_apodizations = 1; |
1891 | | encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; |
1892 | | encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; |
1893 | | #endif |
1894 | 24.0k | #endif |
1895 | 24.0k | ok &= FLAC__stream_encoder_set_max_lpc_order (encoder, compression_levels_[value].max_lpc_order); |
1896 | 24.0k | ok &= FLAC__stream_encoder_set_qlp_coeff_precision (encoder, compression_levels_[value].qlp_coeff_precision); |
1897 | 24.0k | ok &= FLAC__stream_encoder_set_do_qlp_coeff_prec_search (encoder, compression_levels_[value].do_qlp_coeff_prec_search); |
1898 | 24.0k | ok &= FLAC__stream_encoder_set_do_escape_coding (encoder, compression_levels_[value].do_escape_coding); |
1899 | 24.0k | ok &= FLAC__stream_encoder_set_do_exhaustive_model_search (encoder, compression_levels_[value].do_exhaustive_model_search); |
1900 | 24.0k | ok &= FLAC__stream_encoder_set_min_residual_partition_order(encoder, compression_levels_[value].min_residual_partition_order); |
1901 | 24.0k | ok &= FLAC__stream_encoder_set_max_residual_partition_order(encoder, compression_levels_[value].max_residual_partition_order); |
1902 | 24.0k | ok &= FLAC__stream_encoder_set_rice_parameter_search_dist (encoder, compression_levels_[value].rice_parameter_search_dist); |
1903 | 24.0k | return ok; |
1904 | 43.6k | } |
1905 | | |
1906 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, uint32_t value) |
1907 | 19.8k | { |
1908 | 19.8k | FLAC__ASSERT(0 != encoder); |
1909 | 19.8k | FLAC__ASSERT(0 != encoder->private_); |
1910 | 19.8k | FLAC__ASSERT(0 != encoder->protected_); |
1911 | 19.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1912 | 9.77k | return false; |
1913 | 10.0k | encoder->protected_->blocksize = value; |
1914 | 10.0k | return true; |
1915 | 19.8k | } |
1916 | | |
1917 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) |
1918 | 45.8k | { |
1919 | 45.8k | FLAC__ASSERT(0 != encoder); |
1920 | 45.8k | FLAC__ASSERT(0 != encoder->private_); |
1921 | 45.8k | FLAC__ASSERT(0 != encoder->protected_); |
1922 | 45.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1923 | 9.77k | return false; |
1924 | 36.0k | encoder->protected_->do_mid_side_stereo = value; |
1925 | 36.0k | return true; |
1926 | 45.8k | } |
1927 | | |
1928 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) |
1929 | 45.8k | { |
1930 | 45.8k | FLAC__ASSERT(0 != encoder); |
1931 | 45.8k | FLAC__ASSERT(0 != encoder->private_); |
1932 | 45.8k | FLAC__ASSERT(0 != encoder->protected_); |
1933 | 45.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1934 | 9.77k | return false; |
1935 | 36.0k | encoder->protected_->loose_mid_side_stereo = value; |
1936 | 36.0k | return true; |
1937 | 45.8k | } |
1938 | | |
1939 | | /*@@@@add to tests*/ |
1940 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification) |
1941 | 47.2k | { |
1942 | 47.2k | FLAC__ASSERT(0 != encoder); |
1943 | 47.2k | FLAC__ASSERT(0 != encoder->private_); |
1944 | 47.2k | FLAC__ASSERT(0 != encoder->protected_); |
1945 | 47.2k | FLAC__ASSERT(0 != specification); |
1946 | 47.2k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
1947 | 9.77k | return false; |
1948 | | #ifdef FLAC__INTEGER_ONLY_LIBRARY |
1949 | | (void)specification; /* silently ignore since we haven't integerized; will always use a rectangular window */ |
1950 | | #else |
1951 | 37.4k | encoder->protected_->num_apodizations = 0; |
1952 | 71.8k | while(1) { |
1953 | 71.8k | const char *s = strchr(specification, ';'); |
1954 | 71.8k | const size_t n = s? (size_t)(s - specification) : strlen(specification); |
1955 | 71.8k | if (n==8 && 0 == strncmp("bartlett" , specification, n)) |
1956 | 558 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT; |
1957 | 71.2k | else if(n==13 && 0 == strncmp("bartlett_hann", specification, n)) |
1958 | 103 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT_HANN; |
1959 | 71.1k | else if(n==8 && 0 == strncmp("blackman" , specification, n)) |
1960 | 105 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN; |
1961 | 71.0k | else if(n==26 && 0 == strncmp("blackman_harris_4term_92db", specification, n)) |
1962 | 101 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE; |
1963 | 70.9k | else if(n==6 && 0 == strncmp("connes" , specification, n)) |
1964 | 260 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_CONNES; |
1965 | 70.6k | else if(n==7 && 0 == strncmp("flattop" , specification, n)) |
1966 | 135 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_FLATTOP; |
1967 | 70.5k | else if(n>7 && 0 == strncmp("gauss(" , specification, 6)) { |
1968 | 368 | FLAC__real stddev = (FLAC__real)strtod(specification+6, 0); |
1969 | 368 | if (stddev > 0.0 && stddev <= 0.5) { |
1970 | 138 | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.gauss.stddev = stddev; |
1971 | 138 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_GAUSS; |
1972 | 138 | } |
1973 | 368 | } |
1974 | 70.1k | else if(n==7 && 0 == strncmp("hamming" , specification, n)) |
1975 | 220 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HAMMING; |
1976 | 69.9k | else if(n==4 && 0 == strncmp("hann" , specification, n)) |
1977 | 512 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HANN; |
1978 | 69.4k | else if(n==13 && 0 == strncmp("kaiser_bessel", specification, n)) |
1979 | 137 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_KAISER_BESSEL; |
1980 | 69.3k | else if(n==7 && 0 == strncmp("nuttall" , specification, n)) |
1981 | 158 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_NUTTALL; |
1982 | 69.1k | else if(n==9 && 0 == strncmp("rectangle" , specification, n)) |
1983 | 215 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_RECTANGLE; |
1984 | 68.9k | else if(n==8 && 0 == strncmp("triangle" , specification, n)) |
1985 | 497 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TRIANGLE; |
1986 | 68.4k | else if(n>7 && 0 == strncmp("tukey(" , specification, 6)) { |
1987 | 14.7k | FLAC__real p = (FLAC__real)strtod(specification+6, 0); |
1988 | 14.7k | if (p >= 0.0 && p <= 1.0) { |
1989 | 14.5k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = p; |
1990 | 14.5k | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; |
1991 | 14.5k | } |
1992 | 14.7k | } |
1993 | 53.6k | else if(n>15 && 0 == strncmp("partial_tukey(", specification, 14)) { |
1994 | 1.42k | FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0); |
1995 | 1.42k | const char *si_1 = strchr(specification, '/'); |
1996 | 1.42k | FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f; |
1997 | 1.42k | FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; |
1998 | 1.42k | const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); |
1999 | 1.42k | FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; |
2000 | | |
2001 | 1.42k | if (tukey_parts <= 1) { |
2002 | 158 | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; |
2003 | 158 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; |
2004 | 1.26k | }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ |
2005 | 689 | FLAC__int32 m; |
2006 | 6.10k | for(m = 0; m < tukey_parts; m++){ |
2007 | 5.41k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; |
2008 | 5.41k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); |
2009 | 5.41k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); |
2010 | 5.41k | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PARTIAL_TUKEY; |
2011 | 5.41k | } |
2012 | 689 | } |
2013 | 1.42k | } |
2014 | 52.2k | else if(n>16 && 0 == strncmp("punchout_tukey(", specification, 15)) { |
2015 | 1.34k | FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0); |
2016 | 1.34k | const char *si_1 = strchr(specification, '/'); |
2017 | 1.34k | FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f; |
2018 | 1.34k | FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; |
2019 | 1.34k | const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); |
2020 | 1.34k | FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; |
2021 | | |
2022 | 1.34k | if (tukey_parts <= 1) { |
2023 | 419 | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; |
2024 | 419 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; |
2025 | 925 | }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ |
2026 | 419 | FLAC__int32 m; |
2027 | 6.54k | for(m = 0; m < tukey_parts; m++){ |
2028 | 6.12k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; |
2029 | 6.12k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); |
2030 | 6.12k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); |
2031 | 6.12k | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PUNCHOUT_TUKEY; |
2032 | 6.12k | } |
2033 | 419 | } |
2034 | 1.34k | } |
2035 | 50.9k | else if(n>17 && 0 == strncmp("subdivide_tukey(", specification, 16)){ |
2036 | 12.2k | FLAC__int32 parts = (FLAC__int32)strtod(specification+16, 0); |
2037 | 12.2k | if(parts > 1){ |
2038 | 11.9k | const char *si_1 = strchr(specification, '/'); |
2039 | 11.9k | FLAC__real p = si_1?(FLAC__real)strtod(si_1+1, 0):5e-1; |
2040 | 11.9k | if(p > 1) |
2041 | 73 | p = 1; |
2042 | 11.9k | else if(p < 0) |
2043 | 76 | p = 0; |
2044 | 11.9k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.parts = parts; |
2045 | 11.9k | encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.p = p/parts; |
2046 | 11.9k | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_SUBDIVIDE_TUKEY; |
2047 | 11.9k | } |
2048 | 12.2k | } |
2049 | 38.6k | else if(n==5 && 0 == strncmp("welch" , specification, n)) |
2050 | 250 | encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; |
2051 | 71.8k | if (encoder->protected_->num_apodizations == 32) |
2052 | 56 | break; |
2053 | 71.7k | if (s) |
2054 | 34.3k | specification = s+1; |
2055 | 37.4k | else |
2056 | 37.4k | break; |
2057 | 71.7k | } |
2058 | 37.4k | if(encoder->protected_->num_apodizations == 0) { |
2059 | 11.0k | encoder->protected_->num_apodizations = 1; |
2060 | 11.0k | encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; |
2061 | 11.0k | encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; |
2062 | 11.0k | } |
2063 | 37.4k | #endif |
2064 | 37.4k | return true; |
2065 | 47.2k | } |
2066 | | |
2067 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, uint32_t value) |
2068 | 44.0k | { |
2069 | 44.0k | FLAC__ASSERT(0 != encoder); |
2070 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2071 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2072 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2073 | 9.77k | return false; |
2074 | 34.3k | encoder->protected_->max_lpc_order = value; |
2075 | 34.3k | return true; |
2076 | 44.0k | } |
2077 | | |
2078 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, uint32_t value) |
2079 | 44.0k | { |
2080 | 44.0k | FLAC__ASSERT(0 != encoder); |
2081 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2082 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2083 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2084 | 9.77k | return false; |
2085 | 34.2k | encoder->protected_->qlp_coeff_precision = value; |
2086 | 34.2k | return true; |
2087 | 44.0k | } |
2088 | | |
2089 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2090 | 44.2k | { |
2091 | 44.2k | FLAC__ASSERT(0 != encoder); |
2092 | 44.2k | FLAC__ASSERT(0 != encoder->private_); |
2093 | 44.2k | FLAC__ASSERT(0 != encoder->protected_); |
2094 | 44.2k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2095 | 9.77k | return false; |
2096 | 34.4k | encoder->protected_->do_qlp_coeff_prec_search = value; |
2097 | 34.4k | return true; |
2098 | 44.2k | } |
2099 | | |
2100 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2101 | 44.0k | { |
2102 | 44.0k | FLAC__ASSERT(0 != encoder); |
2103 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2104 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2105 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2106 | 9.77k | return false; |
2107 | 34.2k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
2108 | | /* was deprecated since FLAC 1.0.4 (24-Sep-2002), but is needed for |
2109 | | * full spec coverage, so this should be reenabled at some point. |
2110 | | * For now only enable while fuzzing */ |
2111 | 34.2k | encoder->protected_->do_escape_coding = value; |
2112 | | #else |
2113 | | (void)value; |
2114 | | #endif |
2115 | 34.2k | return true; |
2116 | 44.0k | } |
2117 | | |
2118 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2119 | 46.0k | { |
2120 | 46.0k | FLAC__ASSERT(0 != encoder); |
2121 | 46.0k | FLAC__ASSERT(0 != encoder->private_); |
2122 | 46.0k | FLAC__ASSERT(0 != encoder->protected_); |
2123 | 46.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2124 | 9.77k | return false; |
2125 | 36.3k | encoder->protected_->do_exhaustive_model_search = value; |
2126 | 36.3k | return true; |
2127 | 46.0k | } |
2128 | | |
2129 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, uint32_t value) |
2130 | 44.0k | { |
2131 | 44.0k | FLAC__ASSERT(0 != encoder); |
2132 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2133 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2134 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2135 | 9.77k | return false; |
2136 | 34.2k | encoder->protected_->min_residual_partition_order = value; |
2137 | 34.2k | return true; |
2138 | 44.0k | } |
2139 | | |
2140 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, uint32_t value) |
2141 | 44.0k | { |
2142 | 44.0k | FLAC__ASSERT(0 != encoder); |
2143 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2144 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2145 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2146 | 9.77k | return false; |
2147 | 34.2k | encoder->protected_->max_residual_partition_order = value; |
2148 | 34.2k | return true; |
2149 | 44.0k | } |
2150 | | |
2151 | | FLAC_API uint32_t FLAC__stream_encoder_set_num_threads(FLAC__StreamEncoder *encoder, uint32_t value) |
2152 | 19.8k | { |
2153 | 19.8k | #ifdef FLAC__USE_THREADS |
2154 | 19.8k | FLAC__ASSERT(0 != encoder); |
2155 | 19.8k | FLAC__ASSERT(0 != encoder->private_); |
2156 | 19.8k | FLAC__ASSERT(0 != encoder->protected_); |
2157 | | |
2158 | 19.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2159 | 9.77k | return FLAC__STREAM_ENCODER_SET_NUM_THREADS_ALREADY_INITIALIZED; |
2160 | 10.0k | if(value > FLAC__STREAM_ENCODER_MAX_THREADS) |
2161 | 8.85k | return FLAC__STREAM_ENCODER_SET_NUM_THREADS_TOO_MANY_THREADS; |
2162 | 1.21k | if(value == 0) |
2163 | 345 | encoder->protected_->num_threads = 1; |
2164 | 869 | else |
2165 | 869 | encoder->protected_->num_threads = value; |
2166 | 1.21k | return FLAC__STREAM_ENCODER_SET_NUM_THREADS_OK; |
2167 | | #else |
2168 | | (void)encoder; |
2169 | | (void)value; |
2170 | | return FLAC__STREAM_ENCODER_SET_NUM_THREADS_NOT_COMPILED_WITH_MULTITHREADING_ENABLED; |
2171 | | #endif |
2172 | 10.0k | } |
2173 | | |
2174 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, uint32_t value) |
2175 | 44.0k | { |
2176 | 44.0k | FLAC__ASSERT(0 != encoder); |
2177 | 44.0k | FLAC__ASSERT(0 != encoder->private_); |
2178 | 44.0k | FLAC__ASSERT(0 != encoder->protected_); |
2179 | 44.0k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2180 | 9.77k | return false; |
2181 | | #if 0 |
2182 | | /*@@@ deprecated: */ |
2183 | | encoder->protected_->rice_parameter_search_dist = value; |
2184 | | #else |
2185 | 34.2k | (void)value; |
2186 | 34.2k | #endif |
2187 | 34.2k | return true; |
2188 | 44.0k | } |
2189 | | |
2190 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value) |
2191 | 19.9k | { |
2192 | 19.9k | FLAC__ASSERT(0 != encoder); |
2193 | 19.9k | FLAC__ASSERT(0 != encoder->private_); |
2194 | 19.9k | FLAC__ASSERT(0 != encoder->protected_); |
2195 | 19.9k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2196 | 9.77k | return false; |
2197 | 10.1k | value = flac_min(value, (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN) - 1); |
2198 | 10.1k | encoder->protected_->total_samples_estimate = value; |
2199 | 10.1k | return true; |
2200 | 19.9k | } |
2201 | | |
2202 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, uint32_t num_blocks) |
2203 | 0 | { |
2204 | 0 | FLAC__ASSERT(0 != encoder); |
2205 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2206 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2207 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2208 | 0 | return false; |
2209 | 0 | if(0 == metadata) |
2210 | 0 | num_blocks = 0; |
2211 | 0 | if(0 == num_blocks) |
2212 | 0 | metadata = 0; |
2213 | | /* realloc() does not do exactly what we want so... */ |
2214 | 0 | if(encoder->protected_->metadata) { |
2215 | 0 | free(encoder->protected_->metadata); |
2216 | 0 | encoder->protected_->metadata = 0; |
2217 | 0 | encoder->protected_->num_metadata_blocks = 0; |
2218 | 0 | } |
2219 | 0 | if(num_blocks) { |
2220 | 0 | FLAC__StreamMetadata **m; |
2221 | 0 | if(0 == (m = safe_malloc_mul_2op_p(sizeof(m[0]), /*times*/num_blocks))) |
2222 | 0 | return false; |
2223 | 0 | memcpy(m, metadata, sizeof(m[0]) * num_blocks); |
2224 | 0 | encoder->protected_->metadata = m; |
2225 | 0 | encoder->protected_->num_metadata_blocks = num_blocks; |
2226 | 0 | } |
2227 | 0 | #if FLAC__HAS_OGG |
2228 | 0 | if(!FLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks)) |
2229 | 0 | return false; |
2230 | 0 | #endif |
2231 | 0 | return true; |
2232 | 0 | } |
2233 | | |
2234 | | FLAC_API FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2235 | 19.8k | { |
2236 | 19.8k | FLAC__ASSERT(0 != encoder); |
2237 | 19.8k | FLAC__ASSERT(0 != encoder->private_); |
2238 | 19.8k | FLAC__ASSERT(0 != encoder->protected_); |
2239 | 19.8k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2240 | 9.77k | return false; |
2241 | 10.0k | encoder->protected_->limit_min_bitrate = value; |
2242 | 10.0k | return true; |
2243 | 19.8k | } |
2244 | | |
2245 | | /* |
2246 | | * These four functions are not static, but not publicly exposed in |
2247 | | * include/FLAC/ either. They are used by the test suite and in fuzzing |
2248 | | */ |
2249 | | FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2250 | 0 | { |
2251 | 0 | FLAC__ASSERT(0 != encoder); |
2252 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2253 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2254 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2255 | 0 | return false; |
2256 | 0 | encoder->private_->disable_mmx = value & 1; |
2257 | 0 | encoder->private_->disable_sse2 = value & 2; |
2258 | 0 | encoder->private_->disable_ssse3 = value & 4; |
2259 | 0 | encoder->private_->disable_sse41 = value & 8; |
2260 | 0 | encoder->private_->disable_avx2 = value & 16; |
2261 | 0 | encoder->private_->disable_fma = value & 32; |
2262 | 0 | encoder->private_->disable_sse42 = value & 64; |
2263 | 0 | return true; |
2264 | 0 | } |
2265 | | |
2266 | | FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2267 | 0 | { |
2268 | 0 | FLAC__ASSERT(0 != encoder); |
2269 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2270 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2271 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2272 | 0 | return false; |
2273 | 0 | encoder->private_->disable_constant_subframes = value; |
2274 | 0 | return true; |
2275 | 0 | } |
2276 | | |
2277 | | FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2278 | 0 | { |
2279 | 0 | FLAC__ASSERT(0 != encoder); |
2280 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2281 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2282 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2283 | 0 | return false; |
2284 | 0 | encoder->private_->disable_fixed_subframes = value; |
2285 | 0 | return true; |
2286 | 0 | } |
2287 | | |
2288 | | FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) |
2289 | 0 | { |
2290 | 0 | FLAC__ASSERT(0 != encoder); |
2291 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2292 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2293 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) |
2294 | 0 | return false; |
2295 | 0 | encoder->private_->disable_verbatim_subframes = value; |
2296 | 0 | return true; |
2297 | 0 | } |
2298 | | |
2299 | | FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder) |
2300 | 0 | { |
2301 | 0 | FLAC__ASSERT(0 != encoder); |
2302 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2303 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2304 | 0 | return encoder->protected_->state; |
2305 | 0 | } |
2306 | | |
2307 | | FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder) |
2308 | 202k | { |
2309 | 202k | FLAC__ASSERT(0 != encoder); |
2310 | 202k | FLAC__ASSERT(0 != encoder->private_); |
2311 | 202k | FLAC__ASSERT(0 != encoder->protected_); |
2312 | 202k | if(encoder->protected_->verify) |
2313 | 202k | if(encoder->private_->verify.decoder == NULL) |
2314 | 0 | return FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; |
2315 | 202k | else |
2316 | 202k | return FLAC__stream_decoder_get_state(encoder->private_->verify.decoder); |
2317 | 0 | else |
2318 | 0 | return FLAC__STREAM_DECODER_UNINITIALIZED; |
2319 | 202k | } |
2320 | | |
2321 | | FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder) |
2322 | 0 | { |
2323 | 0 | FLAC__ASSERT(0 != encoder); |
2324 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2325 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2326 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) |
2327 | 0 | return FLAC__StreamEncoderStateString[encoder->protected_->state]; |
2328 | 0 | else if(!encoder->private_->verify.decoder) |
2329 | 0 | return FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR]; |
2330 | 0 | else |
2331 | 0 | return FLAC__stream_decoder_get_resolved_state_string(encoder->private_->verify.decoder); |
2332 | 0 | } |
2333 | | |
2334 | | FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, uint32_t *frame_number, uint32_t *channel, uint32_t *sample, FLAC__int32 *expected, FLAC__int32 *got) |
2335 | 0 | { |
2336 | 0 | FLAC__ASSERT(0 != encoder); |
2337 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2338 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2339 | 0 | if(0 != absolute_sample) |
2340 | 0 | *absolute_sample = encoder->private_->verify.error_stats.absolute_sample; |
2341 | 0 | if(0 != frame_number) |
2342 | 0 | *frame_number = encoder->private_->verify.error_stats.frame_number; |
2343 | 0 | if(0 != channel) |
2344 | 0 | *channel = encoder->private_->verify.error_stats.channel; |
2345 | 0 | if(0 != sample) |
2346 | 0 | *sample = encoder->private_->verify.error_stats.sample; |
2347 | 0 | if(0 != expected) |
2348 | 0 | *expected = encoder->private_->verify.error_stats.expected; |
2349 | 0 | if(0 != got) |
2350 | 0 | *got = encoder->private_->verify.error_stats.got; |
2351 | 0 | } |
2352 | | |
2353 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder) |
2354 | 9.77k | { |
2355 | 9.77k | FLAC__ASSERT(0 != encoder); |
2356 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2357 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2358 | 9.77k | return encoder->protected_->verify; |
2359 | 9.77k | } |
2360 | | |
2361 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder) |
2362 | 9.77k | { |
2363 | 9.77k | FLAC__ASSERT(0 != encoder); |
2364 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2365 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2366 | 9.77k | return encoder->protected_->streamable_subset; |
2367 | 9.77k | } |
2368 | | |
2369 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) |
2370 | 0 | { |
2371 | 0 | FLAC__ASSERT(0 != encoder); |
2372 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2373 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2374 | 0 | return encoder->protected_->do_md5; |
2375 | 0 | } |
2376 | | |
2377 | | FLAC_API uint32_t FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder) |
2378 | 9.77k | { |
2379 | 9.77k | FLAC__ASSERT(0 != encoder); |
2380 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2381 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2382 | 9.77k | return encoder->protected_->channels; |
2383 | 9.77k | } |
2384 | | |
2385 | | FLAC_API uint32_t FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder) |
2386 | 398k | { |
2387 | 398k | FLAC__ASSERT(0 != encoder); |
2388 | 398k | FLAC__ASSERT(0 != encoder->private_); |
2389 | 398k | FLAC__ASSERT(0 != encoder->protected_); |
2390 | 398k | return encoder->protected_->bits_per_sample; |
2391 | 398k | } |
2392 | | |
2393 | | FLAC_API uint32_t FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder) |
2394 | 9.77k | { |
2395 | 9.77k | FLAC__ASSERT(0 != encoder); |
2396 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2397 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2398 | 9.77k | return encoder->protected_->sample_rate; |
2399 | 9.77k | } |
2400 | | |
2401 | | FLAC_API uint32_t FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder) |
2402 | 9.77k | { |
2403 | 9.77k | FLAC__ASSERT(0 != encoder); |
2404 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2405 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2406 | 9.77k | return encoder->protected_->blocksize; |
2407 | 9.77k | } |
2408 | | |
2409 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder) |
2410 | 9.77k | { |
2411 | 9.77k | FLAC__ASSERT(0 != encoder); |
2412 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2413 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2414 | 9.77k | return encoder->protected_->do_mid_side_stereo; |
2415 | 9.77k | } |
2416 | | |
2417 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder) |
2418 | 9.77k | { |
2419 | 9.77k | FLAC__ASSERT(0 != encoder); |
2420 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2421 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2422 | 9.77k | return encoder->protected_->loose_mid_side_stereo; |
2423 | 9.77k | } |
2424 | | |
2425 | | FLAC_API uint32_t FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder) |
2426 | 9.77k | { |
2427 | 9.77k | FLAC__ASSERT(0 != encoder); |
2428 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2429 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2430 | 9.77k | return encoder->protected_->max_lpc_order; |
2431 | 9.77k | } |
2432 | | |
2433 | | FLAC_API uint32_t FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder) |
2434 | 9.77k | { |
2435 | 9.77k | FLAC__ASSERT(0 != encoder); |
2436 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2437 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2438 | 9.77k | return encoder->protected_->qlp_coeff_precision; |
2439 | 9.77k | } |
2440 | | |
2441 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder) |
2442 | 9.77k | { |
2443 | 9.77k | FLAC__ASSERT(0 != encoder); |
2444 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2445 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2446 | 9.77k | return encoder->protected_->do_qlp_coeff_prec_search; |
2447 | 9.77k | } |
2448 | | |
2449 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder) |
2450 | 9.77k | { |
2451 | 9.77k | FLAC__ASSERT(0 != encoder); |
2452 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2453 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2454 | 9.77k | return encoder->protected_->do_escape_coding; |
2455 | 9.77k | } |
2456 | | |
2457 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder) |
2458 | 9.77k | { |
2459 | 9.77k | FLAC__ASSERT(0 != encoder); |
2460 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2461 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2462 | 9.77k | return encoder->protected_->do_exhaustive_model_search; |
2463 | 9.77k | } |
2464 | | |
2465 | | FLAC_API uint32_t FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder) |
2466 | 9.77k | { |
2467 | 9.77k | FLAC__ASSERT(0 != encoder); |
2468 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2469 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2470 | 9.77k | return encoder->protected_->min_residual_partition_order; |
2471 | 9.77k | } |
2472 | | |
2473 | | FLAC_API uint32_t FLAC__stream_encoder_get_num_threads(const FLAC__StreamEncoder *encoder) |
2474 | 9.77k | { |
2475 | 9.77k | FLAC__ASSERT(0 != encoder); |
2476 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2477 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2478 | 9.77k | return encoder->protected_->num_threads; |
2479 | 9.77k | } |
2480 | | |
2481 | | FLAC_API uint32_t FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder) |
2482 | 9.77k | { |
2483 | 9.77k | FLAC__ASSERT(0 != encoder); |
2484 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2485 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2486 | 9.77k | return encoder->protected_->max_residual_partition_order; |
2487 | 9.77k | } |
2488 | | |
2489 | | FLAC_API uint32_t FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder) |
2490 | 9.77k | { |
2491 | 9.77k | FLAC__ASSERT(0 != encoder); |
2492 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2493 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2494 | 9.77k | return encoder->protected_->rice_parameter_search_dist; |
2495 | 9.77k | } |
2496 | | |
2497 | | FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder) |
2498 | 9.77k | { |
2499 | 9.77k | FLAC__ASSERT(0 != encoder); |
2500 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2501 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2502 | 9.77k | return encoder->protected_->total_samples_estimate; |
2503 | 9.77k | } |
2504 | | |
2505 | | FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder) |
2506 | 9.77k | { |
2507 | 9.77k | FLAC__ASSERT(0 != encoder); |
2508 | 9.77k | FLAC__ASSERT(0 != encoder->private_); |
2509 | 9.77k | FLAC__ASSERT(0 != encoder->protected_); |
2510 | 9.77k | return encoder->protected_->limit_min_bitrate; |
2511 | 9.77k | } |
2512 | | |
2513 | | FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], uint32_t samples) |
2514 | 0 | { |
2515 | 0 | uint32_t i, j = 0, k = 0, channel; |
2516 | 0 | uint32_t channels; |
2517 | 0 | uint32_t blocksize; |
2518 | 0 | FLAC__int32 sample_max; |
2519 | 0 | FLAC__int32 sample_min; |
2520 | |
|
2521 | 0 | FLAC__ASSERT(0 != encoder); |
2522 | 0 | FLAC__ASSERT(0 != encoder->private_); |
2523 | 0 | FLAC__ASSERT(0 != encoder->protected_); |
2524 | |
|
2525 | 0 | channels = encoder->protected_->channels; |
2526 | 0 | blocksize = encoder->protected_->blocksize; |
2527 | 0 | sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample); |
2528 | 0 | sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample); |
2529 | |
|
2530 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) |
2531 | 0 | return false; |
2532 | | |
2533 | 0 | do { |
2534 | 0 | const uint32_t n = flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j); |
2535 | |
|
2536 | 0 | if(encoder->protected_->verify) |
2537 | 0 | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n); |
2538 | |
|
2539 | 0 | for(channel = 0; channel < channels; channel++) { |
2540 | 0 | if (buffer[channel] == NULL) { |
2541 | 0 | return false; |
2542 | 0 | } |
2543 | 0 | for(i = encoder->private_->current_sample_number, k = j; i <= blocksize && k < samples; i++, k++) { |
2544 | 0 | if(buffer[channel][k] < sample_min || buffer[channel][k] > sample_max){ |
2545 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
2546 | 0 | return false; |
2547 | 0 | } |
2548 | 0 | } |
2549 | 0 | memcpy(&encoder->private_->threadtask[0]->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n); |
2550 | 0 | } |
2551 | 0 | j += n; |
2552 | 0 | encoder->private_->current_sample_number += n; |
2553 | | |
2554 | | /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ |
2555 | 0 | if(encoder->private_->current_sample_number > blocksize) { |
2556 | 0 | FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_); |
2557 | 0 | FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ |
2558 | 0 | if(!process_frame_(encoder, /*is_last_block=*/false)) |
2559 | 0 | return false; |
2560 | | /* move unprocessed overread samples to beginnings of arrays */ |
2561 | 0 | for(channel = 0; channel < channels; channel++) |
2562 | 0 | encoder->private_->threadtask[0]->integer_signal[channel][0] = encoder->private_->threadtask[0]->integer_signal[channel][blocksize]; |
2563 | 0 | encoder->private_->current_sample_number = 1; |
2564 | 0 | } |
2565 | 0 | } while(j < samples); |
2566 | | |
2567 | 0 | return true; |
2568 | 0 | } |
2569 | | |
2570 | | FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], uint32_t samples) |
2571 | 186k | { |
2572 | 186k | uint32_t i, j, k, channel; |
2573 | 186k | uint32_t channels; |
2574 | 186k | uint32_t blocksize; |
2575 | 186k | FLAC__int32 sample_max; |
2576 | 186k | FLAC__int32 sample_min; |
2577 | | |
2578 | 186k | FLAC__ASSERT(0 != encoder); |
2579 | 186k | FLAC__ASSERT(0 != encoder->private_); |
2580 | 186k | FLAC__ASSERT(0 != encoder->protected_); |
2581 | | |
2582 | 186k | channels = encoder->protected_->channels; |
2583 | 186k | blocksize = encoder->protected_->blocksize; |
2584 | 186k | sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample); |
2585 | 186k | sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample); |
2586 | | |
2587 | 186k | if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) |
2588 | 1.04k | return false; |
2589 | | |
2590 | 185k | j = k = 0; |
2591 | 416k | do { |
2592 | 416k | if(encoder->protected_->verify) |
2593 | 365k | append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); |
2594 | | |
2595 | | /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ |
2596 | 23.6M | for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { |
2597 | 52.2M | for(channel = 0; channel < channels; channel++){ |
2598 | 28.9M | if(buffer[k] < sample_min || buffer[k] > sample_max){ |
2599 | 71 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
2600 | 71 | return false; |
2601 | 71 | } |
2602 | 28.9M | encoder->private_->threadtask[0]->integer_signal[channel][i] = buffer[k++]; |
2603 | 28.9M | } |
2604 | 23.2M | } |
2605 | 416k | encoder->private_->current_sample_number = i; |
2606 | | /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ |
2607 | 416k | if(i > blocksize) { |
2608 | 233k | if(!process_frame_(encoder, /*is_last_block=*/false)) |
2609 | 0 | return false; |
2610 | | /* move unprocessed overread samples to beginnings of arrays */ |
2611 | 233k | FLAC__ASSERT(i == blocksize+OVERREAD_); |
2612 | 233k | FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ |
2613 | 529k | for(channel = 0; channel < channels; channel++) |
2614 | 295k | encoder->private_->threadtask[0]->integer_signal[channel][0] = encoder->private_->threadtask[0]->integer_signal[channel][blocksize]; |
2615 | 233k | encoder->private_->current_sample_number = 1; |
2616 | 233k | } |
2617 | 416k | } while(j < samples); |
2618 | | |
2619 | 185k | return true; |
2620 | 185k | } |
2621 | | |
2622 | | /*********************************************************************** |
2623 | | * |
2624 | | * Private class methods |
2625 | | * |
2626 | | ***********************************************************************/ |
2627 | | |
2628 | | void set_defaults_(FLAC__StreamEncoder *encoder) |
2629 | 21.8k | { |
2630 | 21.8k | FLAC__ASSERT(0 != encoder); |
2631 | | |
2632 | | #ifdef FLAC__MANDATORY_VERIFY_WHILE_ENCODING |
2633 | | encoder->protected_->verify = true; |
2634 | | #else |
2635 | 21.8k | encoder->protected_->verify = false; |
2636 | 21.8k | #endif |
2637 | 21.8k | encoder->protected_->streamable_subset = true; |
2638 | 21.8k | encoder->protected_->do_md5 = true; |
2639 | 21.8k | encoder->protected_->do_mid_side_stereo = false; |
2640 | 21.8k | encoder->protected_->loose_mid_side_stereo = false; |
2641 | 21.8k | encoder->protected_->channels = 2; |
2642 | 21.8k | encoder->protected_->bits_per_sample = 16; |
2643 | 21.8k | encoder->protected_->sample_rate = 44100; |
2644 | 21.8k | encoder->protected_->blocksize = 0; |
2645 | 21.8k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2646 | 21.8k | encoder->protected_->num_apodizations = 1; |
2647 | 21.8k | encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; |
2648 | 21.8k | encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; |
2649 | 21.8k | #endif |
2650 | 21.8k | encoder->protected_->max_lpc_order = 0; |
2651 | 21.8k | encoder->protected_->qlp_coeff_precision = 0; |
2652 | 21.8k | encoder->protected_->do_qlp_coeff_prec_search = false; |
2653 | 21.8k | encoder->protected_->do_exhaustive_model_search = false; |
2654 | 21.8k | encoder->protected_->do_escape_coding = false; |
2655 | 21.8k | encoder->protected_->min_residual_partition_order = 0; |
2656 | 21.8k | encoder->protected_->max_residual_partition_order = 0; |
2657 | 21.8k | encoder->protected_->rice_parameter_search_dist = 0; |
2658 | 21.8k | encoder->protected_->total_samples_estimate = 0; |
2659 | 21.8k | encoder->protected_->limit_min_bitrate = false; |
2660 | 21.8k | encoder->protected_->metadata = 0; |
2661 | 21.8k | encoder->protected_->num_metadata_blocks = 0; |
2662 | 21.8k | encoder->protected_->num_threads = 1; |
2663 | | |
2664 | 21.8k | encoder->private_->seek_table = 0; |
2665 | 21.8k | encoder->private_->disable_mmx = false; |
2666 | 21.8k | encoder->private_->disable_sse2 = false; |
2667 | 21.8k | encoder->private_->disable_ssse3 = false; |
2668 | 21.8k | encoder->private_->disable_sse41 = false; |
2669 | 21.8k | encoder->private_->disable_sse42 = false; |
2670 | 21.8k | encoder->private_->disable_avx2 = false; |
2671 | 21.8k | encoder->private_->disable_constant_subframes = false; |
2672 | 21.8k | encoder->private_->disable_fixed_subframes = false; |
2673 | 21.8k | encoder->private_->disable_verbatim_subframes = false; |
2674 | 21.8k | encoder->private_->is_ogg = false; |
2675 | 21.8k | encoder->private_->read_callback = 0; |
2676 | 21.8k | encoder->private_->write_callback = 0; |
2677 | 21.8k | encoder->private_->seek_callback = 0; |
2678 | 21.8k | encoder->private_->tell_callback = 0; |
2679 | 21.8k | encoder->private_->metadata_callback = 0; |
2680 | 21.8k | encoder->private_->progress_callback = 0; |
2681 | 21.8k | encoder->private_->client_data = 0; |
2682 | 21.8k | encoder->private_->num_threadtasks = 1; |
2683 | 21.8k | #ifdef FLAC__USE_THREADS |
2684 | 21.8k | encoder->private_->num_created_threads = 1; |
2685 | 21.8k | encoder->private_->next_thread = 1; |
2686 | 21.8k | encoder->private_->num_running_threads = 1; |
2687 | 21.8k | encoder->private_->num_started_threadtasks = 1; |
2688 | 21.8k | encoder->private_->num_available_threadtasks = 0; |
2689 | 21.8k | encoder->private_->overcommitted_indicator = 0; |
2690 | 21.8k | encoder->private_->next_threadtask = 1; |
2691 | 21.8k | encoder->private_->md5_active = false; |
2692 | 21.8k | encoder->private_->finish_work_threads = false; |
2693 | 21.8k | #endif |
2694 | | |
2695 | 21.8k | #if FLAC__HAS_OGG |
2696 | 21.8k | FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect); |
2697 | 21.8k | #endif |
2698 | | |
2699 | 21.8k | FLAC__stream_encoder_set_compression_level(encoder, 5); |
2700 | 21.8k | } |
2701 | | |
2702 | | void free_(FLAC__StreamEncoder *encoder) |
2703 | 9.77k | { |
2704 | 9.77k | uint32_t i, t, channel; |
2705 | | |
2706 | 9.77k | FLAC__ASSERT(0 != encoder); |
2707 | 9.77k | if(encoder->protected_->metadata) { |
2708 | 0 | free(encoder->protected_->metadata); |
2709 | 0 | encoder->protected_->metadata = 0; |
2710 | 0 | encoder->protected_->num_metadata_blocks = 0; |
2711 | 0 | } |
2712 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2713 | 32.5k | for(i = 0; i < encoder->protected_->num_apodizations; i++) { |
2714 | 22.7k | if(0 != encoder->private_->window_unaligned[i]) { |
2715 | 21.3k | free(encoder->private_->window_unaligned[i]); |
2716 | 21.3k | encoder->private_->window_unaligned[i] = 0; |
2717 | 21.3k | } |
2718 | 22.7k | } |
2719 | 9.77k | #endif |
2720 | 33.5k | for(t = 0; t < encoder->private_->num_threadtasks; t++) { |
2721 | 23.7k | if(0 == encoder->private_->threadtask[t]) |
2722 | 0 | continue; |
2723 | 62.3k | for(i = 0; i < encoder->protected_->channels; i++) { |
2724 | 38.6k | if(0 != encoder->private_->threadtask[t]->integer_signal_unaligned[i]) { |
2725 | 38.6k | free(encoder->private_->threadtask[t]->integer_signal_unaligned[i]); |
2726 | 38.6k | encoder->private_->threadtask[t]->integer_signal_unaligned[i] = 0; |
2727 | 38.6k | } |
2728 | 38.6k | } |
2729 | 71.2k | for(i = 0; i < 2; i++) { |
2730 | 47.4k | if(0 != encoder->private_->threadtask[t]->integer_signal_mid_side_unaligned[i]) { |
2731 | 47.4k | free(encoder->private_->threadtask[t]->integer_signal_mid_side_unaligned[i]); |
2732 | 47.4k | encoder->private_->threadtask[t]->integer_signal_mid_side_unaligned[i] = 0; |
2733 | 47.4k | } |
2734 | 47.4k | } |
2735 | 23.7k | if(0 != encoder->private_->threadtask[t]->integer_signal_33bit_side_unaligned){ |
2736 | 23.7k | free(encoder->private_->threadtask[t]->integer_signal_33bit_side_unaligned); |
2737 | 23.7k | encoder->private_->threadtask[t]->integer_signal_33bit_side_unaligned = 0; |
2738 | 23.7k | } |
2739 | 23.7k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2740 | 23.7k | if(0 != encoder->private_->threadtask[t]->windowed_signal_unaligned) { |
2741 | 15.8k | free(encoder->private_->threadtask[t]->windowed_signal_unaligned); |
2742 | 15.8k | encoder->private_->threadtask[t]->windowed_signal_unaligned = 0; |
2743 | 15.8k | } |
2744 | 23.7k | #endif |
2745 | 62.3k | for(channel = 0; channel < encoder->protected_->channels; channel++) { |
2746 | 115k | for(i = 0; i < 2; i++) { |
2747 | 77.2k | if(0 != encoder->private_->threadtask[t]->residual_workspace_unaligned[channel][i]) { |
2748 | 77.2k | free(encoder->private_->threadtask[t]->residual_workspace_unaligned[channel][i]); |
2749 | 77.2k | encoder->private_->threadtask[t]->residual_workspace_unaligned[channel][i] = 0; |
2750 | 77.2k | } |
2751 | 77.2k | } |
2752 | 38.6k | } |
2753 | 71.2k | for(channel = 0; channel < 2; channel++) { |
2754 | 142k | for(i = 0; i < 2; i++) { |
2755 | 94.9k | if(0 != encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[channel][i]) { |
2756 | 94.9k | free(encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[channel][i]); |
2757 | 94.9k | encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[channel][i] = 0; |
2758 | 94.9k | } |
2759 | 94.9k | } |
2760 | 47.4k | } |
2761 | 23.7k | if(0 != encoder->private_->threadtask[t]->abs_residual_partition_sums_unaligned) { |
2762 | 23.7k | free(encoder->private_->threadtask[t]->abs_residual_partition_sums_unaligned); |
2763 | 23.7k | encoder->private_->threadtask[t]->abs_residual_partition_sums_unaligned = 0; |
2764 | 23.7k | } |
2765 | 23.7k | if(0 != encoder->private_->threadtask[t]->raw_bits_per_partition_unaligned) { |
2766 | 16.3k | free(encoder->private_->threadtask[t]->raw_bits_per_partition_unaligned); |
2767 | 16.3k | encoder->private_->threadtask[t]->raw_bits_per_partition_unaligned = 0; |
2768 | 16.3k | } |
2769 | 213k | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { |
2770 | 189k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][0]); |
2771 | 189k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[i][1]); |
2772 | 189k | } |
2773 | 71.2k | for(i = 0; i < 2; i++) { |
2774 | 47.4k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][0]); |
2775 | 47.4k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[i][1]); |
2776 | 47.4k | } |
2777 | 71.2k | for(i = 0; i < 2; i++) |
2778 | 47.4k | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->threadtask[t]->partitioned_rice_contents_extra[i]); |
2779 | 23.7k | if(t > 0) { |
2780 | 13.9k | #ifdef FLAC__USE_THREADS |
2781 | 13.9k | FLAC__bitwriter_delete(encoder->private_->threadtask[t]->frame); |
2782 | 13.9k | FLAC__mtx_destroy(&encoder->private_->threadtask[t]->mutex_this_task); |
2783 | 13.9k | FLAC__cnd_destroy(&encoder->private_->threadtask[t]->cond_task_done); |
2784 | 13.9k | free(encoder->private_->threadtask[t]); |
2785 | 13.9k | encoder->private_->threadtask[t] = 0; |
2786 | | #else |
2787 | | FLAC__ASSERT(0); |
2788 | | #endif |
2789 | 13.9k | } |
2790 | | |
2791 | 23.7k | } |
2792 | 9.77k | #ifdef FLAC__USE_THREADS |
2793 | 9.77k | if(encoder->protected_->num_threads > 1) { |
2794 | 852 | FLAC__mtx_destroy(&encoder->private_->mutex_md5_fifo); |
2795 | 852 | FLAC__mtx_destroy(&encoder->private_->mutex_work_queue); |
2796 | 852 | FLAC__cnd_destroy(&encoder->private_->cond_md5_emptied); |
2797 | 852 | FLAC__cnd_destroy(&encoder->private_->cond_work_available); |
2798 | 852 | FLAC__cnd_destroy(&encoder->private_->cond_wake_up_thread); |
2799 | 852 | if(encoder->protected_->do_md5) { |
2800 | 2.11k | for(i = 0; i < encoder->protected_->channels; i++) { |
2801 | 1.25k | if(0 != encoder->private_->md5_fifo.data[i]) { |
2802 | 1.25k | free(encoder->private_->md5_fifo.data[i]); |
2803 | 1.25k | encoder->private_->md5_fifo.data[i] = 0; |
2804 | 1.25k | } |
2805 | 1.25k | } |
2806 | 852 | } |
2807 | | |
2808 | 852 | } |
2809 | 9.77k | #endif |
2810 | 9.77k | if(encoder->protected_->verify) { |
2811 | 23.4k | for(i = 0; i < encoder->protected_->channels; i++) { |
2812 | 14.8k | if(0 != encoder->private_->verify.input_fifo.data[i]) { |
2813 | 14.8k | free(encoder->private_->verify.input_fifo.data[i]); |
2814 | 14.8k | encoder->private_->verify.input_fifo.data[i] = 0; |
2815 | 14.8k | } |
2816 | 14.8k | } |
2817 | 8.56k | } |
2818 | 9.77k | } |
2819 | | |
2820 | | FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize) |
2821 | 18.6k | { |
2822 | 18.6k | FLAC__bool ok; |
2823 | 18.6k | uint32_t i, t, channel; |
2824 | | |
2825 | 18.6k | FLAC__ASSERT(new_blocksize > 0); |
2826 | 18.6k | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); |
2827 | | |
2828 | 18.6k | ok = true; |
2829 | | |
2830 | | /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */ |
2831 | 18.6k | if(new_blocksize > encoder->private_->input_capacity) { |
2832 | | |
2833 | | /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2() |
2834 | | * require that the input arrays (in our case the integer signals) |
2835 | | * have a buffer of up to 3 zeroes in front (at negative indices) for |
2836 | | * alignment purposes; we use 4 in front to keep the data well-aligned. |
2837 | | */ |
2838 | 9.77k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2839 | 9.77k | if(ok && encoder->protected_->max_lpc_order > 0) { |
2840 | 29.7k | for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) |
2841 | 21.3k | ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]); |
2842 | 8.38k | } |
2843 | 9.77k | #endif |
2844 | 33.5k | for(t = 0; t < encoder->private_->num_threadtasks; t++) { |
2845 | 62.3k | for(i = 0; ok && i < encoder->protected_->channels; i++) { |
2846 | 38.6k | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->threadtask[t]->integer_signal_unaligned[i], &encoder->private_->threadtask[t]->integer_signal[i]); |
2847 | 38.6k | if(ok) { |
2848 | 38.6k | memset(encoder->private_->threadtask[t]->integer_signal[i], 0, sizeof(FLAC__int32)*4); |
2849 | 38.6k | encoder->private_->threadtask[t]->integer_signal[i] += 4; |
2850 | 38.6k | } |
2851 | 38.6k | } |
2852 | 71.2k | for(i = 0; ok && i < 2; i++) { |
2853 | 47.4k | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->threadtask[t]->integer_signal_mid_side_unaligned[i], &encoder->private_->threadtask[t]->integer_signal_mid_side[i]); |
2854 | 47.4k | if(ok) { |
2855 | 47.4k | memset(encoder->private_->threadtask[t]->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); |
2856 | 47.4k | encoder->private_->threadtask[t]->integer_signal_mid_side[i] += 4; |
2857 | 47.4k | } |
2858 | 47.4k | } |
2859 | 23.7k | ok = ok && FLAC__memory_alloc_aligned_int64_array(new_blocksize+4+OVERREAD_, &encoder->private_->threadtask[t]->integer_signal_33bit_side_unaligned, &encoder->private_->threadtask[t]->integer_signal_33bit_side); |
2860 | 23.7k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2861 | 23.7k | if(ok && encoder->protected_->max_lpc_order > 0) { |
2862 | 15.8k | ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->threadtask[t]->windowed_signal_unaligned, &encoder->private_->threadtask[t]->windowed_signal); |
2863 | 15.8k | } |
2864 | 23.7k | #endif |
2865 | 62.3k | for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { |
2866 | 115k | for(i = 0; ok && i < 2; i++) { |
2867 | 77.2k | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->threadtask[t]->residual_workspace_unaligned[channel][i], &encoder->private_->threadtask[t]->residual_workspace[channel][i]); |
2868 | 77.2k | } |
2869 | 38.6k | } |
2870 | | |
2871 | | |
2872 | 62.3k | for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { |
2873 | 115k | for(i = 0; ok && i < 2; i++) { |
2874 | 77.2k | ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order); |
2875 | 77.2k | ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order); |
2876 | 77.2k | } |
2877 | 38.6k | } |
2878 | | |
2879 | 71.2k | for(channel = 0; ok && channel < 2; channel++) { |
2880 | 142k | for(i = 0; ok && i < 2; i++) { |
2881 | 94.9k | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->threadtask[t]->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->threadtask[t]->residual_workspace_mid_side[channel][i]); |
2882 | 94.9k | } |
2883 | 47.4k | } |
2884 | | |
2885 | 71.2k | for(channel = 0; ok && channel < 2; channel++) { |
2886 | 142k | for(i = 0; ok && i < 2; i++) { |
2887 | 94.9k | ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->threadtask[t]->partitioned_rice_contents_workspace_mid_side[channel][i], encoder->protected_->max_residual_partition_order); |
2888 | 94.9k | } |
2889 | 47.4k | } |
2890 | | |
2891 | 71.2k | for(i = 0; ok && i < 2; i++) { |
2892 | 47.4k | ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->threadtask[t]->partitioned_rice_contents_extra[i], encoder->protected_->max_residual_partition_order); |
2893 | 47.4k | } |
2894 | | |
2895 | | |
2896 | | /* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */ |
2897 | | /*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */ |
2898 | 23.7k | ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->threadtask[t]->abs_residual_partition_sums_unaligned, &encoder->private_->threadtask[t]->abs_residual_partition_sums); |
2899 | 23.7k | if(encoder->protected_->do_escape_coding) |
2900 | 16.3k | ok = ok && FLAC__memory_alloc_aligned_uint32_array(new_blocksize * 2, &encoder->private_->threadtask[t]->raw_bits_per_partition_unaligned, &encoder->private_->threadtask[t]->raw_bits_per_partition); |
2901 | 23.7k | } |
2902 | 9.77k | } |
2903 | 18.6k | if(ok) |
2904 | 18.6k | encoder->private_->input_capacity = new_blocksize; |
2905 | 0 | else { |
2906 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
2907 | 0 | return ok; |
2908 | 0 | } |
2909 | | |
2910 | | |
2911 | | /* now adjust the windows if the blocksize has changed */ |
2912 | 18.6k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
2913 | 18.6k | if(encoder->protected_->max_lpc_order > 0 && new_blocksize > 1) { |
2914 | 54.7k | for(i = 0; i < encoder->protected_->num_apodizations; i++) { |
2915 | 39.4k | switch(encoder->protected_->apodizations[i].type) { |
2916 | 842 | case FLAC__APODIZATION_BARTLETT: |
2917 | 842 | FLAC__window_bartlett(encoder->private_->window[i], new_blocksize); |
2918 | 842 | break; |
2919 | 102 | case FLAC__APODIZATION_BARTLETT_HANN: |
2920 | 102 | FLAC__window_bartlett_hann(encoder->private_->window[i], new_blocksize); |
2921 | 102 | break; |
2922 | 103 | case FLAC__APODIZATION_BLACKMAN: |
2923 | 103 | FLAC__window_blackman(encoder->private_->window[i], new_blocksize); |
2924 | 103 | break; |
2925 | 91 | case FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE: |
2926 | 91 | FLAC__window_blackman_harris_4term_92db_sidelobe(encoder->private_->window[i], new_blocksize); |
2927 | 91 | break; |
2928 | 229 | case FLAC__APODIZATION_CONNES: |
2929 | 229 | FLAC__window_connes(encoder->private_->window[i], new_blocksize); |
2930 | 229 | break; |
2931 | 126 | case FLAC__APODIZATION_FLATTOP: |
2932 | 126 | FLAC__window_flattop(encoder->private_->window[i], new_blocksize); |
2933 | 126 | break; |
2934 | 185 | case FLAC__APODIZATION_GAUSS: |
2935 | 185 | FLAC__window_gauss(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.gauss.stddev); |
2936 | 185 | break; |
2937 | 277 | case FLAC__APODIZATION_HAMMING: |
2938 | 277 | FLAC__window_hamming(encoder->private_->window[i], new_blocksize); |
2939 | 277 | break; |
2940 | 573 | case FLAC__APODIZATION_HANN: |
2941 | 573 | FLAC__window_hann(encoder->private_->window[i], new_blocksize); |
2942 | 573 | break; |
2943 | 106 | case FLAC__APODIZATION_KAISER_BESSEL: |
2944 | 106 | FLAC__window_kaiser_bessel(encoder->private_->window[i], new_blocksize); |
2945 | 106 | break; |
2946 | 136 | case FLAC__APODIZATION_NUTTALL: |
2947 | 136 | FLAC__window_nuttall(encoder->private_->window[i], new_blocksize); |
2948 | 136 | break; |
2949 | 241 | case FLAC__APODIZATION_RECTANGLE: |
2950 | 241 | FLAC__window_rectangle(encoder->private_->window[i], new_blocksize); |
2951 | 241 | break; |
2952 | 709 | case FLAC__APODIZATION_TRIANGLE: |
2953 | 709 | FLAC__window_triangle(encoder->private_->window[i], new_blocksize); |
2954 | 709 | break; |
2955 | 12.6k | case FLAC__APODIZATION_TUKEY: |
2956 | 12.6k | FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); |
2957 | 12.6k | break; |
2958 | 8.34k | case FLAC__APODIZATION_PARTIAL_TUKEY: |
2959 | 8.34k | FLAC__window_partial_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); |
2960 | 8.34k | break; |
2961 | 10.8k | case FLAC__APODIZATION_PUNCHOUT_TUKEY: |
2962 | 10.8k | FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); |
2963 | 10.8k | break; |
2964 | 3.65k | case FLAC__APODIZATION_SUBDIVIDE_TUKEY: |
2965 | 3.65k | FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); |
2966 | 3.65k | break; |
2967 | 268 | case FLAC__APODIZATION_WELCH: |
2968 | 268 | FLAC__window_welch(encoder->private_->window[i], new_blocksize); |
2969 | 268 | break; |
2970 | 0 | default: |
2971 | 0 | FLAC__ASSERT(0); |
2972 | | /* double protection */ |
2973 | 0 | FLAC__window_hann(encoder->private_->window[i], new_blocksize); |
2974 | 0 | break; |
2975 | 39.4k | } |
2976 | 39.4k | } |
2977 | 15.2k | } |
2978 | 18.6k | if (new_blocksize <= FLAC__MAX_LPC_ORDER) { |
2979 | | /* intrinsics autocorrelation routines do not all handle cases in which lag might be |
2980 | | * larger than data_len. Lag is one larger than the LPC order */ |
2981 | 8.58k | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; |
2982 | 8.58k | } |
2983 | 18.6k | #endif |
2984 | | |
2985 | 18.6k | return true; |
2986 | 18.6k | } |
2987 | | |
2988 | | FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderThreadTask *threadtask, uint32_t samples, FLAC__bool is_last_block) |
2989 | 272k | { |
2990 | 272k | const FLAC__byte *buffer; |
2991 | 272k | size_t bytes; |
2992 | | |
2993 | 272k | FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(threadtask->frame)); |
2994 | | |
2995 | 272k | if(!FLAC__bitwriter_get_buffer(threadtask->frame, &buffer, &bytes)) { |
2996 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
2997 | 0 | return false; |
2998 | 0 | } |
2999 | | |
3000 | 272k | if(encoder->protected_->verify) { |
3001 | 218k | encoder->private_->verify.output.data = buffer; |
3002 | 218k | encoder->private_->verify.output.bytes = bytes; |
3003 | 218k | if(encoder->private_->verify.state_hint == ENCODER_IN_MAGIC) { |
3004 | 8.56k | encoder->private_->verify.needs_magic_hack = true; |
3005 | 8.56k | } |
3006 | 210k | else { |
3007 | 210k | if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder) |
3008 | 210k | || (!is_last_block |
3009 | 202k | && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM)) |
3010 | 210k | || encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR /* Happens when error callback was used */) { |
3011 | 0 | FLAC__bitwriter_release_buffer(threadtask->frame); |
3012 | 0 | FLAC__bitwriter_clear(threadtask->frame); |
3013 | 0 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) |
3014 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; |
3015 | 0 | return false; |
3016 | 0 | } |
3017 | 210k | } |
3018 | 218k | } |
3019 | | |
3020 | 272k | if(write_frame_(encoder, buffer, bytes, samples, is_last_block) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3021 | 0 | FLAC__bitwriter_release_buffer(threadtask->frame); |
3022 | 0 | FLAC__bitwriter_clear(threadtask->frame); |
3023 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3024 | 0 | return false; |
3025 | 0 | } |
3026 | | |
3027 | 272k | FLAC__bitwriter_release_buffer(threadtask->frame); |
3028 | 272k | FLAC__bitwriter_clear(threadtask->frame); |
3029 | | |
3030 | 272k | if(samples > 0) { |
3031 | 242k | encoder->private_->streaminfo.data.stream_info.min_framesize = flac_min(bytes, encoder->private_->streaminfo.data.stream_info.min_framesize); |
3032 | 242k | encoder->private_->streaminfo.data.stream_info.max_framesize = flac_max(bytes, encoder->private_->streaminfo.data.stream_info.max_framesize); |
3033 | 242k | } |
3034 | | |
3035 | 272k | return true; |
3036 | 272k | } |
3037 | | |
3038 | | FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, FLAC__bool is_last_block) |
3039 | 272k | { |
3040 | 272k | FLAC__StreamEncoderWriteStatus status; |
3041 | 272k | FLAC__uint64 output_position = 0; |
3042 | | |
3043 | | #if FLAC__HAS_OGG == 0 |
3044 | | (void)is_last_block; |
3045 | | #endif |
3046 | | |
3047 | | /* |
3048 | | * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets. |
3049 | | */ |
3050 | 272k | if(samples == 0) { |
3051 | 29.3k | FLAC__MetadataType type = (buffer[0] & 0x7f); |
3052 | | |
3053 | | /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ |
3054 | 29.3k | if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { |
3055 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3056 | 0 | return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; |
3057 | 0 | } |
3058 | | |
3059 | 29.3k | if(type == FLAC__METADATA_TYPE_STREAMINFO) |
3060 | 9.77k | encoder->protected_->streaminfo_offset = output_position; |
3061 | 19.5k | else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0) |
3062 | 0 | encoder->protected_->seektable_offset = output_position; |
3063 | 29.3k | } |
3064 | | |
3065 | | /* |
3066 | | * Mark the current seek point if hit (if audio_offset == 0 that |
3067 | | * means we're still writing metadata and haven't hit the first |
3068 | | * frame yet) |
3069 | | */ |
3070 | 272k | if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) { |
3071 | 0 | const uint32_t blocksize = FLAC__stream_encoder_get_blocksize(encoder); |
3072 | 0 | const FLAC__uint64 frame_first_sample = encoder->private_->samples_written; |
3073 | 0 | const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1; |
3074 | 0 | FLAC__uint64 test_sample; |
3075 | 0 | uint32_t i; |
3076 | 0 | for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) { |
3077 | 0 | test_sample = encoder->private_->seek_table->points[i].sample_number; |
3078 | 0 | if(test_sample > frame_last_sample) { |
3079 | 0 | break; |
3080 | 0 | } |
3081 | 0 | else if(test_sample >= frame_first_sample) { |
3082 | | /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */ |
3083 | 0 | if(output_position == 0 && encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { |
3084 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3085 | 0 | return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; |
3086 | 0 | } |
3087 | | |
3088 | 0 | encoder->private_->seek_table->points[i].sample_number = frame_first_sample; |
3089 | 0 | encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset; |
3090 | 0 | encoder->private_->seek_table->points[i].frame_samples = blocksize; |
3091 | 0 | encoder->private_->first_seekpoint_to_check++; |
3092 | | /* DO NOT: "break;" and here's why: |
3093 | | * The seektable template may contain more than one target |
3094 | | * sample for any given frame; we will keep looping, generating |
3095 | | * duplicate seekpoints for them, and we'll clean it up later, |
3096 | | * just before writing the seektable back to the metadata. |
3097 | | */ |
3098 | 0 | } |
3099 | 0 | else { |
3100 | 0 | encoder->private_->first_seekpoint_to_check++; |
3101 | 0 | } |
3102 | 0 | } |
3103 | 0 | } |
3104 | | |
3105 | 272k | #if FLAC__HAS_OGG |
3106 | 272k | if(encoder->private_->is_ogg) { |
3107 | 155k | status = FLAC__ogg_encoder_aspect_write_callback_wrapper( |
3108 | 155k | &encoder->protected_->ogg_encoder_aspect, |
3109 | 155k | buffer, |
3110 | 155k | bytes, |
3111 | 155k | samples, |
3112 | 155k | encoder->private_->current_frame_number, |
3113 | 155k | is_last_block, |
3114 | 155k | (FLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, |
3115 | 155k | encoder, |
3116 | 155k | encoder->private_->client_data |
3117 | 155k | ); |
3118 | 155k | } |
3119 | 116k | else |
3120 | 116k | #endif |
3121 | 116k | status = encoder->private_->write_callback(encoder, buffer, bytes, samples, encoder->private_->current_frame_number, encoder->private_->client_data); |
3122 | | |
3123 | 272k | if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3124 | 272k | encoder->private_->bytes_written += bytes; |
3125 | 272k | encoder->private_->samples_written += samples; |
3126 | | /* we keep a high watermark on the number of frames written because |
3127 | | * when the encoder goes back to write metadata, 'current_frame' |
3128 | | * will drop back to 0. |
3129 | | */ |
3130 | 272k | encoder->private_->frames_written = flac_max(encoder->private_->frames_written, encoder->private_->current_frame_number+1); |
3131 | 272k | } |
3132 | 0 | else |
3133 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3134 | | |
3135 | 272k | return status; |
3136 | 272k | } |
3137 | | |
3138 | | /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ |
3139 | | void update_metadata_(const FLAC__StreamEncoder *encoder) |
3140 | 6.62k | { |
3141 | 6.62k | FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; |
3142 | 6.62k | const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; |
3143 | 6.62k | FLAC__uint64 samples = metadata->data.stream_info.total_samples; |
3144 | 6.62k | const uint32_t min_framesize = metadata->data.stream_info.min_framesize; |
3145 | 6.62k | const uint32_t max_framesize = metadata->data.stream_info.max_framesize; |
3146 | 6.62k | const uint32_t bps = metadata->data.stream_info.bits_per_sample; |
3147 | 6.62k | FLAC__StreamEncoderSeekStatus seek_status; |
3148 | | |
3149 | 6.62k | FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); |
3150 | | |
3151 | | /* All this is based on intimate knowledge of the stream header |
3152 | | * layout, but a change to the header format that would break this |
3153 | | * would also break all streams encoded in the previous format. |
3154 | | */ |
3155 | | |
3156 | | /* |
3157 | | * Write MD5 signature |
3158 | | */ |
3159 | 6.62k | { |
3160 | 6.62k | const uint32_t md5_offset = |
3161 | 6.62k | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3162 | 6.62k | ( |
3163 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3164 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + |
3165 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + |
3166 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + |
3167 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + |
3168 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + |
3169 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + |
3170 | 6.62k | FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN |
3171 | 6.62k | ) / 8; |
3172 | | |
3173 | 6.62k | if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { |
3174 | 6.62k | if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) |
3175 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3176 | 6.62k | return; |
3177 | 6.62k | } |
3178 | 0 | if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3179 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3180 | 0 | return; |
3181 | 0 | } |
3182 | 0 | } |
3183 | | |
3184 | | /* |
3185 | | * Write total samples |
3186 | | */ |
3187 | 0 | { |
3188 | 0 | const uint32_t total_samples_byte_offset = |
3189 | 0 | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3190 | 0 | ( |
3191 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3192 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + |
3193 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + |
3194 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + |
3195 | 0 | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + |
3196 | 0 | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + |
3197 | 0 | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN |
3198 | 0 | - 4 |
3199 | 0 | ) / 8; |
3200 | 0 | FLAC__uint64 samples_uint36 = samples; |
3201 | 0 | if(samples > (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) |
3202 | 0 | samples_uint36 = 0; |
3203 | |
|
3204 | 0 | b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples_uint36 >> 32) & 0x0F); |
3205 | 0 | b[1] = (FLAC__byte)((samples_uint36 >> 24) & 0xFF); |
3206 | 0 | b[2] = (FLAC__byte)((samples_uint36 >> 16) & 0xFF); |
3207 | 0 | b[3] = (FLAC__byte)((samples_uint36 >> 8) & 0xFF); |
3208 | 0 | b[4] = (FLAC__byte)(samples_uint36 & 0xFF); |
3209 | 0 | if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { |
3210 | 0 | if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) |
3211 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3212 | 0 | return; |
3213 | 0 | } |
3214 | 0 | if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3215 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3216 | 0 | return; |
3217 | 0 | } |
3218 | 0 | } |
3219 | | |
3220 | | /* |
3221 | | * Write min/max framesize |
3222 | | */ |
3223 | 0 | { |
3224 | 0 | const uint32_t min_framesize_offset = |
3225 | 0 | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3226 | 0 | ( |
3227 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3228 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN |
3229 | 0 | ) / 8; |
3230 | |
|
3231 | 0 | b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF); |
3232 | 0 | b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF); |
3233 | 0 | b[2] = (FLAC__byte)(min_framesize & 0xFF); |
3234 | 0 | b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF); |
3235 | 0 | b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF); |
3236 | 0 | b[5] = (FLAC__byte)(max_framesize & 0xFF); |
3237 | 0 | if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { |
3238 | 0 | if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) |
3239 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3240 | 0 | return; |
3241 | 0 | } |
3242 | 0 | if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3243 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3244 | 0 | return; |
3245 | 0 | } |
3246 | 0 | } |
3247 | | |
3248 | | /* |
3249 | | * Write seektable |
3250 | | */ |
3251 | 0 | if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) { |
3252 | 0 | uint32_t i; |
3253 | | |
3254 | | /* Convert unused seekpoints to placeholders */ |
3255 | 0 | for(i = 0; i < encoder->private_->seek_table->num_points; i++) |
3256 | 0 | if(encoder->private_->seek_table->points[i].sample_number > samples) |
3257 | 0 | encoder->private_->seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; |
3258 | |
|
3259 | 0 | FLAC__format_seektable_sort(encoder->private_->seek_table); |
3260 | |
|
3261 | 0 | FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table)); |
3262 | |
|
3263 | 0 | if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) { |
3264 | 0 | if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR) |
3265 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3266 | 0 | return; |
3267 | 0 | } |
3268 | | |
3269 | 0 | for(i = 0; i < encoder->private_->seek_table->num_points; i++) { |
3270 | 0 | FLAC__uint64 xx; |
3271 | 0 | uint32_t x; |
3272 | 0 | xx = encoder->private_->seek_table->points[i].sample_number; |
3273 | 0 | b[7] = (FLAC__byte)xx; xx >>= 8; |
3274 | 0 | b[6] = (FLAC__byte)xx; xx >>= 8; |
3275 | 0 | b[5] = (FLAC__byte)xx; xx >>= 8; |
3276 | 0 | b[4] = (FLAC__byte)xx; xx >>= 8; |
3277 | 0 | b[3] = (FLAC__byte)xx; xx >>= 8; |
3278 | 0 | b[2] = (FLAC__byte)xx; xx >>= 8; |
3279 | 0 | b[1] = (FLAC__byte)xx; xx >>= 8; |
3280 | 0 | b[0] = (FLAC__byte)xx; xx >>= 8; |
3281 | 0 | xx = encoder->private_->seek_table->points[i].stream_offset; |
3282 | 0 | b[15] = (FLAC__byte)xx; xx >>= 8; |
3283 | 0 | b[14] = (FLAC__byte)xx; xx >>= 8; |
3284 | 0 | b[13] = (FLAC__byte)xx; xx >>= 8; |
3285 | 0 | b[12] = (FLAC__byte)xx; xx >>= 8; |
3286 | 0 | b[11] = (FLAC__byte)xx; xx >>= 8; |
3287 | 0 | b[10] = (FLAC__byte)xx; xx >>= 8; |
3288 | 0 | b[9] = (FLAC__byte)xx; xx >>= 8; |
3289 | 0 | b[8] = (FLAC__byte)xx; xx >>= 8; |
3290 | 0 | x = encoder->private_->seek_table->points[i].frame_samples; |
3291 | 0 | b[17] = (FLAC__byte)x; x >>= 8; |
3292 | 0 | b[16] = (FLAC__byte)x; x >>= 8; |
3293 | 0 | if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { |
3294 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; |
3295 | 0 | return; |
3296 | 0 | } |
3297 | 0 | } |
3298 | 0 | } |
3299 | 0 | } |
3300 | | |
3301 | | #if FLAC__HAS_OGG |
3302 | | /* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks. */ |
3303 | | void update_ogg_metadata_(FLAC__StreamEncoder *encoder) |
3304 | 3.08k | { |
3305 | | /* the # of bytes in the 1st packet that precede the STREAMINFO */ |
3306 | 3.08k | static const uint32_t FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH = |
3307 | 3.08k | FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH + |
3308 | 3.08k | FLAC__OGG_MAPPING_MAGIC_LENGTH + |
3309 | 3.08k | FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH + |
3310 | 3.08k | FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH + |
3311 | 3.08k | FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH + |
3312 | 3.08k | FLAC__STREAM_SYNC_LENGTH |
3313 | 3.08k | ; |
3314 | 3.08k | FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; |
3315 | 3.08k | const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; |
3316 | 3.08k | const FLAC__uint64 samples = metadata->data.stream_info.total_samples; |
3317 | 3.08k | const uint32_t min_framesize = metadata->data.stream_info.min_framesize; |
3318 | 3.08k | const uint32_t max_framesize = metadata->data.stream_info.max_framesize; |
3319 | 3.08k | ogg_page page; |
3320 | | |
3321 | 3.08k | FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); |
3322 | 3.08k | FLAC__ASSERT(0 != encoder->private_->seek_callback); |
3323 | | |
3324 | | /* Pre-check that client supports seeking, since we don't want the |
3325 | | * ogg_helper code to ever have to deal with this condition. |
3326 | | */ |
3327 | 3.08k | if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED) |
3328 | 3.08k | return; |
3329 | | |
3330 | | /* All this is based on intimate knowledge of the stream header |
3331 | | * layout, but a change to the header format that would break this |
3332 | | * would also break all streams encoded in the previous format. |
3333 | | */ |
3334 | | |
3335 | | /** |
3336 | | ** Write STREAMINFO stats |
3337 | | **/ |
3338 | 0 | simple_ogg_page__init(&page); |
3339 | 0 | if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) { |
3340 | 0 | simple_ogg_page__clear(&page); |
3341 | 0 | return; /* state already set */ |
3342 | 0 | } |
3343 | | |
3344 | | /* |
3345 | | * Write MD5 signature |
3346 | | */ |
3347 | 0 | { |
3348 | 0 | const uint32_t md5_offset = |
3349 | 0 | FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + |
3350 | 0 | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3351 | 0 | ( |
3352 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3353 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + |
3354 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + |
3355 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + |
3356 | 0 | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + |
3357 | 0 | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + |
3358 | 0 | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + |
3359 | 0 | FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN |
3360 | 0 | ) / 8; |
3361 | |
|
3362 | 0 | if(md5_offset + 16 > (uint32_t)page.body_len) { |
3363 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; |
3364 | 0 | simple_ogg_page__clear(&page); |
3365 | 0 | return; |
3366 | 0 | } |
3367 | 0 | memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16); |
3368 | 0 | } |
3369 | | |
3370 | | /* |
3371 | | * Write total samples |
3372 | | */ |
3373 | 0 | { |
3374 | 0 | const uint32_t total_samples_byte_offset = |
3375 | 0 | FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + |
3376 | 0 | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3377 | 0 | ( |
3378 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3379 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + |
3380 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + |
3381 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + |
3382 | 0 | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + |
3383 | 0 | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + |
3384 | 0 | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN |
3385 | 0 | - 4 |
3386 | 0 | ) / 8; |
3387 | |
|
3388 | 0 | if(total_samples_byte_offset + 5 > (uint32_t)page.body_len) { |
3389 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; |
3390 | 0 | simple_ogg_page__clear(&page); |
3391 | 0 | return; |
3392 | 0 | } |
3393 | 0 | b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0; |
3394 | 0 | b[0] |= (FLAC__byte)((samples >> 32) & 0x0F); |
3395 | 0 | b[1] = (FLAC__byte)((samples >> 24) & 0xFF); |
3396 | 0 | b[2] = (FLAC__byte)((samples >> 16) & 0xFF); |
3397 | 0 | b[3] = (FLAC__byte)((samples >> 8) & 0xFF); |
3398 | 0 | b[4] = (FLAC__byte)(samples & 0xFF); |
3399 | 0 | memcpy(page.body + total_samples_byte_offset, b, 5); |
3400 | 0 | } |
3401 | | |
3402 | | /* |
3403 | | * Write min/max framesize |
3404 | | */ |
3405 | 0 | { |
3406 | 0 | const uint32_t min_framesize_offset = |
3407 | 0 | FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH + |
3408 | 0 | FLAC__STREAM_METADATA_HEADER_LENGTH + |
3409 | 0 | ( |
3410 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + |
3411 | 0 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN |
3412 | 0 | ) / 8; |
3413 | |
|
3414 | 0 | if(min_framesize_offset + 6 > (uint32_t)page.body_len) { |
3415 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; |
3416 | 0 | simple_ogg_page__clear(&page); |
3417 | 0 | return; |
3418 | 0 | } |
3419 | 0 | b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF); |
3420 | 0 | b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF); |
3421 | 0 | b[2] = (FLAC__byte)(min_framesize & 0xFF); |
3422 | 0 | b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF); |
3423 | 0 | b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF); |
3424 | 0 | b[5] = (FLAC__byte)(max_framesize & 0xFF); |
3425 | 0 | memcpy(page.body + min_framesize_offset, b, 6); |
3426 | 0 | } |
3427 | 0 | if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) { |
3428 | 0 | simple_ogg_page__clear(&page); |
3429 | 0 | return; /* state already set */ |
3430 | 0 | } |
3431 | 0 | simple_ogg_page__clear(&page); |
3432 | 0 | } |
3433 | | #endif |
3434 | | |
3435 | | FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block) |
3436 | 242k | { |
3437 | 242k | FLAC__uint16 crc; |
3438 | 242k | #ifdef FLAC__USE_THREADS |
3439 | 242k | uint32_t i; |
3440 | 242k | #endif |
3441 | 242k | if(encoder->protected_->num_threads < 2 || is_last_block) { |
3442 | | |
3443 | 141k | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); |
3444 | | |
3445 | | /* |
3446 | | * Accumulate raw signal to the MD5 signature |
3447 | | */ |
3448 | 141k | if(encoder->protected_->do_md5 && !FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->threadtask[0]->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) { |
3449 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3450 | 0 | return false; |
3451 | 0 | } |
3452 | | |
3453 | | /* |
3454 | | * Process the frame header and subframes into the frame bitbuffer |
3455 | | */ |
3456 | 141k | encoder->private_->threadtask[0]->current_frame_number = encoder->private_->current_frame_number; |
3457 | 141k | if(!process_subframes_(encoder, encoder->private_->threadtask[0])) { |
3458 | | /* the above function sets the state for us in case of an error */ |
3459 | 0 | return false; |
3460 | 0 | } |
3461 | | |
3462 | | /* |
3463 | | * Zero-pad the frame to a byte_boundary |
3464 | | */ |
3465 | 141k | if(!FLAC__bitwriter_zero_pad_to_byte_boundary(encoder->private_->threadtask[0]->frame)) { |
3466 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3467 | 0 | return false; |
3468 | 0 | } |
3469 | | |
3470 | | /* |
3471 | | * CRC-16 the whole thing |
3472 | | */ |
3473 | 141k | FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->threadtask[0]->frame)); |
3474 | 141k | if( |
3475 | 141k | !FLAC__bitwriter_get_write_crc16(encoder->private_->threadtask[0]->frame, &crc) || |
3476 | 141k | !FLAC__bitwriter_write_raw_uint32(encoder->private_->threadtask[0]->frame, crc, FLAC__FRAME_FOOTER_CRC_LEN) |
3477 | 141k | ) { |
3478 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3479 | 0 | return false; |
3480 | 0 | } |
3481 | | |
3482 | | /* |
3483 | | * Write it |
3484 | | */ |
3485 | 141k | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[0], encoder->protected_->blocksize, is_last_block)) { |
3486 | | /* the above function sets the state for us in case of an error */ |
3487 | 0 | return false; |
3488 | 0 | } |
3489 | 141k | } |
3490 | 101k | else { |
3491 | 101k | #ifdef FLAC__USE_THREADS |
3492 | | /* This bit is quite complicated, so here are some pointers: |
3493 | | * |
3494 | | * When this bit of code is reached for the first time, new threads are spawned and |
3495 | | * threadtasks are populated until the total number of threads equals the requested number |
3496 | | * of threads. Next, threadtasks are populated until they there are no more available. |
3497 | | * Next, this main thread checks whether the threadtask that is due chronologically is |
3498 | | * done. If it is, the bitbuffer is written and the threadtask memory reused for the next |
3499 | | * frame. If it is not done, the main thread checks whether there is enough work left in the |
3500 | | * queue. If there is a lot of work left, the main thread starts on some of it too. |
3501 | | * If not a lot of work is left, the main thread goes to sleep until the frame due first is |
3502 | | * finished. |
3503 | | * |
3504 | | * - encoder->private_->next_thread is the number of the next thread to be created or, when |
3505 | | * the required number of threads is created, the next threadtask to be populated, |
3506 | | * or, when all threadtasks have been populated once, the next threadtask that needs |
3507 | | * to finish and thus reused. |
3508 | | * - encoder->private_->next_threadtask is the number of the next threadtask that a thread |
3509 | | * can start work on. |
3510 | | * |
3511 | | * So, in effect, next_thread is (after startup) a pointer considering the chronological |
3512 | | * order, so input/output isn't shuffled. next_threadtask is a pointer to the next task that |
3513 | | * hasn't been picked up by a thread yet. This distinction enables threads to work on frames |
3514 | | * in a non-chronological order |
3515 | | * |
3516 | | * encoder->protected_->num_threads is the max number of threads that can be spawned |
3517 | | * encoder->private_->num_created_threads is the number of threads that has been spawned |
3518 | | * encoder->private_->num_threadtasks keeps track of how many threadtasks are available |
3519 | | * encoder->private_->num_started_threadtasks keeps track of how many threadtasks have been populated |
3520 | | * |
3521 | | * NOTE: thread no. 0 and threadtask no. 0 are reserved for non-threaded operations, so next_thread |
3522 | | * and next_threadtask start at 1 |
3523 | | */ |
3524 | 101k | if(encoder->private_->num_created_threads < encoder->protected_->num_threads) { |
3525 | | /* Create a new thread */ |
3526 | 2.92k | FLAC__thrd_create(&encoder->private_->thread[encoder->private_->next_thread], |
3527 | 2.92k | process_frame_thread_, encoder); |
3528 | 2.92k | encoder->private_->num_created_threads++; |
3529 | 2.92k | } |
3530 | 98.5k | else if(encoder->private_->num_started_threadtasks == encoder->private_->num_threadtasks) { |
3531 | | /* If the first task in the queue is still running, check whether there is enough work |
3532 | | * left in the queue. If there is, start on some |
3533 | | * First, check whether the mutex for the next due task is locked or free. If it is free (and thus acquired now) and |
3534 | | * the task is done, proceed to the next bit (writing the bitbuffer). If it is either currently locked or not yet |
3535 | | * processed, choose between starting on some work (if there is enough work in the queue) or waiting for the task |
3536 | | * to finish. Either way, release the mutex first, so it doesn't get interlocked with the work queue mutex */ |
3537 | 95.5k | int mutex_result = (FLAC__mtx_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task) == FLAC__thrd_success) ? 0 : 1; |
3538 | 109k | while(mutex_result || !encoder->private_->threadtask[encoder->private_->next_thread]->task_done) { |
3539 | 13.7k | if(!mutex_result) |
3540 | 5.09k | FLAC__mtx_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3541 | | |
3542 | 13.7k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3543 | 13.7k | if(encoder->private_->num_available_threadtasks > (encoder->protected_->num_threads - 1)) { |
3544 | 12.9k | FLAC__StreamEncoderThreadTask * task = NULL; |
3545 | 12.9k | task = encoder->private_->threadtask[encoder->private_->next_threadtask]; |
3546 | 12.9k | encoder->private_->num_available_threadtasks--; |
3547 | 12.9k | encoder->private_->next_threadtask++; |
3548 | 12.9k | if(encoder->private_->next_threadtask == encoder->private_->num_threadtasks) |
3549 | 2.20k | encoder->private_->next_threadtask = 1; |
3550 | 12.9k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3551 | 12.9k | FLAC__mtx_lock(&task->mutex_this_task); |
3552 | 12.9k | process_frame_thread_inner_(encoder, task); |
3553 | 12.9k | mutex_result = (FLAC__mtx_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task) == FLAC__thrd_success) ? 0 : 1; |
3554 | 12.9k | } |
3555 | 739 | else { |
3556 | 739 | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3557 | 739 | FLAC__mtx_lock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3558 | 744 | while(!encoder->private_->threadtask[encoder->private_->next_thread]->task_done) |
3559 | 5 | FLAC__cnd_wait(&encoder->private_->threadtask[encoder->private_->next_thread]->cond_task_done,&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3560 | 739 | mutex_result = 0; |
3561 | 739 | } |
3562 | 13.7k | } |
3563 | | /* Task is finished, write bitbuffer */ |
3564 | 95.5k | if(!encoder->private_->threadtask[encoder->private_->next_thread]->returnvalue) { |
3565 | 0 | FLAC__mtx_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3566 | 0 | return false; |
3567 | 0 | } |
3568 | 95.5k | if(!write_bitbuffer_(encoder, encoder->private_->threadtask[encoder->private_->next_thread], encoder->protected_->blocksize, is_last_block)) { |
3569 | | /* the above function sets the state for us in case of an error */ |
3570 | 0 | FLAC__mtx_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3571 | 0 | return false; |
3572 | 0 | } |
3573 | 95.5k | FLAC__mtx_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3574 | 95.5k | } |
3575 | | /* Copy input data for MD5 calculation */ |
3576 | 101k | if(encoder->protected_->do_md5) { |
3577 | 101k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3578 | 101k | while(encoder->private_->md5_fifo.tail + encoder->protected_->blocksize > encoder->private_->md5_fifo.size) { |
3579 | 483 | FLAC__cnd_wait(&encoder->private_->cond_md5_emptied,&encoder->private_->mutex_work_queue); |
3580 | 483 | } |
3581 | 101k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3582 | 101k | FLAC__mtx_lock(&encoder->private_->mutex_md5_fifo); |
3583 | 207k | for(i = 0; i < encoder->protected_->channels; i++) |
3584 | 106k | memcpy(encoder->private_->md5_fifo.data[i]+encoder->private_->md5_fifo.tail, encoder->private_->threadtask[0]->integer_signal[i], encoder->protected_->blocksize * sizeof(encoder->private_->threadtask[0]->integer_signal[i][0])); |
3585 | 101k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3586 | 101k | encoder->private_->md5_fifo.tail += encoder->protected_->blocksize; |
3587 | 101k | FLAC__cnd_signal(&encoder->private_->cond_work_available); |
3588 | 101k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3589 | 101k | FLAC__mtx_unlock(&encoder->private_->mutex_md5_fifo); |
3590 | 101k | } |
3591 | | |
3592 | | /* Copy input data for frame creation */ |
3593 | 101k | FLAC__mtx_lock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3594 | 207k | for(i = 0; i < encoder->protected_->channels; i++) |
3595 | 106k | memcpy(encoder->private_->threadtask[encoder->private_->next_thread]->integer_signal[i], encoder->private_->threadtask[0]->integer_signal[i], encoder->protected_->blocksize * sizeof(encoder->private_->threadtask[0]->integer_signal[i][0])); |
3596 | | |
3597 | 101k | encoder->private_->threadtask[encoder->private_->next_thread]->current_frame_number = encoder->private_->current_frame_number; |
3598 | 101k | FLAC__mtx_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); |
3599 | | |
3600 | 101k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3601 | 101k | if(encoder->private_->num_started_threadtasks < encoder->private_->num_threadtasks) |
3602 | 5.93k | encoder->private_->num_started_threadtasks++; |
3603 | 101k | encoder->private_->num_available_threadtasks++; |
3604 | 101k | encoder->private_->threadtask[encoder->private_->next_thread]->task_done = false; |
3605 | 101k | FLAC__cnd_signal(&encoder->private_->cond_work_available); |
3606 | 101k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3607 | | |
3608 | 101k | encoder->private_->next_thread++; |
3609 | 101k | if(encoder->private_->next_thread == encoder->private_->num_threadtasks) |
3610 | 10.6k | encoder->private_->next_thread = 1; |
3611 | | #else |
3612 | | FLAC__ASSERT(0); |
3613 | | #endif |
3614 | 101k | } |
3615 | | |
3616 | | /* |
3617 | | * Get ready for the next frame |
3618 | | */ |
3619 | 242k | encoder->private_->current_sample_number = 0; |
3620 | 242k | encoder->private_->current_frame_number++; |
3621 | 242k | encoder->private_->streaminfo.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize; |
3622 | | |
3623 | 242k | return true; |
3624 | 242k | } |
3625 | | |
3626 | | #ifdef FLAC__USE_THREADS |
3627 | 2.92k | FLAC__thread_return_type process_frame_thread_(void * args) { |
3628 | 2.92k | FLAC__StreamEncoder * encoder = args; |
3629 | 2.92k | uint32_t channel; |
3630 | | |
3631 | 2.92k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3632 | 2.92k | encoder->private_->num_running_threads++; |
3633 | 2.92k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3634 | | |
3635 | 127k | while(1) { |
3636 | 127k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3637 | 127k | if(encoder->private_->finish_work_threads) { |
3638 | 52 | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3639 | 52 | return FLAC__thread_default_return_value; |
3640 | 52 | } |
3641 | | /* The code below pauses and restarts threads if it is noticed threads are often put too sleep |
3642 | | * because of a lack of work. This reduces overhead when too many threads are active. The |
3643 | | * overcommited indicator is increased when no tasks are available, decreased when more tasks |
3644 | | * are available then threads are running, and reset when a thread is woken up or put to sleep */ |
3645 | 127k | if(encoder->private_->num_available_threadtasks == 0) |
3646 | 28.5k | encoder->private_->overcommitted_indicator++; |
3647 | 98.7k | else if(encoder->private_->num_available_threadtasks > encoder->private_->num_running_threads) |
3648 | 36.0k | encoder->private_->overcommitted_indicator--; |
3649 | 127k | if(encoder->private_->overcommitted_indicator < -20) { |
3650 | 1.05k | encoder->private_->overcommitted_indicator = 0; |
3651 | 1.05k | FLAC__cnd_signal(&encoder->private_->cond_wake_up_thread); |
3652 | 1.05k | } |
3653 | 126k | else if(encoder->private_->overcommitted_indicator > 20 && encoder->private_->num_running_threads > 2) { |
3654 | 643 | encoder->private_->overcommitted_indicator = 0; |
3655 | 643 | encoder->private_->num_running_threads--; |
3656 | 643 | FLAC__cnd_wait(&encoder->private_->cond_wake_up_thread, &encoder->private_->mutex_work_queue); |
3657 | 643 | encoder->private_->num_running_threads++; |
3658 | 643 | } |
3659 | 164k | while(encoder->private_->num_available_threadtasks == 0 && (encoder->private_->md5_active || encoder->private_->md5_fifo.tail == 0)) { |
3660 | 40.3k | if(encoder->private_->finish_work_threads) { |
3661 | 2.87k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3662 | 2.87k | return FLAC__thread_default_return_value; |
3663 | 2.87k | } |
3664 | 37.5k | FLAC__cnd_wait(&encoder->private_->cond_work_available, &encoder->private_->mutex_work_queue); |
3665 | 37.5k | } |
3666 | 124k | if(encoder->protected_->do_md5 && !encoder->private_->md5_active && encoder->private_->md5_fifo.tail > 0) { |
3667 | 36.0k | uint32_t length = 0; |
3668 | 36.0k | encoder->private_->md5_active = true; |
3669 | 83.7k | while(encoder->private_->md5_fifo.tail > 0) { |
3670 | 47.7k | length = encoder->private_->md5_fifo.tail; |
3671 | 47.7k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3672 | 47.7k | if(!FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->md5_fifo.data, encoder->protected_->channels, length, (encoder->protected_->bits_per_sample+7) / 8)) { |
3673 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3674 | 0 | return FLAC__thread_default_return_value; |
3675 | 0 | } |
3676 | 47.7k | FLAC__mtx_lock(&encoder->private_->mutex_md5_fifo); |
3677 | 97.0k | for(channel = 0; channel < encoder->protected_->channels; channel++) |
3678 | 49.2k | memmove(&encoder->private_->md5_fifo.data[channel][0], &encoder->private_->md5_fifo.data[channel][length], (encoder->private_->md5_fifo.tail-length) * sizeof(encoder->private_->md5_fifo.data[0][0])); |
3679 | 47.7k | FLAC__mtx_lock(&encoder->private_->mutex_work_queue); |
3680 | 47.7k | encoder->private_->md5_fifo.tail -= length; |
3681 | 47.7k | FLAC__cnd_signal(&encoder->private_->cond_md5_emptied); |
3682 | 47.7k | FLAC__mtx_unlock(&encoder->private_->mutex_md5_fifo); |
3683 | 47.7k | } |
3684 | 36.0k | encoder->private_->md5_active = false; |
3685 | 36.0k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3686 | 36.0k | } |
3687 | 88.5k | else if(encoder->private_->num_available_threadtasks > 0) { |
3688 | 88.5k | FLAC__StreamEncoderThreadTask * task = NULL; |
3689 | 88.5k | task = encoder->private_->threadtask[encoder->private_->next_threadtask]; |
3690 | 88.5k | encoder->private_->num_available_threadtasks--; |
3691 | 88.5k | encoder->private_->next_threadtask++; |
3692 | 88.5k | if(encoder->private_->next_threadtask == encoder->private_->num_threadtasks) |
3693 | 8.45k | encoder->private_->next_threadtask = 1; |
3694 | 88.5k | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3695 | 88.5k | FLAC__mtx_lock(&task->mutex_this_task); |
3696 | 88.5k | if(!process_frame_thread_inner_(encoder, task)) |
3697 | 0 | return FLAC__thread_default_return_value; |
3698 | 88.5k | } |
3699 | 18.4E | else { |
3700 | 18.4E | FLAC__mtx_unlock(&encoder->private_->mutex_work_queue); |
3701 | 18.4E | } |
3702 | 124k | } |
3703 | 2.92k | } |
3704 | | |
3705 | 101k | FLAC__bool process_frame_thread_inner_(FLAC__StreamEncoder * encoder, FLAC__StreamEncoderThreadTask * task) { |
3706 | 101k | FLAC__bool ok = true; |
3707 | 101k | FLAC__uint16 crc; |
3708 | | |
3709 | | /* |
3710 | | * Process the frame header and subframes into the frame bitbuffer |
3711 | | */ |
3712 | 101k | if(ok && !process_subframes_(encoder, task)) { |
3713 | | /* the above function sets the state for us in case of an error */ |
3714 | 0 | ok = false; |
3715 | 0 | } |
3716 | | |
3717 | | /* |
3718 | | * Zero-pad the frame to a byte_boundary |
3719 | | */ |
3720 | 101k | if(ok && !FLAC__bitwriter_zero_pad_to_byte_boundary(task->frame)) { |
3721 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3722 | 0 | ok = false; |
3723 | 0 | } |
3724 | | |
3725 | | /* |
3726 | | * CRC-16 the whole thing |
3727 | | */ |
3728 | 101k | FLAC__ASSERT(!ok || FLAC__bitwriter_is_byte_aligned(task->frame)); |
3729 | 101k | if( |
3730 | 101k | ok && |
3731 | 100k | ( |
3732 | 100k | !FLAC__bitwriter_get_write_crc16(task->frame, &crc) || |
3733 | 100k | !FLAC__bitwriter_write_raw_uint32(task->frame, crc, FLAC__FRAME_FOOTER_CRC_LEN) |
3734 | 100k | ) |
3735 | 101k | ) { |
3736 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; |
3737 | 0 | ok = false; |
3738 | 0 | } |
3739 | 101k | task->returnvalue = ok; |
3740 | 101k | task->task_done = true; |
3741 | 101k | FLAC__cnd_signal(&task->cond_task_done); |
3742 | 101k | FLAC__mtx_unlock(&task->mutex_this_task); |
3743 | 101k | return true; |
3744 | 101k | } |
3745 | | #endif |
3746 | | |
3747 | | FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderThreadTask * threadtask) |
3748 | 242k | { |
3749 | 242k | FLAC__FrameHeader frame_header; |
3750 | 242k | uint32_t channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order; |
3751 | 242k | FLAC__bool do_independent, do_mid_side, all_subframes_constant = true; |
3752 | | |
3753 | 242k | threadtask->disable_constant_subframes = encoder->private_->disable_constant_subframes; |
3754 | | |
3755 | | /* |
3756 | | * Calculate the min,max Rice partition orders |
3757 | | */ |
3758 | | |
3759 | 242k | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); |
3760 | 242k | max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order); |
3761 | 242k | min_partition_order = flac_min(min_partition_order, max_partition_order); |
3762 | | |
3763 | | /* |
3764 | | * Setup the frame |
3765 | | */ |
3766 | 242k | frame_header.blocksize = encoder->protected_->blocksize; |
3767 | 242k | frame_header.sample_rate = encoder->protected_->sample_rate; |
3768 | 242k | frame_header.channels = encoder->protected_->channels; |
3769 | 242k | frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */ |
3770 | 242k | frame_header.bits_per_sample = encoder->protected_->bits_per_sample; |
3771 | 242k | frame_header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; |
3772 | 242k | frame_header.number.frame_number = threadtask->current_frame_number; |
3773 | | |
3774 | | /* |
3775 | | * Figure out what channel assignments to try |
3776 | | */ |
3777 | 242k | if(encoder->protected_->do_mid_side_stereo) { |
3778 | 42.6k | if(encoder->protected_->loose_mid_side_stereo) { |
3779 | 3.23k | uint64_t sumAbsLR = 0, sumAbsMS = 0; |
3780 | 3.23k | uint32_t i; |
3781 | 3.23k | if(encoder->protected_->bits_per_sample < 25) { |
3782 | 22.0k | for(i = 1; i < encoder->protected_->blocksize; i++) { |
3783 | 20.7k | int32_t predictionLeft = threadtask->integer_signal[0][i] - threadtask->integer_signal[0][i-1]; |
3784 | 20.7k | int32_t predictionRight = threadtask->integer_signal[1][i] - threadtask->integer_signal[1][i-1]; |
3785 | 20.7k | sumAbsLR += abs(predictionLeft) + abs(predictionRight); |
3786 | 20.7k | sumAbsMS += abs((predictionLeft + predictionRight) >> 1) + abs(predictionLeft - predictionRight); |
3787 | 20.7k | } |
3788 | 1.29k | } |
3789 | 1.93k | else { /* bps 25 or higher */ |
3790 | 1.57M | for(i = 1; i < encoder->protected_->blocksize; i++) { |
3791 | 1.57M | int64_t predictionLeft = (int64_t)threadtask->integer_signal[0][i] - (int64_t)threadtask->integer_signal[0][i-1]; |
3792 | 1.57M | int64_t predictionRight = (int64_t)threadtask->integer_signal[1][i] - (int64_t)threadtask->integer_signal[1][i-1]; |
3793 | 1.57M | sumAbsLR += local_abs64(predictionLeft) + local_abs64(predictionRight); |
3794 | 1.57M | sumAbsMS += local_abs64((predictionLeft + predictionRight) >> 1) + local_abs64(predictionLeft - predictionRight); |
3795 | 1.57M | } |
3796 | 1.93k | } |
3797 | 3.23k | if(sumAbsLR < sumAbsMS) { |
3798 | 913 | do_independent = true; |
3799 | 913 | do_mid_side = false; |
3800 | 913 | frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; |
3801 | 913 | } |
3802 | 2.31k | else { |
3803 | 2.31k | do_independent = false; |
3804 | 2.31k | do_mid_side = true; |
3805 | 2.31k | frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; |
3806 | 2.31k | } |
3807 | 3.23k | } |
3808 | 39.3k | else { |
3809 | 39.3k | do_independent = true; |
3810 | 39.3k | do_mid_side = true; |
3811 | 39.3k | } |
3812 | 42.6k | } |
3813 | 200k | else { |
3814 | 200k | do_independent = true; |
3815 | 200k | do_mid_side = false; |
3816 | 200k | } |
3817 | | |
3818 | 242k | FLAC__ASSERT(do_independent || do_mid_side); |
3819 | | |
3820 | | /* |
3821 | | * Prepare mid-side signals if applicable |
3822 | | */ |
3823 | 242k | if(do_mid_side) { |
3824 | 41.7k | uint32_t i; |
3825 | 41.7k | FLAC__ASSERT(encoder->protected_->channels == 2); |
3826 | 41.7k | if(encoder->protected_->bits_per_sample < 32) |
3827 | 329k | for(i = 0; i < encoder->protected_->blocksize; i++) { |
3828 | 317k | threadtask->integer_signal_mid_side[1][i] = threadtask->integer_signal[0][i] - threadtask->integer_signal[1][i]; |
3829 | 317k | threadtask->integer_signal_mid_side[0][i] = (threadtask->integer_signal[0][i] + threadtask->integer_signal[1][i]) >> 1; /* NOTE: not the same as 'mid = (signal[0][j] + signal[1][j]) / 2' ! */ |
3830 | 317k | } |
3831 | 29.6k | else |
3832 | 4.04M | for(i = 0; i <= encoder->protected_->blocksize; i++) { |
3833 | 4.01M | threadtask->integer_signal_33bit_side[i] = (FLAC__int64)threadtask->integer_signal[0][i] - (FLAC__int64)threadtask->integer_signal[1][i]; |
3834 | 4.01M | threadtask->integer_signal_mid_side[0][i] = ((FLAC__int64)threadtask->integer_signal[0][i] + (FLAC__int64)threadtask->integer_signal[1][i]) >> 1; /* NOTE: not the same as 'mid = (signal[0][j] + signal[1][j]) / 2' ! */ |
3835 | 4.01M | } |
3836 | 41.7k | } |
3837 | | |
3838 | | |
3839 | | /* |
3840 | | * Check for wasted bits; set effective bps for each subframe |
3841 | | */ |
3842 | 242k | if(do_independent) { |
3843 | 546k | for(channel = 0; channel < encoder->protected_->channels; channel++) { |
3844 | 305k | uint32_t w = get_wasted_bits_(threadtask->integer_signal[channel], encoder->protected_->blocksize); |
3845 | 305k | if (w > encoder->protected_->bits_per_sample) { |
3846 | 0 | w = encoder->protected_->bits_per_sample; |
3847 | 0 | } |
3848 | 305k | threadtask->subframe_workspace[channel][0].wasted_bits = threadtask->subframe_workspace[channel][1].wasted_bits = w; |
3849 | 305k | threadtask->subframe_bps[channel] = encoder->protected_->bits_per_sample - w; |
3850 | 305k | } |
3851 | 240k | } |
3852 | 242k | if(do_mid_side) { |
3853 | 41.7k | FLAC__ASSERT(encoder->protected_->channels == 2); |
3854 | 125k | for(channel = 0; channel < 2; channel++) { |
3855 | 83.3k | uint32_t w; |
3856 | 83.3k | if(encoder->protected_->bits_per_sample < 32 || channel == 0) |
3857 | 53.7k | w = get_wasted_bits_(threadtask->integer_signal_mid_side[channel], encoder->protected_->blocksize); |
3858 | 29.6k | else |
3859 | 29.6k | w = get_wasted_bits_wide_(threadtask->integer_signal_33bit_side, threadtask->integer_signal_mid_side[channel], encoder->protected_->blocksize); |
3860 | | |
3861 | 83.3k | if (w > encoder->protected_->bits_per_sample) { |
3862 | 0 | w = encoder->protected_->bits_per_sample; |
3863 | 0 | } |
3864 | 83.3k | threadtask->subframe_workspace_mid_side[channel][0].wasted_bits = threadtask->subframe_workspace_mid_side[channel][1].wasted_bits = w; |
3865 | 83.3k | threadtask->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1); |
3866 | 83.3k | } |
3867 | 41.7k | } |
3868 | | |
3869 | | /* |
3870 | | * First do a normal encoding pass of each independent channel |
3871 | | */ |
3872 | 242k | if(do_independent) { |
3873 | 545k | for(channel = 0; channel < encoder->protected_->channels; channel++) { |
3874 | 305k | if(encoder->protected_->limit_min_bitrate && all_subframes_constant && (channel + 1) == encoder->protected_->channels){ |
3875 | | /* This frame contains only constant subframes at this point. |
3876 | | * To prevent the frame from becoming too small, make sure |
3877 | | * the last subframe isn't constant */ |
3878 | 62.1k | threadtask->disable_constant_subframes = true; |
3879 | 62.1k | } |
3880 | 305k | if(! |
3881 | 305k | process_subframe_( |
3882 | 305k | encoder, |
3883 | 305k | threadtask, |
3884 | 305k | min_partition_order, |
3885 | 305k | max_partition_order, |
3886 | 305k | &frame_header, |
3887 | 305k | threadtask->subframe_bps[channel], |
3888 | 305k | threadtask->integer_signal[channel], |
3889 | 305k | threadtask->subframe_workspace_ptr[channel], |
3890 | 305k | threadtask->partitioned_rice_contents_workspace_ptr[channel], |
3891 | 305k | threadtask->residual_workspace[channel], |
3892 | 305k | threadtask->best_subframe+channel, |
3893 | 305k | threadtask->best_subframe_bits+channel |
3894 | 305k | ) |
3895 | 305k | ) |
3896 | 0 | return false; |
3897 | 305k | if(threadtask->subframe_workspace[channel][threadtask->best_subframe[channel]].type != FLAC__SUBFRAME_TYPE_CONSTANT) |
3898 | 204k | all_subframes_constant = false; |
3899 | 305k | } |
3900 | 239k | } |
3901 | | |
3902 | | /* |
3903 | | * Now do mid and side channels if requested |
3904 | | */ |
3905 | 242k | if(do_mid_side) { |
3906 | 41.7k | FLAC__ASSERT(encoder->protected_->channels == 2); |
3907 | | |
3908 | 125k | for(channel = 0; channel < 2; channel++) { |
3909 | 83.4k | void *integer_signal_; |
3910 | 83.4k | if(threadtask->subframe_bps_mid_side[channel] <= 32) |
3911 | 69.2k | integer_signal_ = threadtask->integer_signal_mid_side[channel]; |
3912 | 14.1k | else |
3913 | 14.1k | integer_signal_ = threadtask->integer_signal_33bit_side; |
3914 | 83.4k | if(! |
3915 | 83.4k | process_subframe_( |
3916 | 83.4k | encoder, |
3917 | 83.4k | threadtask, |
3918 | 83.4k | min_partition_order, |
3919 | 83.4k | max_partition_order, |
3920 | 83.4k | &frame_header, |
3921 | 83.4k | threadtask->subframe_bps_mid_side[channel], |
3922 | 83.4k | integer_signal_, |
3923 | 83.4k | threadtask->subframe_workspace_ptr_mid_side[channel], |
3924 | 83.4k | threadtask->partitioned_rice_contents_workspace_ptr_mid_side[channel], |
3925 | 83.4k | threadtask->residual_workspace_mid_side[channel], |
3926 | 83.4k | threadtask->best_subframe_mid_side+channel, |
3927 | 83.4k | threadtask->best_subframe_bits_mid_side+channel |
3928 | 83.4k | ) |
3929 | 83.4k | ) |
3930 | 0 | return false; |
3931 | 83.4k | } |
3932 | 41.7k | } |
3933 | | |
3934 | | /* |
3935 | | * Compose the frame bitbuffer |
3936 | | */ |
3937 | 242k | if((do_independent && do_mid_side) || encoder->protected_->loose_mid_side_stereo) { |
3938 | 42.6k | uint32_t left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */ |
3939 | 42.6k | FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */ |
3940 | 42.6k | FLAC__ChannelAssignment channel_assignment; |
3941 | | |
3942 | 42.6k | FLAC__ASSERT(encoder->protected_->channels == 2); |
3943 | | |
3944 | 42.6k | if(!encoder->protected_->loose_mid_side_stereo) { |
3945 | 39.3k | uint32_t bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */ |
3946 | 39.3k | uint32_t min_bits; |
3947 | 39.3k | int ca; |
3948 | | |
3949 | 39.3k | FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT == 0); |
3950 | 39.3k | FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE == 1); |
3951 | 39.3k | FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE == 2); |
3952 | 39.3k | FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_MID_SIDE == 3); |
3953 | | |
3954 | | /* We have to figure out which channel assignent results in the smallest frame */ |
3955 | 39.3k | bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = threadtask->best_subframe_bits [0] + threadtask->best_subframe_bits [1]; |
3956 | 39.3k | bits[FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ] = threadtask->best_subframe_bits [0] + threadtask->best_subframe_bits_mid_side[1]; |
3957 | 39.3k | bits[FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = threadtask->best_subframe_bits [1] + threadtask->best_subframe_bits_mid_side[1]; |
3958 | 39.3k | bits[FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ] = threadtask->best_subframe_bits_mid_side[0] + threadtask->best_subframe_bits_mid_side[1]; |
3959 | | |
3960 | 39.3k | channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; |
3961 | 39.3k | min_bits = bits[channel_assignment]; |
3962 | | |
3963 | | /* When doing loose mid-side stereo, ignore left-side |
3964 | | * and right-side options */ |
3965 | 157k | for(ca = 1; ca <= 3; ca++) { |
3966 | 118k | if(bits[ca] < min_bits) { |
3967 | 41.1k | min_bits = bits[ca]; |
3968 | 41.1k | channel_assignment = (FLAC__ChannelAssignment)ca; |
3969 | 41.1k | } |
3970 | 118k | } |
3971 | 39.3k | frame_header.channel_assignment = channel_assignment; |
3972 | 39.3k | } |
3973 | | |
3974 | 42.6k | if(!FLAC__frame_add_header(&frame_header, threadtask->frame)) { |
3975 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
3976 | 0 | return false; |
3977 | 0 | } |
3978 | | |
3979 | 42.6k | switch(frame_header.channel_assignment) { |
3980 | 10.0k | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: |
3981 | 10.0k | left_subframe = &threadtask->subframe_workspace [0][threadtask->best_subframe [0]]; |
3982 | 10.0k | right_subframe = &threadtask->subframe_workspace [1][threadtask->best_subframe [1]]; |
3983 | 10.0k | break; |
3984 | 14.6k | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: |
3985 | 14.6k | left_subframe = &threadtask->subframe_workspace [0][threadtask->best_subframe [0]]; |
3986 | 14.6k | right_subframe = &threadtask->subframe_workspace_mid_side[1][threadtask->best_subframe_mid_side[1]]; |
3987 | 14.6k | break; |
3988 | 6.97k | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: |
3989 | 6.97k | left_subframe = &threadtask->subframe_workspace_mid_side[1][threadtask->best_subframe_mid_side[1]]; |
3990 | 6.97k | right_subframe = &threadtask->subframe_workspace [1][threadtask->best_subframe [1]]; |
3991 | 6.97k | break; |
3992 | 10.9k | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: |
3993 | 10.9k | left_subframe = &threadtask->subframe_workspace_mid_side[0][threadtask->best_subframe_mid_side[0]]; |
3994 | 10.9k | right_subframe = &threadtask->subframe_workspace_mid_side[1][threadtask->best_subframe_mid_side[1]]; |
3995 | 10.9k | break; |
3996 | 0 | default: |
3997 | 0 | FLAC__ASSERT(0); |
3998 | 42.6k | } |
3999 | | |
4000 | 42.6k | switch(frame_header.channel_assignment) { |
4001 | 10.0k | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: |
4002 | 10.0k | left_bps = threadtask->subframe_bps [0]; |
4003 | 10.0k | right_bps = threadtask->subframe_bps [1]; |
4004 | 10.0k | break; |
4005 | 14.6k | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: |
4006 | 14.6k | left_bps = threadtask->subframe_bps [0]; |
4007 | 14.6k | right_bps = threadtask->subframe_bps_mid_side[1]; |
4008 | 14.6k | break; |
4009 | 6.97k | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: |
4010 | 6.97k | left_bps = threadtask->subframe_bps_mid_side[1]; |
4011 | 6.97k | right_bps = threadtask->subframe_bps [1]; |
4012 | 6.97k | break; |
4013 | 10.9k | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: |
4014 | 10.9k | left_bps = threadtask->subframe_bps_mid_side[0]; |
4015 | 10.9k | right_bps = threadtask->subframe_bps_mid_side[1]; |
4016 | 10.9k | break; |
4017 | 0 | default: |
4018 | 0 | FLAC__ASSERT(0); |
4019 | 42.6k | } |
4020 | | |
4021 | | /* note that encoder_add_subframe_ sets the state for us in case of an error */ |
4022 | 42.6k | if(!add_subframe_(encoder, frame_header.blocksize, left_bps , left_subframe , threadtask->frame)) |
4023 | 0 | return false; |
4024 | 42.6k | if(!add_subframe_(encoder, frame_header.blocksize, right_bps, right_subframe, threadtask->frame)) |
4025 | 0 | return false; |
4026 | 42.6k | } |
4027 | 200k | else { |
4028 | 200k | FLAC__ASSERT(do_independent); |
4029 | 200k | if(!FLAC__frame_add_header(&frame_header, threadtask->frame)) { |
4030 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
4031 | 0 | return false; |
4032 | 0 | } |
4033 | | |
4034 | 424k | for(channel = 0; channel < encoder->protected_->channels; channel++) { |
4035 | 224k | if(!add_subframe_(encoder, frame_header.blocksize, threadtask->subframe_bps[channel], &threadtask->subframe_workspace[channel][threadtask->best_subframe[channel]], threadtask->frame)) { |
4036 | | /* the above function sets the state for us in case of an error */ |
4037 | 0 | return false; |
4038 | 0 | } |
4039 | 224k | } |
4040 | 200k | } |
4041 | | |
4042 | 242k | return true; |
4043 | 242k | } |
4044 | | |
4045 | | FLAC__bool process_subframe_( |
4046 | | FLAC__StreamEncoder *encoder, |
4047 | | FLAC__StreamEncoderThreadTask *threadtask, |
4048 | | uint32_t min_partition_order, |
4049 | | uint32_t max_partition_order, |
4050 | | const FLAC__FrameHeader *frame_header, |
4051 | | uint32_t subframe_bps, |
4052 | | const void *integer_signal, |
4053 | | FLAC__Subframe *subframe[2], |
4054 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], |
4055 | | FLAC__int32 *residual[2], |
4056 | | uint32_t *best_subframe, |
4057 | | uint32_t *best_bits |
4058 | | ) |
4059 | 388k | { |
4060 | 388k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4061 | 388k | float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; |
4062 | | #else |
4063 | | FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; |
4064 | | #endif |
4065 | 388k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4066 | 388k | double lpc_residual_bits_per_sample; |
4067 | 388k | apply_apodization_state_struct apply_apodization_state; |
4068 | 388k | double lpc_error[FLAC__MAX_LPC_ORDER]; |
4069 | 388k | uint32_t min_lpc_order, max_lpc_order, lpc_order, guess_lpc_order; |
4070 | 388k | uint32_t min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; |
4071 | 388k | #endif |
4072 | 388k | uint32_t min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; |
4073 | 388k | uint32_t _candidate_bits, _best_bits; |
4074 | 388k | uint32_t _best_subframe; |
4075 | | /* only use RICE2 partitions if stream bps > 16 */ |
4076 | 388k | const uint32_t rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; |
4077 | | |
4078 | 388k | FLAC__ASSERT(frame_header->blocksize > 0); |
4079 | | |
4080 | | /* verbatim subframe is the baseline against which we measure other compressed subframes */ |
4081 | 388k | _best_subframe = 0; |
4082 | 388k | if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) |
4083 | 0 | _best_bits = UINT32_MAX; |
4084 | 388k | else |
4085 | 388k | _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); |
4086 | 388k | *best_bits = _best_bits; |
4087 | | |
4088 | 388k | if(frame_header->blocksize > FLAC__MAX_FIXED_ORDER) { |
4089 | 384k | uint32_t signal_is_constant = false; |
4090 | | /* The next formula determines when to use a 64-bit accumulator |
4091 | | * for the error of a fixed predictor, and when a 32-bit one. As |
4092 | | * the error of a 4th order predictor for a given sample is the |
4093 | | * sum of 17 sample values (1+4+6+4+1) and there are blocksize - |
4094 | | * order error values to be summed, the maximum total error is |
4095 | | * maximum_sample_value * (blocksize - order) * 17. As ilog2(x) |
4096 | | * calculates floor(2log(x)), the result must be 31 or lower |
4097 | | */ |
4098 | 384k | if(subframe_bps < 28){ |
4099 | 77.6k | if(subframe_bps + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)*17) < 32) |
4100 | 54.9k | guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); |
4101 | 22.6k | else |
4102 | 22.6k | guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); |
4103 | 77.6k | } |
4104 | 306k | else |
4105 | 306k | if(subframe_bps <= 32) |
4106 | 292k | guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_limit_residual(((FLAC__int32 *)integer_signal+FLAC__MAX_FIXED_ORDER),frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); |
4107 | 14.0k | else |
4108 | 14.0k | guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual_33bit(((FLAC__int64 *)integer_signal+FLAC__MAX_FIXED_ORDER),frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); |
4109 | | |
4110 | | /* check for constant subframe */ |
4111 | 384k | if( |
4112 | 384k | !threadtask->disable_constant_subframes && |
4113 | 321k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4114 | 321k | fixed_residual_bits_per_sample[1] == 0.0 |
4115 | | #else |
4116 | | fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO |
4117 | | #endif |
4118 | 384k | ) { |
4119 | | /* the above means it's possible all samples are the same value; now double-check it: */ |
4120 | 113k | uint32_t i; |
4121 | 113k | signal_is_constant = true; |
4122 | 113k | if(subframe_bps <= 32){ |
4123 | 112k | const FLAC__int32 *integer_signal_ = integer_signal; |
4124 | 1.91M | for(i = 1; i < frame_header->blocksize; i++) { |
4125 | 1.80M | if(integer_signal_[0] != integer_signal_[i]) { |
4126 | 3.14k | signal_is_constant = false; |
4127 | 3.14k | break; |
4128 | 3.14k | } |
4129 | 1.80M | } |
4130 | 112k | } |
4131 | 790 | else { |
4132 | 790 | const FLAC__int64 *integer_signal_ = integer_signal; |
4133 | 13.6k | for(i = 1; i < frame_header->blocksize; i++) { |
4134 | 12.8k | if(integer_signal_[0] != integer_signal_[i]) { |
4135 | 0 | signal_is_constant = false; |
4136 | 0 | break; |
4137 | 0 | } |
4138 | 12.8k | } |
4139 | 790 | } |
4140 | 113k | } |
4141 | 384k | if(signal_is_constant) { |
4142 | 110k | if(subframe_bps <= 32) |
4143 | 109k | _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int32 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); |
4144 | 789 | else |
4145 | 789 | _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int64 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); |
4146 | | |
4147 | 110k | if(_candidate_bits < _best_bits) { |
4148 | 110k | _best_subframe = !_best_subframe; |
4149 | 110k | _best_bits = _candidate_bits; |
4150 | 110k | } |
4151 | 110k | } |
4152 | 273k | else { |
4153 | 274k | if(!encoder->private_->disable_fixed_subframes || (encoder->protected_->max_lpc_order == 0 && _best_bits == UINT_MAX)) { |
4154 | | /* encode fixed */ |
4155 | 274k | if(encoder->protected_->do_exhaustive_model_search) { |
4156 | 192k | min_fixed_order = 0; |
4157 | 192k | max_fixed_order = FLAC__MAX_FIXED_ORDER; |
4158 | 192k | } |
4159 | 81.7k | else { |
4160 | 81.7k | min_fixed_order = max_fixed_order = guess_fixed_order; |
4161 | 81.7k | } |
4162 | 274k | if(max_fixed_order >= frame_header->blocksize) |
4163 | 0 | max_fixed_order = frame_header->blocksize - 1; |
4164 | 1.31M | for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) { |
4165 | 1.04M | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4166 | 1.04M | if(fixed_residual_bits_per_sample[fixed_order] >= (float)subframe_bps) |
4167 | 300k | continue; /* don't even try */ |
4168 | | #else |
4169 | | if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps) |
4170 | | continue; /* don't even try */ |
4171 | | #endif |
4172 | 740k | _candidate_bits = |
4173 | 740k | evaluate_fixed_subframe_( |
4174 | 740k | encoder, |
4175 | 740k | threadtask, |
4176 | 740k | integer_signal, |
4177 | 740k | residual[!_best_subframe], |
4178 | 740k | threadtask->abs_residual_partition_sums, |
4179 | 740k | threadtask->raw_bits_per_partition, |
4180 | 740k | frame_header->blocksize, |
4181 | 740k | subframe_bps, |
4182 | 740k | fixed_order, |
4183 | 740k | rice_parameter_limit, |
4184 | 740k | min_partition_order, |
4185 | 740k | max_partition_order, |
4186 | 740k | encoder->protected_->do_escape_coding, |
4187 | 740k | encoder->protected_->rice_parameter_search_dist, |
4188 | 740k | subframe[!_best_subframe], |
4189 | 740k | partitioned_rice_contents[!_best_subframe] |
4190 | 740k | ); |
4191 | 740k | if(_candidate_bits < _best_bits) { |
4192 | 222k | _best_subframe = !_best_subframe; |
4193 | 222k | _best_bits = _candidate_bits; |
4194 | 222k | } |
4195 | 740k | } |
4196 | 274k | } |
4197 | | |
4198 | 273k | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4199 | | /* encode lpc */ |
4200 | 273k | if(encoder->protected_->max_lpc_order > 0) { |
4201 | 222k | if(encoder->protected_->max_lpc_order >= frame_header->blocksize) |
4202 | 13.8k | max_lpc_order = frame_header->blocksize-1; |
4203 | 208k | else |
4204 | 208k | max_lpc_order = encoder->protected_->max_lpc_order; |
4205 | 222k | if(max_lpc_order > 0) { |
4206 | 222k | apply_apodization_state.a = 0; |
4207 | 222k | apply_apodization_state.b = 1; |
4208 | 222k | apply_apodization_state.c = 0; |
4209 | 295M | while (apply_apodization_state.a < encoder->protected_->num_apodizations) { |
4210 | 295M | uint32_t max_lpc_order_this_apodization = max_lpc_order; |
4211 | | |
4212 | 295M | if(!apply_apodization_(encoder, threadtask, &apply_apodization_state, |
4213 | 295M | frame_header->blocksize, lpc_error, |
4214 | 295M | &max_lpc_order_this_apodization, |
4215 | 295M | subframe_bps, integer_signal, |
4216 | 295M | &guess_lpc_order)) |
4217 | | /* If apply_apodization_ fails, try next apodization */ |
4218 | 295M | continue; |
4219 | | |
4220 | 350k | if(encoder->protected_->do_exhaustive_model_search) { |
4221 | 256k | min_lpc_order = 1; |
4222 | 256k | } |
4223 | 94.9k | else { |
4224 | 94.9k | min_lpc_order = max_lpc_order_this_apodization = guess_lpc_order; |
4225 | 94.9k | } |
4226 | 3.66M | for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order_this_apodization; lpc_order++) { |
4227 | 3.31M | lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order); |
4228 | 3.31M | if(lpc_residual_bits_per_sample >= (double)subframe_bps) |
4229 | 26.5k | continue; /* don't even try */ |
4230 | 3.28M | if(encoder->protected_->do_qlp_coeff_prec_search) { |
4231 | 1.78M | min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; |
4232 | | /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ |
4233 | 1.78M | if(subframe_bps <= 17) { |
4234 | 200k | max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION); |
4235 | 200k | max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); |
4236 | 200k | } |
4237 | 1.58M | else |
4238 | 1.58M | max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; |
4239 | 1.78M | } |
4240 | 1.50M | else { |
4241 | 1.50M | min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision; |
4242 | 1.50M | } |
4243 | 23.8M | for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { |
4244 | 20.6M | _candidate_bits = |
4245 | 20.6M | evaluate_lpc_subframe_( |
4246 | 20.6M | encoder, |
4247 | 20.6M | threadtask, |
4248 | 20.6M | integer_signal, |
4249 | 20.6M | residual[!_best_subframe], |
4250 | 20.6M | threadtask->abs_residual_partition_sums, |
4251 | 20.6M | threadtask->raw_bits_per_partition, |
4252 | 20.6M | threadtask->lp_coeff[lpc_order-1], |
4253 | 20.6M | frame_header->blocksize, |
4254 | 20.6M | subframe_bps, |
4255 | 20.6M | lpc_order, |
4256 | 20.6M | qlp_coeff_precision, |
4257 | 20.6M | rice_parameter_limit, |
4258 | 20.6M | min_partition_order, |
4259 | 20.6M | max_partition_order, |
4260 | 20.6M | encoder->protected_->do_escape_coding, |
4261 | 20.6M | encoder->protected_->rice_parameter_search_dist, |
4262 | 20.6M | subframe[!_best_subframe], |
4263 | 20.6M | partitioned_rice_contents[!_best_subframe] |
4264 | 20.6M | ); |
4265 | 20.6M | if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ |
4266 | 17.3M | if(_candidate_bits < _best_bits) { |
4267 | 36.1k | _best_subframe = !_best_subframe; |
4268 | 36.1k | _best_bits = _candidate_bits; |
4269 | 36.1k | } |
4270 | 17.3M | } |
4271 | 20.6M | } |
4272 | 3.28M | } |
4273 | 350k | } |
4274 | 222k | } |
4275 | 222k | } |
4276 | 273k | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ |
4277 | 273k | } |
4278 | 384k | } |
4279 | | |
4280 | | /* under rare circumstances this can happen when all but lpc subframe types are disabled: */ |
4281 | 388k | if(_best_bits == UINT32_MAX) { |
4282 | 0 | FLAC__ASSERT(_best_subframe == 0); |
4283 | 0 | _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); |
4284 | 0 | } |
4285 | | |
4286 | 388k | *best_subframe = _best_subframe; |
4287 | 388k | *best_bits = _best_bits; |
4288 | | |
4289 | 388k | return true; |
4290 | 388k | } |
4291 | | |
4292 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4293 | 295M | static inline void set_next_subdivide_tukey(FLAC__int32 parts, uint32_t * apodizations, uint32_t * current_depth, uint32_t * current_part){ |
4294 | | // current_part is interleaved: even are partial, odd are punchout |
4295 | 295M | if(*current_depth == 2){ |
4296 | | // For depth 2, we only do partial, no punchout as that is almost redundant |
4297 | 7.20k | if(*current_part == 0){ |
4298 | 3.60k | *current_part = 2; |
4299 | 3.60k | }else{ /* *current_path == 2 */ |
4300 | 3.60k | *current_part = 0; |
4301 | 3.60k | (*current_depth)++; |
4302 | 3.60k | } |
4303 | 295M | }else if((*current_part) < (2*(*current_depth)-1)){ |
4304 | 295M | (*current_part)++; |
4305 | 295M | }else{ /* (*current_part) >= (2*(*current_depth)-1) */ |
4306 | 64.4k | *current_part = 0; |
4307 | 64.4k | (*current_depth)++; |
4308 | 64.4k | } |
4309 | | |
4310 | | /* Now check if we are done with this SUBDIVIDE_TUKEY apodization */ |
4311 | 295M | if(*current_depth > (uint32_t) parts){ |
4312 | 3.60k | (*apodizations)++; |
4313 | 3.60k | *current_depth = 1; |
4314 | 3.60k | *current_part = 0; |
4315 | 3.60k | } |
4316 | 295M | } |
4317 | | |
4318 | | FLAC__bool apply_apodization_(FLAC__StreamEncoder *encoder, |
4319 | | FLAC__StreamEncoderThreadTask *threadtask, |
4320 | | apply_apodization_state_struct *apply_apodization_state, |
4321 | | uint32_t blocksize, |
4322 | | double *lpc_error, |
4323 | | uint32_t *max_lpc_order_this_apodization, |
4324 | | uint32_t subframe_bps, |
4325 | | const void *integer_signal, |
4326 | | uint32_t *guess_lpc_order) |
4327 | 295M | { |
4328 | 295M | apply_apodization_state->current_apodization = &encoder->protected_->apodizations[apply_apodization_state->a]; |
4329 | | |
4330 | 295M | if(apply_apodization_state->b == 1) { |
4331 | | /* window full subblock */ |
4332 | 253k | if(subframe_bps <= 32) |
4333 | 237k | FLAC__lpc_window_data(integer_signal, encoder->private_->window[apply_apodization_state->a], threadtask->windowed_signal, blocksize); |
4334 | 16.0k | else |
4335 | 16.0k | FLAC__lpc_window_data_wide(integer_signal, encoder->private_->window[apply_apodization_state->a], threadtask->windowed_signal, blocksize); |
4336 | 253k | encoder->private_->local_lpc_compute_autocorrelation(threadtask->windowed_signal, blocksize, (*max_lpc_order_this_apodization)+1, apply_apodization_state->autoc); |
4337 | 253k | if(apply_apodization_state->current_apodization->type == FLAC__APODIZATION_SUBDIVIDE_TUKEY){ |
4338 | 3.60k | uint32_t i; |
4339 | 35.5k | for(i = 0; i < *max_lpc_order_this_apodization; i++) |
4340 | 31.9k | memcpy(apply_apodization_state->autoc_root, apply_apodization_state->autoc, *max_lpc_order_this_apodization*sizeof(apply_apodization_state->autoc[0])); |
4341 | | |
4342 | 3.60k | (apply_apodization_state->b)++; |
4343 | 250k | }else{ |
4344 | 250k | (apply_apodization_state->a)++; |
4345 | 250k | } |
4346 | 253k | } |
4347 | 295M | else { |
4348 | | /* window part of subblock */ |
4349 | 295M | if(blocksize/apply_apodization_state->b <= FLAC__MAX_LPC_ORDER) { |
4350 | | /* intrinsics autocorrelation routines do not all handle cases in which lag might be |
4351 | | * larger than data_len, and some routines round lag up to the nearest multiple of 4 |
4352 | | * As little gain is expected from using LPC on part of a signal as small as 32 samples |
4353 | | * and to enable widening this rounding up to larger values in the future, windowing |
4354 | | * parts smaller than or equal to FLAC__MAX_LPC_ORDER (which is 32) samples is not supported */ |
4355 | 295M | set_next_subdivide_tukey(apply_apodization_state->current_apodization->parameters.subdivide_tukey.parts, &apply_apodization_state->a, &apply_apodization_state->b, &apply_apodization_state->c); |
4356 | 295M | return false; |
4357 | 295M | } |
4358 | 99.8k | if(!(apply_apodization_state->c % 2)) { |
4359 | | /* on even c, evaluate the (c/2)th partial window of size blocksize/b */ |
4360 | 52.8k | if(subframe_bps <= 32) |
4361 | 49.4k | FLAC__lpc_window_data_partial(integer_signal, encoder->private_->window[apply_apodization_state->a], threadtask->windowed_signal, blocksize, blocksize/apply_apodization_state->b/2, (apply_apodization_state->c/2*blocksize)/apply_apodization_state->b); |
4362 | 3.39k | else |
4363 | 3.39k | FLAC__lpc_window_data_partial_wide(integer_signal, encoder->private_->window[apply_apodization_state->a], threadtask->windowed_signal, blocksize, blocksize/apply_apodization_state->b/2, (apply_apodization_state->c/2*blocksize)/apply_apodization_state->b); |
4364 | 52.8k | encoder->private_->local_lpc_compute_autocorrelation(threadtask->windowed_signal, blocksize/apply_apodization_state->b, (*max_lpc_order_this_apodization)+1, apply_apodization_state->autoc); |
4365 | 52.8k | } |
4366 | 47.0k | else { |
4367 | | /* on uneven c, evaluate the root window (over the whole block) minus the previous partial window |
4368 | | * similar to tukey_punchout apodization but more efficient */ |
4369 | 47.0k | uint32_t i; |
4370 | 620k | for(i = 0; i < *max_lpc_order_this_apodization; i++) |
4371 | 573k | apply_apodization_state->autoc[i] = apply_apodization_state->autoc_root[i] - apply_apodization_state->autoc[i]; |
4372 | 47.0k | } |
4373 | | /* Next function sets a, b and c appropriate for next iteration */ |
4374 | 99.8k | set_next_subdivide_tukey(apply_apodization_state->current_apodization->parameters.subdivide_tukey.parts, &apply_apodization_state->a, &apply_apodization_state->b, &apply_apodization_state->c); |
4375 | 99.8k | } |
4376 | | |
4377 | 353k | if(apply_apodization_state->autoc[0] == 0.0) /* Signal seems to be constant, so we can't do lp. Constant detection is probably disabled */ |
4378 | 2.84k | return false; |
4379 | 350k | FLAC__lpc_compute_lp_coefficients(apply_apodization_state->autoc, max_lpc_order_this_apodization, threadtask->lp_coeff, lpc_error); |
4380 | 350k | *guess_lpc_order = |
4381 | 350k | FLAC__lpc_compute_best_order( |
4382 | 350k | lpc_error, |
4383 | 350k | *max_lpc_order_this_apodization, |
4384 | 350k | blocksize, |
4385 | 350k | subframe_bps + ( |
4386 | 350k | encoder->protected_->do_qlp_coeff_prec_search? |
4387 | 164k | FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */ |
4388 | 350k | encoder->protected_->qlp_coeff_precision |
4389 | 350k | ) |
4390 | 350k | ); |
4391 | 350k | return true; |
4392 | 353k | } |
4393 | | #endif |
4394 | | |
4395 | | FLAC__bool add_subframe_( |
4396 | | FLAC__StreamEncoder *encoder, |
4397 | | uint32_t blocksize, |
4398 | | uint32_t subframe_bps, |
4399 | | const FLAC__Subframe *subframe, |
4400 | | FLAC__BitWriter *frame |
4401 | | ) |
4402 | 309k | { |
4403 | 309k | switch(subframe->type) { |
4404 | 104k | case FLAC__SUBFRAME_TYPE_CONSTANT: |
4405 | 104k | if(!FLAC__subframe_add_constant(&(subframe->data.constant), subframe_bps, subframe->wasted_bits, frame)) { |
4406 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
4407 | 0 | return false; |
4408 | 0 | } |
4409 | 104k | break; |
4410 | 139k | case FLAC__SUBFRAME_TYPE_FIXED: |
4411 | 139k | if(!FLAC__subframe_add_fixed(&(subframe->data.fixed), blocksize - subframe->data.fixed.order, subframe_bps, subframe->wasted_bits, frame)) { |
4412 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
4413 | 0 | return false; |
4414 | 0 | } |
4415 | 139k | break; |
4416 | 139k | case FLAC__SUBFRAME_TYPE_LPC: |
4417 | 18.1k | if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) { |
4418 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
4419 | 0 | return false; |
4420 | 0 | } |
4421 | 18.1k | break; |
4422 | 48.1k | case FLAC__SUBFRAME_TYPE_VERBATIM: |
4423 | 48.1k | if(!FLAC__subframe_add_verbatim(&(subframe->data.verbatim), blocksize, subframe_bps, subframe->wasted_bits, frame)) { |
4424 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; |
4425 | 0 | return false; |
4426 | 0 | } |
4427 | 48.1k | break; |
4428 | 48.1k | default: |
4429 | 0 | FLAC__ASSERT(0); |
4430 | 309k | } |
4431 | | |
4432 | 310k | return true; |
4433 | 309k | } |
4434 | | |
4435 | | #define SPOTCHECK_ESTIMATE 0 |
4436 | | #if SPOTCHECK_ESTIMATE |
4437 | | static void spotcheck_subframe_estimate_( |
4438 | | FLAC__StreamEncoder *encoder, |
4439 | | uint32_t blocksize, |
4440 | | uint32_t subframe_bps, |
4441 | | const FLAC__Subframe *subframe, |
4442 | | uint32_t estimate |
4443 | | ) |
4444 | | { |
4445 | | FLAC__bool ret; |
4446 | | FLAC__BitWriter *frame = FLAC__bitwriter_new(); |
4447 | | if(frame == 0) { |
4448 | | flac_fprintf(stderr, "EST: can't allocate frame\n"); |
4449 | | return; |
4450 | | } |
4451 | | if(!FLAC__bitwriter_init(frame)) { |
4452 | | flac_fprintf(stderr, "EST: can't init frame\n"); |
4453 | | return; |
4454 | | } |
4455 | | ret = add_subframe_(encoder, blocksize, subframe_bps, subframe, frame); |
4456 | | FLAC__ASSERT(ret); |
4457 | | { |
4458 | | const uint32_t actual = FLAC__bitwriter_get_input_bits_unconsumed(frame); |
4459 | | if(estimate != actual) |
4460 | | flac_fprintf(stderr, "EST: bad, frame#%u sub#%%d type=%8s est=%u, actual=%u, delta=%d\n", encoder->private_->current_frame_number, FLAC__SubframeTypeString[subframe->type], estimate, actual, (int)actual-(int)estimate); |
4461 | | } |
4462 | | FLAC__bitwriter_delete(frame); |
4463 | | } |
4464 | | #endif |
4465 | | |
4466 | | uint32_t evaluate_constant_subframe_( |
4467 | | FLAC__StreamEncoder *encoder, |
4468 | | const FLAC__int64 signal, |
4469 | | uint32_t blocksize, |
4470 | | uint32_t subframe_bps, |
4471 | | FLAC__Subframe *subframe |
4472 | | ) |
4473 | 110k | { |
4474 | 110k | uint32_t estimate; |
4475 | 110k | subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT; |
4476 | 110k | subframe->data.constant.value = signal; |
4477 | | |
4478 | 110k | estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + subframe_bps; |
4479 | | |
4480 | | #if SPOTCHECK_ESTIMATE |
4481 | | spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); |
4482 | | #else |
4483 | 110k | (void)encoder, (void)blocksize; |
4484 | 110k | #endif |
4485 | | |
4486 | 110k | return estimate; |
4487 | 110k | } |
4488 | | |
4489 | | uint32_t evaluate_fixed_subframe_( |
4490 | | FLAC__StreamEncoder *encoder, |
4491 | | FLAC__StreamEncoderThreadTask *threadtask, |
4492 | | const void *signal, |
4493 | | FLAC__int32 residual[], |
4494 | | FLAC__uint64 abs_residual_partition_sums[], |
4495 | | uint32_t raw_bits_per_partition[], |
4496 | | uint32_t blocksize, |
4497 | | uint32_t subframe_bps, |
4498 | | uint32_t order, |
4499 | | uint32_t rice_parameter_limit, |
4500 | | uint32_t min_partition_order, |
4501 | | uint32_t max_partition_order, |
4502 | | FLAC__bool do_escape_coding, |
4503 | | uint32_t rice_parameter_search_dist, |
4504 | | FLAC__Subframe *subframe, |
4505 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents |
4506 | | ) |
4507 | 741k | { |
4508 | 741k | uint32_t i, residual_bits, estimate; |
4509 | 741k | const uint32_t residual_samples = blocksize - order; |
4510 | | |
4511 | 741k | if((subframe_bps + order) <= 32) |
4512 | 432k | FLAC__fixed_compute_residual(((FLAC__int32 *)signal)+order, residual_samples, order, residual); |
4513 | 308k | else if(subframe_bps <= 32) |
4514 | 294k | FLAC__fixed_compute_residual_wide(((FLAC__int32 *)signal)+order, residual_samples, order, residual); |
4515 | 14.3k | else |
4516 | 14.3k | FLAC__fixed_compute_residual_wide_33bit(((FLAC__int64 *)signal)+order, residual_samples, order, residual); |
4517 | | |
4518 | 741k | subframe->type = FLAC__SUBFRAME_TYPE_FIXED; |
4519 | | |
4520 | 741k | subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; |
4521 | 741k | subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; |
4522 | 741k | subframe->data.fixed.residual = residual; |
4523 | | |
4524 | 741k | residual_bits = |
4525 | 741k | find_best_partition_order_( |
4526 | 741k | encoder->private_, |
4527 | 741k | threadtask, |
4528 | 741k | residual, |
4529 | 741k | abs_residual_partition_sums, |
4530 | 741k | raw_bits_per_partition, |
4531 | 741k | residual_samples, |
4532 | 741k | order, |
4533 | 741k | rice_parameter_limit, |
4534 | 741k | min_partition_order, |
4535 | 741k | max_partition_order, |
4536 | 741k | subframe_bps, |
4537 | 741k | do_escape_coding, |
4538 | 741k | rice_parameter_search_dist, |
4539 | 741k | &subframe->data.fixed.entropy_coding_method |
4540 | 741k | ); |
4541 | | |
4542 | 741k | subframe->data.fixed.order = order; |
4543 | 741k | if(subframe_bps <= 32) |
4544 | 1.87M | for(i = 0; i < order; i++) |
4545 | 1.14M | subframe->data.fixed.warmup[i] = ((FLAC__int32 *)signal)[i]; |
4546 | 15.3k | else |
4547 | 30.0k | for(i = 0; i < order; i++) |
4548 | 14.7k | subframe->data.fixed.warmup[i] = ((FLAC__int64 *)signal)[i]; |
4549 | | |
4550 | 741k | estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps); |
4551 | 741k | if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow |
4552 | 740k | estimate += residual_bits; |
4553 | 518 | else |
4554 | 518 | estimate = UINT32_MAX; |
4555 | | |
4556 | | #if SPOTCHECK_ESTIMATE |
4557 | | spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); |
4558 | | #endif |
4559 | | |
4560 | 741k | return estimate; |
4561 | 741k | } |
4562 | | |
4563 | | #ifndef FLAC__INTEGER_ONLY_LIBRARY |
4564 | | uint32_t evaluate_lpc_subframe_( |
4565 | | FLAC__StreamEncoder *encoder, |
4566 | | FLAC__StreamEncoderThreadTask *threadtask, |
4567 | | const void *signal, |
4568 | | FLAC__int32 residual[], |
4569 | | FLAC__uint64 abs_residual_partition_sums[], |
4570 | | uint32_t raw_bits_per_partition[], |
4571 | | const FLAC__real lp_coeff[], |
4572 | | uint32_t blocksize, |
4573 | | uint32_t subframe_bps, |
4574 | | uint32_t order, |
4575 | | uint32_t qlp_coeff_precision, |
4576 | | uint32_t rice_parameter_limit, |
4577 | | uint32_t min_partition_order, |
4578 | | uint32_t max_partition_order, |
4579 | | FLAC__bool do_escape_coding, |
4580 | | uint32_t rice_parameter_search_dist, |
4581 | | FLAC__Subframe *subframe, |
4582 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents |
4583 | | ) |
4584 | 20.6M | { |
4585 | 20.6M | FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /* WATCHOUT: the size is important; some x86 intrinsic routines need more than lpc order elements */ |
4586 | 20.6M | uint32_t i, residual_bits, estimate; |
4587 | 20.6M | int quantization, ret; |
4588 | 20.6M | const uint32_t residual_samples = blocksize - order; |
4589 | | |
4590 | | /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ |
4591 | 20.6M | if(subframe_bps <= 17) { |
4592 | 2.08M | FLAC__ASSERT(order > 0); |
4593 | 2.08M | FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER); |
4594 | 2.08M | qlp_coeff_precision = flac_min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order)); |
4595 | 2.08M | } |
4596 | | |
4597 | 20.6M | ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization); |
4598 | 20.6M | if(ret != 0) |
4599 | 871k | return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */ |
4600 | | |
4601 | 19.7M | if(FLAC__lpc_max_residual_bps(subframe_bps, qlp_coeff, order, quantization) > 32) { |
4602 | 13.7M | if(subframe_bps <= 32){ |
4603 | 12.5M | if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual)) |
4604 | 2.13M | return 0; |
4605 | 12.5M | } |
4606 | 1.18M | else |
4607 | 1.18M | if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(((FLAC__int64 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual)) |
4608 | 386k | return 0; |
4609 | 13.7M | } |
4610 | 5.97M | else |
4611 | 5.97M | if(FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) <= 32) |
4612 | 3.42M | if(subframe_bps <= 16 && qlp_coeff_precision <= 16) |
4613 | 1.80M | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); |
4614 | 1.61M | else |
4615 | 1.61M | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); |
4616 | 2.55M | else |
4617 | 2.55M | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); |
4618 | | |
4619 | 17.2M | subframe->type = FLAC__SUBFRAME_TYPE_LPC; |
4620 | | |
4621 | 17.2M | subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; |
4622 | 17.2M | subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; |
4623 | 17.2M | subframe->data.lpc.residual = residual; |
4624 | | |
4625 | 17.2M | residual_bits = |
4626 | 17.2M | find_best_partition_order_( |
4627 | 17.2M | encoder->private_, |
4628 | 17.2M | threadtask, |
4629 | 17.2M | residual, |
4630 | 17.2M | abs_residual_partition_sums, |
4631 | 17.2M | raw_bits_per_partition, |
4632 | 17.2M | residual_samples, |
4633 | 17.2M | order, |
4634 | 17.2M | rice_parameter_limit, |
4635 | 17.2M | min_partition_order, |
4636 | 17.2M | max_partition_order, |
4637 | 17.2M | subframe_bps, |
4638 | 17.2M | do_escape_coding, |
4639 | 17.2M | rice_parameter_search_dist, |
4640 | 17.2M | &subframe->data.lpc.entropy_coding_method |
4641 | 17.2M | ); |
4642 | | |
4643 | 17.2M | subframe->data.lpc.order = order; |
4644 | 17.2M | subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision; |
4645 | 17.2M | subframe->data.lpc.quantization_level = quantization; |
4646 | 17.2M | memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER); |
4647 | 17.2M | if(subframe_bps <= 32) |
4648 | 147M | for(i = 0; i < order; i++) |
4649 | 131M | subframe->data.lpc.warmup[i] = ((FLAC__int32 *)signal)[i]; |
4650 | 928k | else |
4651 | 8.20M | for(i = 0; i < order; i++) |
4652 | 7.27M | subframe->data.lpc.warmup[i] = ((FLAC__int64 *)signal)[i]; |
4653 | | |
4654 | | |
4655 | 17.2M | estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)); |
4656 | 17.2M | if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow |
4657 | 17.3M | estimate += residual_bits; |
4658 | 18.4E | else |
4659 | 18.4E | estimate = UINT32_MAX; |
4660 | | |
4661 | | #if SPOTCHECK_ESTIMATE |
4662 | | spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); |
4663 | | #endif |
4664 | | |
4665 | 17.2M | return estimate; |
4666 | 19.7M | } |
4667 | | #endif |
4668 | | |
4669 | | uint32_t evaluate_verbatim_subframe_( |
4670 | | FLAC__StreamEncoder *encoder, |
4671 | | const void *signal, |
4672 | | uint32_t blocksize, |
4673 | | uint32_t subframe_bps, |
4674 | | FLAC__Subframe *subframe |
4675 | | ) |
4676 | 388k | { |
4677 | 388k | uint32_t estimate; |
4678 | | |
4679 | 388k | subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; |
4680 | | |
4681 | 388k | if(subframe_bps <= 32){ |
4682 | 374k | subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; |
4683 | 374k | subframe->data.verbatim.data.int32 = signal; |
4684 | 374k | } |
4685 | 14.4k | else { |
4686 | 14.4k | subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64; |
4687 | 14.4k | subframe->data.verbatim.data.int64 = signal; |
4688 | 14.4k | } |
4689 | | |
4690 | 388k | estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps); |
4691 | | |
4692 | | #if SPOTCHECK_ESTIMATE |
4693 | | spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); |
4694 | | #else |
4695 | 388k | (void)encoder; |
4696 | 388k | #endif |
4697 | | |
4698 | 388k | return estimate; |
4699 | 388k | } |
4700 | | |
4701 | | uint32_t find_best_partition_order_( |
4702 | | FLAC__StreamEncoderPrivate *private_, |
4703 | | FLAC__StreamEncoderThreadTask *threadtask, |
4704 | | const FLAC__int32 residual[], |
4705 | | FLAC__uint64 abs_residual_partition_sums[], |
4706 | | uint32_t raw_bits_per_partition[], |
4707 | | uint32_t residual_samples, |
4708 | | uint32_t predictor_order, |
4709 | | uint32_t rice_parameter_limit, |
4710 | | uint32_t min_partition_order, |
4711 | | uint32_t max_partition_order, |
4712 | | uint32_t bps, |
4713 | | FLAC__bool do_escape_coding, |
4714 | | uint32_t rice_parameter_search_dist, |
4715 | | FLAC__EntropyCodingMethod *best_ecm |
4716 | | ) |
4717 | 17.6M | { |
4718 | 17.6M | uint32_t residual_bits, best_residual_bits = 0; |
4719 | 17.6M | uint32_t best_parameters_index = 0; |
4720 | 17.6M | uint32_t best_partition_order = 0; |
4721 | 17.6M | const uint32_t blocksize = residual_samples + predictor_order; |
4722 | | |
4723 | 17.6M | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); |
4724 | 17.6M | min_partition_order = flac_min(min_partition_order, max_partition_order); |
4725 | | |
4726 | 17.6M | private_->local_precompute_partition_info_sums(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); |
4727 | | |
4728 | 17.6M | if(do_escape_coding) |
4729 | 14.2M | precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); |
4730 | | |
4731 | 17.6M | { |
4732 | 17.6M | int partition_order; |
4733 | 17.6M | uint32_t sum; |
4734 | | |
4735 | 35.7M | for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) { |
4736 | 18.1M | FLAC__ASSERT(do_escape_coding != /* XOR */ (raw_bits_per_partition == NULL)); |
4737 | 18.1M | if(! |
4738 | 18.1M | set_partitioned_rice_( |
4739 | | #ifdef EXACT_RICE_BITS_CALCULATION |
4740 | | residual, |
4741 | | #endif |
4742 | 18.1M | abs_residual_partition_sums+sum, |
4743 | 18.1M | do_escape_coding ? raw_bits_per_partition+sum : NULL, |
4744 | 18.1M | residual_samples, |
4745 | 18.1M | predictor_order, |
4746 | 18.1M | rice_parameter_limit, |
4747 | 18.1M | rice_parameter_search_dist, |
4748 | 18.1M | (uint32_t)partition_order, |
4749 | 18.1M | do_escape_coding, |
4750 | 18.1M | &threadtask->partitioned_rice_contents_extra[!best_parameters_index], |
4751 | 18.1M | &residual_bits |
4752 | 18.1M | ) |
4753 | 18.1M | ) |
4754 | 0 | { |
4755 | 0 | FLAC__ASSERT(best_residual_bits != 0); |
4756 | 0 | break; |
4757 | 0 | } |
4758 | 18.1M | sum += 1u << partition_order; |
4759 | 18.1M | if(best_residual_bits == 0 || residual_bits < best_residual_bits) { |
4760 | 18.0M | best_residual_bits = residual_bits; |
4761 | 18.0M | best_parameters_index = !best_parameters_index; |
4762 | 18.0M | best_partition_order = partition_order; |
4763 | 18.0M | } |
4764 | 18.1M | } |
4765 | 17.6M | } |
4766 | | |
4767 | 17.6M | best_ecm->data.partitioned_rice.order = best_partition_order; |
4768 | | |
4769 | 17.6M | { |
4770 | | /* |
4771 | | * We are allowed to de-const the pointer based on our special |
4772 | | * knowledge; it is const to the outside world. |
4773 | | */ |
4774 | 17.6M | FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents; |
4775 | 17.6M | uint32_t partition; |
4776 | | |
4777 | | /* save best parameters and raw_bits */ |
4778 | 17.6M | memcpy(prc->parameters, threadtask->partitioned_rice_contents_extra[best_parameters_index].parameters, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order))); |
4779 | 17.6M | if(do_escape_coding) |
4780 | 14.1M | memcpy(prc->raw_bits, threadtask->partitioned_rice_contents_extra[best_parameters_index].raw_bits, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order))); |
4781 | | /* |
4782 | | * Now need to check if the type should be changed to |
4783 | | * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the |
4784 | | * size of the rice parameters. |
4785 | | */ |
4786 | 27.1M | for(partition = 0; partition < (1u<<best_partition_order); partition++) { |
4787 | 23.3M | if(prc->parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { |
4788 | 13.7M | best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2; |
4789 | 13.7M | break; |
4790 | 13.7M | } |
4791 | 23.3M | } |
4792 | 17.6M | } |
4793 | | |
4794 | 17.6M | return best_residual_bits; |
4795 | 17.6M | } |
4796 | | |
4797 | | void precompute_partition_info_sums_( |
4798 | | const FLAC__int32 residual[], |
4799 | | FLAC__uint64 abs_residual_partition_sums[], |
4800 | | uint32_t residual_samples, |
4801 | | uint32_t predictor_order, |
4802 | | uint32_t min_partition_order, |
4803 | | uint32_t max_partition_order, |
4804 | | uint32_t bps |
4805 | | ) |
4806 | 0 | { |
4807 | 0 | const uint32_t default_partition_samples = (residual_samples + predictor_order) >> max_partition_order; |
4808 | 0 | uint32_t partitions = 1u << max_partition_order; |
4809 | |
|
4810 | 0 | FLAC__ASSERT(default_partition_samples > predictor_order); |
4811 | | |
4812 | | /* first do max_partition_order */ |
4813 | 0 | { |
4814 | 0 | const uint32_t threshold = 32 - FLAC__bitmath_ilog2(default_partition_samples); |
4815 | 0 | uint32_t partition, residual_sample, end = (uint32_t)(-(int)predictor_order); |
4816 | | /* WATCHOUT: "bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum assumed size of the average residual magnitude */ |
4817 | 0 | if(bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < threshold) { |
4818 | 0 | for(partition = residual_sample = 0; partition < partitions; partition++) { |
4819 | 0 | FLAC__uint32 abs_residual_partition_sum = 0; |
4820 | 0 | end += default_partition_samples; |
4821 | 0 | for( ; residual_sample < end; residual_sample++) |
4822 | 0 | abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */ |
4823 | 0 | abs_residual_partition_sums[partition] = abs_residual_partition_sum; |
4824 | 0 | } |
4825 | 0 | } |
4826 | 0 | else { /* have to pessimistically use 64 bits for accumulator */ |
4827 | 0 | for(partition = residual_sample = 0; partition < partitions; partition++) { |
4828 | 0 | FLAC__uint64 abs_residual_partition_sum64 = 0; |
4829 | 0 | end += default_partition_samples; |
4830 | 0 | for( ; residual_sample < end; residual_sample++) |
4831 | 0 | abs_residual_partition_sum64 += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */ |
4832 | 0 | abs_residual_partition_sums[partition] = abs_residual_partition_sum64; |
4833 | 0 | } |
4834 | 0 | } |
4835 | 0 | } |
4836 | | |
4837 | | /* now merge partitions for lower orders */ |
4838 | 0 | { |
4839 | 0 | uint32_t from_partition = 0, to_partition = partitions; |
4840 | 0 | int partition_order; |
4841 | 0 | for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) { |
4842 | 0 | uint32_t i; |
4843 | 0 | partitions >>= 1; |
4844 | 0 | for(i = 0; i < partitions; i++) { |
4845 | 0 | abs_residual_partition_sums[to_partition++] = |
4846 | 0 | abs_residual_partition_sums[from_partition ] + |
4847 | 0 | abs_residual_partition_sums[from_partition+1]; |
4848 | 0 | from_partition += 2; |
4849 | 0 | } |
4850 | 0 | } |
4851 | 0 | } |
4852 | 0 | } |
4853 | | |
4854 | | void precompute_partition_info_escapes_( |
4855 | | const FLAC__int32 residual[], |
4856 | | uint32_t raw_bits_per_partition[], |
4857 | | uint32_t residual_samples, |
4858 | | uint32_t predictor_order, |
4859 | | uint32_t min_partition_order, |
4860 | | uint32_t max_partition_order |
4861 | | ) |
4862 | 14.2M | { |
4863 | 14.2M | int partition_order; |
4864 | 14.2M | uint32_t from_partition, to_partition = 0; |
4865 | 14.2M | const uint32_t blocksize = residual_samples + predictor_order; |
4866 | | |
4867 | | /* first do max_partition_order */ |
4868 | 14.2M | for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) { |
4869 | 14.2M | FLAC__int32 r; |
4870 | 14.2M | FLAC__uint32 rmax; |
4871 | 14.2M | uint32_t partition, partition_sample, partition_samples, residual_sample; |
4872 | 14.2M | const uint32_t partitions = 1u << partition_order; |
4873 | 14.2M | const uint32_t default_partition_samples = blocksize >> partition_order; |
4874 | | |
4875 | 14.2M | FLAC__ASSERT(default_partition_samples > predictor_order); |
4876 | | |
4877 | 47.4M | for(partition = residual_sample = 0; partition < partitions; partition++) { |
4878 | 33.2M | partition_samples = default_partition_samples; |
4879 | 33.2M | if(partition == 0) |
4880 | 14.2M | partition_samples -= predictor_order; |
4881 | 33.2M | rmax = 0; |
4882 | 2.19G | for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) { |
4883 | 2.16G | r = residual[residual_sample++]; |
4884 | | /* OPT: maybe faster: rmax |= r ^ (r>>31) */ |
4885 | 2.16G | if(r < 0) |
4886 | 499M | rmax |= ~r; |
4887 | 1.66G | else |
4888 | 1.66G | rmax |= r; |
4889 | 2.16G | } |
4890 | | /* now we know all residual values are in the range [-rmax-1,rmax] */ |
4891 | 33.2M | raw_bits_per_partition[partition] = rmax? FLAC__bitmath_ilog2(rmax) + 2 : 1; |
4892 | 33.2M | } |
4893 | 14.2M | to_partition = partitions; |
4894 | 14.2M | break; /*@@@ yuck, should remove the 'for' loop instead */ |
4895 | 14.2M | } |
4896 | | |
4897 | | /* now merge partitions for lower orders */ |
4898 | 14.7M | for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) { |
4899 | 461k | uint32_t m; |
4900 | 461k | uint32_t i; |
4901 | 461k | const uint32_t partitions = 1u << partition_order; |
4902 | 1.86M | for(i = 0; i < partitions; i++) { |
4903 | 1.40M | m = raw_bits_per_partition[from_partition]; |
4904 | 1.40M | from_partition++; |
4905 | 1.40M | raw_bits_per_partition[to_partition] = flac_max(m, raw_bits_per_partition[from_partition]); |
4906 | 1.40M | from_partition++; |
4907 | 1.40M | to_partition++; |
4908 | 1.40M | } |
4909 | 461k | } |
4910 | 14.2M | } |
4911 | | |
4912 | | #ifdef EXACT_RICE_BITS_CALCULATION |
4913 | | static inline uint32_t count_rice_bits_in_partition_( |
4914 | | const uint32_t rice_parameter, |
4915 | | const uint32_t partition_samples, |
4916 | | const FLAC__int32 *residual |
4917 | | ) |
4918 | | { |
4919 | | uint32_t i; |
4920 | | uint64_t partition_bits = |
4921 | | FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ |
4922 | | (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */ |
4923 | | ; |
4924 | | for(i = 0; i < partition_samples; i++) |
4925 | | partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter ); |
4926 | | return (uint32_t)(flac_min(partition_bits,UINT32_MAX)); // To make sure the return value doesn't overflow |
4927 | | } |
4928 | | #else |
4929 | | static inline uint32_t count_rice_bits_in_partition_( |
4930 | | const uint32_t rice_parameter, |
4931 | | const uint32_t partition_samples, |
4932 | | const FLAC__uint64 abs_residual_partition_sum |
4933 | | ) |
4934 | 43.4M | { |
4935 | 43.4M | return (uint32_t)(flac_min( // To make sure the return value doesn't overflow |
4936 | 43.4M | FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ |
4937 | 43.4M | (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */ |
4938 | 43.4M | ( |
4939 | 43.4M | rice_parameter? |
4940 | 43.4M | (abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */ |
4941 | 43.4M | : (abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */ |
4942 | 43.4M | ) |
4943 | 43.4M | - (partition_samples >> 1),UINT32_MAX)); |
4944 | | /* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum. |
4945 | | * The actual number of bits used is closer to the sum(for all i in the partition) of abs(residual[i])>>(rice_parameter-1) |
4946 | | * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out. |
4947 | | * So the subtraction term tries to guess how many extra bits were contributed. |
4948 | | * If the LSBs are randomly distributed, this should average to 0.5 extra bits per sample. |
4949 | | */ |
4950 | 0 | ; |
4951 | 0 | } |
4952 | | #endif |
4953 | | |
4954 | | FLAC__bool set_partitioned_rice_( |
4955 | | #ifdef EXACT_RICE_BITS_CALCULATION |
4956 | | const FLAC__int32 residual[], |
4957 | | #endif |
4958 | | const FLAC__uint64 abs_residual_partition_sums[], |
4959 | | const uint32_t raw_bits_per_partition[], |
4960 | | const uint32_t residual_samples, |
4961 | | const uint32_t predictor_order, |
4962 | | const uint32_t rice_parameter_limit, |
4963 | | const uint32_t rice_parameter_search_dist, |
4964 | | const uint32_t partition_order, |
4965 | | const FLAC__bool search_for_escapes, |
4966 | | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, |
4967 | | uint32_t *bits |
4968 | | ) |
4969 | 18.1M | { |
4970 | 18.1M | uint32_t rice_parameter, partition_bits; |
4971 | 18.1M | uint32_t best_partition_bits, best_rice_parameter = 0; |
4972 | 18.1M | uint32_t bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; |
4973 | 18.1M | uint32_t *parameters, *raw_bits; |
4974 | 18.1M | uint32_t partition, residual_sample; |
4975 | 18.1M | uint32_t partition_samples, partition_samples_base; |
4976 | 18.1M | uint32_t partition_samples_fixed_point_divisor, partition_samples_fixed_point_divisor_base; |
4977 | 18.1M | const uint32_t partitions = 1u << partition_order; |
4978 | 18.1M | FLAC__uint64 mean; |
4979 | | #ifdef ENABLE_RICE_PARAMETER_SEARCH |
4980 | | uint32_t min_rice_parameter, max_rice_parameter; |
4981 | | #else |
4982 | 18.1M | (void)rice_parameter_search_dist; |
4983 | 18.1M | #endif |
4984 | | |
4985 | 18.1M | FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); |
4986 | | |
4987 | 18.1M | parameters = partitioned_rice_contents->parameters; |
4988 | 18.1M | raw_bits = partitioned_rice_contents->raw_bits; |
4989 | | |
4990 | 18.1M | partition_samples_base = (residual_samples+predictor_order) >> partition_order; |
4991 | | |
4992 | | /* Integer division is slow. To speed up things, precalculate a fixed point |
4993 | | * divisor, as all partitions except the first are the same size. 18 bits |
4994 | | * are taken because maximum block size is 65535, max partition size for |
4995 | | * partitions other than 0 is 32767 (15 bit), max abs residual is 2^31, |
4996 | | * which leaves 18 bit */ |
4997 | 18.1M | partition_samples_fixed_point_divisor_base = 0x40000 / partition_samples_base; |
4998 | | |
4999 | 61.4M | for(partition = residual_sample = 0; partition < partitions; partition++) { |
5000 | 43.3M | partition_samples = partition_samples_base; |
5001 | 43.3M | if(partition > 0) { |
5002 | 25.4M | partition_samples_fixed_point_divisor = partition_samples_fixed_point_divisor_base; |
5003 | 25.4M | } |
5004 | 17.8M | else { |
5005 | 17.8M | if(partition_samples <= predictor_order) |
5006 | 0 | return false; |
5007 | 17.8M | else |
5008 | 17.8M | partition_samples -= predictor_order; |
5009 | 17.8M | partition_samples_fixed_point_divisor = 0x40000 / partition_samples; |
5010 | 17.8M | } |
5011 | 43.3M | mean = abs_residual_partition_sums[partition]; |
5012 | | /* 'mean' is not a good name for the variable, it is |
5013 | | * actually the sum of magnitudes of all residual values |
5014 | | * in the partition, so the actual mean is |
5015 | | * mean/partition_samples |
5016 | | */ |
5017 | 43.3M | if(mean < 2 || (((mean - 1)*partition_samples_fixed_point_divisor)>>18) == 0) |
5018 | 12.4M | rice_parameter = 0; |
5019 | 30.8M | else |
5020 | 30.8M | rice_parameter = FLAC__bitmath_ilog2_wide(((mean - 1)*partition_samples_fixed_point_divisor)>>18) + 1; |
5021 | | |
5022 | 43.3M | if(rice_parameter >= rice_parameter_limit) { |
5023 | 1.99M | rice_parameter = rice_parameter_limit - 1; |
5024 | 1.99M | } |
5025 | | |
5026 | 43.3M | best_partition_bits = UINT32_MAX; |
5027 | | #ifdef ENABLE_RICE_PARAMETER_SEARCH |
5028 | | if(rice_parameter_search_dist) { |
5029 | | if(rice_parameter < rice_parameter_search_dist) |
5030 | | min_rice_parameter = 0; |
5031 | | else |
5032 | | min_rice_parameter = rice_parameter - rice_parameter_search_dist; |
5033 | | max_rice_parameter = rice_parameter + rice_parameter_search_dist; |
5034 | | if(max_rice_parameter >= rice_parameter_limit) { |
5035 | | max_rice_parameter = rice_parameter_limit - 1; |
5036 | | } |
5037 | | } |
5038 | | else |
5039 | | min_rice_parameter = max_rice_parameter = rice_parameter; |
5040 | | |
5041 | | for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { |
5042 | | #endif |
5043 | | #ifdef EXACT_RICE_BITS_CALCULATION |
5044 | | partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample); |
5045 | | #else |
5046 | 43.3M | partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]); |
5047 | 43.3M | #endif |
5048 | 43.4M | if(partition_bits < best_partition_bits) { |
5049 | 43.4M | best_rice_parameter = rice_parameter; |
5050 | 43.4M | best_partition_bits = partition_bits; |
5051 | 43.4M | } |
5052 | | #ifdef ENABLE_RICE_PARAMETER_SEARCH |
5053 | | } |
5054 | | #endif |
5055 | 43.3M | if(search_for_escapes) { |
5056 | 34.5M | partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; |
5057 | 34.5M | if(partition_bits <= best_partition_bits && raw_bits_per_partition[partition] < 32) { |
5058 | 3.19M | raw_bits[partition] = raw_bits_per_partition[partition]; |
5059 | 3.19M | best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ |
5060 | 3.19M | best_partition_bits = partition_bits; |
5061 | 3.19M | } |
5062 | 31.3M | else |
5063 | 31.3M | raw_bits[partition] = 0; |
5064 | 34.5M | } |
5065 | 43.3M | parameters[partition] = best_rice_parameter; |
5066 | 43.3M | if(best_partition_bits < UINT32_MAX - bits_) // To make sure _bits doesn't overflow |
5067 | 43.5M | bits_ += best_partition_bits; |
5068 | 18.4E | else |
5069 | 18.4E | bits_ = UINT32_MAX; |
5070 | 43.3M | residual_sample += partition_samples; |
5071 | 43.3M | } |
5072 | | |
5073 | 18.1M | *bits = bits_; |
5074 | 18.1M | return true; |
5075 | 18.1M | } |
5076 | | |
5077 | | uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples) |
5078 | 359k | { |
5079 | 359k | uint32_t i, shift; |
5080 | 359k | FLAC__int32 x = 0; |
5081 | | |
5082 | 1.06M | for(i = 0; i < samples && !(x&1); i++) |
5083 | 706k | x |= signal[i]; |
5084 | | |
5085 | 359k | if(x == 0) { |
5086 | 3.07k | shift = 0; |
5087 | 3.07k | } |
5088 | 356k | else { |
5089 | 434k | for(shift = 0; !(x&1); shift++) |
5090 | 78.5k | x >>= 1; |
5091 | 356k | } |
5092 | | |
5093 | 359k | if(shift > 0) { |
5094 | 279k | for(i = 0; i < samples; i++) |
5095 | 264k | signal[i] >>= shift; |
5096 | 15.0k | } |
5097 | | |
5098 | 359k | return shift; |
5099 | 359k | } |
5100 | | |
5101 | | uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples) |
5102 | 29.6k | { |
5103 | 29.6k | uint32_t i, shift; |
5104 | 29.6k | FLAC__int64 x = 0; |
5105 | | |
5106 | 711k | for(i = 0; i < samples && !(x&1); i++) |
5107 | 681k | x |= signal_wide[i]; |
5108 | | |
5109 | 29.6k | if(x == 0) { |
5110 | 2.44k | shift = 1; |
5111 | 2.44k | } |
5112 | 27.2k | else { |
5113 | 98.2k | for(shift = 0; !(x&1); shift++) |
5114 | 71.0k | x >>= 1; |
5115 | 27.2k | } |
5116 | | |
5117 | 29.6k | if(shift > 0) { |
5118 | 459k | for(i = 0; i < samples; i++) |
5119 | 444k | signal[i] = (FLAC__int32)(signal_wide[i] >> shift); |
5120 | 15.5k | } |
5121 | | |
5122 | 29.6k | return shift; |
5123 | 29.6k | } |
5124 | | |
5125 | | |
5126 | | void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples) |
5127 | 0 | { |
5128 | 0 | uint32_t channel; |
5129 | |
|
5130 | 0 | for(channel = 0; channel < channels; channel++) |
5131 | 0 | memcpy(&fifo->data[channel][fifo->tail], &input[channel][input_offset], sizeof(FLAC__int32) * wide_samples); |
5132 | |
|
5133 | 0 | fifo->tail += wide_samples; |
5134 | |
|
5135 | 0 | FLAC__ASSERT(fifo->tail <= fifo->size); |
5136 | 0 | } |
5137 | | |
5138 | | void append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples) |
5139 | 365k | { |
5140 | 365k | uint32_t channel; |
5141 | 365k | uint32_t sample, wide_sample; |
5142 | 365k | uint32_t tail = fifo->tail; |
5143 | | |
5144 | 365k | sample = input_offset * channels; |
5145 | 22.6M | for(wide_sample = 0; wide_sample < wide_samples; wide_sample++) { |
5146 | 50.2M | for(channel = 0; channel < channels; channel++) |
5147 | 27.9M | fifo->data[channel][tail] = input[sample++]; |
5148 | 22.2M | tail++; |
5149 | 22.2M | } |
5150 | 365k | fifo->tail = tail; |
5151 | | |
5152 | 365k | FLAC__ASSERT(fifo->tail <= fifo->size); |
5153 | 365k | } |
5154 | | |
5155 | | FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) |
5156 | 226k | { |
5157 | 226k | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; |
5158 | 226k | const size_t encoded_bytes = encoder->private_->verify.output.bytes; |
5159 | 226k | (void)decoder; |
5160 | | |
5161 | 226k | if(encoder->private_->verify.needs_magic_hack) { |
5162 | 8.56k | FLAC__ASSERT(*bytes >= FLAC__STREAM_SYNC_LENGTH); |
5163 | 8.56k | *bytes = FLAC__STREAM_SYNC_LENGTH; |
5164 | 8.56k | memcpy(buffer, FLAC__STREAM_SYNC_STRING, *bytes); |
5165 | 8.56k | encoder->private_->verify.needs_magic_hack = false; |
5166 | 8.56k | } |
5167 | 218k | else { |
5168 | 218k | if(encoded_bytes == 0) { |
5169 | | /* |
5170 | | * If we get here, a FIFO underflow has occurred, |
5171 | | * which means there is a bug somewhere. |
5172 | | */ |
5173 | 0 | FLAC__ASSERT(0); |
5174 | 0 | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; |
5175 | 0 | } |
5176 | 218k | else if(encoded_bytes < *bytes) |
5177 | 210k | *bytes = encoded_bytes; |
5178 | 218k | memcpy(buffer, encoder->private_->verify.output.data, *bytes); |
5179 | 218k | encoder->private_->verify.output.data += *bytes; |
5180 | 218k | encoder->private_->verify.output.bytes -= *bytes; |
5181 | 218k | } |
5182 | | |
5183 | 226k | return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; |
5184 | 226k | } |
5185 | | |
5186 | | FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) |
5187 | 193k | { |
5188 | 193k | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder *)client_data; |
5189 | 193k | uint32_t channel; |
5190 | 193k | const uint32_t channels = frame->header.channels; |
5191 | 193k | const uint32_t blocksize = frame->header.blocksize; |
5192 | 193k | const uint32_t bytes_per_block = sizeof(FLAC__int32) * blocksize; |
5193 | | |
5194 | 193k | (void)decoder; |
5195 | | |
5196 | 193k | if(encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) { |
5197 | | /* This is set when verify_error_callback_ was called */ |
5198 | 0 | return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; |
5199 | 0 | } |
5200 | | |
5201 | 452k | for(channel = 0; channel < channels; channel++) { |
5202 | 259k | if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) { |
5203 | 0 | uint32_t i, sample = 0; |
5204 | 0 | FLAC__int32 expect = 0, got = 0; |
5205 | |
|
5206 | 0 | for(i = 0; i < blocksize; i++) { |
5207 | 0 | if(buffer[channel][i] != encoder->private_->verify.input_fifo.data[channel][i]) { |
5208 | 0 | sample = i; |
5209 | 0 | expect = (FLAC__int32)encoder->private_->verify.input_fifo.data[channel][i]; |
5210 | 0 | got = (FLAC__int32)buffer[channel][i]; |
5211 | 0 | break; |
5212 | 0 | } |
5213 | 0 | } |
5214 | 0 | FLAC__ASSERT(i < blocksize); |
5215 | 0 | FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); |
5216 | 0 | encoder->private_->verify.error_stats.absolute_sample = frame->header.number.sample_number + sample; |
5217 | 0 | encoder->private_->verify.error_stats.frame_number = (uint32_t)(frame->header.number.sample_number / blocksize); |
5218 | 0 | encoder->private_->verify.error_stats.channel = channel; |
5219 | 0 | encoder->private_->verify.error_stats.sample = sample; |
5220 | 0 | encoder->private_->verify.error_stats.expected = expect; |
5221 | 0 | encoder->private_->verify.error_stats.got = got; |
5222 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA; |
5223 | 0 | return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; |
5224 | 0 | } |
5225 | 259k | } |
5226 | | /* dequeue the frame from the fifo */ |
5227 | 193k | encoder->private_->verify.input_fifo.tail -= blocksize; |
5228 | 452k | for(channel = 0; channel < channels; channel++) |
5229 | 259k | memmove(&encoder->private_->verify.input_fifo.data[channel][0], &encoder->private_->verify.input_fifo.data[channel][blocksize], encoder->private_->verify.input_fifo.tail * sizeof(encoder->private_->verify.input_fifo.data[0][0])); |
5230 | 193k | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; |
5231 | 193k | } |
5232 | | |
5233 | | void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) |
5234 | 8.56k | { |
5235 | 8.56k | (void)decoder, (void)metadata, (void)client_data; |
5236 | 8.56k | } |
5237 | | |
5238 | | void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) |
5239 | 0 | { |
5240 | 0 | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; |
5241 | 0 | (void)decoder, (void)status; |
5242 | 0 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; |
5243 | 0 | } |
5244 | | |
5245 | | FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) |
5246 | 0 | { |
5247 | 0 | (void)client_data; |
5248 | |
|
5249 | 0 | *bytes = fread(buffer, 1, *bytes, encoder->private_->file); |
5250 | 0 | if (*bytes == 0) { |
5251 | 0 | if (feof(encoder->private_->file)) |
5252 | 0 | return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; |
5253 | 0 | else if (ferror(encoder->private_->file)) |
5254 | 0 | return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; |
5255 | 0 | } |
5256 | 0 | return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; |
5257 | 0 | } |
5258 | | |
5259 | | FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) |
5260 | 0 | { |
5261 | 0 | (void)client_data; |
5262 | |
|
5263 | 0 | if(fseeko(encoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) |
5264 | 0 | return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; |
5265 | 0 | else |
5266 | 0 | return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; |
5267 | 0 | } |
5268 | | |
5269 | | FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) |
5270 | 0 | { |
5271 | 0 | FLAC__off_t offset; |
5272 | |
|
5273 | 0 | (void)client_data; |
5274 | |
|
5275 | 0 | offset = ftello(encoder->private_->file); |
5276 | |
|
5277 | 0 | if(offset < 0) { |
5278 | 0 | return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; |
5279 | 0 | } |
5280 | 0 | else { |
5281 | 0 | *absolute_byte_offset = (FLAC__uint64)offset; |
5282 | 0 | return FLAC__STREAM_ENCODER_TELL_STATUS_OK; |
5283 | 0 | } |
5284 | 0 | } |
5285 | | |
5286 | | #ifdef FLAC__VALGRIND_TESTING |
5287 | | static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) |
5288 | | { |
5289 | | size_t ret = fwrite(ptr, size, nmemb, stream); |
5290 | | if(!ferror(stream)) |
5291 | | fflush(stream); |
5292 | | return ret; |
5293 | | } |
5294 | | #else |
5295 | 0 | #define local__fwrite fwrite |
5296 | | #endif |
5297 | | |
5298 | | FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, uint32_t samples, uint32_t current_frame, void *client_data) |
5299 | 0 | { |
5300 | 0 | (void)client_data, (void)current_frame; |
5301 | |
|
5302 | 0 | if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, encoder->private_->file) == bytes) { |
5303 | 0 | FLAC__bool call_it = 0 != encoder->private_->progress_callback && ( |
5304 | 0 | #if FLAC__HAS_OGG |
5305 | | /* We would like to be able to use 'samples > 0' in the |
5306 | | * clause here but currently because of the nature of our |
5307 | | * Ogg writing implementation, 'samples' is always 0 (see |
5308 | | * ogg_encoder_aspect.c). The downside is extra progress |
5309 | | * callbacks. |
5310 | | */ |
5311 | 0 | encoder->private_->is_ogg? true : |
5312 | 0 | #endif |
5313 | 0 | samples > 0 |
5314 | 0 | ); |
5315 | 0 | if(call_it) { |
5316 | | /* NOTE: We have to add +bytes, +samples, and +1 to the stats |
5317 | | * because at this point in the callback chain, the stats |
5318 | | * have not been updated. Only after we return and control |
5319 | | * gets back to write_frame_() are the stats updated |
5320 | | */ |
5321 | 0 | encoder->private_->progress_callback(encoder, encoder->private_->bytes_written+bytes, encoder->private_->samples_written+samples, encoder->private_->frames_written+(samples?1:0), encoder->private_->total_frames_estimate, encoder->private_->client_data); |
5322 | 0 | } |
5323 | 0 | return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; |
5324 | 0 | } |
5325 | 0 | else |
5326 | 0 | return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; |
5327 | 0 | } |
5328 | | |
5329 | | /* |
5330 | | * This will forcibly set stdout to binary mode (for OSes that require it) |
5331 | | */ |
5332 | | FILE *get_binary_stdout_(void) |
5333 | 0 | { |
5334 | | /* if something breaks here it is probably due to the presence or |
5335 | | * absence of an underscore before the identifiers 'setmode', |
5336 | | * 'fileno', and/or 'O_BINARY'; check your system header files. |
5337 | | */ |
5338 | | #if defined _MSC_VER || defined __MINGW32__ |
5339 | | _setmode(_fileno(stdout), _O_BINARY); |
5340 | | #elif defined __EMX__ |
5341 | | setmode(fileno(stdout), O_BINARY); |
5342 | | #endif |
5343 | |
|
5344 | | return stdout; |
5345 | 0 | } |