summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg
diff options
context:
space:
mode:
authorRodeo <[email protected]>2013-01-22 23:53:36 +0000
committerRodeo <[email protected]>2013-01-22 23:53:36 +0000
commit05b674cf2f7eb8137fb275d54e9531efbb6efe21 (patch)
tree1872d6c8a56457a2ffb865bbc8f16f6830782680 /contrib/ffmpeg
parentf89cb4e117fa98fe3d6b8820b3d7f4a80a6acc4a (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.patch41
-rw-r--r--contrib/ffmpeg/A02-truehd-channel-order.patch207
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",