⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stream_decoder.c

📁 wince下著名的视频播放器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 + -