📄 stream_decoder.c
字号:
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: if(!find_metadata_(decoder)) return false; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_READ_METADATA: if(!read_metadata_(decoder)) return false; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: case FLAC__STREAM_DECODER_READ_FRAME: case FLAC__STREAM_DECODER_END_OF_STREAM: case FLAC__STREAM_DECODER_ABORTED: return true; default: FLAC__ASSERT(0); return false; } }}FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder){ FLAC__bool dummy; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->protected_); while(1) { switch(decoder->protected_->state) { case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: if(!find_metadata_(decoder)) return false; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_READ_METADATA: if(!read_metadata_(decoder)) return false; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: if(!frame_sync_(decoder)) return true; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_READ_FRAME: if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true)) return false; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_END_OF_STREAM: case FLAC__STREAM_DECODER_ABORTED: return true; default: FLAC__ASSERT(0); return false; } }}FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder){ FLAC__bool got_a_frame; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->protected_); while(1) { switch(decoder->protected_->state) { case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: case FLAC__STREAM_DECODER_READ_METADATA: return false; /* above function sets the status for us */ case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: if(!frame_sync_(decoder)) return true; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_READ_FRAME: if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false)) return false; /* above function sets the status for us */ if(got_a_frame) return true; /* above function sets the status for us */ break; case FLAC__STREAM_DECODER_END_OF_STREAM: case FLAC__STREAM_DECODER_ABORTED: return true; default: FLAC__ASSERT(0); return false; } }}/*********************************************************************** * * Protected class methods * ***********************************************************************/unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder){ FLAC__ASSERT(0 != decoder); return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input);}/*********************************************************************** * * Private class methods * ***********************************************************************/void set_defaults_(FLAC__StreamDecoder *decoder){ decoder->private_->read_callback = 0; decoder->private_->write_callback = 0; decoder->private_->metadata_callback = 0; decoder->private_->error_callback = 0; decoder->private_->client_data = 0; memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true; decoder->private_->metadata_filter_ids_count = 0;}FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels){ unsigned i; FLAC__int32 *tmp; if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) return true; /* simply using realloc() is not practical because the number of channels may change mid-stream */ for(i = 0; i < FLAC__MAX_CHANNELS; i++) { if(0 != decoder->private_->output[i]) { free(decoder->private_->output[i]-4); decoder->private_->output[i] = 0; } if(0 != decoder->private_->residual_unaligned[i]) { free(decoder->private_->residual_unaligned[i]); decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } } for(i = 0; i < channels; i++) { /* WATCHOUT: * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the * output arrays have a buffer of up to 3 zeroes in front * (at negative indices) for alignment purposes; we use 4 * to keep the data well-aligned. */ tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4)); if(tmp == 0) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } memset(tmp, 0, sizeof(FLAC__int32)*4); decoder->private_->output[i] = tmp + 4; /* WATCHOUT: * minimum of quadword alignment for PPC vector optimizations is REQUIRED: */ if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } } decoder->private_->output_capacity = size; decoder->private_->output_channels = channels; return true;}FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id){ unsigned i; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++) if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))) return true; return false;}FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder){ FLAC__uint32 x; unsigned i, id; FLAC__bool first = true; FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); for(i = id = 0; i < 4; ) { if(decoder->private_->cached) { x = (FLAC__uint32)decoder->private_->lookahead; decoder->private_->cached = false; } else { if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } if(x == FLAC__STREAM_SYNC_STRING[i]) { first = true; i++; id = 0; continue; } if(x == ID3V2_TAG_[id]) { id++; i = 0; if(id == 3) { if(!skip_id3v2_tag_(decoder)) return false; /* the read_callback_ sets the state for us */ } continue; } if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ decoder->private_->header_warmup[0] = (FLAC__byte)x; if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ /* else we have to check if the second byte is the end of a sync code */ if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ decoder->private_->lookahead = (FLAC__byte)x; decoder->private_->cached = true; } else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ decoder->private_->header_warmup[1] = (FLAC__byte)x; decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; return true; } } i = 0; if(first) { decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); first = false; } } decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA; return true;}FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder){ FLAC__bool is_last; FLAC__uint32 i, x, type, length; FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ is_last = x? true : false; if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(type == FLAC__METADATA_TYPE_STREAMINFO) { if(!read_metadata_streaminfo_(decoder, is_last, length)) return false; decoder->private_->has_stream_info = true; if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO]) decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data); } else if(type == FLAC__METADATA_TYPE_SEEKTABLE) { if(!read_metadata_seektable_(decoder, is_last, length)) return false; decoder->private_->has_seek_table = true; if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE]) decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); } else { FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; unsigned real_length = length; FLAC__StreamMetadata block; block.is_last = is_last; block.type = (FLAC__MetadataType)type; block.length = length; if(type == FLAC__METADATA_TYPE_APPLICATION) { if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) skip_it = !skip_it; } if(skip_it) { if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, real_length, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } else { switch(type) { case FLAC__METADATA_TYPE_PADDING: /* skip the padding bytes */ if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, real_length, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ break; case FLAC__METADATA_TYPE_APPLICATION: /* remember, we read the ID already */ if(real_length > 0) { if(0 == (block.data.application.data = (FLAC__byte*)malloc(real_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } else block.data.application.data = 0; break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) return false; break; case FLAC__METADATA_TYPE_CUESHEET: if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) return false; break; case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_SEEKTABLE: FLAC__ASSERT(0); break; default: if(real_length > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -