diff options
author | Niklas Haas <git@haasn.dev> | 2022-06-16 03:12:44 +0200 |
---|---|---|
committer | Niklas Haas <github-daiK1o@haasn.dev> | 2022-09-02 01:27:31 +0200 |
commit | 9be52e5dd8d5b4ae56dfd68430191c818f646beb (patch) | |
tree | f341b8121532e07205c4da16a9d4312c4669aeda /audio/aframe.c | |
parent | 04062b6f897960938649047c3e2c5ceb08bae295 (diff) | |
download | mpv-9be52e5dd8d5b4ae56dfd68430191c818f646beb.tar.bz2 mpv-9be52e5dd8d5b4ae56dfd68430191c818f646beb.tar.xz |
ad_lavc: strip non-normalized floats
`opus` codec likes returning denormalized floats in some cases, causing
wacky issues.
Fixes #10290
Diffstat (limited to 'audio/aframe.c')
-rw-r--r-- | audio/aframe.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/audio/aframe.c b/audio/aframe.c index 6781bb7b55..9b0827f64c 100644 --- a/audio/aframe.c +++ b/audio/aframe.c @@ -466,6 +466,37 @@ void mp_aframe_skip_samples(struct mp_aframe *f, int samples) f->pts += samples / mp_aframe_get_effective_rate(f); } +// sanitize a floating point sample value +#define sanitizef(f) do { \ + if (!isnormal(f)) \ + (f) = 0; \ +} while (0) + +void mp_aframe_sanitize_float(struct mp_aframe *mpa) +{ + int format = af_fmt_from_planar(mp_aframe_get_format(mpa)); + if (format != AF_FORMAT_FLOAT && format != AF_FORMAT_DOUBLE) + return; + int num_planes = mp_aframe_get_planes(mpa); + uint8_t **planes = mp_aframe_get_data_rw(mpa); + if (!planes) + return; + for (int p = 0; p < num_planes; p++) { + void *ptr = planes[p]; + int total = mp_aframe_get_total_plane_samples(mpa); + switch (format) { + case AF_FORMAT_FLOAT: + for (int s = 0; s < total; s++) + sanitizef(((float *)ptr)[s]); + break; + case AF_FORMAT_DOUBLE: + for (int s = 0; s < total; s++) + sanitizef(((double *)ptr)[s]); + break; + } + } +} + // Return the timestamp of the sample just after the end of this frame. double mp_aframe_end_pts(struct mp_aframe *f) { |