Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DOCS/interface-changes/audio-spdif-dsd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add `dsd` choice to `--audio-spdif` for DSD-over-PCM (DoP) passthrough
15 changes: 10 additions & 5 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2121,11 +2121,16 @@ Audio
List of codecs for which compressed audio passthrough should be used. This
works for both classic S/PDIF and HDMI.

Possible codecs are ``ac3``, ``dts``, ``dts-hd``, ``eac3``, ``truehd``.
Multiple codecs can be specified by separating them with ``,``. ``dts``
refers to low bitrate DTS core, while ``dts-hd`` refers to DTS MA (receiver
and OS support varies). If both ``dts`` and ``dts-hd`` are specified, it
behaves equivalent to specifying ``dts-hd`` only.
Possible codecs are ``ac3``, ``dts``, ``dts-hd``, ``eac3``, ``truehd``,
``dsd``. Multiple codecs can be specified by separating them with ``,``.
``dts`` refers to low bitrate DTS core, while ``dts-hd`` refers to DTS MA
(receiver and OS support varies). If both ``dts`` and ``dts-hd`` are
specified, it behaves equivalent to specifying ``dts-hd`` only.

``dsd`` enables bit-perfect passthrough of DSD audio, requires an audio
output with exclusive device access (currently ``wasapi``) and a DAC that
accepts DoP at the resulting PCM rate (176.4 kHz for DSD64, 352.8 kHz for
DSD128, and so on).

In earlier mpv versions you could use ``--ad`` to force the spdif wrapper.
This does not work anymore.
Expand Down
14 changes: 8 additions & 6 deletions audio/aframe.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ struct mp_aframe {
AVFrame *av_frame;
// We support channel layouts different from AVFrame channel masks
struct mp_chmap chmap;
// We support spdif formats, which are allocated as AV_SAMPLE_FMT_S16.
// We support bitstream formats, which are allocated as fake integer PCM
// of matching sample size.
int format;
double pts;
double speed;
Expand Down Expand Up @@ -306,9 +307,10 @@ bool mp_aframe_set_format(struct mp_aframe *frame, int format)
return false;
enum AVSampleFormat av_format = af_to_avformat(format);
if (av_format == AV_SAMPLE_FMT_NONE && format) {
if (!af_fmt_is_spdif(format))
if (af_fmt_is_pcm(format))
return false;
av_format = AV_SAMPLE_FMT_S16;
av_format = af_fmt_to_bytes(format) == 4 ? AV_SAMPLE_FMT_S32
: AV_SAMPLE_FMT_S16;
}
frame->format = format;
frame->av_frame->format = av_format;
Expand Down Expand Up @@ -488,7 +490,7 @@ double mp_aframe_duration(struct mp_aframe *f)

// Clip the given frame to the given timestamp range. Adjusts the frame size
// and timestamp.
// Refuses to change spdif frames.
// Refuses to change bitstream (spdif/DoP) frames.
void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end)
{
double f_end = mp_aframe_end_pts(f);
Expand All @@ -500,7 +502,7 @@ void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end)
if (f->pts >= end) {
f->av_frame->nb_samples = 0;
} else {
if (af_fmt_is_spdif(mp_aframe_get_format(f)))
if (!af_fmt_is_pcm(mp_aframe_get_format(f)))
return;
int new = (end - f->pts) * rate;
f->av_frame->nb_samples = MPCLAMP(new, 0, f->av_frame->nb_samples);
Expand All @@ -513,7 +515,7 @@ void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end)
f->av_frame->nb_samples = 0;
f->pts = f_end;
} else {
if (af_fmt_is_spdif(mp_aframe_get_format(f)))
if (!af_fmt_is_pcm(mp_aframe_get_format(f)))
return;
int skip = (start - f->pts) * rate;
skip = MPCLAMP(skip, 0, f->av_frame->nb_samples);
Expand Down
Loading
Loading