This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 2c7e3ed47ac26f3b6becb14ffddfa9ccf90d82ff
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Tue Aug 11 12:14:55 2026 +0200
Commit:     Kacper Michajłow <[email protected]>
CommitDate: Sun Sep 6 00:48:25 2026 +0200

    avcodec/dstdec: use libswresample for the PCM output
    
    Decode into packed DSD bytes unconditionally and convert to the default
    AV_SAMPLE_FMT_FLT output with libswresample instead of the local
    dsd2pcm copy.
    
    If libswresample is disabled, the PCM output is not offered and the
    decoder outputs only AV_SAMPLE_FMT_DSD.
    
    Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavcodec/dstdec.c  | 89 +++++++++++++++++++++++++++++++++-------------------
 tests/fate/audio.mak |  2 +-
 2 files changed, 57 insertions(+), 34 deletions(-)

diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c
index 7551453726..58feb5a593 100644
--- a/libavcodec/dstdec.c
+++ b/libavcodec/dstdec.c
@@ -25,7 +25,10 @@
  * ISO/IEC 14496-3 Part 3 Subpart 10: Technical description of lossless coding 
of oversampled audio
  */
 
+#include "config.h"
+
 #include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/reverse.h"
 #include "codec_internal.h"
@@ -35,6 +38,10 @@
 #include "golomb.h"
 #include "dsd.h"
 
+#if CONFIG_SWRESAMPLE
+#include "libswresample/swresample.h"
+#endif
+
 #define DST_MAX_CHANNELS 6
 #define DST_MAX_ELEMENTS (2 * DST_MAX_CHANNELS)
 
@@ -73,14 +80,15 @@ typedef struct DSTContext {
     Table fsets, probs;
     DECLARE_ALIGNED(16, uint8_t, status)[DST_MAX_CHANNELS][16];
     DECLARE_ALIGNED(16, int16_t, filter)[DST_MAX_ELEMENTS][16][256];
-    DSDContext dsdctx[DST_MAX_CHANNELS];
+#if CONFIG_SWRESAMPLE
+    struct SwrContext *swr;
+    uint8_t *scratch;
+    unsigned scratch_size;
+#endif
 } DSTContext;
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    DSTContext *s = avctx->priv_data;
-    int i;
-
     if (avctx->ch_layout.nb_channels > DST_MAX_CHANNELS) {
         avpriv_request_sample(avctx, "Channel count %d", 
avctx->ch_layout.nb_channels);
         return AVERROR_PATCHWELCOME;
@@ -96,14 +104,24 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return AVERROR_PATCHWELCOME;
     }
 
-    avctx->sample_fmt = avctx->request_sample_fmt == AV_SAMPLE_FMT_DSD
-                        ? AV_SAMPLE_FMT_DSD : AV_SAMPLE_FMT_FLT;
+    avctx->sample_fmt = AV_SAMPLE_FMT_DSD;
 
-    for (i = 0; i < avctx->ch_layout.nb_channels; i++)
-        memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf));
+#if CONFIG_SWRESAMPLE
+    if (avctx->request_sample_fmt != AV_SAMPLE_FMT_DSD)
+        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+#endif
 
-    ff_init_dsd_data();
+    return 0;
+}
 
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+#if CONFIG_SWRESAMPLE
+    DSTContext *s = avctx->priv_data;
+
+    swr_free(&s->swr);
+    av_freep(&s->scratch);
+#endif
     return 0;
 }
 
@@ -249,12 +267,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
     unsigned i, ch, same_map, dst_x_bit;
     unsigned half_prob[DST_MAX_CHANNELS];
     const int channels = avctx->ch_layout.nb_channels;
-    const int bps = avctx->sample_fmt == AV_SAMPLE_FMT_DSD ? 1 : 4;
     DSTContext *s = avctx->priv_data;
     GetBitContext *gb = &s->gb;
     ArithCoder *ac = &s->ac;
     uint8_t *dsd;
-    float *pcm;
     int ret;
 
     if (avpkt->size <= 1)
@@ -264,7 +280,19 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
     dsd = frame->data[0];
-    pcm = (float *)frame->data[0];
+
+#if CONFIG_SWRESAMPLE
+    if (avctx->sample_fmt != AV_SAMPLE_FMT_DSD) {
+        if (!s->swr && (ret = ff_dsd_to_pcm_init(avctx, &s->swr)) < 0)
+            return ret;
+
+        av_fast_malloc(&s->scratch, &s->scratch_size,
+                       frame->nb_samples * channels);
+        if (!s->scratch)
+            return AVERROR(ENOMEM);
+        dsd = s->scratch;
+    }
+#endif
 
     if ((ret = init_get_bits8(gb, avpkt->data, avpkt->size)) < 0)
         return ret;
@@ -275,18 +303,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
         skip_bits1(gb);
         if (get_bits(gb, 6))
             return AVERROR_INVALIDDATA;
-        if (bps == 1) {
-            memcpy(dsd, avpkt->data + 1, n);
-            memset(dsd + n, 0x69, total - n);
-        } else {
-            // DSD bytes are stored in every 4th byte, as expected by the
-            // in-place DSD to PCM conversion. Pad short frames with silence.
-            for (i = 0; i < n; i++)
-                dsd[i * 4] = avpkt->data[1 + i];
-            for (; i < total; i++)
-                dsd[i * 4] = 0x69;
-        }
-        goto dsd;
+        // pad short frames with silence
+        memcpy(dsd, avpkt->data + 1, n);
+        memset(dsd + n, 0x69, total - n);
+        goto done;
     }
 
     /* Segmentation (10.4, 10.5, 10.6) */
@@ -350,7 +370,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
         return ret;
 
     memset(s->status, 0xAA, sizeof(s->status));
-    memset(dsd, 0, frame->nb_samples * bps * channels);
+    memset(dsd, 0, frame->nb_samples * channels);
 
     ac_get(ac, gb, prob_dst_x_bit(s->fsets.coeff[0][0]), &dst_x_bit);
 
@@ -378,21 +398,23 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
 
             ac_get(ac, gb, prob, &residual);
             v = ((predict >> 15) ^ residual) & 1;
-            dsd[((i >> 3) * channels + ch) * bps] |= v << (7 - (i & 0x7 ));
+            dsd[(i >> 3) * channels + ch] |= v << (7 - (i & 0x7 ));
 
             AV_WL64A(status + 8, (AV_RL64A(status + 8) << 1) | 
((AV_RL64A(status) >> 63) & 1));
             AV_WL64A(status, (AV_RL64A(status) << 1) | v);
         }
     }
 
-dsd:
-    if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
-        for (i = 0; i < channels; i++) {
-            ff_dsd2pcm_translate(&s->dsdctx[i], frame->nb_samples, 0,
-                                 frame->data[0] + i * 4,
-                                 channels * 4, pcm + i, channels);
-        }
+done:
+#if CONFIG_SWRESAMPLE
+    if (s->swr) {
+        ret = swr_convert(s->swr, &frame->data[0], frame->nb_samples,
+                          (const uint8_t *const []){ s->scratch },
+                          frame->nb_samples);
+        if (ret != frame->nb_samples)
+            return ret < 0 ? ret : AVERROR_BUG;
     }
+#endif
 
     *got_frame_ptr = 1;
 
@@ -406,6 +428,7 @@ const FFCodec ff_dst_decoder = {
     .p.id           = AV_CODEC_ID_DST,
     .priv_data_size = sizeof(DSTContext),
     .init           = decode_init,
+    .close          = decode_close,
     FF_CODEC_DECODE_CB(decode_frame),
     .p.capabilities = AV_CODEC_CAP_DR1,
 };
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index c21578947a..c14365942f 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -37,7 +37,7 @@ fate-dss-lp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/lp.dss 
-frames 30 -af aresa
 FATE_SAMPLES_AUDIO-$(call FRAMECRC, DSS, DSS_SP) += fate-dss-sp
 fate-dss-sp: CMD = framecrc -i $(TARGET_SAMPLES)/dss/sp.dss -frames 30
 
-FATE_SAMPLES_AUDIO-$(call PCM, DSF, DST, ARESAMPLE_FILTER) += fate-dsf-dst
+FATE_SAMPLES_AUDIO-$(call PCM, DSF, DST, ARESAMPLE_FILTER SWRESAMPLE) += 
fate-dsf-dst
 fate-dsf-dst: CMD = pcm -i $(TARGET_SAMPLES)/dst/dst-64fs44-2ch.dff
 fate-dsf-dst: CMP = oneoff
 fate-dsf-dst: REF = $(SAMPLES)/dst/dst-64fs44-2ch.pcm

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to