mirror of https://github.com/mpv-player/mpv
ad_lavc: strip non-normalized floats
`opus` codec likes returning denormalized floats in some cases, causing wacky issues. Fixes #10290
This commit is contained in:
parent
04062b6f89
commit
9be52e5dd8
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,7 @@ char *mp_aframe_format_str_buf(char *buf, size_t buf_size, struct mp_aframe *fmt
|
|||
#define mp_aframe_format_str(fmt) mp_aframe_format_str_buf((char[32]){0}, 32, (fmt))
|
||||
|
||||
void mp_aframe_skip_samples(struct mp_aframe *f, int samples);
|
||||
void mp_aframe_sanitize_float(struct mp_aframe *f);
|
||||
double mp_aframe_end_pts(struct mp_aframe *f);
|
||||
double mp_aframe_duration(struct mp_aframe *f);
|
||||
void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end);
|
||||
|
|
|
@ -260,6 +260,9 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out)
|
|||
priv->trim_samples -= trim;
|
||||
}
|
||||
|
||||
// Strip possibly bogus float values like Infinity, NaN, denormalized
|
||||
mp_aframe_sanitize_float(mpframe);
|
||||
|
||||
if (mp_aframe_get_size(mpframe) > 0) {
|
||||
*out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue