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);
|
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.
|
// Return the timestamp of the sample just after the end of this frame.
|
||||||
double mp_aframe_end_pts(struct mp_aframe *f)
|
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))
|
#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_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_end_pts(struct mp_aframe *f);
|
||||||
double mp_aframe_duration(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);
|
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;
|
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) {
|
if (mp_aframe_get_size(mpframe) > 0) {
|
||||||
*out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
|
*out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue