📄 stream_decoder.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 <stdio.h>#include <stdlib.h> /* for malloc() */#include <string.h> /* for memset/memcpy() */#include "FLAC/assert.h"#include "protected/stream_decoder.h"#include "private/bitbuffer.h"#include "private/bitmath.h"#include "private/cpu.h"#include "private/crc.h"#include "private/fixed.h"#include "private/format.h"#include "private/lpc.h"#include "private/memory.h"#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef max#undef max#endif#define max(a,b) ((a)>(b)?(a):(b))/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */#ifdef _MSC_VER#define FLAC__U64L(x) x#else#define FLAC__U64L(x) x##LLU#endif/*********************************************************************** * * Private static data * ***********************************************************************/static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };/*********************************************************************** * * Private class method prototypes * ***********************************************************************/static void set_defaults_(FLAC__StreamDecoder *decoder);static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels);static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id);static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder);static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder);static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length);static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj);static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder);static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode);static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder);static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual);static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);static FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data);/*********************************************************************** * * Private class data * ***********************************************************************/typedef struct FLAC__StreamDecoderPrivate { FLAC__StreamDecoderReadCallback read_callback; FLAC__StreamDecoderWriteCallback write_callback; FLAC__StreamDecoderMetadataCallback metadata_callback; FLAC__StreamDecoderErrorCallback error_callback; /* generic 32-bit datapath: */ void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); /* generic 64-bit datapath: */ void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void *client_data; FLAC__BitBuffer *input; FLAC__int32 *output[FLAC__MAX_CHANNELS]; FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; unsigned output_capacity, output_channels; FLAC__uint32 last_frame_number; FLAC__uint32 last_block_size; FLAC__uint64 samples_decoded; FLAC__bool has_stream_info, has_seek_table; FLAC__StreamMetadata stream_info; FLAC__StreamMetadata seek_table; FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ FLAC__byte *metadata_filter_ids; unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ FLAC__Frame frame; FLAC__bool cached; /* true if there is a byte in lookahead */ FLAC__CPUInfo cpuinfo; FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */ FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */ /* unaligned (original) pointers to allocated data */ FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS];} FLAC__StreamDecoderPrivate;/*********************************************************************** * * Public static class data * ***********************************************************************/FLAC_API const char * const FLAC__StreamDecoderStateString[] = { "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", "FLAC__STREAM_DECODER_READ_METADATA", "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", "FLAC__STREAM_DECODER_READ_FRAME", "FLAC__STREAM_DECODER_END_OF_STREAM", "FLAC__STREAM_DECODER_ABORTED", "FLAC__STREAM_DECODER_UNPARSEABLE_STREAM", "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_DECODER_ALREADY_INITIALIZED", "FLAC__STREAM_DECODER_INVALID_CALLBACK", "FLAC__STREAM_DECODER_UNINITIALIZED"};FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = { "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", "FLAC__STREAM_DECODER_READ_STATUS_ABORT"};FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = { "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT"};FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = { "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH"};/*********************************************************************** * * Class constructor/destructor * ***********************************************************************/FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(){ FLAC__StreamDecoder *decoder; unsigned i; FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder)); if(decoder == 0) { return 0; } decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected)); if(decoder->protected_ == 0) { free(decoder); return 0; } decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate)); if(decoder->private_ == 0) { free(decoder->protected_); free(decoder); return 0; } decoder->private_->input = FLAC__bitbuffer_new(); if(decoder->private_->input == 0) { free(decoder->private_); free(decoder->protected_); free(decoder); return 0; } decoder->private_->metadata_filter_ids_capacity = 16; if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { FLAC__bitbuffer_delete(decoder->private_->input); free(decoder->private_); free(decoder->protected_); free(decoder); return 0; } for(i = 0; i < FLAC__MAX_CHANNELS; i++) { decoder->private_->output[i] = 0; decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } decoder->private_->output_capacity = 0; decoder->private_->output_channels = 0; decoder->private_->has_seek_table = false; for(i = 0; i < FLAC__MAX_CHANNELS; i++) FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]); set_defaults_(decoder); decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; return decoder;}FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder){ unsigned i; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->protected_); FLAC__ASSERT(0 != decoder->private_); FLAC__ASSERT(0 != decoder->private_->input); FLAC__stream_decoder_finish(decoder); if(0 != decoder->private_->metadata_filter_ids) free(decoder->private_->metadata_filter_ids); FLAC__bitbuffer_delete(decoder->private_->input); for(i = 0; i < FLAC__MAX_CHANNELS; i++) FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]); free(decoder->private_); free(decoder->protected_); free(decoder);}/*********************************************************************** * * Public class methods * ***********************************************************************/FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder){ FLAC__ASSERT(0 != decoder); if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) return decoder->protected_->state = FLAC__STREAM_DECODER_ALREADY_INITIALIZED; if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK; if(!FLAC__bitbuffer_init(decoder->private_->input)) return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; decoder->private_->last_frame_number = 0; decoder->private_->last_block_size = 0; decoder->private_->samples_decoded = 0; decoder->private_->has_stream_info = false; decoder->private_->cached = false; /* * get the CPU info and set the function pointers */ FLAC__cpu_info(&decoder->private_->cpuinfo); /* first default to the non-asm routines */ decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal; /* now override with asm where appropriate */#ifndef FLAC__NO_ASM if(decoder->private_->cpuinfo.use_asm) {#ifdef FLAC__CPU_IA32 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);#ifdef FLAC__HAS_NASM if(decoder->private_->cpuinfo.data.ia32.mmx) { decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx; } else { decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32; }#endif#elif defined FLAC__CPU_PPC FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); if(decoder->private_->cpuinfo.data.ppc.altivec) { decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8; }#endif }#endif if(!FLAC__stream_decoder_reset(decoder)) return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -