📄 stream_encoder.c
字号:
/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <limits.h>#include <stdio.h>#include <stdlib.h> /* for malloc() */#include <string.h> /* for memcpy() */#include "FLAC/assert.h"#include "FLAC/stream_decoder.h"#include "protected/stream_encoder.h"#include "private/bitbuffer.h"#include "private/bitmath.h"#include "private/crc.h"#include "private/cpu.h"#include "private/fixed.h"#include "private/format.h"#include "private/lpc.h"#include "private/md5.h"#include "private/memory.h"#include "private/stream_encoder_framing.h"#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef min#undef min#endif#define min(x,y) ((x)<(y)?(x):(y))#ifdef max#undef max#endif#define max(x,y) ((x)>(y)?(x):(y))typedef struct { FLAC__int32 *data[FLAC__MAX_CHANNELS]; unsigned size; /* of each data[] in samples */ unsigned tail;} verify_input_fifo;typedef struct { const FLAC__byte *data; unsigned capacity; unsigned bytes;} verify_output;typedef enum { ENCODER_IN_MAGIC = 0, ENCODER_IN_METADATA = 1, ENCODER_IN_AUDIO = 2} EncoderStateHint;/*********************************************************************** * * Private class method prototypes * ***********************************************************************/static void set_defaults_(FLAC__StreamEncoder *encoder);static void free_(FLAC__StreamEncoder *encoder);static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size);static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples);static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame);static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame);static FLAC__bool process_subframe_( FLAC__StreamEncoder *encoder, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[],#ifndef FLAC__INTEGER_ONLY_LIBRARY const FLAC__real real_signal[],#endif FLAC__Subframe *subframe[2], FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], FLAC__int32 *residual[2], unsigned *best_subframe, unsigned *best_bits);static FLAC__bool add_subframe_( FLAC__StreamEncoder *encoder, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__Subframe *subframe, FLAC__BitBuffer *frame);static unsigned evaluate_constant_subframe_( const FLAC__int32 signal, unsigned subframe_bps, FLAC__Subframe *subframe);static unsigned evaluate_fixed_subframe_( FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents);#ifndef FLAC__INTEGER_ONLY_LIBRARYstatic unsigned evaluate_lpc_subframe_( FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], const FLAC__real lp_coeff[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents);#endifstatic unsigned evaluate_verbatim_subframe_( const FLAC__int32 signal[], unsigned blocksize, unsigned subframe_bps, FLAC__Subframe *subframe);static unsigned find_best_partition_order_( struct FLAC__StreamEncoderPrivate *private_, const FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice);static void precompute_partition_info_sums_( const FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order);static void precompute_partition_info_escapes_( const FLAC__int32 residual[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order);#ifdef DONT_ESTIMATE_RICE_BITSstatic FLAC__bool set_partitioned_rice_( const FLAC__uint32 abs_residual[], const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, unsigned *bits);static FLAC__bool set_partitioned_rice_with_precompute_( const FLAC__int32 residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, unsigned *bits);#elsestatic FLAC__bool set_partitioned_rice_( const FLAC__uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, unsigned *bits);static FLAC__bool set_partitioned_rice_with_precompute_( const FLAC__uint32 abs_residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, unsigned *bits);#endifstatic unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples);/* verify-related routines: */static void append_to_verify_fifo_( verify_input_fifo *fifo, const FLAC__int32 * const input[], unsigned input_offset, unsigned channels, unsigned wide_samples);static void append_to_verify_fifo_interleaved_( verify_input_fifo *fifo, const FLAC__int32 input[], unsigned input_offset, unsigned channels, unsigned wide_samples);static FLAC__StreamDecoderReadStatus verify_read_callback_( const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);static FLAC__StreamDecoderWriteStatus verify_write_callback_( const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);static void verify_metadata_callback_( const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);static void verify_error_callback_( const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);/*********************************************************************** * * 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -