summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-11-10 15:02:25 +0100
committerwm4 <wm4@nowhere>2019-11-10 15:13:25 +0100
commit4667b3a18263b46846ed37dabc70d27732ec6f7a (patch)
tree4ce04016ee946811a31884ecdefd46a9c1025d57 /audio
parent35de8ea0a8a665321e814efe5e59b7dd6c237cd1 (diff)
downloadmpv-4667b3a18263b46846ed37dabc70d27732ec6f7a.tar.bz2
mpv-4667b3a18263b46846ed37dabc70d27732ec6f7a.tar.xz
audio: work around ffmpeg being a piece of shit
The "amultiply" filter crashes in AVX mode on unaligned access if an audio pointer is unaligned (on 32 or 64 bytes I assume). A requirement that audio data needs to be aligned isn't documented anywhere. In our case, the data is still sample- and channel-aligned, which is completely sane. Sure, you can imagine optimizations which make some algorithms even faster by requiring higher alignment. But, and this is a big but, you shouldn't crash api users because you just invented a new undocumented requirement. And even more importantly, your user-crashing optimization won't matter because it's just a trivial algorithm working on audio. You don't need to pretend to be an optimization devil, and nobody will give you a prize for this. But no, lets random make API users crash (and then probably blame them for it!) for something that wouldn't matter at all. Not to mention that they do "document" some requirements on _video_ data, yet their vf_crop probably can still produce unaligned video pointers. Oh how hilarious that the same documentation also talks about libswscale alignment requirements. (This is weird because libswscale is just one of many, many things which consume video data. Also did you know that zimg, written in C++ and using intrinsics, i.e. the antithesis to FFmpeg development, is much faster than libswscale, easier to use, and produces more correct results, even if you ignore that libswscale flat out doesn't support some very important features?) Fucking tired of this bullshit. Can't wait until someone comes up with a better framework than this... (well let's not write this out). Fix this by copying instead of adjusting the start pointer when skipping samples. This makes general operations slower just to fix interoperating with a single filter. Thank you for your "optimization", FFmpeg. Go die in a fire. Didn't check whether this is correct. It probably is? If the frame needs to be copied (due to COW), and memory allocation fails, it just silently (or audibly lol) doesn't skip samples, because a never-fail function can suddenly fail. Well, who cares. Fixes: #7141
Diffstat (limited to 'audio')
-rw-r--r--audio/aframe.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/audio/aframe.c b/audio/aframe.c
index bc43bc98d2..118962f35b 100644
--- a/audio/aframe.c
+++ b/audio/aframe.c
@@ -410,10 +410,16 @@ void mp_aframe_skip_samples(struct mp_aframe *f, int samples)
{
assert(samples >= 0 && samples <= mp_aframe_get_size(f));
+ if (av_frame_make_writable(f->av_frame) < 0)
+ return; // go complain to ffmpeg
+
int num_planes = mp_aframe_get_planes(f);
size_t sstride = mp_aframe_get_sstride(f);
- for (int n = 0; n < num_planes; n++)
- f->av_frame->extended_data[n] += samples * sstride;
+ for (int n = 0; n < num_planes; n++) {
+ memmove(f->av_frame->extended_data[n],
+ f->av_frame->extended_data[n] + samples * sstride,
+ (f->av_frame->nb_samples - samples) * sstride);
+ }
f->av_frame->nb_samples -= samples;