[PR] avcodec/s302m: enable non-PCM decoding (PR #24075)

Gyan Doshi via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178644393120.59.2143624657094700914@29965ddac10e>
PR #24075 opened by Gyan Doshi (GyanD)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24075
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24075.patch

Set up framework for non-PCM decoding in-place and add support for Dolby-E decoding.

Useful for direct transcoding of non-PCM audio in live inputs.

  ```fate-samples
  s302m/s302_20bits_DolbyE_16bits.ts
  s302m/s302_20bits_DolbyE_20bits.ts
  s302m/s302_24bits_DolbyE_20bits.ts
  ```

Originally posted to the ML in early 2024.


>From 7a269eb77e267028a0b31b84bca5b9f973512a9e Mon Sep 17 00:00:00 2001
From: Gyan Doshi <[email protected]>
Date: Sat, 30 Dec 2023 16:55:51 +0530
Subject: [PATCH 1/2] avcodec/s302m: enable non-PCM decoding

Set up framework for non-PCM decoding in-place and
add support for Dolby-E decoding.

Useful for direct transcoding of non-PCM audio in live inputs.
---
 configure          |   1 +
 doc/decoders.texi  |  40 +++
 libavcodec/s302m.c | 600 +++++++++++++++++++++++++++++++++++++--------
 3 files changed, 532 insertions(+), 109 deletions(-)

diff --git a/configure b/configure
index f2896b81c7..3d7c07446d 100755
--- a/configure
+++ b/configure
@@ -3290,6 +3290,7 @@ rv20_encoder_select="h263_encoder"
 rv30_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
 rv40_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
 rv60_decoder_select="videodsp golomb"
+s302m_decoder_select="dolby_e_decoder"
 screenpresso_decoder_deps="zlib"
 shorten_decoder_select="bswapdsp"
 sipr_decoder_select="lsp celp_math"
diff --git a/doc/decoders.texi b/doc/decoders.texi
index 57af9f0dbf..828ad64ce7 100644
--- a/doc/decoders.texi
+++ b/doc/decoders.texi
@@ -391,6 +391,46 @@ Decodes the LPCM variant stored in DVD-Audio AOB files. Unlike DVD-Video
 LPCM it supports sample rates up to 192 kHz and allows splitting the
 channels into two groups with different quantization.
 
+@section s302m
+
+SMPTE ST 302 decoder.
+
+SMPTE ST 302 is a method for storing AES3 data format within an MPEG Transport
+Stream. AES3 streams can contain LPCM streams of 2, 4, 6 or 8 channels with a
+bit depth of 16, 20 or 24-bits at a sample rate of 48 kHz.
+They can also contain non-PCM codec streams such as AC-3 or Dolby-E.
+
+Decoding non-PCM streams directly requires that the necessary stream decoder be
+present in the build. At present, only Dolby-E decoding is supported.
+
+@subsection Options
+
+The following options are supported by the s302m decoder.
+
+@table @option
+@item non_pcm_mode @var{mode}
+Specify how to process non-PCM streams
+
+@table @samp
+@item copy
+Treat data as if it were LPCM.
+@item drop
+Discard the stream.
+@item decode_copy
+Decode if possible eise treat the same as @code{copy}.
+@item decode_drop
+Decode if possible eise treat the same as @code{drop}.
+@end table
+
+The default value is @code{decode_drop}. This option does not affect the processing of
+LPCM streams.
+
+@item non_pcm_options @var{options}
+Set options for non-PCM decoder using a list of key=value pairs separated by ":".
+Consult the docs for the non-PCM decoder for its options.
+
+@end table
+
 @c man end AUDIO DECODERS
 
 @chapter Subtitles Decoders
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index f8ab0337e2..d890b6f117 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -24,21 +24,264 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "libavutil/log.h"
+#include "libavutil/dict.h"
 #include "libavutil/reverse.h"
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "get_bits.h"
 #include "decode.h"
 
 #define AES3_HEADER_LEN 4
 
+#define NONPCMSYNC_16MARKER      0x4E1F0F8720
+#define NONPCMSYNC_20MARKER      0x4E1F60F872A0
+#define NONPCMSYNC_24MARKER      0x7E1F690F872A50
+
+#define NONPCMSYNC_16_IN_20MARKER      0x04E1F00F8720
+#define NONPCMSYNC_20_IN_24MARKER      0x04E1F600F872A0
+
+#define IS_NONPCMSYNC_16(state)   ((state & 0xFFFF0FFFF0)     == NONPCMSYNC_16MARKER)
+#define IS_NONPCMSYNC_20(state)   ((state & 0xFFFFF0FFFFF0)   == NONPCMSYNC_20MARKER)
+#define IS_NONPCMSYNC_24(state)   ((state & 0xFFFFFF0FFFFFF0) == NONPCMSYNC_24MARKER)
+
+#define IS_NONPCMSYNC_16_IN_20(state)   ((state & 0x0FFFF00FFFF0)   == NONPCMSYNC_16_IN_20MARKER)
+#define IS_NONPCMSYNC_20_IN_24(state)   ((state & 0x0FFFFF00FFFFF0) == NONPCMSYNC_20_IN_24MARKER)
+
+#define IS_NONPCMSYNC(bit,state)  ( ((bit == 16) &&  IS_NONPCMSYNC_16(state)) || \
+                                    ((bit == 20) && (IS_NONPCMSYNC_20(state) || IS_NONPCMSYNC_16_IN_20(state))) || \
+                                    ((bit == 24) && (IS_NONPCMSYNC_24(state) || IS_NONPCMSYNC_20_IN_24(state))) \
+                                  )
+
+enum non_pcm_modes {
+    NON_PCM_COPY,
+    NON_PCM_DROP,
+    NON_PCM_DEC_ELSE_COPY,
+    NON_PCM_DEC_ELSE_DROP,
+};
+
 typedef struct S302Context {
     AVClass *class;
+
+    int avctx_props_set;
+
+    int channels;
+    int bits;
+
     int non_pcm_mode;
+    int non_pcm_data_type;
+    int non_pcm_bits;
+    int non_pcm_dec;
+
+    AVCodecContext *non_pcm_ctx;
+    AVDictionary   *non_pcm_opts;
+    AVPacket *packet;
+    AVFrame  *frame;
 } S302Context;
 
