summaryrefslogtreecommitdiff
path: root/libavcodec/mlpdec.c
diff options
context:
space:
mode:
authorRamiro Polla <ramiro.polla@gmail.com>2009-03-20 13:07:09 +0000
committerRamiro Polla <ramiro.polla@gmail.com>2009-03-20 13:07:09 +0000
commit9731e7f13e1fa043b5918a7be6273df0f20b1568 (patch)
tree4102160ae28d93f08e16f0e186dbe5005c912c6a /libavcodec/mlpdec.c
parentcbf3cf19f3dec3a3788b15d31db9795de5e42ed9 (diff)
mlp, truehd: support non 1:1 channel mapping.
Originally committed as revision 18074 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/mlpdec.c')
-rw-r--r--libavcodec/mlpdec.c25
1 files 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;
}