diff mbox series

[FFmpeg-devel] ffprobe/eac3/mlp/dca: add detection of spatial audio extensions

Message ID 20230217194634.4154710-1-marth64@proxyid.net
State New
Headers show
Series [FFmpeg-devel] ffprobe/eac3/mlp/dca: add detection of spatial audio extensions | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Marth64 Feb. 17, 2023, 7:46 p.m. UTC
Signed-off-by: Marth64 <marth64@proxyid.net>
---
Update doc/APIchanges and update libavcodec minor version

 doc/APIchanges             |  4 ++++
 libavcodec/ac3dec.c        |  4 ++++
 libavcodec/ac3dec.h        |  1 +
 libavcodec/avcodec.h       | 18 ++++++++++++------
 libavcodec/codec_desc.c    |  2 ++
 libavcodec/dca_syncwords.h |  3 +++
 libavcodec/dca_xll.c       | 27 ++++++++++++++++++++++++++-
 libavcodec/dca_xll.h       |  3 +++
 libavcodec/eac3dec.c       | 11 ++++++++++-
 libavcodec/mlpdec.c        | 15 +++++++++++++--
 libavcodec/profiles.c      | 24 ++++++++++++++++++------
 libavcodec/profiles.h      |  2 ++
 libavcodec/version.h       |  2 +-
 13 files changed, 99 insertions(+), 17 deletions(-)

Comments