+static av_cold int s302m_init(AVCodecContext *avctx)
+{
+    S302Context *s = avctx->priv_data;
+
+    s->non_pcm_data_type = -1;
+
+    return 0;
+}
+
+static int s302m_non_pcm_inspect(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
+                                  int *offset, int *length)
+{
+    S302Context *s = avctx->priv_data;
+    const uint8_t *pos = buf;
+    int ret, aes_frm_size, data_type, length_code = 0, pkt_left = buf_size;
+    uint64_t state = 0;
+    uint32_t size;
+
+    if (s->channels != 2) {
+        goto end;
+    }
+
+    aes_frm_size = (s->bits + 4) * 2 / 8;
+    if (pkt_left < aes_frm_size * 2)  // not enough to contain data_type & length_code
+        return AVERROR_INVALIDDATA;
+
+    while (!IS_NONPCMSYNC(s->bits,state) && pkt_left-- >= 1)
+        state = (state << 8) | *pos++;
+
+    if (IS_NONPCMSYNC(s->bits,state)) {
+        GetBitContext gb;
+
+        if (pkt_left < aes_frm_size * 8) {
+            av_log(avctx, AV_LOG_ERROR, "truncated non-pcm frame detected\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        ret = init_get_bits8(&gb, pos, aes_frm_size);
+        if (ret < 0)
+            return ret;
+
+        if (s->bits == 16) {
+            s->non_pcm_bits = 16;
+        } else if (s->bits == 20) {
+            if (IS_NONPCMSYNC_16_IN_20(state))
+                s->non_pcm_bits = 16;
+            else
+                s->non_pcm_bits = 20;
+        } else if (s->bits == 24) {
+            if (IS_NONPCMSYNC_20_IN_24(state))
+                s->non_pcm_bits = 20;
+            else
+                s->non_pcm_bits = 24;
+        }
+
+        skip_bits(&gb, s->bits - 16);
+
+        data_type = ff_reverse[(uint8_t)get_bits(&gb, 5)] >> 3;
+
+        if (s->non_pcm_data_type == -1) {
+            s->non_pcm_data_type = data_type;
+            av_log(avctx, AV_LOG_INFO, "stream has non-pcm data of type %d with %d-bit words in aes3 payload of size %d bits\n", data_type, s->non_pcm_bits, s->bits);
+        } else if (s->non_pcm_data_type != data_type) {
+            av_log(avctx, AV_LOG_DEBUG, "type mismatch of non-pcm type in packet %d vs stream %d. Dropping.\n", data_type, s->non_pcm_data_type);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (s->non_pcm_mode == NON_PCM_COPY)
+            return 0;
+        else if (s->non_pcm_mode == NON_PCM_DROP)
+            return AVERROR_INVALIDDATA;
+
+        skip_bits(&gb, 15);
+
+        size = get_bits(&gb, s->bits);
+
+        length_code = ((ff_reverse[(uint8_t)((size & 0xFF)          )] << 16) |
+                       (ff_reverse[(uint8_t)((size & 0xFF00)   >> 8 )] << 8 ) |
+                       (ff_reverse[(uint8_t)((size & 0xFF0000) >> 16)]      ) ) >> (24 - s->non_pcm_bits);
+
+        skip_bits(&gb, 4);
+
+        *offset = get_bits_count(&gb)/8 + buf_size - pkt_left;
+        *length = length_code;
+
+        av_log(avctx, AV_LOG_TRACE, "located non-pcm packet at offset %d length code %d.\n", AES3_HEADER_LEN + *offset, length_code);
+
+        return data_type;
+    }
+
+end:
+    if (s->non_pcm_data_type == -1) {
+        s->non_pcm_data_type = 32;  // indicate stream should be treated as LPCM
+        return 0;
+    } else
+        return AVERROR_INVALIDDATA;
+}
+
+static int s302m_setup_non_pcm_handling(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+    S302Context *s = avctx->priv_data;
+    const AVCodec *codec;
+    enum AVCodecID codec_id;
+    AVDictionary *dec_opts = NULL;
+    int ret;
+
+    if (s->non_pcm_mode > NON_PCM_DROP) {
+        switch (s->non_pcm_data_type) {
+        case 0x1C:
+            codec_id = AV_CODEC_ID_DOLBY_E;
+            break;
+        default:
+            avpriv_report_missing_feature(avctx, "decode of non-pcm data type %d", s->non_pcm_data_type);
+            ret = AVERROR_PATCHWELCOME;
+            goto fail;
+        }
+
+        codec = avcodec_find_decoder(codec_id);
+        if (!codec) {
+            ret = AVERROR_DECODER_NOT_FOUND;
+            goto fail;
+        }
+
+        s->non_pcm_ctx = avcodec_alloc_context3(codec);
+        if (!s->non_pcm_ctx) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        av_dict_copy(&dec_opts, s->non_pcm_opts, 0);
+
+        ret = avcodec_open2(s->non_pcm_ctx, codec, &dec_opts);
+        av_dict_free(&dec_opts);
+        if (ret < 0)
+            goto fail;
+
+        s->packet = av_packet_alloc();
+        if (!s->packet) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        s->frame = av_frame_alloc();
+        if (!s->frame) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    } else
+        return 0;
+
+    s->non_pcm_dec = 1;
+    return 0;
+
+fail:
+    avcodec_free_context(&s->non_pcm_ctx);
+    av_packet_free(&s->packet);
+    av_frame_free(&s->frame);
+
+    if (s->non_pcm_mode == NON_PCM_DEC_ELSE_COPY)
+        s->non_pcm_mode = NON_PCM_COPY;
+    else if (s->non_pcm_mode == NON_PCM_DEC_ELSE_DROP)
+        s->non_pcm_mode = NON_PCM_DROP;
+
+    return ret;
+}
+
+static int s302m_get_non_pcm_pkt_size(AVCodecContext *avctx, int buf_size, int offset,
+                                      int length_code, int *dec_pkt_size)
+{
+    S302Context *s = avctx->priv_data;
+    int nb_words, word_size, aesframe_size, s302m_read_size;
+
+    if (offset < 0 || offset >= buf_size)
+        return AVERROR_INVALIDDATA;
+
+    switch (s->non_pcm_data_type) {
+    case 0x1C:
+        goto dolby_e;
+    default:
+        return AVERROR_INVALIDDATA;
+    }
+
+dolby_e:
+    {
+    nb_words = length_code / s->non_pcm_bits;
+    nb_words += nb_words & 1;
+
+    word_size = s->non_pcm_bits + 7 >> 3;
+    aesframe_size = (s->bits + 4) * 2 / 8;  // 2 subframes, each with payload + VUCF bits
+
+    *dec_pkt_size = nb_words * word_size;
+    s302m_read_size = aesframe_size * nb_words/2;
+
+    if (offset + s302m_read_size > buf_size)
+        return AVERROR_INVALIDDATA;
+
+    return s302m_read_size;
+    }
+}
+
 static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
                                     int buf_size)
 {
+    S302Context *s = avctx->priv_data;
     uint32_t h;
     int frame_size, channels, bits;
 
@@ -66,33 +309,15 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
         return AVERROR_INVALIDDATA;
     }
 
-    /* Set output properties */
-    avctx->bits_per_raw_sample = bits;
-    if (bits > 16)
-        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
-    else
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    if (!s->channels)
+        s->channels = channels;
+    else if (s->channels != channels)
+        return AVERROR_INVALIDDATA;
 
-    av_channel_layout_uninit(&avctx->ch_layout);
-    switch(channels) {
-        case 2:
-            avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
-            break;
-        case 4:
-            avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
-            break;
-        case 6:
-            avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
-            break;
-        case 8:
-            av_channel_layout_from_mask(&avctx->ch_layout,
-                                        AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
-            break;
-        default:
-            avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
-            avctx->ch_layout.nb_channels = channels;
-            break;
-    }
+    if (!s->bits)
+        s->bits = bits;
+    else if (s->bits != bits)
+        return AVERROR_INVALIDDATA;
 
     return frame_size;
 }
@@ -103,119 +328,273 @@ static int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame,
     S302Context *s = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    int block_size, ret, channels;
-    int i;
-    int non_pcm_data_type = -1;
+    int block_size, ret, channels, frame_size;
+    int non_pcm_offset = -1, non_pcm_length = 0;
+    int dec_pkt_size = 0;
 
-    int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
+    if (s->non_pcm_mode == NON_PCM_DROP && s->non_pcm_data_type != -1 && s->non_pcm_data_type != 32)
+        return avpkt->size;
+
+    frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
     if (frame_size < 0)
         return frame_size;
 
     buf_size -= AES3_HEADER_LEN;
     buf      += AES3_HEADER_LEN;
 
-    /* get output buffer */
-    block_size = (avctx->bits_per_raw_sample + 4) / 4;
-    channels = avctx->ch_layout.nb_channels;
-    frame->nb_samples = 2 * (buf_size / block_size) / channels;
-    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
-        return ret;
+    // set non-pcm status if not determined
+    // else extract offset and length if non-pcm can be decoded
+    if (s->non_pcm_data_type == -1 || s->non_pcm_dec) {
+        ret = s302m_non_pcm_inspect(avctx, buf, buf_size, &non_pcm_offset, &non_pcm_length);
+        if (ret >= 0 && s->non_pcm_data_type != 32 && !s->non_pcm_dec)
+            ret = s302m_setup_non_pcm_handling(avctx, buf, buf_size);
+        else if (ret < 0)
+            return avpkt->size;
+    }
 
-    avctx->bit_rate = 48000 * channels * (avctx->bits_per_raw_sample + 4) +
-                      32 * 48000 / frame->nb_samples;
-    buf_size = (frame->nb_samples * channels / 2) * block_size;
+    if (s->non_pcm_data_type == -1)
+        return AVERROR_INVALIDDATA;  // we should know data type in order to proceed with output
+
+    if (!s->non_pcm_dec && !s->avctx_props_set) {
+        /* Set output properties */
+        avctx->bits_per_raw_sample = s->non_pcm_bits ? s->non_pcm_bits : s->bits;
+        if (avctx->bits_per_raw_sample > 16)
+            avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+        else
+            avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+        av_channel_layout_uninit(&avctx->ch_layout);
+        switch(s->channels) {
+            case 2:
+                avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
+                break;
+            case 4:
+                avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD;
+                break;
+            case 6:
+                avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK;
+                break;
+            case 8:
+                av_channel_layout_from_mask(&avctx->ch_layout,
+                                            AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX);
+                break;
+            default:
+                avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+                avctx->ch_layout.nb_channels = channels;
+                break;
+        }
+
+        avctx->sample_rate = 48000;
+        s->avctx_props_set = 1;
+    }
+
+    if (s->non_pcm_dec) {
+        buf_size = s302m_get_non_pcm_pkt_size(avctx, buf_size, non_pcm_offset, non_pcm_length, &dec_pkt_size);
+        if (buf_size < 0)
+            return AVERROR_INVALIDDATA;
+        buf += non_pcm_offset;
+
+        if (dec_pkt_size > s->packet->size) {
+            ret = av_grow_packet(s->packet, dec_pkt_size - s->packet->size);
+            if (ret < 0)
+                return ret;
+        }
+        ret = av_packet_make_writable(s->packet);
+        if (ret < 0)
+            return ret;
+        memset(s->packet->data, 0, s->packet->size);
+
+        ret = av_packet_copy_props(s->packet, avpkt);
+        if (ret < 0)
+            return ret;
+    } else {
+        /* get output buffer */
+        block_size = (s->bits + 4) / 4;
+        channels = s->channels;
+        frame->nb_samples = 2 * (buf_size / block_size) / channels;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+            return ret;
+
+        buf_size = (frame->nb_samples * channels / 2) * block_size;
+
+        avctx->bit_rate = 48000 * s->channels * ((s->non_pcm_bits ? s->non_pcm_bits : s->bits) + 4) +
+                          32 * 48000 / frame->nb_samples;
+    }
+
+    if (s->bits == 24) {
+        uint8_t  *p   = NULL;
+        uint32_t *f32 = NULL;
+
+        if (s->non_pcm_dec)
+            p = (uint8_t *)s->packet->data;
+        else
+            f32 = (uint32_t *)frame->data[0];
 
-    if (avctx->bits_per_raw_sample == 24) {
-        uint32_t *o = (uint32_t *)frame->data[0];
         for (; buf_size > 6; buf_size -= 7) {
-            *o++ = ((unsigned)ff_reverse[buf[2]]        << 24) |
-                   (ff_reverse[buf[1]]        << 16) |
-                   (ff_reverse[buf[0]]        <<  8);
-            *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) |
-                   (ff_reverse[buf[5]]        << 20) |
-                   (ff_reverse[buf[4]]        << 12) |
-                   (ff_reverse[buf[3] & 0x0f] <<  4);
+            uint8_t b[6];
+
+            b[0] = (ff_reverse[buf[2]       ]      ) ;
+            b[1] = (ff_reverse[buf[1]       ]      ) ;
+            b[2] = (ff_reverse[buf[0]       ]      ) ;
+            b[3] = (ff_reverse[buf[6] & 0xf0] <<  4) |
+                   (ff_reverse[buf[5] & 0x0f] >>  4) ;
+            b[4] = (ff_reverse[buf[5] & 0xf0] <<  4) |
+                   (ff_reverse[buf[4] & 0x0f] >>  4) ;
+            b[5] = (ff_reverse[buf[4] & 0xf0] <<  4) |
+                   (ff_reverse[buf[3] & 0x0f] >>  4) ;
+
+            if (s->non_pcm_bits == 20) {
+                b[2] &= 0xf0;
+                b[5] &= 0xf0;
+            }
+
+            if (s->non_pcm_dec)
+                for (int i = 0; i < 6; i++)
+                    *p++ = b[i];
+            else {
+                *f32++ = AV_RB24(&b[0]) << 8;
+                *f32++ = AV_RB24(&b[3]) << 8;
+            }
             buf += 7;
         }
-        o = (uint32_t *)frame->data[0];
-        if (channels == 2)
-            for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
-                if (o[i] || o[i+1] || o[i+2] || o[i+3])
-                    break;
-                if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
-                    non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
-                    break;
-                }
-            }
-    } else if (avctx->bits_per_raw_sample == 20) {
-        uint32_t *o = (uint32_t *)frame->data[0];
+    } else if (s->bits == 20) {
+        uint8_t  *p   = NULL;
+        uint16_t *f16 = NULL;
+        uint32_t *f32 = NULL;
+
+        if (s->non_pcm_dec)
+            p = (uint8_t *)s->packet->data;
+        else if (s->non_pcm_bits == 16)
+            f16 = (uint16_t *)frame->data[0];
+        else
+            f32 = (uint32_t *)frame->data[0];
+
         for (; buf_size > 5; buf_size -= 6) {
-            *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) |
-                   (ff_reverse[buf[1]]        << 20) |
-                   (ff_reverse[buf[0]]        << 12);
-            *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) |
-                   (ff_reverse[buf[4]]        << 20) |
-                   (ff_reverse[buf[3]]        << 12);
+            uint8_t b[6];
+
+            b[0] = (ff_reverse[buf[2] & 0xf0] <<  4) |
+                   (ff_reverse[buf[1] & 0x0f] >>  4) ;
+            b[1] = (ff_reverse[buf[1] & 0xf0] <<  4) |
+                   (ff_reverse[buf[0] & 0x0f] >>  4) ;
+            b[2] = (ff_reverse[buf[0] & 0xf0] <<  4) ;
+            b[3] = (ff_reverse[buf[5] & 0xf0] <<  4) |
+                   (ff_reverse[buf[4] & 0x0f] >>  4) ;
+            b[4] = (ff_reverse[buf[4] & 0xf0] <<  4) |
+                   (ff_reverse[buf[3] & 0x0f] >>  4) ;
+            b[5] = (ff_reverse[buf[3] & 0xf0] <<  4) ;
+
+            if (s->non_pcm_dec) {
+                for (int i = 0; i < 6; i++) {
+                    if (s->non_pcm_bits == 16 && (i % 3 == 2))
+                        continue;
+                    *p++ = b[i];
+                }
+            } else if (s->non_pcm_bits == 16) {
+                *f16++ = AV_RB16(&b[0]);
+                *f16++ = AV_RB16(&b[3]);
+            } else {
+                *f32++ = AV_RB24(&b[0]) << 8;
+                *f32++ = AV_RB24(&b[3]) << 8;
+            }
             buf += 6;
         }
-        o = (uint32_t *)frame->data[0];
-        if (channels == 2)
-            for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
-                if (o[i] || o[i+1] || o[i+2] || o[i+3])
-                    break;
-                if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
-                    non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
-                    break;
-                }
-            }
     } else {
-        uint16_t *o = (uint16_t *)frame->data[0];
+        uint8_t  *p   = NULL;
+        uint16_t *f16 = NULL;
+
+        if (s->non_pcm_dec)
+            p = (uint8_t *)s->packet->data;
+        else
+            f16 = (uint16_t *)frame->data[0];
+
         for (; buf_size > 4; buf_size -= 5) {
-            *o++ = (ff_reverse[buf[1]]        <<  8) |
-                    ff_reverse[buf[0]];
-            *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
-                   (ff_reverse[buf[3]]        <<  4) |
-                   (ff_reverse[buf[2]]        >>  4);
+            uint8_t b[4];
+
+            b[0] = (ff_reverse[buf[1]       ]      ) ;
+            b[1] = (ff_reverse[buf[0]       ]      ) ;
+            b[2] = (ff_reverse[buf[4] & 0xf0] <<  4) |
+                   (ff_reverse[buf[3] & 0x0f] >>  4) ;
+            b[3] = (ff_reverse[buf[3] & 0xf0] <<  4) |
+                   (ff_reverse[buf[2] & 0x0f] >>  4) ;
+
+            if (s->non_pcm_dec)
+                for (int i = 0; i < 4; i++)
+                    *p++ = b[i];
+            else {
+                *f16++ = AV_RB16(&b[0]);
+                *f16++ = AV_RB16(&b[2]);
+            }
             buf += 5;
         }
-        o = (uint16_t *)frame->data[0];
-        if (channels == 2)
-            for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
-                if (o[i] || o[i+1] || o[i+2] || o[i+3])
-                    break;
-                if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
-                    non_pcm_data_type = (o[i+6] & 0x1F);
-                    break;
-                }
+    }
+
+    if (s->non_pcm_dec) {
+        ret = avcodec_send_packet(s->non_pcm_ctx, s->packet);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "error %d submitting non-pcm packet with pts %"PRId64" for decoding\n", ret, s->packet->pts);
+            return ret;
+        }
+        ret = avcodec_receive_frame(s->non_pcm_ctx, s->frame);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "error %d receiving non-pcm decoded frame for packet with pts %"PRId64"\n", ret, s->packet->pts);
+            return ret;
+        }
+
+        if (!s->avctx_props_set) {
+            avctx->sample_fmt  = s->non_pcm_ctx->sample_fmt;
+            avctx->sample_rate = s->non_pcm_ctx->sample_rate;
+
+            av_channel_layout_uninit(&avctx->ch_layout);
+            ret = av_channel_layout_copy(&avctx->ch_layout, &s->non_pcm_ctx->ch_layout);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR, "error %d when copying channel layout from non-pcm decoder context to parent context.\n", ret);
+                return ret;
             }
-    }
-
-    if (non_pcm_data_type != -1) {
-        if (s->non_pcm_mode == 3) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "S302 non PCM mode with data type %d not supported\n",
-                   non_pcm_data_type);
-            return AVERROR_PATCHWELCOME;
+            s->avctx_props_set = 1;
         }
-        if (s->non_pcm_mode & 1) {
-            return avpkt->size;
-        }
-    }
 
-    avctx->sample_rate = 48000;
+        frame->nb_samples = s->frame->nb_samples;
+        ret = ff_get_buffer(avctx, frame, 0);
+        if (ret < 0)
+            return ret;
+
+        for (int ch = 0; ch < s->frame->ch_layout.nb_channels; ch++)
+            memcpy(frame->extended_data[ch], s->frame->extended_data[ch],
+                   av_get_bytes_per_sample(s->non_pcm_ctx->sample_fmt) * s->frame->nb_samples);
+    }
 
     *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
+static void s302m_flush(AVCodecContext *avctx)
+{
+    S302Context *s = avctx->priv_data;
+
+    if (s->non_pcm_dec && s->non_pcm_ctx)
+        avcodec_flush_buffers(s->non_pcm_ctx);
+}
+
+static av_cold int s302m_close(AVCodecContext *avctx)
+{
+    S302Context *s = avctx->priv_data;
+
+    avcodec_free_context(&s->non_pcm_ctx);
+    av_packet_free(&s->packet);
+    av_frame_free(&s->frame);
+
+    return 0;
+}
+
 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
 static const AVOption s302m_options[] = {
-    {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
-    {"copy"        , "Pass NON-PCM through unchanged"     , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
-    {"drop"        , "Drop NON-PCM"                       , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
-    {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
-    {"decode_drop" , "Decode if possible else drop"       , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
+    {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = NON_PCM_DEC_ELSE_DROP}, NON_PCM_COPY, NON_PCM_DEC_ELSE_DROP, FLAGS, "non_pcm_mode"},
+    {"copy"        , "Pass NON-PCM through unchanged"     , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_COPY},          0, 3, FLAGS, "non_pcm_mode"},
+    {"drop"        , "Drop NON-PCM"                       , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DROP},          0, 3, FLAGS, "non_pcm_mode"},
+    {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_COPY}, 0, 3, FLAGS, "non_pcm_mode"},
+    {"decode_drop" , "Decode if possible else drop"       , 0, AV_OPT_TYPE_CONST, {.i64 = NON_PCM_DEC_ELSE_DROP}, 0, 3, FLAGS, "non_pcm_mode"},
+    {"non_pcm_options", "Set options for non-pcm decoder",  offsetof(S302Context, non_pcm_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
     {NULL}
 };
 
@@ -231,6 +610,9 @@ const FFCodec ff_s302m_decoder = {
     CODEC_LONG_NAME("SMPTE 302M"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_S302M,
+    .init           = s302m_init,
+    .close          = s302m_close,
+    .flush          = s302m_flush,
     .p.priv_class   = &s302m_class,
     .priv_data_size = sizeof(S302Context),
     FF_CODEC_DECODE_CB(s302m_decode_frame),
-- 
2.52.0


>From 1a9f5baed5c7d4dc2d9d34f8f52bb21062430155 Mon Sep 17 00:00:00 2001
From: Gyan Doshi <[email protected]>
Date: Tue, 16 Jan 2024 13:27:40 +0530
Subject: [PATCH 2/2] fate: add tests for dolby_e decoding in s302m

Three tests, one each for

1) 16-bit Dolby-E words in 20-bits AES3 words
2) 20-bit Dolby-E words in 20-bits AES3 words
3) 20-bit Dolby-E words in 24-bits AES3 words
---
 tests/fate/acodec.mak               |  15 ++
 tests/ref/acodec/s302m-20-dolbye-16 | 221 ++++++++++++++++++++++++++++
 tests/ref/acodec/s302m-20-dolbye-20 | 127 ++++++++++++++++
 tests/ref/acodec/s302m-24-dolbye-20 | 170 +++++++++++++++++++++
 4 files changed, 533 insertions(+)
 create mode 100644 tests/ref/acodec/s302m-20-dolbye-16
 create mode 100644 tests/ref/acodec/s302m-20-dolbye-20
 create mode 100644 tests/ref/acodec/s302m-24-dolbye-20

diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index 54884371ac..34fdadefa0 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -165,6 +165,21 @@ fate-acodec-s302m: CODEC = s302m
 fate-acodec-s302m: ENCOPTS = -af aresample=48000:tsf=s16p -strict -2
 fate-acodec-s302m: DECOPTS = -af aresample=44100:tsf=s16p
 
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-20-dolbye-16
+fate-acodec-s302m-20-dolbye-16: CMD = framecrc -auto_conversion_filters \
+  -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_20bits_DolbyE_16bits.ts \
+  -vn -c:a pcm_s16le
+
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-20-dolbye-20
+fate-acodec-s302m-20-dolbye-20: CMD = framecrc -auto_conversion_filters \
+  -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_20bits_DolbyE_20bits.ts \
+  -vn -c:a pcm_s16le
+
+FATE_ACODEC-$(call FRAMECRC, MPEGTS, S302M DOLBY_E) += fate-acodec-s302m-24-dolbye-20
+fate-acodec-s302m-24-dolbye-20: CMD = framecrc -auto_conversion_filters \
+  -non_pcm_mode decode_copy -i $(TARGET_SAMPLES)/s302m/s302_24bits_DolbyE_20bits.ts \
+  -vn -c:a pcm_s16le
+
 FATE_ACODEC-$(call ENCDEC, WAVPACK, WV, ARESAMPLE_FILTER) += fate-acodec-wavpack
 fate-acodec-wavpack: FMT = wv
 fate-acodec-wavpack: CODEC = wavpack -compression_level 1
diff --git a/tests/ref/acodec/s302m-20-dolbye-16 b/tests/ref/acodec/s302m-20-dolbye-16
new file mode 100644
index 0000000000..e0c7b9e13b
--- /dev/null
+++ b/tests/ref/acodec/s302m-20-dolbye-16
@@ -0,0 +1,221 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 5.1(side)
+0,          0,          0,     1792,    21504, 0x9136aa8a
+0,       1792,       1792,     1792,    21504, 0x6b8b42f0
+0,       3584,       3584,     1792,    21504, 0xc73c0342
+0,       5376,       5376,     1792,    21504, 0x9d777e2a
+0,       7168,       7168,     1792,    21504, 0x2ee86c97
+0,       8960,       8960,     1792,    21504, 0xfdd41829
+0,      10752,      10752,     1792,    21504, 0x58ea1b12
+0,      12544,      12544,     1792,    21504, 0xa81a35f4
+0,      14336,      14336,     1792,    21504, 0x2bd9bb62
+0,      16128,      16128,     1792,    21504, 0x0648940e
+0,      17920,      17920,     1792,    21504, 0x377452f9
+0,      19712,      19712,     1792,    21504, 0xf50f26b9
+0,      21504,      21504,     1792,    21504, 0x935e7c69
+0,      23296,      23296,     1792,    21504, 0x99363659
+0,      25088,      25088,     1792,    21504, 0x78212dd2
+0,      26880,      26880,     1792,    21504, 0x687f5776
+0,      28672,      28672,     1792,    21504, 0xd6d3320c
+0,      30464,      30464,     1792,    21504, 0x96e1b731
+0,      32256,      32256,     1792,    21504, 0xbb0b9cd9
+0,      34048,      34048,     1792,    21504, 0x819db403
+0,      35840,      35840,     1792,    21504, 0xa95c859a
+0,      37632,      37632,     1792,    21504, 0xd9cd11cc
+0,      39424,      39424,     1792,    21504, 0xe7a3abbf
+0,      41216,      41216,     1792,    21504, 0x975e4ddc
+0,      43008,      43008,     1792,    21504, 0x329af143
+0,      44800,      44800,     1792,    21504, 0x9bb6281b
+0,      46592,      46592,     1792,    21504, 0x96cc0fa8
+0,      48384,      48384,     1792,    21504, 0xaae03a7d
+0,      50176,      50176,     1792,    21504, 0x2a5d6225
+0,      51968,      51968,     1792,    21504, 0xf7cc19f5
+0,      53760,      53760,     1792,    21504, 0x89e85e67
+0,      55552,      55552,     1792,    21504, 0x607ab65e
+0,      57344,      57344,     1792,    21504, 0x95c0ad8f
+0,      59136,      59136,     1792,    21504, 0x6b9e8b96
+0,      60928,      60928,     1792,    21504, 0x7b83696c
+0,      62720,      62720,     1792,    21504, 0xac0b6fbf
+0,      64512,      64512,     1792,    21504, 0xfa249f22
+0,      66304,      66304,     1792,    21504, 0x51acbb93
+0,      68096,      68096,     1792,    21504, 0xd77b34be
+0,      69888,      69888,     1792,    21504, 0xd5494a86
+0,      71680,      71680,     1792,    21504, 0xd83c3d91
+0,      73472,      73472,     1792,    21504, 0xa476ccd8
+0,      75264,      75264,     1792,    21504, 0x2aafc337
+0,      77056,      77056,     1792,    21504, 0xeee70084
+0,      78848,      78848,     1792,    21504, 0xd60a3c93
+0,      80640,      80640,     1792,    21504, 0x43ac0f84
+0,      82432,      82432,     1792,    21504, 0x8aeb9355
+0,      84224,      84224,     1792,    21504, 0xe548d9ec
+0,      86016,      86016,     1792,    21504, 0x13c71471
+0,      87808,      87808,     1792,    21504, 0x328bde19
+0,      89600,      89600,     1792,    21504, 0xe21f9541
+0,      91392,      91392,     1792,    21504, 0xf01f7709
+0,      93184,      93184,     1792,    21504, 0x7eed888b
+0,      94976,      94976,     1792,    21504, 0x93ce6bd6
+0,      96768,      96768,     1792,    21504, 0x25a00dce
+0,      98560,      98560,     1792,    21504, 0xf3b782e5
+0,     100352,     100352,     1792,    21504, 0x50cfeff9
+0,     102144,     102144,     1792,    21504, 0x8a49dc66
+0,     103936,     103936,     1792,    21504, 0x992102d0
+0,     105728,     105728,     1792,    21504, 0x948cf82a
+0,     107520,     107520,     1792,    21504, 0x8d21d0f4
+0,     109312,     109312,     1792,    21504, 0x4c3075a2
+0,     111104,     111104,     1792,    21504, 0xdd958734
+0,     112896,     112896,     1792,    21504, 0xdd98493b
+0,     114688,     114688,     1792,    21504, 0x65273440
+0,     116480,     116480,     1792,    21504, 0xefa1df42
+0,     118272,     118272,     1792,    21504, 0x60c90e3f
+0,     120064,     120064,     1792,    21504, 0x31500c0b
+0,     121856,     121856,     1792,    21504, 0xb5cfee25
+0,     123648,     123648,     1792,    21504, 0xb7377ca2
+0,     125440,     125440,     1792,    21504, 0x2cec434f
+0,     127232,     127232,     1792,    21504, 0x5a42a510
+0,     129024,     129024,     1792,    21504, 0xa3a27927
+0,     130816,     130816,     1792,    21504, 0x9faf946f
+0,     132608,     132608,     1792,    21504, 0x05c9ce85
+0,     134400,     134400,     1792,    21504, 0xdd2d2579
+0,     136192,     136192,     1792,    21504, 0x422b6910
+0,     137984,     137984,     1792,    21504, 0xbd87a267
+0,     139776,     139776,     1792,    21504, 0x8ff262b6
+0,     141568,     141568,     1792,    21504, 0x2c134aea
+0,     143360,     143360,     1792,    21504, 0x4b756eef
+0,     145152,     145152,     1792,    21504, 0xe871ccba
+0,     146944,     146944,     1792,    21504, 0x048f2364
+0,     148736,     148736,     1792,    21504, 0x2fbc747d
+0,     150528,     150528,     1792,    21504, 0x1c4ad508
+0,     152320,     152320,     1792,    21504, 0xdc3d010e
+0,     154112,     154112,     1792,    21504, 0xf0bee87a
+0,     155904,     155904,     1792,    21504, 0xc4c53799
+0,     157696,     157696,     1792,    21504, 0xa815039c
+0,     159488,     159488,     1792,    21504, 0x70e02a19
+0,     161280,     161280,     1792,    21504, 0x25f640d4
+0,     163072,     163072,     1792,    21504, 0xeb34e7d1
+0,     164864,     164864,     1792,    21504, 0x98fb0d91
+0,     166656,     166656,     1792,    21504, 0xac0c2d8c
+0,     168448,     168448,     1792,    21504, 0x6292368a
+0,     170240,     170240,     1792,    21504, 0x2f78c7a8
+0,     172032,     172032,     1792,    21504, 0x43268663
+0,     173824,     173824,     1792,    21504, 0x5834f0f9
+0,     175616,     175616,     1792,    21504, 0x7bab1336
+0,     177408,     177408,     1792,    21504, 0xb6736af6
+0,     179200,     179200,     1792,    21504, 0xd4681bfa
+0,     180992,     180992,     1792,    21504, 0xc2199d49
+0,     182784,     182784,     1792,    21504, 0x366a1ae0
+0,     184576,     184576,     1792,    21504, 0x7fde6d4b
+0,     186368,     186368,     1792,    21504, 0x8ac70491
+0,     188160,     188160,     1792,    21504, 0x08bbf02e
+0,     189952,     189952,     1792,    21504, 0x9fbd8944
+0,     191744,     191744,     1792,    21504, 0x04b12848
+0,     193536,     193536,     1792,    21504, 0xcb23ae72
+0,     195328,     195328,     1792,    21504, 0xd5571f70
+0,     197120,     197120,     1792,    21504, 0x820cb277
+0,     198912,     198912,     1792,    21504, 0x1352bb72
+0,     200704,     200704,     1792,    21504, 0x008aa81c
+0,     202496,     202496,     1792,    21504, 0x14cc97e2
+0,     204288,     204288,     1792,    21504, 0x1599fdd7
+0,     206080,     206080,     1792,    21504, 0x8e5fcec5
+0,     207872,     207872,     1792,    21504, 0x8fa3f712
+0,     209664,     209664,     1792,    21504, 0xee373f8a
+0,     211456,     211456,     1792,    21504, 0x78d5d931
+0,     213248,     213248,     1792,    21504, 0x48132510
+0,     215040,     215040,     1792,    21504, 0x3bddeb6a
+0,     216832,     216832,     1792,    21504, 0xe4b7dade
+0,     218624,     218624,     1792,    21504, 0x39660d3b
+0,     220416,     220416,     1792,    21504, 0x57e5529e
+0,     222208,     222208,     1792,    21504, 0xe7047887
+0,     224000,     224000,     1792,    21504, 0x58b47398
+0,     225792,     225792,     1792,    21504, 0x1c209a7a
+0,     227584,     227584,     1792,    21504, 0x9880d68e
+0,     229376,     229376,     1792,    21504, 0xe529880f
+0,     231168,     231168,     1792,    21504, 0xc5a3a5ff
+0,     232960,     232960,     1792,    21504, 0x9b344d76
+0,     234752,     234752,     1792,    21504, 0xeb73e24c
+0,     236544,     236544,     1792,    21504, 0xeae26f88
+0,     238336,     238336,     1792,    21504, 0xdc02c37a
+0,     240128,     240128,     1792,    21504, 0xd7102ba8
+0,     241920,     241920,     1792,    21504, 0x40ecab7e
+0,     243712,     243712,     1792,    21504, 0x57bdf0ba
+0,     245504,     245504,     1792,    21504, 0xc5961f22
+0,     247296,     247296,     1792,    21504, 0x3649ea62
+0,     249088,     249088,     1792,    21504, 0x47960ac6
+0,     250880,     250880,     1792,    21504, 0xd19597be
+0,     252672,     252672,     1792,    21504, 0xa3b2f62b
+0,     254464,     254464,     1792,    21504, 0x99abea1e
+0,     256256,     256256,     1792,    21504, 0xcee9f230
+0,     258048,     258048,     1792,    21504, 0xdc0ce362
+0,     259840,     259840,     1792,    21504, 0xc6da4814
+0,     261632,     261632,     1792,    21504, 0x2fe37803
+0,     263424,     263424,     1792,    21504, 0x2a6e4f0c
+0,     265216,     265216,     1792,    21504, 0x0b8d59b3
+0,     267008,     267008,     1792,    21504, 0xebcdbc2e
+0,     268800,     268800,     1792,    21504, 0xe236b4c4
+0,     270592,     270592,     1792,    21504, 0x631726e6
+0,     272384,     272384,     1792,    21504, 0xf00db632
+0,     274176,     274176,     1792,    21504, 0x2f679a9b
+0,     275968,     275968,     1792,    21504, 0xaa74d412
+0,     277760,     277760,     1792,    21504, 0x64abf8f3
+0,     279552,     279552,     1792,    21504, 0x352b8366
+0,     281344,     281344,     1792,    21504, 0x35addc2c
+0,     283136,     283136,     1792,    21504, 0x20093740
+0,     284928,     284928,     1792,    21504, 0x5ac2c7cd
+0,     286720,     286720,     1792,    21504, 0xb12329a4
+0,     288512,     288512,     1792,    21504, 0xe4cdfece
+0,     290304,     290304,     1792,    21504, 0xb5477f3b
+0,     292096,     292096,     1792,    21504, 0x68f0b7fc
+0,     293888,     293888,     1792,    21504, 0x7ddbff47
+0,     295680,     295680,     1792,    21504, 0xd4048c58
+0,     297472,     297472,     1792,    21504, 0x582a008d
+0,     299264,     299264,     1792,    21504, 0xacc3e45d
+0,     301056,     301056,     1792,    21504, 0xa41dc633
+0,     302848,     302848,     1792,    21504, 0x700345de
+0,     304640,     304640,     1792,    21504, 0xd8f5c071
+0,     306432,     306432,     1792,    21504, 0x671d777e
+0,     308224,     308224,     1792,    21504, 0x7bc98c57
+0,     310016,     310016,     1792,    21504, 0xebb4dd91
+0,     311808,     311808,     1792,    21504, 0xaffbcc2e
+0,     313600,     313600,     1792,    21504, 0xd97328ea
+0,     315392,     315392,     1792,    21504, 0xa40a3495
+0,     317184,     317184,     1792,    21504, 0x86a82b6f
+0,     318976,     318976,     1792,    21504, 0x1009f9fa
+0,     320768,     320768,     1792,    21504, 0x4bb3b64a
+0,     322560,     322560,     1792,    21504, 0x4ea9ebd3
+0,     324352,     324352,     1792,    21504, 0x4bb33092
+0,     326144,     326144,     1792,    21504, 0x27b8ce5f
+0,     327936,     327936,     1792,    21504, 0x7a7192e7
+0,     329728,     329728,     1792,    21504, 0x49972389
+0,     331520,     331520,     1792,    21504, 0x707a8d22
+0,     333312,     333312,     1792,    21504, 0x21ee3ee7
+0,     335104,     335104,     1792,    21504, 0xe01a4599
+0,     336896,     336896,     1792,    21504, 0x4282e560
+0,     338688,     338688,     1792,    21504, 0x44539c70
+0,     340480,     340480,     1792,    21504, 0xac084971
+0,     342272,     342272,     1792,    21504, 0xc0dafcb4
+0,     344064,     344064,     1792,    21504, 0x3248760d
+0,     345856,     345856,     1792,    21504, 0x18a4f9e5
+0,     347648,     347648,     1792,    21504, 0x71f8e059
+0,     349440,     349440,     1792,    21504, 0xea7282ea
+0,     351232,     351232,     1792,    21504, 0x25c0919c
+0,     353024,     353024,     1792,    21504, 0x5b0886cf
+0,     354816,     354816,     1792,    21504, 0x909f2352
+0,     356608,     356608,     1792,    21504, 0x37458b4a
+0,     358400,     358400,     1792,    21504, 0x678ac27a
+0,     360192,     360192,     1792,    21504, 0x2a25cabb
+0,     361984,     361984,     1792,    21504, 0xa0bcd6d8
+0,     363776,     363776,     1792,    21504, 0x39366653
+0,     365568,     365568,     1792,    21504, 0xa173abac
+0,     367360,     367360,     1792,    21504, 0x737a1781
+0,     369152,     369152,     1792,    21504, 0xa2ba122e
+0,     370944,     370944,     1792,    21504, 0x63135aef
+0,     372736,     372736,     1792,    21504, 0xc9bd4ccc
+0,     374528,     374528,     1792,    21504, 0xd8aab65d
+0,     376320,     376320,     1792,    21504, 0x1f35ca2e
+0,     378112,     378112,     1792,    21504, 0x002ea8b9
+0,     379904,     379904,     1792,    21504, 0xa5e1b4d0
+0,     381696,     381696,     1792,    21504, 0xd2fa9e4a
+0,     383488,     383488,     1792,    21504, 0xcfd58c02
+0,     385280,     385280,     1792,    21504, 0x0fa5edf4
diff --git a/tests/ref/acodec/s302m-20-dolbye-20 b/tests/ref/acodec/s302m-20-dolbye-20
new file mode 100644
index 0000000000..f19d0f0b19
--- /dev/null
+++ b/tests/ref/acodec/s302m-20-dolbye-20
@@ -0,0 +1,127 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 7.1
+0,          0,          0,     1792,    28672, 0xafcc7cdc
+0,       1792,       1792,     1792,    28672, 0x6779af9c
+0,       3584,       3584,     1792,    28672, 0x85383174
+0,       5376,       5376,     1792,    28672, 0xf31ac9ba
+0,       7168,       7168,     1792,    28672, 0x6d38995e
+0,       8960,       8960,     1792,    28672, 0x0ea74b36
+0,      10752,      10752,     1792,    28672, 0x5b599a77
+0,      12544,      12544,     1792,    28672, 0x697aa42c
+0,      14336,      14336,     1792,    28672, 0x0a2812a5
+0,      16128,      16128,     1792,    28672, 0x738239fc
+0,      17920,      17920,     1792,    28672, 0x0a091522
+0,      19712,      19712,     1792,    28672, 0x926829c7
+0,      21504,      21504,     1792,    28672, 0x1e02c825
+0,      23296,      23296,     1792,    28672, 0x00b969df
+0,      25088,      25088,     1792,    28672, 0x8864a003
+0,      26880,      26880,     1792,    28672, 0x5e48b960
+0,      28672,      28672,     1792,    28672, 0xd6bc9752
+0,      30464,      30464,     1792,    28672, 0x6ddc6c53
+0,      32256,      32256,     1792,    28672, 0x4779e77e
+0,      34048,      34048,     1792,    28672, 0x42cf2f9d
+0,      35840,      35840,     1792,    28672, 0x8b9ba6bd
+0,      37632,      37632,     1792,    28672, 0x5947fe3d
+0,      39424,      39424,     1792,    28672, 0x13b13fb9
+0,      41216,      41216,     1792,    28672, 0x8f707e79
+0,      43008,      43008,     1792,    28672, 0x2da453c2
+0,      44800,      44800,     1792,    28672, 0x71b53009
+0,      46592,      46592,     1792,    28672, 0x261aee06
+0,      48384,      48384,     1792,    28672, 0xf17e2267
+0,      50176,      50176,     1792,    28672, 0xb050e6ad
+0,      51968,      51968,     1792,    28672, 0x5bac3a6e
+0,      53760,      53760,     1792,    28672, 0x8864fd2a
+0,      55552,      55552,     1792,    28672, 0x76e3e5c2
+0,      57344,      57344,     1792,    28672, 0xb0dfb4eb
+0,      59136,      59136,     1792,    28672, 0x759ccffd
+0,      60928,      60928,     1792,    28672, 0xc05465ff
+0,      62720,      62720,     1792,    28672, 0x6cdb97ce
+0,      64512,      64512,     1792,    28672, 0x6d095222
+0,      66304,      66304,     1792,    28672, 0xb73a46a9
+0,      68096,      68096,     1792,    28672, 0xe7972758
+0,      69888,      69888,     1792,    28672, 0x13957aec
+0,      71680,      71680,     1792,    28672, 0xd98da4be
+0,      73472,      73472,     1792,    28672, 0x5b71520b
+0,      75264,      75264,     1792,    28672, 0x7f2b5780
+0,      77056,      77056,     1792,    28672, 0x998dfb6d
+0,      78848,      78848,     1792,    28672, 0x74cdcf9d
+0,      80640,      80640,     1792,    28672, 0x0d0561e5
+0,      82432,      82432,     1792,    28672, 0x3d52043c
+0,      84224,      84224,     1792,    28672, 0x91292607
+0,      86016,      86016,     1792,    28672, 0x09ce094f
+0,      87808,      87808,     1792,    28672, 0xb4f535a7
+0,      89600,      89600,     1792,    28672, 0xade53075
+0,      91392,      91392,     1792,    28672, 0xd2180e7a
+0,      93184,      93184,     1792,    28672, 0x93383890
+0,      94976,      94976,     1792,    28672, 0xe9885e95
+0,      96768,      96768,     1792,    28672, 0x95a7648c
+0,      98560,      98560,     1792,    28672, 0xc92504d0
+0,     100352,     100352,     1792,    28672, 0xe68650cb
+0,     102144,     102144,     1792,    28672, 0x8f0fe748
+0,     103936,     103936,     1792,    28672, 0xed292e2c
+0,     105728,     105728,     1792,    28672, 0xf3f2e270
+0,     107520,     107520,     1792,    28672, 0x52156585
+0,     109312,     109312,     1792,    28672, 0x2b4e6f80
+0,     111104,     111104,     1792,    28672, 0x20c3e16f
+0,     112896,     112896,     1792,    28672, 0xc5684fa4
+0,     114688,     114688,     1792,    28672, 0xc583d3f7
+0,     116480,     116480,     1792,    28672, 0xfac32c30
+0,     118272,     118272,     1792,    28672, 0x4bbb4646
+0,     120064,     120064,     1792,    28672, 0x119f0385
+0,     121856,     121856,     1792,    28672, 0x934bce21
+0,     123648,     123648,     1792,    28672, 0x9c7414fb
+0,     125440,     125440,     1792,    28672, 0xdfc81ba0
+0,     127232,     127232,     1792,    28672, 0x319cd9d7
+0,     129024,     129024,     1792,    28672, 0x5cb03e9e
+0,     130816,     130816,     1792,    28672, 0xc6b466b5
+0,     132608,     132608,     1792,    28672, 0x34ded4e4
+0,     134400,     134400,     1792,    28672, 0xa882395b
+0,     136192,     136192,     1792,    28672, 0x4181cd56
+0,     137984,     137984,     1792,    28672, 0x7fd2ef9b
+0,     139776,     139776,     1792,    28672, 0xcedcdfd0
+0,     141568,     141568,     1792,    28672, 0xaa74647b
+0,     143360,     143360,     1792,    28672, 0xf7159e6e
+0,     145152,     145152,     1792,    28672, 0x629a2808
+0,     146944,     146944,     1792,    28672, 0x98c5f445
+0,     148736,     148736,     1792,    28672, 0xe6f59ec4
+0,     150528,     150528,     1792,    28672, 0xbbe36f6c
+0,     152320,     152320,     1792,    28672, 0xd4798e38
+0,     154112,     154112,     1792,    28672, 0x6bfd5400
+0,     155904,     155904,     1792,    28672, 0x8b5f72e9
+0,     157696,     157696,     1792,    28672, 0x847e5637
+0,     159488,     159488,     1792,    28672, 0xe4cb8f75
+0,     161280,     161280,     1792,    28672, 0x005b69fc
+0,     163072,     163072,     1792,    28672, 0x5626bd05
+0,     164864,     164864,     1792,    28672, 0x1b3d7d91
+0,     166656,     166656,     1792,    28672, 0x41bb9890
+0,     168448,     168448,     1792,    28672, 0x2867c152
+0,     170240,     170240,     1792,    28672, 0xd34cb130
+0,     172032,     172032,     1792,    28672, 0x8e0231e0
+0,     173824,     173824,     1792,    28672, 0x44091a11
+0,     175616,     175616,     1792,    28672, 0x38a76d79
+0,     177408,     177408,     1792,    28672, 0xa9bf2434
+0,     179200,     179200,     1792,    28672, 0xefd1aa69
+0,     180992,     180992,     1792,    28672, 0x02676349
+0,     182784,     182784,     1792,    28672, 0x5000fa7e
+0,     184576,     184576,     1792,    28672, 0x9ed251d6
+0,     186368,     186368,     1792,    28672, 0x80e8740a
+0,     188160,     188160,     1792,    28672, 0x17af21c8
+0,     189952,     189952,     1792,    28672, 0x60d53ee2
+0,     191744,     191744,     1792,    28672, 0x25c7e866
+0,     193536,     193536,     1792,    28672, 0xe058a7a5
+0,     195328,     195328,     1792,    28672, 0xc23b7195
+0,     197120,     197120,     1792,    28672, 0x1c5e4edf
+0,     198912,     198912,     1792,    28672, 0x6daba516
+0,     200704,     200704,     1792,    28672, 0x9e9434ea
+0,     202496,     202496,     1792,    28672, 0x72be8da3
+0,     204288,     204288,     1792,    28672, 0x0172327d
+0,     206080,     206080,     1792,    28672, 0xc7b6006f
+0,     207872,     207872,     1792,    28672, 0x4378142c
+0,     209664,     209664,     1792,    28672, 0x5ec9bb1a
+0,     211456,     211456,     1792,    28672, 0x74bce720
+0,     213248,     213248,     1792,    28672, 0xbf7cc959
+0,     215040,     215040,     1792,    28672, 0x545ef21b
+0,     216832,     216832,     1792,    28672, 0x8fc6d2c0
diff --git a/tests/ref/acodec/s302m-24-dolbye-20 b/tests/ref/acodec/s302m-24-dolbye-20
new file mode 100644
index 0000000000..e77cf24ded
--- /dev/null
+++ b/tests/ref/acodec/s302m-24-dolbye-20
@@ -0,0 +1,170 @@
+#tb 0: 1/44800
+#media_type 0: audio
+#codec_id 0: pcm_s16le
+#sample_rate 0: 44800
+#channel_layout_name 0: 7.1
+0,          0,          0,     1792,    28672, 0x95445465
+0,       1792,       1792,     1792,    28672, 0x87b4bf1e
+0,       3584,       3584,     1792,    28672, 0x1a29c210
+0,       5376,       5376,     1792,    28672, 0xf616964a
+0,       7168,       7168,     1792,    28672, 0x5d61da52
+0,       8960,       8960,     1792,    28672, 0xa4caee00
+0,      10752,      10752,     1792,    28672, 0x070796bf
+0,      12544,      12544,     1792,    28672, 0x93dc7e75
+0,      14336,      14336,     1792,    28672, 0x2a0b29d9
+0,      16128,      16128,     1792,    28672, 0x2d5fc18b
+0,      17920,      17920,     1792,    28672, 0xc4ffda50
+0,      19712,      19712,     1792,    28672, 0x569cad29
+0,      21504,      21504,     1792,    28672, 0x8ee9be26
+0,      23296,      23296,     1792,    28672, 0x1311c083
+0,      25088,      25088,     1792,    28672, 0x052edc47
+0,      26880,      26880,     1792,    28672, 0xa1c818d7
+0,      28672,      28672,     1792,    28672, 0x9af8a5ad
+0,      30464,      30464,     1792,    28672, 0x721f2943
+0,      32256,      32256,     1792,    28672, 0xb11f5696
+0,      34048,      34048,     1792,    28672, 0xf1687bc0
+0,      35840,      35840,     1792,    28672, 0x65b0b51d
+0,      37632,      37632,     1792,    28672, 0x0b0c03ed
+0,      39424,      39424,     1792,    28672, 0xfcdae7d3
+0,      41216,      41216,     1792,    28672, 0x185cd05f
+0,      43008,      43008,     1792,    28672, 0xc68effa3
+0,      44800,      44800,     1792,    28672, 0x7e049d24
+0,      46592,      46592,     1792,    28672, 0x6de1075f
+0,      48384,      48384,     1792,    28672, 0x3d05cca4
+0,      50176,      50176,     1792,    28672, 0x0f69105b
+0,      51968,      51968,     1792,    28672, 0xa74fa091
+0,      53760,      53760,     1792,    28672, 0xdf7133b8
+0,      55552,      55552,     1792,    28672, 0x926b9501
+0,      57344,      57344,     1792,    28672, 0x3030e01f
+0,      59136,      59136,     1792,    28672, 0xc6972cc4
+0,      60928,      60928,     1792,    28672, 0xae728cbc
+0,      62720,      62720,     1792,    28672, 0x9c67b48b
+0,      64512,      64512,     1792,    28672, 0xc5a959fd
+0,      66304,      66304,     1792,    28672, 0xfdce63e6
+0,      68096,      68096,     1792,    28672, 0x76d4b7ee
+0,      69888,      69888,     1792,    28672, 0xb434cdb9
+0,      71680,      71680,     1792,    28672, 0xf5acbe03
+0,      73472,      73472,     1792,    28672, 0xfc0cd3f3
+0,      75264,      75264,     1792,    28672, 0x8fc77f0e
+0,      77056,      77056,     1792,    28672, 0x696a4e65
+0,      78848,      78848,     1792,    28672, 0x7ba12041
+0,      80640,      80640,     1792,    28672, 0x361cf723
+0,      82432,      82432,     1792,    28672, 0x39e5b0e0
+0,      84224,      84224,     1792,    28672, 0x9ada3053
+0,      86016,      86016,     1792,    28672, 0x0e2b1e6a
+0,      87808,      87808,     1792,    28672, 0xbaee59ab
+0,      89600,      89600,     1792,    28672, 0xb3a4d79a
+0,      91392,      91392,     1792,    28672, 0x27c8c10b
+0,      93184,      93184,     1792,    28672, 0xac80c8b6
+0,      94976,      94976,     1792,    28672, 0x81fdab74
+0,      96768,      96768,     1792,    28672, 0x61616f5b
+0,      98560,      98560,     1792,    28672, 0x52fc6929
+0,     100352,     100352,     1792,    28672, 0x00b3c31f
+0,     102144,     102144,     1792,    28672, 0x42167448
+0,     103936,     103936,     1792,    28672, 0x837e83b7
+0,     105728,     105728,     1792,    28672, 0x85b44868
+0,     107520,     107520,     1792,    28672, 0xadff8622
+0,     109312,     109312,     1792,    28672, 0x431a4e70
+0,     111104,     111104,     1792,    28672, 0x741610e5
+0,     112896,     112896,     1792,    28672, 0x6d028788
+0,     114688,     114688,     1792,    28672, 0xdf965bf7
+0,     116480,     116480,     1792,    28672, 0xaddfb6af
+0,     118272,     118272,     1792,    28672, 0xcb92def7
+0,     120064,     120064,     1792,    28672, 0xd1554d02
+0,     121856,     121856,     1792,    28672, 0x73f4c559
+0,     123648,     123648,     1792,    28672, 0x6f21f1cf
+0,     125440,     125440,     1792,    28672, 0x4db4b98a
+0,     127232,     127232,     1792,    28672, 0x5421dd30
+0,     129024,     129024,     1792,    28672, 0x115c79dc
+0,     130816,     130816,     1792,    28672, 0x8ea20a47
+0,     132608,     132608,     1792,    28672, 0x5cc7442b
+0,     134400,     134400,     1792,    28672, 0x1a56b340
+0,     136192,     136192,     1792,    28672, 0x824b4c80
+0,     137984,     137984,     1792,    28672, 0x1f836508
+0,     139776,     139776,     1792,    28672, 0xf858b763
+0,     141568,     141568,     1792,    28672, 0x06b8e360
+0,     143360,     143360,     1792,    28672, 0xec69151b
+0,     145152,     145152,     1792,    28672, 0x85393407
+0,     146944,     146944,     1792,    28672, 0x67185428
+0,     148736,     148736,     1792,    28672, 0xc949590d
+0,     150528,     150528,     1792,    28672, 0xb51a60c5
+0,     152320,     152320,     1792,    28672, 0x16d97145
+0,     154112,     154112,     1792,    28672, 0xf2e424e8
+0,     155904,     155904,     1792,    28672, 0x966df23d
+0,     157696,     157696,     1792,    28672, 0x4b76484e
+0,     159488,     159488,     1792,    28672, 0x09123aee
+0,     161280,     161280,     1792,    28672, 0xf982c429
+0,     163072,     163072,     1792,    28672, 0x402909fd
+0,     164864,     164864,     1792,    28672, 0xf660b6e7
+0,     166656,     166656,     1792,    28672, 0x4ff88563
+0,     168448,     168448,     1792,    28672, 0xe8390c49
+0,     170240,     170240,     1792,    28672, 0x29c5f5e2
+0,     172032,     172032,     1792,    28672, 0x1728b69c
+0,     173824,     173824,     1792,    28672, 0xb44e116d
+0,     175616,     175616,     1792,    28672, 0x0eef525f
+0,     177408,     177408,     1792,    28672, 0xaaed3647
+0,     179200,     179200,     1792,    28672, 0x5142208e
+0,     180992,     180992,     1792,    28672, 0x0e508d98
+0,     182784,     182784,     1792,    28672, 0xa53bacea
+0,     184576,     184576,     1792,    28672, 0xe0458b56
+0,     186368,     186368,     1792,    28672, 0xf9d854b3
+0,     188160,     188160,     1792,    28672, 0x5cae832d
+0,     189952,     189952,     1792,    28672, 0x6622952f
+0,     191744,     191744,     1792,    28672, 0x6b123bb3
+0,     193536,     193536,     1792,    28672, 0x947bc6a8
+0,     195328,     195328,     1792,    28672, 0x1d49e016
+0,     197120,     197120,     1792,    28672, 0xd7166c77
+0,     198912,     198912,     1792,    28672, 0x079623b0
+0,     200704,     200704,     1792,    28672, 0x00bb8bae
+0,     202496,     202496,     1792,    28672, 0x14f639f0
+0,     204288,     204288,     1792,    28672, 0xeb469a8d
+0,     206080,     206080,     1792,    28672, 0xf6702b9d
+0,     207872,     207872,     1792,    28672, 0x4996a3b4
+0,     209664,     209664,     1792,    28672, 0x8041d137
+0,     211456,     211456,     1792,    28672, 0x2e44983c
+0,     213248,     213248,     1792,    28672, 0x2065a2c9
+0,     215040,     215040,     1792,    28672, 0x90be25e7
+0,     216832,     216832,     1792,    28672, 0x5d31a6c4
+0,     218624,     218624,     1792,    28672, 0x6b6e452c
+0,     220416,     220416,     1792,    28672, 0xc836bd59
+0,     222208,     222208,     1792,    28672, 0x13575340
+0,     224000,     224000,     1792,    28672, 0x0f42a7cb
+0,     225792,     225792,     1792,    28672, 0xba0bbb76
+0,     227584,     227584,     1792,    28672, 0x7d251bd6
+0,     229376,     229376,     1792,    28672, 0x4c0d7d4e
+0,     231168,     231168,     1792,    28672, 0x9f812c3d
+0,     232960,     232960,     1792,    28672, 0xf48e7e24
+0,     234752,     234752,     1792,    28672, 0x89cc47c4
+0,     236544,     236544,     1792,    28672, 0xbe6c913a
+0,     238336,     238336,     1792,    28672, 0x3783546e
+0,     240128,     240128,     1792,    28672, 0xd73d62d2
+0,     241920,     241920,     1792,    28672, 0x8473ffd1
+0,     243712,     243712,     1792,    28672, 0x353ae430
+0,     245504,     245504,     1792,    28672, 0xbc74d0d6
+0,     247296,     247296,     1792,    28672, 0x67dd42ba
+0,     249088,     249088,     1792,    28672, 0x32c28b0f
+0,     250880,     250880,     1792,    28672, 0x6798ba73
+0,     252672,     252672,     1792,    28672, 0x2342e18e
+0,     254464,     254464,     1792,    28672, 0x93c30e5b
+0,     256256,     256256,     1792,    28672, 0x521b4c34
+0,     258048,     258048,     1792,    28672, 0x4ff173fb
+0,     259840,     259840,     1792,    28672, 0x144cd84d
+0,     261632,     261632,     1792,    28672, 0x0b79131a
+0,     263424,     263424,     1792,    28672, 0x8136d27a
+0,     265216,     265216,     1792,    28672, 0xcc62b7d5
+0,     267008,     267008,     1792,    28672, 0xbdab12f7
+0,     268800,     268800,     1792,    28672, 0x71455124
+0,     270592,     270592,     1792,    28672, 0x0d05b187
+0,     272384,     272384,     1792,    28672, 0xa734c089
+0,     274176,     274176,     1792,    28672, 0xb18695ca
+0,     275968,     275968,     1792,    28672, 0x9401890d
+0,     277760,     277760,     1792,    28672, 0x0d719e68
+0,     279552,     279552,     1792,    28672, 0x0415a6aa
+0,     281344,     281344,     1792,    28672, 0x23cfd606
+0,     283136,     283136,     1792,    28672, 0x37fd4513
+0,     284928,     284928,     1792,    28672, 0xcbcc645c
+0,     286720,     286720,     1792,    28672, 0x478d37fe
+0,     288512,     288512,     1792,    28672, 0xb354ea3b
+0,     290304,     290304,     1792,    28672, 0x8d769c69
+0,     292096,     292096,     1792,    28672, 0x60068eed
+0,     293888,     293888,     1792,    28672, 0x1fd254b4
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.