Hi,
This series adds support for the Olympus Digital Speech Standard Pro
(DS2) audio format, used by Olympus DS-, DM-, and DPM-series dictation
recorders. It is the successor to the DSS format already supported in
FFmpeg (libavcodec/dss_sp.c and libavformat/dss.c, Oleksij Rempel,
2014). The two formats share a similar 0x600 header layout but use
different codebooks and frame structures; this series is complementary
to the existing DSS support, and the demuxer only accepts the DS2 magic
(\x03ds2), so DSS files keep routing to the existing dss_sp path.
Trac ticket #6091, open since October 2017, is closed by this series.
1/2 avcodec, avformat: add Olympus DS2 decoder and demuxer
The CELP decoder (both modes: SP 12 kHz, QP 16 kHz) and the .ds2
container demuxer. Codec by Patrick Domack, implemented from a
specification reverse-engineered from the Olympus DLLs by Kieran
Hirpara.
2/2 avformat/ds2: re-anchor QP frames across segment boundaries
The QP demuxer re-anchors each block's frames at payload offset
2*byte1 - 6 so paused / voice-activated recordings decode
correctly; a flat read desyncs from the first pause onward. Adds
FATE coverage, including a paused-recording regression vector.
Changes since v2 (single patch, 2026-05-26,
<[email protected]>)
----------------------------------------------
- Split into a 2-patch series. 1/2 is the v2 decoder + demuxer,
unchanged except for an ASCII cleanup (U+00D7 '×' -> 'x' in two
comment lines, which a reviewer had flagged in advance).
- New 2/2 fixes the QP demuxer for paused recordings. v2 read the QP
block stream as a flat concatenation, which is correct only on
gap-free audio; real dictation pauses at segment boundaries, and the
v2 demuxer desynced there to end-of-file. Each QP block re-anchors
its frames at payload offset 2*byte1 - 6 (empty blocks being the
zero-fresh-frames special case); at a re-sync block the leading bytes
are an orphaned straddle tail and the partial frame in flight is
stale. frame_count over-counts on these blocks (observed 19), so the
block end bounds framing, not the count. The rule was
reverse-engineered from, and confirmed byte-for-byte against, the
Olympus DssParser.dll captured at runtime.
- Adds FATE: fate-ds2-qp (continuous) and fate-ds2-qp-paused. The
latter contains a real re-sync block and guards the 2/2 fix - the v2
demuxer fails it while the fixed demuxer passes.
FATE samples (for samples.ffmpeg.org/A-codecs/DS2/)
---------------------------------------------------
- sample-qp.ds2 (continuous QP, 37 s, 129 KiB) - a public vendor test
file from dictate.com.au, produced specifically as a codec-testing
artefact. Real audio, no client content. If maintainers want an
explicit CC0 grant on file we will obtain one from the host before
upload.
- paused-qp.ds2 (paused QP, 21 KiB) - a purpose-built regression
vector. The block framing that triggers the re-sync path is kept
intact, but every audio-payload and metadata byte has been replaced,
so the file carries no speech and no identifying metadata.
Contributed under CC0 by the submitter; no third-party licensing
question.
Authorship and licensing
-------------------------
The codec specification was reverse-engineered from the Olympus DLLs
(DssDecoder.dll, dss32.dll) via Ghidra by Kieran Hirpara
(https://github.com/hirparak/dss-codec, MIT, 2026), with byte-for-byte
verification against the official Olympus DirectShow filter. The C
decoder in 1/2 is by Patrick Domack, implemented from the trac #6091
specification text; its numerical quantization tables are shared with
Hirpara's reference implementation. Both the algorithm and the tables
are MIT-licensed. Patrick relicensed his contribution under MIT /
public-domain terms explicitly for upstream FFmpeg merge:
https://github.com/hirparak/dss-codec/issues/1
Patrick has explicitly opted out of ffmpeg-devel interaction but remains
available for codec-internals questions via the issue thread above. I
handle the mailing-list traffic and am the DCO signer on both patches.
The QP re-anchoring in 2/2 and the FATE preparation were done by the
submitter; the full reverse-engineering write-up is public at
https://github.com/Guillain-RDCDE/DS2-Anywhere (docs/06, docs/07).
The series applies cleanly on master (HEAD c2312363, 2026-07-20),
builds, and both FATE tests pass.
Thanks,
Guillain
Guillain d'Erceville (1):
avformat/ds2: re-anchor QP frames across segment boundaries
Patrick Domack (1):
avcodec, avformat: add Olympus DS2 decoder and demuxer
doc/general_contents.texi | 4 +
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 1 +
libavcodec/codec_desc.c | 7 +
libavcodec/codec_id.h | 1 +
libavcodec/ds2.c | 986 +++++++++++++++
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/ds2.c | 535 ++++++++
tests/fate/audio.mak | 6 +
tests/ref/fate/ds2-qp | 2315 ++++++++++++++++++++++++++++++++++
tests/ref/fate/ds2-qp-paused | 365 ++++++
12 files changed, 4223 insertions(+)
create mode 100644 libavcodec/ds2.c
create mode 100644 libavformat/ds2.c
create mode 100644 tests/ref/fate/ds2-qp
create mode 100644 tests/ref/fate/ds2-qp-paused
--
2.43.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]