int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
{
- int ratebits;
+ int ratebits, channel_arrangement;
uint16_t checksum;
- assert(get_bits_count(gb) == 0);
+ av_assert1(get_bits_count(gb) == 0);
if (gb->size_in_bits < 28 << 3) {
av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
skip_bits(gb, 11);
- mh->channels_mlp = get_bits(gb, 5);
+ channel_arrangement = get_bits(gb, 5);
+ mh->channels_mlp = mlp_channels[channel_arrangement];
- mh->channel_layout_mlp = mlp_layout[channel_arrangement];
++ mh->channel_layout_mlp = ff_mlp_layout[channel_arrangement];
} else if (mh->stream_type == 0xba) {
mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
mh->group2_bits = 0;
skip_bits(gb, 8);
- mh->channels_thd_stream1 = get_bits(gb, 5);
+ channel_arrangement = get_bits(gb, 5);
+ mh->channels_thd_stream1 = truehd_channels(channel_arrangement);
- mh->channel_layout_thd_stream1 = truehd_layout(channel_arrangement);
++ mh->channel_layout_thd_stream1 = ff_truehd_layout(channel_arrangement);
skip_bits(gb, 2);
- mh->channels_thd_stream2 = get_bits(gb, 13);
+ channel_arrangement = get_bits(gb, 13);
+ mh->channels_thd_stream2 = truehd_channels(channel_arrangement);
- mh->channel_layout_thd_stream2 = truehd_layout(channel_arrangement);
++ mh->channel_layout_thd_stream2 = ff_truehd_layout(channel_arrangement);
} else
return AVERROR_INVALIDDATA;
avctx->sample_rate = mh.group1_samplerate;
s->duration = mh.access_unit_size;
+ if(!avctx->channels || !avctx->channel_layout) {
if (mh.stream_type == 0xbb) {
/* MLP stream */
- avctx->channels = mlp_channels[mh.channels_mlp];
- avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
+ avctx->channels = mh.channels_mlp;
+ avctx->channel_layout = mh.channel_layout_mlp;
} else { /* mh.stream_type == 0xba */
/* TrueHD stream */
if (mh.channels_thd_stream2) {
- avctx->channels = truehd_channels(mh.channels_thd_stream2);
- avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
+ avctx->channels = mh.channels_thd_stream2;
+ avctx->channel_layout = mh.channel_layout_thd_stream2;
} else {
- avctx->channels = truehd_channels(mh.channels_thd_stream1);
- avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
+ avctx->channels = mh.channels_thd_stream1;
+ avctx->channel_layout = mh.channel_layout_thd_stream1;
}
}
+ }
if (!mh.is_vbr) /* Stream is CBR */
avctx->bit_rate = mh.peak_bitrate;
for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
m->substream[substr].restart_seen = 0;
++#if 0
+ if (mh.stream_type == 0xbb) {
+ /* MLP stream */
+ m->avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
+ } else { /* mh.stream_type == 0xba */
+ /* TrueHD stream */
+ if (mh.channels_thd_stream2) {
+ m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
+ } else {
+ m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
+ }
+ if (m->avctx->channels<=2 && m->avctx->channel_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
+ av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");
+ m->max_decoded_substream = 0;
+ if (m->avctx->channels==2)
+ m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+ }
+ if (m->avctx->channels &&
+ !m->avctx->request_channels && !m->avctx->request_channel_layout &&
+ av_get_channel_layout_nb_channels(m->avctx->channel_layout) != m->avctx->channels) {
+ m->avctx->channel_layout = 0;
+ av_log_ask_for_sample(m->avctx, "Unknown channel layout.");
+ }
+ }
+
++#else
+ /* Set the layout for each substream. When there's more than one, the first
+ * substream is Stereo. Subsequent substreams' layouts are indicated in the
+ * major sync. */
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
+ if ((substr = (mh.num_substreams > 1)))
+ m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+ m->substream[substr].ch_layout = mh.channel_layout_mlp;
+ } else {
+ if ((substr = (mh.num_substreams > 1)))
+ m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+ if (mh.num_substreams > 2)
+ if (mh.channel_layout_thd_stream2)
+ m->substream[2].ch_layout = mh.channel_layout_thd_stream2;
+ else
+ m->substream[2].ch_layout = mh.channel_layout_thd_stream1;
+ m->substream[substr].ch_layout = mh.channel_layout_thd_stream1;
++
++ if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
++ av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");
++ m->max_decoded_substream = 0;
++ if (m->avctx->channels==2)
++ m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
++ }
+ }
+
++#endif
++
+ m->needs_reordering = mh.channels_mlp >= 18 && mh.channels_mlp <= 20;
+
return 0;
}