cp->huff_lsbs = 24;
}
- if (substr == m->max_decoded_substream) {
+ if (substr == m->max_decoded_substream)
m->avctx->channels = s->max_matrix_channel + 1;
- }
return 0;
}
// Filter is 0 for FIR, 1 for IIR.
assert(filter < 2);
- m->filter_changed[channel][filter]++;
+ if (m->filter_changed[channel][filter]++ > 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
+ return -1;
+ }
order = get_bits(gbp, 4);
if (order > max_order) {
/** Read parameters for primitive matrices. */
-static int read_matrix_params(MLPDecodeContext *m, SubStream *s, GetBitContext *gbp)
+static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitContext *gbp)
{
+ SubStream *s = &m->substream[substr];
unsigned int mat, ch;
+ if (m->matrix_changed++ > 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n");
+ return -1;
+ }
+
s->num_primitive_matrices = get_bits(gbp, 4);
- m->matrix_changed++;
for (mat = 0; mat < s->num_primitive_matrices; mat++) {
int frac_bits, max_chan;
unsigned int ch;
if (s->param_presence_flags & PARAM_PRESENCE)
- if (get_bits1(gbp))
- s->param_presence_flags = get_bits(gbp, 8);
+ if (get_bits1(gbp))
+ s->param_presence_flags = get_bits(gbp, 8);
if (s->param_presence_flags & PARAM_BLOCKSIZE)
if (get_bits1(gbp)) {
}
if (s->param_presence_flags & PARAM_MATRIX)
- if (get_bits1(gbp)) {
- if (read_matrix_params(m, s, gbp) < 0)
+ if (get_bits1(gbp))
+ if (read_matrix_params(m, substr, gbp) < 0)
return -1;
- }
if (s->param_presence_flags & PARAM_OUTSHIFT)
if (get_bits1(gbp))
- for (ch = 0; ch <= s->max_matrix_channel; ch++) {
+ for (ch = 0; ch <= s->max_matrix_channel; ch++)
s->output_shift[ch] = get_sbits(gbp, 4);
- }
if (s->param_presence_flags & PARAM_QUANTSTEP)
if (get_bits1(gbp))
}
for (ch = s->min_channel; ch <= s->max_channel; ch++)
- if (get_bits1(gbp)) {
+ if (get_bits1(gbp))
if (read_channel_params(m, substr, gbp, ch) < 0)
return -1;
- }
return 0;
}
memset(&m->bypassed_lsbs[s->blockpos][0], 0,
s->blocksize * sizeof(m->bypassed_lsbs[0]));
- for (i = 0; i < s->blocksize; i++) {
+ for (i = 0; i < s->blocksize; i++)
if (read_huff_channels(m, gbp, substr, i) < 0)
return -1;
- }
- for (ch = s->min_channel; ch <= s->max_channel; ch++) {
+ for (ch = s->min_channel; ch <= s->max_channel; ch++)
filter_channel(m, substr, ch);
- }
s->blockpos += s->blocksize;
int matrix_noise_shift = s->matrix_noise_shift[mat];
unsigned int dest_ch = s->matrix_out_ch[mat];
int32_t mask = MSB_MASK(s->quant_step_size[dest_ch]);
+ int32_t *coeffs = s->matrix_coeff[mat];
+ int index = s->num_primitive_matrices - mat;
+ int index2 = 2 * index + 1;
/* TODO: DSPContext? */
for (i = 0; i < s->blockpos; i++) {
+ int32_t bypassed_lsb = m->bypassed_lsbs[i][mat];
+ int32_t *samples = m->sample_buffer[i];
int64_t accum = 0;
- for (src_ch = 0; src_ch <= maxchan; src_ch++) {
- accum += (int64_t)m->sample_buffer[i][src_ch]
- * s->matrix_coeff[mat][src_ch];
- }
+
+ for (src_ch = 0; src_ch <= maxchan; src_ch++)
+ accum += (int64_t) samples[src_ch] * coeffs[src_ch];
+
if (matrix_noise_shift) {
- uint32_t index = s->num_primitive_matrices - mat;
- index = (i * (index * 2 + 1) + index) & (m->access_unit_size_pow2 - 1);
+ index &= m->access_unit_size_pow2 - 1;
accum += m->noise_buffer[index] << (matrix_noise_shift + 7);
+ index += index2;
}
- m->sample_buffer[i][dest_ch] = ((accum >> 14) & mask)
- + m->bypassed_lsbs[i][mat];
+
+ samples[dest_ch] = ((accum >> 14) & mask) + bypassed_lsb;
}
}
}
s->blockpos = 0;
do {
- unsigned int ch;
-
if (get_bits1(&gb)) {
if (get_bits1(&gb)) {
/* A restart header should be present. */
s->restart_seen = 1;
}
- if (!s->restart_seen) {
+ if (!s->restart_seen)
goto next_substr;
- }
-
if (read_decoding_params(m, &gb, substr) < 0)
goto next_substr;
}
- if (m->matrix_changed > 1) {
- av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n");
+ if (!s->restart_seen)
goto next_substr;
- }
- for (ch = 0; ch < s->max_channel; ch++)
- if (m->filter_changed[ch][FIR] > 1 ||
- m->filter_changed[ch][IIR] > 1) {
- av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
- goto next_substr;
- }
-
- if (!s->restart_seen) {
- goto next_substr;
- }
if (read_block_data(m, &gb, substr) < 0)
return -1;
} while (!get_bits1(&gb));
skip_bits(&gb, (-get_bits_count(&gb)) & 15);
+
if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32) {
int shorten_by;
if (substr == m->max_decoded_substream)
av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");
}
+
if (substream_parity_present[substr]) {
uint8_t parity, checksum;
if ( get_bits(&gb, 8) != checksum)
av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n" , substr);
}
- if (substream_data_len[substr] * 8 != get_bits_count(&gb)) {
+
+ if (substream_data_len[substr] * 8 != get_bits_count(&gb))
goto substream_length_mismatch;
- }
next_substr:
- if (!s->restart_seen) {
+ if (!s->restart_seen)
av_log(m->avctx, AV_LOG_ERROR,
"No restart header present in substream %d.\n", substr);
- }
buf += substream_data_len[substr];
}