From 9731e7f13e1fa043b5918a7be6273df0f20b1568 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Fri, 20 Mar 2009 13:07:09 +0000 Subject: [PATCH] mlp, truehd: support non 1:1 channel mapping. Originally committed as revision 18074 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/mlpdec.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 06304288ed..c5a97acf5d 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -58,6 +58,8 @@ typedef struct SubStream { uint8_t max_channel; //! The number of channels input into the rematrix stage. uint8_t max_matrix_channel; + //! For each channel output by the matrix, the output channel to map it to + uint8_t ch_assign[MAX_CHANNELS]; //! The left shift applied to random noise in 0x31ea substreams. uint8_t noise_shift; @@ -380,16 +382,19 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); + memset(s->ch_assign, 0, sizeof(s->ch_assign)); + 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) { + if (ch_assign > s->max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, - "Non-1:1 channel assignments are used in this stream. %s\n", - sample_message); + "Assignment of matrix channel %d to invalid output channel %d. %s\n", + ch, ch_assign, sample_message); return -1; } + s->ch_assign[ch_assign] = ch; } checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); @@ -421,7 +426,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, } if (substr == m->max_decoded_substream) { - m->avctx->channels = s->max_channel + 1; + m->avctx->channels = s->max_matrix_channel + 1; } return 0; @@ -831,7 +836,7 @@ static int output_data_internal(MLPDecodeContext *m, unsigned int substr, uint8_t *data, unsigned int *data_size, int is32) { SubStream *s = &m->substream[substr]; - unsigned int i, ch = 0; + unsigned int i, out_ch = 0; int32_t *data_32 = (int32_t*) data; int16_t *data_16 = (int16_t*) data; @@ -839,15 +844,17 @@ static int output_data_internal(MLPDecodeContext *m, unsigned int substr, return -1; for (i = 0; i < s->blockpos; i++) { - for (ch = 0; ch <= s->max_channel; ch++) { - int32_t sample = m->sample_buffer[i][ch] << s->output_shift[ch]; - s->lossless_check_data ^= (sample & 0xffffff) << ch; + for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) { + int mat_ch = s->ch_assign[out_ch]; + int32_t sample = m->sample_buffer[i][mat_ch] + << s->output_shift[mat_ch]; + s->lossless_check_data ^= (sample & 0xffffff) << mat_ch; if (is32) *data_32++ = sample << 8; else *data_16++ = sample >> 8; } } - *data_size = i * ch * (is32 ? 4 : 2); + *data_size = i * out_ch * (is32 ? 4 : 2); return 0; }