📄 stream_encoder.c
字号:
*
* Private class data
*
***********************************************************************/
typedef struct FLAC__StreamEncoderPrivate {
unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */
FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -