1
0
mirror of https://git.ffmpeg.org/ffmpeg.git synced 2026-10-24 02:09:03 +03:00

avutil/samplefmt: add AV_SAMPLE_FMT_DSD

DSD (Direct Stream Digital) is one-bit sigma-delta modulated audio,
found on Super Audio CDs and in DSF/DSDIFF files. libavcodec has
several decoders producing it internally (dsd_*, dst, wavpack DSD),
each converting to float PCM as part of decoding, which makes the
bitstream itself inaccessible to API users.

Add a dedicated sample format so raw DSD can be carried through the
pipeline, e.g. for bit-perfect pass-through to DSD capable DACs.

The format has no planar variant, altform references itself.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
This commit is contained in:
Kacper Michajłow
2026-08-11 11:24:12 +02:00
parent 2bdbf5c67e
commit 655dc1af76
5 changed files with 27 additions and 4 deletions

View File

@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2026-06-23.
API changes, most recent first:
2026-09-xx - xxxxxxxxxx - lavu 61.7.100 - samplefmt.h
Add AV_SAMPLE_FMT_DSD.
2026-09-01 - xxxxxxxxxx - lavc 63.10.100 - avcodec.h
Add AVCodecContext.skip_pred.

View File

@@ -46,6 +46,7 @@ static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = {
[AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 },
[AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT },
[AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL },
[AV_SAMPLE_FMT_DSD] = { .name = "dsd", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_DSD },
};
const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
@@ -250,9 +251,14 @@ int av_samples_set_silence(uint8_t * const *audio_data, int offset, int nb_sampl
int planes = planar ? nb_channels : 1;
int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels);
int data_size = nb_samples * block_align;
int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 ||
sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00;
int i;
int fill_char, i;
if (sample_fmt == AV_SAMPLE_FMT_U8 || sample_fmt == AV_SAMPLE_FMT_U8P)
fill_char = 0x80;
else if (sample_fmt == AV_SAMPLE_FMT_DSD)
fill_char = 0x69; // only ultrasonic tones, filtered out on playback
else
fill_char = 0x00;
offset *= block_align;

View File

@@ -68,6 +68,14 @@ enum AVSampleFormat {
AV_SAMPLE_FMT_S64, ///< signed 64 bits
AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar
/**
* DSD (Direct Stream Digital) bitstream, interleaved. Each byte
* carries 8 consecutive one-bit samples, most significant bit first.
* One sample in the API sense is one such byte, so the sample rate
* is 1/8th of the DSD bit rate.
*/
AV_SAMPLE_FMT_DSD,
AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically
};

View File

@@ -79,7 +79,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 61
#define LIBAVUTIL_VERSION_MINOR 6
#define LIBAVUTIL_VERSION_MINOR 7
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

View File

@@ -11,6 +11,7 @@ Testing name/format round-trip
9: name=dblp roundtrip=OK
10: name=s64 roundtrip=OK
11: name=s64p roundtrip=OK
12: name=dsd roundtrip=OK
NONE name: (null)
NB name: (null)
unknown: -1
@@ -28,6 +29,7 @@ fltp: 4
dblp: 8
s64: 8
s64p: 8
dsd: 1
NONE: 0
Testing av_sample_fmt_is_planar()
@@ -43,6 +45,7 @@ fltp: 1
dblp: 1
s64: 0
s64p: 1
dsd: 0
NONE: 0
Testing packed/planar conversions
@@ -58,6 +61,7 @@ fltp: packed=flt planar=fltp
dblp: packed=dbl planar=dblp
s64: packed=s64 planar=s64p
s64p: packed=s64 planar=s64p
dsd: packed=dsd planar=dsd
Testing av_get_alt_sample_fmt()
u8: alt_packed=u8 alt_planar=u8p
@@ -72,6 +76,7 @@ fltp: alt_packed=flt alt_planar=fltp
dblp: alt_packed=dbl alt_planar=dblp
s64: alt_packed=s64 alt_planar=s64p
s64p: alt_packed=s64 alt_planar=s64p
dsd: alt_packed=dsd alt_planar=dsd
Testing av_get_sample_fmt_string()
header: name depth
@@ -87,6 +92,7 @@ fltp 32
dblp 64
s64 64
s64p 64
dsd 8
Testing av_samples_get_buffer_size()
2ch 1024smp s16: 4096