diff options
author | Rodeo <[email protected]> | 2013-01-22 23:53:36 +0000 |
---|---|---|
committer | Rodeo <[email protected]> | 2013-01-22 23:53:36 +0000 |
commit | 05b674cf2f7eb8137fb275d54e9531efbb6efe21 (patch) | |
tree | 1872d6c8a56457a2ffb865bbc8f16f6830782680 /contrib/ffmpeg | |
parent | f89cb4e117fa98fe3d6b8820b3d7f4a80a6acc4a (diff) |
Sync TrueHD channel order fix with Libav.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5194 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'contrib/ffmpeg')
-rw-r--r-- | contrib/ffmpeg/A02-channel-layout-order.patch | 41 | ||||
-rw-r--r-- | contrib/ffmpeg/A02-truehd-channel-order.patch | 207 |
2 files changed, 207 insertions, 41 deletions
diff --git a/contrib/ffmpeg/A02-channel-layout-order.patch b/contrib/ffmpeg/A02-channel-layout-order.patch deleted file mode 100644 index ce57af038..000000000 --- a/contrib/ffmpeg/A02-channel-layout-order.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c -index 3852f6e..c7217c8 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" -@@ -435,6 +436,28 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, - s->ch_assign[ch_assign] = ch; - } - -+ if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) { -+ switch (m->avctx->channel_layout) { -+ case AV_CH_LAYOUT_6POINT1: -+ case (AV_CH_LAYOUT_6POINT1|AV_CH_TOP_CENTER): -+ case (AV_CH_LAYOUT_6POINT1|AV_CH_TOP_FRONT_CENTER): -+ { -+ int i = s->ch_assign[6]; -+ s->ch_assign[6] = s->ch_assign[5]; -+ s->ch_assign[5] = s->ch_assign[4]; -+ s->ch_assign[4] = i; -+ break; -+ } -+ case AV_CH_LAYOUT_7POINT1: -+ case (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER): -+ FFSWAP(int, s->ch_assign[4], s->ch_assign[6]); -+ FFSWAP(int, s->ch_assign[5], s->ch_assign[7]); -+ break; -+ default: -+ break; -+ } -+ } -+ - checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); - - if (checksum != get_bits(gbp, 8)) diff --git a/contrib/ffmpeg/A02-truehd-channel-order.patch b/contrib/ffmpeg/A02-truehd-channel-order.patch new file mode 100644 index 000000000..a3d767755 --- /dev/null +++ b/contrib/ffmpeg/A02-truehd-channel-order.patch @@ -0,0 +1,207 @@ +diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c +index d1a3dc1..31c79c9 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 35bb312..e874426 100644 +--- a/libavcodec/mlp_parser.h ++++ b/libavcodec/mlp_parser.h +@@ -31,25 +31,28 @@ + + typedef struct MLPHeaderInfo + { +- int stream_type; ///< 0xBB for MLP, 0xBA for TrueHD ++ int stream_type; ///< 0xBB for MLP, 0xBA for TrueHD + +- int group1_bits; ///< The bit depth of the first substream +- int group2_bits; ///< Bit depth of the second substream (MLP only) ++ int group1_bits; ///< The bit depth of the first substream ++ int group2_bits; ///< Bit depth of the second substream (MLP only) + +- int group1_samplerate; ///< Sample rate of first substream +- int group2_samplerate; ///< Sample rate of second substream (MLP only) ++ 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 ++ 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 + +- int is_vbr; ///< Stream is VBR instead of CBR +- int peak_bitrate; ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR ++ int is_vbr; ///< Stream is VBR instead of CBR ++ int peak_bitrate; ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR + +- int num_substreams; ///< Number of substreams within stream ++ int num_substreams; ///< Number of substreams within stream + } MLPHeaderInfo; + + +diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c +index 3852f6e..f8c647a 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]; +@@ -146,6 +149,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. */ +@@ -325,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; + } + +@@ -426,6 +477,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", |