📄 stream_encoder.c
字号:
FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */ FLAC__real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */#endif unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */ unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */ FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */ FLAC__int32 *residual_workspace_mid_side[2][2]; FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2]; FLAC__Subframe subframe_workspace_mid_side[2][2]; FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2]; FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2]; FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2]; FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2]; FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2]; FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2]; unsigned best_subframe[FLAC__MAX_CHANNELS]; /* index into the above workspaces */ unsigned best_subframe_mid_side[2]; unsigned best_subframe_bits[FLAC__MAX_CHANNELS]; /* size in bits of the best subframe for each channel */ unsigned best_subframe_bits_mid_side[2]; FLAC__uint32 *abs_residual; /* workspace where abs(candidate residual) is stored */ FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ FLAC__BitBuffer *frame; /* the current frame being worked on */ unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ FLAC__ChannelAssignment last_channel_assignment; FLAC__StreamMetadata metadata; unsigned current_sample_number; unsigned current_frame_number; struct FLAC__MD5Context md5context; FLAC__CPUInfo cpuinfo;#ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);#else unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);#endif#ifndef FLAC__INTEGER_ONLY_LIBRARY void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);#endif FLAC__bool use_wide_by_block; /* use slow 64-bit versions of some functions because of the block size */ FLAC__bool use_wide_by_partition; /* use slow 64-bit versions of some functions because of the min partition order and blocksize */ FLAC__bool use_wide_by_order; /* use slow 64-bit versions of some functions because of the lpc order */ FLAC__bool precompute_partition_sums; /* our initial guess as to whether precomputing the partitions sums will be a speed improvement */ FLAC__bool disable_constant_subframes; FLAC__bool disable_fixed_subframes; FLAC__bool disable_verbatim_subframes; FLAC__StreamEncoderWriteCallback write_callback; FLAC__StreamEncoderMetadataCallback metadata_callback; void *client_data; /* unaligned (original) pointers to allocated data */ FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS]; FLAC__int32 *integer_signal_mid_side_unaligned[2];#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; FLAC__real *real_signal_mid_side_unaligned[2];#endif FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2]; FLAC__int32 *residual_workspace_mid_side_unaligned[2][2]; FLAC__uint32 *abs_residual_unaligned; FLAC__uint64 *abs_residual_partition_sums_unaligned; unsigned *raw_bits_per_partition_unaligned; /* * These fields have been moved here from private function local * declarations merely to save stack space during encoding. */#ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */#endif FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */ /* * The data for the verify section */ struct { FLAC__StreamDecoder *decoder; EncoderStateHint state_hint; FLAC__bool needs_magic_hack; verify_input_fifo input_fifo; verify_output output; struct { FLAC__uint64 absolute_sample; unsigned frame_number; unsigned channel; unsigned sample; FLAC__int32 expected; FLAC__int32 got; } error_stats; } verify; FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */} FLAC__StreamEncoderPrivate;/*********************************************************************** * * Public static class data * ***********************************************************************/FLAC_API const char * const FLAC__StreamEncoderStateString[] = { "FLAC__STREAM_ENCODER_OK", "FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR", "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA", "FLAC__STREAM_ENCODER_INVALID_CALLBACK", "FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS", "FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE", "FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE", "FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE", "FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER", "FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION", "FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH", "FLAC__STREAM_ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH", "FLAC__STREAM_ENCODER_ILLEGAL_MID_SIDE_FORCE", "FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER", "FLAC__STREAM_ENCODER_NOT_STREAMABLE", "FLAC__STREAM_ENCODER_FRAMING_ERROR", "FLAC__STREAM_ENCODER_INVALID_METADATA", "FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING", "FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING", "FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_ENCODER_ALREADY_INITIALIZED", "FLAC__STREAM_ENCODER_UNINITIALIZED"};FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = { "FLAC__STREAM_ENCODER_WRITE_STATUS_OK", "FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR"};/*********************************************************************** * * Class constructor/destructor * */FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(){ FLAC__StreamEncoder *encoder; unsigned i; FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ encoder = (FLAC__StreamEncoder*)calloc(1, sizeof(FLAC__StreamEncoder)); if(encoder == 0) { return 0; } encoder->protected_ = (FLAC__StreamEncoderProtected*)calloc(1, sizeof(FLAC__StreamEncoderProtected)); if(encoder->protected_ == 0) { free(encoder); return 0; } encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate)); if(encoder->private_ == 0) { free(encoder->protected_); free(encoder); return 0; } encoder->private_->frame = FLAC__bitbuffer_new(); if(encoder->private_->frame == 0) { free(encoder->private_); free(encoder->protected_); free(encoder); return 0; } set_defaults_(encoder); encoder->private_->is_being_deleted = false; for(i = 0; i < FLAC__MAX_CHANNELS; i++) { encoder->private_->subframe_workspace_ptr[i][0] = &encoder->private_->subframe_workspace[i][0]; encoder->private_->subframe_workspace_ptr[i][1] = &encoder->private_->subframe_workspace[i][1]; } for(i = 0; i < 2; i++) { encoder->private_->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->subframe_workspace_mid_side[i][0]; encoder->private_->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->subframe_workspace_mid_side[i][1]; } for(i = 0; i < FLAC__MAX_CHANNELS; i++) { encoder->private_->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->partitioned_rice_contents_workspace[i][0]; encoder->private_->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->partitioned_rice_contents_workspace[i][1]; } for(i = 0; i < 2; i++) { encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]; encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]; } for(i = 0; i < FLAC__MAX_CHANNELS; i++) { FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][0]); FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][1]); } for(i = 0; i < 2; i++) { FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); } for(i = 0; i < 2; i++) FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]); encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; return encoder;}FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder){ unsigned i; FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->protected_); FLAC__ASSERT(0 != encoder->private_); FLAC__ASSERT(0 != encoder->private_->frame); encoder->private_->is_being_deleted = true; FLAC__stream_encoder_finish(encoder); if(0 != encoder->private_->verify.decoder) FLAC__stream_decoder_delete(encoder->private_->verify.decoder); for(i = 0; i < FLAC__MAX_CHANNELS; i++) { FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][0]); FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][1]); } for(i = 0; i < 2; i++) { FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); } for(i = 0; i < 2; i++) FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_extra[i]); FLAC__bitbuffer_delete(encoder->private_->frame); free(encoder->private_); free(encoder->protected_); free(encoder);}/*********************************************************************** * * Public class methods * ***********************************************************************/FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder){ unsigned i; FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment; FLAC__ASSERT(0 != encoder); if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) return encoder->protected_->state = FLAC__STREAM_ENCODER_ALREADY_INITIALIZED; encoder->protected_->state = FLAC__STREAM_ENCODER_OK; if(0 == encoder->private_->write_callback || 0 == encoder->private_->metadata_callback) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_CALLBACK; if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS; if(encoder->protected_->do_mid_side_stereo && encoder->protected_->channels != 2) return encoder->protected_->state = FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH; if(encoder->protected_->loose_mid_side_stereo && !encoder->protected_->do_mid_side_stereo) return encoder->protected_->state = FLAC__STREAM_ENCODER_ILLEGAL_MID_SIDE_FORCE; if(encoder->protected_->bits_per_sample >= 32) encoder->protected_->do_mid_side_stereo = false; /* since we do 32-bit math, the side channel would have 33 bps and overflow */ if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE; if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate)) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE; if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE; if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER; if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order) return encoder->protected_->state = FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER; if(encoder->protected_->qlp_coeff_precision == 0) { if(encoder->protected_->bits_per_sample < 16) { /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ /* @@@ until then we'll make a guess */ encoder->protected_->qlp_coeff_precision = max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); } else if(encoder->protected_->bits_per_sample == 16) { if(encoder->protected_->blocksize <= 192) encoder->protected_->qlp_coeff_precision = 7; else if(encoder->protected_->blocksize <= 384) encoder->protected_->qlp_coeff_precision = 8; else if(encoder->protected_->blocksize <= 576) encoder->protected_->qlp_coeff_precision = 9; else if(encoder->protected_->blocksize <= 1152) encoder->protected_->qlp_coeff_precision = 10; else if(encoder->protected_->blocksize <= 2304) encoder->protected_->qlp_coeff_precision = 11; else if(encoder->protected_->blocksize <= 4608) encoder->protected_->qlp_coeff_precision = 12; else encoder->protected_->qlp_coeff_precision = 13; } else { if(encoder->protected_->blocksize <= 384) encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2; else if(encoder->protected_->blocksize <= 1152) encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1; else encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; } FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION); } else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -