From 077beee4653fb8185f802836bf18cff534e68060 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 21 Jan 2013 19:43:06 +0100 Subject: [PATCH 1/4] x86: ac3: Fix HAVE_MMXEXT condition to only refer to external assembly CC: libav-stable@libav.org (cherry picked from commit 4f56e773fe8a554b8c2662650aaf799c2ece2721) Signed-off-by: Reinhard Tartler --- libavcodec/x86/ac3dsp.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index a5d9458b39..45c30d1ae8 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -66,7 +66,7 @@ cglobal ac3_exponent_min, 3, 4, 2, exp, reuse_blks, expn, offset %define LOOP_ALIGN INIT_MMX mmx AC3_EXPONENT_MIN -%if HAVE_MMXEXT +%if HAVE_MMXEXT_EXTERNAL %define LOOP_ALIGN ALIGN 16 INIT_MMX mmxext AC3_EXPONENT_MIN From 5393a5600ddb870b3d7cbd427cdd82b2f583b265 Mon Sep 17 00:00:00 2001 From: Tim Walker Date: Mon, 31 Dec 2012 15:33:25 +0100 Subject: [PATCH 2/4] mlpdec: set the channel layout. Fixes bug 401. Signed-off-by: Justin Ruggles CC:libav-stable@libav.org (cherry picked from commit 1fd2deedcc6400e08b31566a547a5fac3b38cefb) Signed-off-by: Reinhard Tartler --- libavcodec/mlpdec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 3852f6eff8..8e3a510868 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -463,8 +463,10 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, cp->huff_lsbs = 24; } - if (substr == m->max_decoded_substream) - m->avctx->channels = s->max_matrix_channel + 1; + if (substr == m->max_decoded_substream) { + m->avctx->channels = s->max_matrix_channel + 1; + m->avctx->channel_layout = s->ch_layout; + } return 0; } From 59f22ef91a1e84caadccc5a179b4a973267243b4 Mon Sep 17 00:00:00 2001 From: Tim Walker Date: Mon, 31 Dec 2012 15:33:24 +0100 Subject: [PATCH 3/4] mlpdec: TrueHD: use Libav channel order. Fixes bug 208. Signed-off-by: Justin Ruggles CC:libav-stable@libav.org (cherry picked from commit 3ffcccb4fbaae4d5ad775506f1f2761f2029affa) Signed-off-by: Reinhard Tartler --- libavcodec/mlpdec.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 8e3a510868..de08f1ab62 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -146,6 +146,36 @@ typedef struct MLPDecodeContext { MLPDSPContext dsp; } MLPDecodeContext; +static const uint64_t thd_channel_order[] = { + AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT, // LR + AV_CH_FRONT_CENTER, // C + AV_CH_LOW_FREQUENCY, // LFE + AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT, // LRs + AV_CH_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_RIGHT, // LRvh + AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, // LRc + AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT, // LRrs + AV_CH_BACK_CENTER, // Cs + AV_CH_TOP_CENTER, // Ts + AV_CH_SURROUND_DIRECT_LEFT, AV_CH_SURROUND_DIRECT_RIGHT, // LRsd + AV_CH_WIDE_LEFT, AV_CH_WIDE_RIGHT, // LRw + AV_CH_TOP_FRONT_CENTER, // Cvh + AV_CH_LOW_FREQUENCY_2, // LFE2 +}; + +static uint64_t thd_channel_layout_extract_channel(uint64_t channel_layout, + int index) +{ + int i; + + if (av_get_channel_layout_nb_channels(channel_layout) <= index) + return 0; + + for (i = 0; i < FF_ARRAY_ELEMS(thd_channel_order); i++) + if (channel_layout & thd_channel_order[i] && !index--) + return thd_channel_order[i]; + return 0; +} + static VLC huff_vlc[3]; /** Initialize static data, constant between all invocations of the codec. */ @@ -426,6 +456,12 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, for (ch = 0; ch <= s->max_matrix_channel; ch++) { int ch_assign = get_bits(gbp, 6); + if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) { + uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout, + ch_assign); + ch_assign = av_get_channel_layout_channel_index(s->ch_layout, + channel); + } if (ch_assign > s->max_matrix_channel) { av_log_ask_for_sample(m->avctx, "Assignment of matrix channel %d to invalid output channel %d.\n", From 5af78cc98d807f3b43510410dad46e1840c5c99f Mon Sep 17 00:00:00 2001 From: Tim Walker Date: Mon, 31 Dec 2012 15:33:23 +0100 Subject: [PATCH 4/4] mlp: store the channel layout for each substream. Also stop storing the channel arrangement in the header info, as it's unused outside of ff_mlp_read_major_sync. Signed-off-by: Justin Ruggles CC:libav-stable@libav.org (cherry picked from commit 99ccd2ba10eac2b282c272ad9e75f082123c765a) Signed-off-by: Reinhard Tartler --- libavcodec/mlp_parser.c | 26 ++++++++++++++++---------- libavcodec/mlp_parser.h | 9 ++++++--- libavcodec/mlpdec.c | 21 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index d1a3dc1ba0..31c79c9ca2 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -126,7 +126,7 @@ static uint64_t truehd_layout(int chanmap) 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); @@ -157,7 +157,9 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) 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]; } else if (mh->stream_type == 0xba) { mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? mh->group2_bits = 0; @@ -168,11 +170,15 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) 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); 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); } else return AVERROR_INVALIDDATA; @@ -316,16 +322,16 @@ static int mlp_parse(AVCodecParserContext *s, if (mh.stream_type == 0xbb) { /* MLP stream */ - avctx->channels = mlp_channels[mh.channels_mlp]; - avctx->channel_layout = 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 = 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 = truehd_layout(mh.channels_thd_stream1); + avctx->channels = mh.channels_thd_stream1; + avctx->channel_layout = mh.channel_layout_thd_stream1; } } diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h index 35bb312f17..24b4169419 100644 --- a/libavcodec/mlp_parser.h +++ b/libavcodec/mlp_parser.h @@ -39,9 +39,12 @@ typedef struct MLPHeaderInfo int group1_samplerate; ///< Sample rate of first substream int group2_samplerate; ///< Sample rate of second substream (MLP only) - int channels_mlp; ///< Channel arrangement for MLP streams - int channels_thd_stream1; ///< Channel arrangement for substream 1 of TrueHD streams (5.1) - int channels_thd_stream2; ///< Channel arrangement for substream 2 of TrueHD streams (7.1) + int channels_mlp; ///< Channel count for MLP streams + int channels_thd_stream1; ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation") + int channels_thd_stream2; ///< Channel count for substream 2 of TrueHD streams ("8-channel presentation") + uint64_t channel_layout_mlp; ///< Channel layout for MLP streams + uint64_t channel_layout_thd_stream1; ///< Channel layout for substream 1 of TrueHD streams ("6-channel presentation") + uint64_t channel_layout_thd_stream2; ///< Channel layout for substream 2 of TrueHD streams ("8-channel presentation") int access_unit_size; ///< Number of samples per coded frame int access_unit_size_pow2; ///< Next power of two above number of samples per frame diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index de08f1ab62..80ff4017f7 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "libavutil/intreadwrite.h" +#include "libavutil/channel_layout.h" #include "get_bits.h" #include "internal.h" #include "libavutil/crc.h" @@ -56,6 +57,8 @@ typedef struct SubStream { 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 channel layout for this substream + uint64_t ch_layout; /// Channel coding parameters for channels in the substream ChannelParams channel_params[MAX_CHANNELS]; @@ -355,6 +358,24 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) for (substr = 0; substr < MAX_SUBSTREAMS; substr++) m->substream[substr].restart_seen = 0; + /* 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; + } + return 0; }