James Almer Feb. 17, 2023, 10:43 p.m. UTC | #1
On 2/17/2023 4:46 PM, Marth64 wrote:
> Signed-off-by: Marth64 <marth64@proxyid.net>
> ---
> Update doc/APIchanges and update libavcodec minor version
> 
>   doc/APIchanges             |  4 ++++
>   libavcodec/ac3dec.c        |  4 ++++
>   libavcodec/ac3dec.h        |  1 +
>   libavcodec/avcodec.h       | 18 ++++++++++++------
>   libavcodec/codec_desc.c    |  2 ++
>   libavcodec/dca_syncwords.h |  3 +++
>   libavcodec/dca_xll.c       | 27 ++++++++++++++++++++++++++-
>   libavcodec/dca_xll.h       |  3 +++
>   libavcodec/eac3dec.c       | 11 ++++++++++-
>   libavcodec/mlpdec.c        | 15 +++++++++++++--
>   libavcodec/profiles.c      | 24 ++++++++++++++++++------
>   libavcodec/profiles.h      |  2 ++
>   libavcodec/version.h       |  2 +-
>   13 files changed, 99 insertions(+), 17 deletions(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 6baf914760..04dda4132e 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,10 @@ libavutil:     2021-04-27
>   
>   API changes, most recent first:
>   
> +2023-0x-xx - xxxxxxxxxx - lavc 59.64.100
> +  Add DCA_SYNCWORD_XLL_X and DCA_SYNCWORD_XLL_X_IMAX syncword constants
> +  as part of facilitating DTS:X and DTS:X IMAX detection.

This should mention the new API that's exposed in public headers. In 
this case it's the new FF_PROFILE_* defines.

Also, could you split this in three patches? One for DTS, one for EAC3 
and one for TrueHD? The order is not important, and the version bump and 
the APIChanges entry would then be added in the last patch.
Also, remove the mention about ffprobe since you're not touching it at 
all. The new profiles will be reported by any tool that prints them, 
like ffmpeg, not just ffprobe.
Marth64 Feb. 17, 2023, 11:09 p.m. UTC | #2
Yes will take care of it, np

On Fri, Feb 17, 2023 at 4:42 PM James Almer <jamrial@gmail.com> wrote:

> On 2/17/2023 4:46 PM, Marth64 wrote:
> > Signed-off-by: Marth64 <marth64@proxyid.net>
> > ---
> > Update doc/APIchanges and update libavcodec minor version
> >
> >   doc/APIchanges             |  4 ++++
> >   libavcodec/ac3dec.c        |  4 ++++
> >   libavcodec/ac3dec.h        |  1 +
> >   libavcodec/avcodec.h       | 18 ++++++++++++------
> >   libavcodec/codec_desc.c    |  2 ++
> >   libavcodec/dca_syncwords.h |  3 +++
> >   libavcodec/dca_xll.c       | 27 ++++++++++++++++++++++++++-
> >   libavcodec/dca_xll.h       |  3 +++
> >   libavcodec/eac3dec.c       | 11 ++++++++++-
> >   libavcodec/mlpdec.c        | 15 +++++++++++++--
> >   libavcodec/profiles.c      | 24 ++++++++++++++++++------
> >   libavcodec/profiles.h      |  2 ++
> >   libavcodec/version.h       |  2 +-
> >   13 files changed, 99 insertions(+), 17 deletions(-)
> >
> > diff --git a/doc/APIchanges b/doc/APIchanges
> > index 6baf914760..04dda4132e 100644
> > --- a/doc/APIchanges
> > +++ b/doc/APIchanges
> > @@ -14,6 +14,10 @@ libavutil:     2021-04-27
> >
> >   API changes, most recent first:
> >
> > +2023-0x-xx - xxxxxxxxxx - lavc 59.64.100
> > +  Add DCA_SYNCWORD_XLL_X and DCA_SYNCWORD_XLL_X_IMAX syncword constants
> > +  as part of facilitating DTS:X and DTS:X IMAX detection.
>
> This should mention the new API that's exposed in public headers. In
> this case it's the new FF_PROFILE_* defines.
>
> Also, could you split this in three patches? One for DTS, one for EAC3
> and one for TrueHD? The order is not important, and the version bump and
> the APIChanges entry would then be added in the last patch.
> Also, remove the mention about ffprobe since you're not touching it at
> all. The new profiles will be reported by any tool that prints them,
> like ffmpeg, not just ffprobe.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index 6baf914760..04dda4132e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@  libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2023-0x-xx - xxxxxxxxxx - lavc 59.64.100
+  Add DCA_SYNCWORD_XLL_X and DCA_SYNCWORD_XLL_X_IMAX syncword constants
+  as part of facilitating DTS:X and DTS:X IMAX detection.
+
 2023-0x-xx - xxxxxxxxxx - lavc 59.63.100
   Allow AV_CODEC_FLAG_COPY_OPAQUE to be used with decoders.
 
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 0b120e6140..d7070645e6 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -43,6 +43,7 @@ 
 #include "ac3dec.h"
 #include "ac3dec_data.h"
 #include "ac3defs.h"
+#include "avcodec.h"
 #include "decode.h"
 #include "kbdwin.h"
 
@@ -1714,6 +1715,9 @@  skip:
     if (!err) {
         avctx->sample_rate = s->sample_rate;
         avctx->bit_rate    = s->bit_rate + s->prev_bit_rate;
+
+        if (s->eac3_extension_type_a == 1)
+            avctx->profile = FF_PROFILE_EAC3_DDP_ATMOS;
     }
 
     if (!avctx->sample_rate) {
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index 138b462abb..0829f4b40d 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -102,6 +102,7 @@  typedef struct AC3DecodeContext {
     int eac3;                               ///< indicates if current frame is E-AC-3
     int eac3_frame_dependent_found;         ///< bitstream has E-AC-3 dependent frame(s)
     int eac3_subsbtreamid_found;            ///< bitstream has E-AC-3 additional substream(s)
+    int eac3_extension_type_a;              ///< bitstream has E-AC-3 extension type A enabled frame(s)
     int dolby_surround_mode;                ///< dolby surround mode                    (dsurmod)
     int dolby_surround_ex_mode;             ///< dolby surround ex mode                 (dsurexmod)
     int dolby_headphone_mode;               ///< dolby headphone mode                   (dheadphonmod)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 755e543fac..2d3a7a4625 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1616,12 +1616,18 @@  typedef struct AVCodecContext {
 #define FF_PROFILE_DNXHR_HQX     4
 #define FF_PROFILE_DNXHR_444     5
 
-#define FF_PROFILE_DTS         20
-#define FF_PROFILE_DTS_ES      30
-#define FF_PROFILE_DTS_96_24   40
-#define FF_PROFILE_DTS_HD_HRA  50
-#define FF_PROFILE_DTS_HD_MA   60
-#define FF_PROFILE_DTS_EXPRESS 70
+#define FF_PROFILE_DTS                20
+#define FF_PROFILE_DTS_ES             30
+#define FF_PROFILE_DTS_96_24          40
+#define FF_PROFILE_DTS_HD_HRA         50
+#define FF_PROFILE_DTS_HD_MA          60
+#define FF_PROFILE_DTS_HD_MA_X        61
+#define FF_PROFILE_DTS_HD_MA_X_IMAX   62
+#define FF_PROFILE_DTS_EXPRESS        70
+
+#define FF_PROFILE_EAC3_DDP_ATMOS         30
+
+#define FF_PROFILE_TRUEHD_ATMOS           30
 
 #define FF_PROFILE_MPEG2_422    0
 #define FF_PROFILE_MPEG2_HIGH   1
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 57d0f98211..f33bbcd124 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -2931,6 +2931,7 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .name      = "eac3",
         .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+        .profiles  = NULL_IF_CONFIG_SMALL(ff_eac3_profiles),
     },
     {
         .id        = AV_CODEC_ID_SIPR,
@@ -2959,6 +2960,7 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .name      = "truehd",
         .long_name = NULL_IF_CONFIG_SMALL("TrueHD"),
         .props     = AV_CODEC_PROP_LOSSLESS,
+        .profiles  = NULL_IF_CONFIG_SMALL(ff_truehd_profiles),
     },
     {
         .id        = AV_CODEC_ID_MP4ALS,
diff --git a/libavcodec/dca_syncwords.h b/libavcodec/dca_syncwords.h
index 4d2cd5f56d..649bbd90dc 100644
--- a/libavcodec/dca_syncwords.h
+++ b/libavcodec/dca_syncwords.h
@@ -33,4 +33,7 @@ 
 #define    DCA_SYNCWORD_SUBSTREAM_CORE       0x02B09261U
 #define    DCA_SYNCWORD_REV1AUX              0x9A1105A0U
 
+#define    DCA_SYNCWORD_XLL_X                0x02000850U
+#define    DCA_SYNCWORD_XLL_X_IMAX           0xF14000D0U
+
 #endif /* AVCODEC_DCA_SYNCWORDS_H */
diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c
index fe2c766d98..802ad1197d 100644
--- a/libavcodec/dca_xll.c
+++ b/libavcodec/dca_xll.c
@@ -19,6 +19,7 @@ 
  */
 
 #include "libavutil/channel_layout.h"
+#include "avcodec.h"
 #include "dcadec.h"
 #include "dcadata.h"
 #include "dcamath.h"
@@ -1054,10 +1055,27 @@  static int parse_frame(DCAXllDecoder *s, const uint8_t *data, int size, DCAExssA
         return ret;
     if ((ret = parse_band_data(s)) < 0)
         return ret;
+
+     if (s->frame_size * 8 > FFALIGN(get_bits_count(&s->gb), 32)) {
+        unsigned int extradata_syncword;
+
+        // Align to dword
+        skip_bits_long(&s->gb, -get_bits_count(&s->gb) & 31);
+
+        extradata_syncword = show_bits_long(&s->gb, 32);
+
+        if (extradata_syncword == DCA_SYNCWORD_XLL_X) {
+            s->x_syncword_present = 1;
+        } else if ((extradata_syncword >> 1) == (DCA_SYNCWORD_XLL_X_IMAX >> 1)) {
+            s->x_imax_syncword_present = 1;
+        }
+    }
+
     if (ff_dca_seek_bits(&s->gb, s->frame_size * 8)) {
         av_log(s->avctx, AV_LOG_ERROR, "Read past end of XLL frame\n");
         return AVERROR_INVALIDDATA;
     }
+
     return ret;
 }
 
@@ -1428,8 +1446,15 @@  int ff_dca_xll_filter_frame(DCAXllDecoder *s, AVFrame *frame)
         return AVERROR(EINVAL);
     }
 
+    if (s->x_imax_syncword_present) {
+        avctx->profile = FF_PROFILE_DTS_HD_MA_X_IMAX;
+    } else if (s->x_syncword_present) {
+        avctx->profile = FF_PROFILE_DTS_HD_MA_X;
+    } else {
+        avctx->profile = FF_PROFILE_DTS_HD_MA;
+    }
+
     avctx->bits_per_raw_sample = p->storage_bit_res;
-    avctx->profile = FF_PROFILE_DTS_HD_MA;
     avctx->bit_rate = 0;
 
     frame->nb_samples = nsamples = s->nframesamples << (s->nfreqbands - 1);
diff --git a/libavcodec/dca_xll.h b/libavcodec/dca_xll.h
index d7c1a13ec8..a22bbb8d77 100644
--- a/libavcodec/dca_xll.h
+++ b/libavcodec/dca_xll.h
@@ -135,6 +135,9 @@  typedef struct DCAXllDecoder {
 
     DCADSPContext   *dcadsp;
 
+    int    x_syncword_present;        ///< Syncword for extension data at end of frame (DTS:X) is present
+    int    x_imax_syncword_present;   ///< Syncword for extension data at end of frame (DTS:X IMAX) is present
+
     int     output_mask;
     int32_t *output_samples[DCA_SPEAKER_COUNT];
 } DCAXllDecoder;
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index deca51dd3d..5c71751a0c 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -464,7 +464,16 @@  static int ff_eac3_parse_header(AC3DecodeContext *s)
     if (get_bits1(gbc)) {
         int addbsil = get_bits(gbc, 6);
         for (i = 0; i < addbsil + 1; i++) {
-            skip_bits(gbc, 8); // skip additional bit stream info
+            if (i == 0) {
+                /* In this 8 bit chunk, the LSB is equal to flag_ec3_extension_type_a
+                   which can be used to detect Atmos presence */
+                skip_bits(gbc, 7);
+                if (get_bits1(gbc)) {
+                    s->eac3_extension_type_a = 1;
+                }
+            } else {
+                skip_bits(gbc, 8); // skip additional bit stream info
+            }
         }
     }
 
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index 0ee1f0982c..e95357e35a 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -28,20 +28,21 @@ 
 
 #include <stdint.h>
 
-#include "avcodec.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/thread.h"
 #include "libavutil/opt.h"
+#include "avcodec.h"
 #include "codec_internal.h"
+#include "config.h"
 #include "decode.h"
 #include "get_bits.h"
 #include "mlp_parse.h"
 #include "mlpdsp.h"
 #include "mlp.h"
-#include "config.h"
+#include "profiles.h"
 
 /** number of bits used for VLC lookup - longest Huffman code is 9 */
 #if ARCH_ARM
@@ -392,6 +393,15 @@  static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
     m->num_substreams        = mh.num_substreams;
     m->substream_info        = mh.substream_info;
 
+    /*  If there is a 4th substream and the MSB of substream_info is set,
+     *  there is a 16-channel spatial presentation (Atmos in TrueHD).
+     */
+    if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD
+            && m->num_substreams == 4
+            && m->substream_info >> 7 == 1) {
+        m->avctx->profile     = FF_PROFILE_TRUEHD_ATMOS;
+    }
+
     /* 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);
 
@@ -1452,5 +1462,6 @@  const FFCodec ff_truehd_decoder = {
     FF_CODEC_DECODE_CB(read_access_unit),
     .flush          = mlp_decode_flush,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+    .p.profiles     = NULL_IF_CONFIG_SMALL(ff_truehd_profiles),
 };
 #endif /* CONFIG_TRUEHD_DECODER */
diff --git a/libavcodec/profiles.c b/libavcodec/profiles.c
index 7af7fbeb13..52066185b1 100644
--- a/libavcodec/profiles.c
+++ b/libavcodec/profiles.c
@@ -36,15 +36,27 @@  const AVProfile ff_aac_profiles[] = {
 };
 
 const AVProfile ff_dca_profiles[] = {
-    { FF_PROFILE_DTS,         "DTS"         },
-    { FF_PROFILE_DTS_ES,      "DTS-ES"      },
-    { FF_PROFILE_DTS_96_24,   "DTS 96/24"   },
-    { FF_PROFILE_DTS_HD_HRA,  "DTS-HD HRA"  },
-    { FF_PROFILE_DTS_HD_MA,   "DTS-HD MA"   },
-    { FF_PROFILE_DTS_EXPRESS, "DTS Express" },
+    { FF_PROFILE_DTS,                "DTS"                    },
+    { FF_PROFILE_DTS_ES,             "DTS-ES"                 },
+    { FF_PROFILE_DTS_96_24,          "DTS 96/24"              },
+    { FF_PROFILE_DTS_HD_HRA,         "DTS-HD HRA"             },
+    { FF_PROFILE_DTS_HD_MA,          "DTS-HD MA"              },
+    { FF_PROFILE_DTS_HD_MA_X,        "DTS-HD MA + DTS:X"      },
+    { FF_PROFILE_DTS_HD_MA_X_IMAX,   "DTS-HD MA + DTS:X IMAX" },
+    { FF_PROFILE_DTS_EXPRESS,        "DTS Express"            },
     { FF_PROFILE_UNKNOWN },
 };
 
+const AVProfile ff_eac3_profiles[] = {
+  { FF_PROFILE_EAC3_DDP_ATMOS, "Dolby Digital Plus + Dolby Atmos"},
+  { FF_PROFILE_UNKNOWN },
+};
+
+const AVProfile ff_truehd_profiles[] = {
+  { FF_PROFILE_TRUEHD_ATMOS,   "Dolby TrueHD + Dolby Atmos"},
+  { FF_PROFILE_UNKNOWN },
+};
+
 const AVProfile ff_dnxhd_profiles[] = {
   { FF_PROFILE_DNXHD,      "DNXHD"},
   { FF_PROFILE_DNXHR_LB,   "DNXHR LB"},
diff --git a/libavcodec/profiles.h b/libavcodec/profiles.h
index 41a19aa9ad..1d523992fc 100644
--- a/libavcodec/profiles.h
+++ b/libavcodec/profiles.h
@@ -58,6 +58,8 @@ 
 
 extern const AVProfile ff_aac_profiles[];
 extern const AVProfile ff_dca_profiles[];
+extern const AVProfile ff_eac3_profiles[];
+extern const AVProfile ff_truehd_profiles[];
 extern const AVProfile ff_dnxhd_profiles[];
 extern const AVProfile ff_h264_profiles[];
 extern const AVProfile ff_hevc_profiles[];
diff --git a/libavcodec/version.h b/libavcodec/version.h
index a80dc4776d..80d3aae05e 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@ 
 
 #include "version_major.h"
 
-#define LIBAVCODEC_VERSION_MINOR  63
+#define LIBAVCODEC_VERSION_MINOR  64
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \