]> granicus.if.org Git - handbrake/commitdiff
libav: backport fixes for Dolby Atmos streams.
authorTim Walker <tdskywalker@gmail.com>
Sat, 21 Nov 2015 19:42:19 +0000 (20:42 +0100)
committerTim Walker <tdskywalker@gmail.com>
Sat, 21 Nov 2015 20:07:29 +0000 (21:07 +0100)
Atmos data isn't decoded, but it's properly skipped now (no more
errors and log spam, should make scan way faster for such tracks).

contrib/ffmpeg/A12-atmos-substream.patch [new file with mode: 0644]

diff --git a/contrib/ffmpeg/A12-atmos-substream.patch b/contrib/ffmpeg/A12-atmos-substream.patch
new file mode 100644 (file)
index 0000000..fd27fcf
--- /dev/null
@@ -0,0 +1,181 @@
+From d46e6f2723d51a9aa0c09e69bbc17ae71774b7c1 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Fri, 26 Sep 2014 13:49:20 +0200
+Subject: [PATCH 1/2] mlpdec: support major sync headers with optional
+ extension blocks
+
+Signed-off-by: Anton Khirnov <anton@khirnov.net>
+(cherry picked from commit f36f6a608b5b2c17f8876195c61621c8f8607cee)
+Signed-off-by: Tim Walker <tdskywalker@gmail.com>
+---
+ libavcodec/mlp_parser.c | 29 ++++++++++++++++++++++++-----
+ libavcodec/mlp_parser.h |  1 +
+ libavcodec/mlpdec.c     |  7 ++++++-
+ 3 files changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
+index 075227f..0c7d4a2 100644
+--- a/libavcodec/mlp_parser.c
++++ b/libavcodec/mlp_parser.c
+@@ -119,6 +119,23 @@ static uint64_t truehd_layout(int chanmap)
+     return layout;
+ }
++static int ff_mlp_get_major_sync_size(const uint8_t * buf, int bufsize)
++{
++    int has_extension, extensions = 0;
++    int size = 28;
++    if (bufsize < 28)
++        return -1;
++
++    if (AV_RB32(buf) == 0xf8726fba) {
++        has_extension = buf[25] & 1;
++        if (has_extension) {
++            extensions = buf[26] >> 4;
++            size += 2 + extensions * 2;
++        }
++    }
++    return size;
++}
++
+ /** Read a major sync info header - contains high level information about
+  *  the stream - sample rate, channel arrangement etc. Most of this
+  *  information is not actually necessary for decoding, only for playback.
+@@ -127,18 +144,19 @@ static uint64_t truehd_layout(int chanmap)
+ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
+ {
+-    int ratebits, channel_arrangement;
++    int ratebits, channel_arrangement, header_size;
+     uint16_t checksum;
+     assert(get_bits_count(gb) == 0);
+-    if (gb->size_in_bits < 28 << 3) {
++    header_size = ff_mlp_get_major_sync_size(gb->buffer, gb->size_in_bits >> 3);
++    if (header_size < 0 || gb->size_in_bits < header_size << 3) {
+         av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
+         return -1;
+     }
+-    checksum = ff_mlp_checksum16(gb->buffer, 26);
+-    if (checksum != AV_RL16(gb->buffer+26)) {
++    checksum = ff_mlp_checksum16(gb->buffer, header_size - 2);
++    if (checksum != AV_RL16(gb->buffer+header_size-2)) {
+         av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n");
+         return AVERROR_INVALIDDATA;
+     }
+@@ -147,6 +165,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
+         return AVERROR_INVALIDDATA;
+     mh->stream_type = get_bits(gb, 8);
++    mh->header_size = header_size;
+     if (mh->stream_type == 0xbb) {
+         mh->group1_bits = mlp_quants[get_bits(gb, 4)];
+@@ -197,7 +216,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
+     mh->num_substreams = get_bits(gb, 4);
+-    skip_bits_long(gb, 4 + 11 * 8);
++    skip_bits_long(gb, 4 + (header_size - 17) * 8);
+     return 0;
+ }
+diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h
+index 7530fac..06ab421 100644
+--- a/libavcodec/mlp_parser.h
++++ b/libavcodec/mlp_parser.h
+@@ -32,6 +32,7 @@
+ typedef struct MLPHeaderInfo
+ {
+     int stream_type;                        ///< 0xBB for MLP, 0xBA for TrueHD
++    int header_size;                        ///< Size of the major sync header, in bytes
+     int group1_bits;                        ///< The bit depth of the first substream
+     int group2_bits;                        ///< Bit depth of the second substream (MLP only)
+diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
+index 6baf4c1..ad9e54f 100644
+--- a/libavcodec/mlpdec.c
++++ b/libavcodec/mlpdec.c
+@@ -132,6 +132,9 @@ typedef struct MLPDecodeContext {
+     /// Current access unit being read has a major sync.
+     int         is_major_sync_unit;
++    /// Size of the major sync unit, in bytes
++    int         major_sync_header_size;
++
+     /// Set if a valid major sync block has been read. Otherwise no decoding is possible.
+     uint8_t     params_valid;
+@@ -346,6 +349,8 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
+         return AVERROR_PATCHWELCOME;
+     }
++    m->major_sync_header_size = mh.header_size;
++
+     m->access_unit_size      = mh.access_unit_size;
+     m->access_unit_size_pow2 = mh.access_unit_size_pow2;
+@@ -1105,7 +1110,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data,
+         if (read_major_sync(m, &gb) < 0)
+             goto error;
+         m->is_major_sync_unit = 1;
+-        header_size += 28;
++        header_size += m->major_sync_header_size;
+     }
+     if (!m->params_valid) {
+-- 
+2.4.9 (Apple Git-60)
+
+
+From 99d4726e198d321158139f327c9c21dec58bc376 Mon Sep 17 00:00:00 2001
+From: Hendrik Leppkes <h.leppkes@gmail.com>
+Date: Fri, 26 Sep 2014 13:49:21 +0200
+Subject: [PATCH 2/2] mlpdec: support TrueHD streams with an Atmos substream
+
+The fourth substream is being discarded, since its not raw audio data,
+but an encoded Atmos stream which needs a specialized decoder.
+
+Fixes decoding of the true hd stream from Transformers\ -\ Age\ of\ Extinction\ 2014\ 1080P-003.mkv
+
+Signed-off-by: Anton Khirnov <anton@khirnov.net>
+(cherry picked from commit dc2d0e06af459af9a7f91b65e0a3119acc4f1baa)
+Signed-off-by: Tim Walker <tdskywalker@gmail.com>
+---
+ libavcodec/mlp.h    | 2 +-
+ libavcodec/mlpdec.c | 4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h
+index 5a4ee5f..8a1584e 100644
+--- a/libavcodec/mlp.h
++++ b/libavcodec/mlp.h
+@@ -45,7 +45,7 @@
+ /** Maximum number of substreams that can be decoded.
+  *  MLP's limit is 2. TrueHD supports at least up to 3.
+  */
+-#define MAX_SUBSTREAMS      3
++#define MAX_SUBSTREAMS      4
+ /** which multiple of 48000 the maximum sample rate is */
+ #define MAX_RATEFACTOR      4
+diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
+index ad9e54f..5ace18d 100644
+--- a/libavcodec/mlpdec.c
++++ b/libavcodec/mlpdec.c
+@@ -355,7 +355,9 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
+     m->access_unit_size_pow2 = mh.access_unit_size_pow2;
+     m->num_substreams        = mh.num_substreams;
+-    m->max_decoded_substream = m->num_substreams - 1;
++
++    /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */
++    m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2);
+     m->avctx->sample_rate    = mh.group1_samplerate;
+     m->avctx->frame_size     = mh.access_unit_size;
+-- 
+2.4.9 (Apple Git-60)
+