📄 mlpdec.c
字号:
return -1; } m->access_unit_size = mh.access_unit_size; m->access_unit_size_pow2 = mh.access_unit_size_pow2; m->num_substreams = mh.num_substreams; m->max_decoded_substream = m->num_substreams - 1; m->avctx->sample_rate = mh.group1_samplerate; m->avctx->frame_size = mh.access_unit_size;#ifdef CONFIG_AUDIO_NONSHORT m->avctx->bits_per_sample = mh.group1_bits; if (mh.group1_bits > 16) { m->avctx->sample_fmt = SAMPLE_FMT_S32; }#endif m->params_valid = 1; for (substr = 0; substr < MAX_SUBSTREAMS; substr++) m->substream[substr].restart_seen = 0; return 0;}/** Read a restart header from a block in a substream. This contains parameters * required to decode the audio that do not change very often. Generally * (always) present only in blocks following a major sync. */static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, const uint8_t *buf, unsigned int substr){ SubStream *s = &m->substream[substr]; unsigned int ch; int sync_word, tmp; uint8_t checksum; uint8_t lossless_check; int start_count = get_bits_count(gbp); sync_word = get_bits(gbp, 13); if (sync_word != 0x31ea >> 1) { av_log(m->avctx, AV_LOG_ERROR, "restart header sync incorrect (got 0x%04x)\n", sync_word); return -1; } s->noise_type = get_bits1(gbp); skip_bits(gbp, 16); /* Output timestamp */ s->min_channel = get_bits(gbp, 4); s->max_channel = get_bits(gbp, 4); s->max_matrix_channel = get_bits(gbp, 4); if (s->min_channel > s->max_channel) { av_log(m->avctx, AV_LOG_ERROR, "Substream min channel cannot be greater than max channel.\n"); return -1; } if (m->avctx->request_channels > 0 && s->max_channel + 1 >= m->avctx->request_channels && substr < m->max_decoded_substream) { av_log(m->avctx, AV_LOG_INFO, "Extracting %d channel downmix from substream %d. " "Further substreams will be skipped.\n", s->max_channel + 1, substr); m->max_decoded_substream = substr; } s->noise_shift = get_bits(gbp, 4); s->noisegen_seed = get_bits(gbp, 23); skip_bits(gbp, 19); s->data_check_present = get_bits1(gbp); lossless_check = get_bits(gbp, 8); if (substr == m->max_decoded_substream && s->lossless_check_data != 0xffffffff) { tmp = s->lossless_check_data; tmp ^= tmp >> 16; tmp ^= tmp >> 8; tmp &= 0xff; if (tmp != lossless_check) av_log(m->avctx, AV_LOG_WARNING, "Lossless check failed - expected %02x, calculated %02x.\n", lossless_check, tmp); else dprintf(m->avctx, "Lossless check passed for substream %d (%x).\n", substr, tmp); } skip_bits(gbp, 16); for (ch = 0; ch <= s->max_matrix_channel; ch++) { int ch_assign = get_bits(gbp, 6); dprintf(m->avctx, "ch_assign[%d][%d] = %d\n", substr, ch, ch_assign); if (ch_assign != ch) { av_log(m->avctx, AV_LOG_ERROR, "Non-1:1 channel assignments are used in this stream. %s\n", sample_message); return -1; } } checksum = mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); if (checksum != get_bits(gbp, 8)) av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n"); /* Set default decoding parameters. */ s->param_presence_flags = 0xff; s->num_primitive_matrices = 0; s->blocksize = 8; s->lossless_check_data = 0; memset(s->output_shift , 0, sizeof(s->output_shift )); memset(s->quant_step_size, 0, sizeof(s->quant_step_size)); for (ch = s->min_channel; ch <= s->max_channel; ch++) { m->filter_order[ch][FIR] = 0; m->filter_order[ch][IIR] = 0; m->filter_shift[ch][FIR] = 0; m->filter_shift[ch][IIR] = 0; /* Default audio coding is 24-bit raw PCM. */ m->huff_offset [ch] = 0; m->sign_huff_offset[ch] = (-1) << 23; m->codebook [ch] = 0; m->huff_lsbs [ch] = 24; } if (substr == m->max_decoded_substream) { m->avctx->channels = s->max_channel + 1; } return 0;}/** Read parameters for one of the prediction filters. */static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, unsigned int channel, unsigned int filter){ const char fchar = filter ? 'I' : 'F'; int i, order; // Filter is 0 for FIR, 1 for IIR. assert(filter < 2); order = get_bits(gbp, 4); if (order > MAX_FILTER_ORDER) { av_log(m->avctx, AV_LOG_ERROR, "%cIR filter order %d is greater than maximum %d.\n", fchar, order, MAX_FILTER_ORDER); return -1; } m->filter_order[channel][filter] = order; if (order > 0) { int coeff_bits, coeff_shift; m->filter_shift[channel][filter] = get_bits(gbp, 4); coeff_bits = get_bits(gbp, 5); coeff_shift = get_bits(gbp, 3); if (coeff_bits < 1 || coeff_bits > 16) { av_log(m->avctx, AV_LOG_ERROR, "%cIR filter coeff_bits must be between 1 and 16.\n", fchar); return -1; } if (coeff_bits + coeff_shift > 16) { av_log(m->avctx, AV_LOG_ERROR, "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n", fchar); return -1; } for (i = 0; i < order; i++) m->filter_coeff[channel][filter][i] = get_sbits(gbp, coeff_bits) << coeff_shift; if (get_bits1(gbp)) { int state_bits, state_shift; if (filter == FIR) { av_log(m->avctx, AV_LOG_ERROR, "FIR filter has state data specified.\n"); return -1; } state_bits = get_bits(gbp, 4); state_shift = get_bits(gbp, 4); /* TODO: Check validity of state data. */ for (i = 0; i < order; i++) m->filter_state[channel][filter][i] = get_sbits(gbp, state_bits) << state_shift; } } return 0;}/** Read decoding parameters that change more often than those in the restart * header. */static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, unsigned int substr){ SubStream *s = &m->substream[substr]; unsigned int mat, ch; if (get_bits1(gbp)) s->param_presence_flags = get_bits(gbp, 8); if (s->param_presence_flags & PARAM_BLOCKSIZE) if (get_bits1(gbp)) { s->blocksize = get_bits(gbp, 9); if (s->blocksize > MAX_BLOCKSIZE) { av_log(m->avctx, AV_LOG_ERROR, "block size too large\n"); s->blocksize = 0; return -1; } } if (s->param_presence_flags & PARAM_MATRIX) if (get_bits1(gbp)) { s->num_primitive_matrices = get_bits(gbp, 4); for (mat = 0; mat < s->num_primitive_matrices; mat++) { int frac_bits, max_chan; s->matrix_out_ch[mat] = get_bits(gbp, 4); frac_bits = get_bits(gbp, 4); s->lsb_bypass [mat] = get_bits1(gbp); if (s->matrix_out_ch[mat] > s->max_channel) { av_log(m->avctx, AV_LOG_ERROR, "Invalid channel %d specified as output from matrix.\n", s->matrix_out_ch[mat]); return -1; } if (frac_bits > 14) { av_log(m->avctx, AV_LOG_ERROR, "Too many fractional bits specified.\n"); return -1; } max_chan = s->max_matrix_channel; if (!s->noise_type) max_chan+=2; for (ch = 0; ch <= max_chan; ch++) { int coeff_val = 0; if (get_bits1(gbp)) coeff_val = get_sbits(gbp, frac_bits + 2); s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits); } if (s->noise_type) s->matrix_noise_shift[mat] = get_bits(gbp, 4); else s->matrix_noise_shift[mat] = 0; } } if (s->param_presence_flags & PARAM_OUTSHIFT) if (get_bits1(gbp)) for (ch = 0; ch <= s->max_matrix_channel; ch++) { s->output_shift[ch] = get_bits(gbp, 4); dprintf(m->avctx, "output shift[%d] = %d\n", ch, s->output_shift[ch]); /* TODO: validate */ } if (s->param_presence_flags & PARAM_QUANTSTEP) if (get_bits1(gbp)) for (ch = 0; ch <= s->max_channel; ch++) { s->quant_step_size[ch] = get_bits(gbp, 4); /* TODO: validate */ m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch); } for (ch = s->min_channel; ch <= s->max_channel; ch++) if (get_bits1(gbp)) { if (s->param_presence_flags & PARAM_FIR) if (get_bits1(gbp)) if (read_filter_params(m, gbp, ch, FIR) < 0) return -1; if (s->param_presence_flags & PARAM_IIR) if (get_bits1(gbp)) if (read_filter_params(m, gbp, ch, IIR) < 0) return -1; if (m->filter_order[ch][FIR] && m->filter_order[ch][IIR] && m->filter_shift[ch][FIR] != m->filter_shift[ch][IIR]) { av_log(m->avctx, AV_LOG_ERROR, "FIR and IIR filters must use the same precision.\n"); return -1; } /* The FIR and IIR filters must have the same precision. * To simplify the filtering code, only the precision of the * FIR filter is considered. If only the IIR filter is employed, * the FIR filter precision is set to that of the IIR filter, so * that the filtering code can use it. */ if (!m->filter_order[ch][FIR] && m->filter_order[ch][IIR]) m->filter_shift[ch][FIR] = m->filter_shift[ch][IIR]; if (s->param_presence_flags & PARAM_HUFFOFFSET) if (get_bits1(gbp)) m->huff_offset[ch] = get_sbits(gbp, 15); m->codebook [ch] = get_bits(gbp, 2); m->huff_lsbs[ch] = get_bits(gbp, 5); m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch); /* TODO: validate */ } return 0;}#define MSB_MASK(bits) (-1u << bits)/** Generate PCM samples using the prediction filters and residual values * read from the data stream, and update the filter state. */static void filter_channel(MLPDecodeContext *m, unsigned int substr, unsigned int channel){ SubStream *s = &m->substream[substr]; int32_t filter_state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FILTER_ORDER]; unsigned int filter_shift = m->filter_shift[channel][FIR]; int32_t mask = MSB_MASK(s->quant_step_size[channel]); int index = MAX_BLOCKSIZE; int j, i; for (j = 0; j < NUM_FILTERS; j++) { memcpy(& filter_state_buffer [j][MAX_BLOCKSIZE], &m->filter_state[channel][j][0], MAX_FILTER_ORDER * sizeof(int32_t)); } for (i = 0; i < s->blocksize; i++) { int32_t residual = m->sample_buffer[i + s->blockpos][channel]; unsigned int order; int64_t accum = 0; int32_t result; /* TODO: Move this code to DSPContext? */ for (j = 0; j < NUM_FILTERS; j++) for (order = 0; order < m->filter_order[channel][j]; order++) accum += (int64_t)filter_state_buffer[j][index + order] * m->filter_coeff[channel][j][order]; accum = accum >> filter_shift; result = (accum + residual) & mask; --index; filter_state_buffer[FIR][index] = result; filter_state_buffer[IIR][index] = result - accum; m->sample_buffer[i + s->blockpos][channel] = result; } for (j = 0; j < NUM_FILTERS; j++) { memcpy(&m->filter_state[channel][j][0], & filter_state_buffer [j][index], MAX_FILTER_ORDER * sizeof(int32_t)); }}/** Read a block of PCM residual data (or actual if no filtering active). */static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, unsigned int substr){ SubStream *s = &m->substream[substr]; unsigned int i, ch, expected_stream_pos = 0; if (s->data_check_present) { expected_stream_pos = get_bits_count(gbp); expected_stream_pos += get_bits(gbp, 16); av_log(m->avctx, AV_LOG_WARNING, "This file contains some features " "we have not tested yet. %s\n", sample_message); } if (s->blockpos + s->blocksize > m->access_unit_size) { av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -