From 9b536630f1362db1d40bd187f2d077b0de9ad6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 19 Jan 2025 14:29:33 +0000 Subject: [PATCH] avaudenc: fix crash in avenc_ac3 if input buffers are insufficiently aligned Memcpy if needed to ensure sufficient alignment, as some SIMD instructions might require more alignment than we provide by default (e.g. vmovaps requires 32 bytes, but gstreamer uses malloc alignment by default which is 16 bytes here on x86_64). And in any case buffers might be trimmed, so the only alignment we can expect is sample frame alignment which might be even smaller than 16 bytes. Part-of: --- subprojects/gst-libav/ext/libav/gstavaudenc.c | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-libav/ext/libav/gstavaudenc.c b/subprojects/gst-libav/ext/libav/gstavaudenc.c index 87b8b6ceaa..0a6da7be0b 100644 --- a/subprojects/gst-libav/ext/libav/gstavaudenc.c +++ b/subprojects/gst-libav/ext/libav/gstavaudenc.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -48,6 +49,8 @@ enum PROP_CFG_BASE, }; +GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE); + static void gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass); static void gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass); static void gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc); @@ -150,6 +153,8 @@ gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass) GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_set_format); gstaudioencoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_handle_frame); + + GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE"); } static void @@ -517,7 +522,27 @@ gst_ffmpegaudenc_send_frame (GstFFMpegAudEnc * ffmpegaudenc, GstBuffer * buffer) gst_buffer_unref (buffer); buffer_info->buffer = NULL; } else { - frame->data[0] = audio_in; + // This is the worst case requirement. It might be possible to query the + // specific alignment requirement for the encoder and transforms in use. + size_t min_align = av_cpu_max_align (); + + if (((size_t) audio_in & (min_align - 1)) == 0) { + frame->data[0] = audio_in; + } else { + GST_CAT_TRACE_OBJECT (GST_CAT_PERFORMANCE, ffmpegaudenc, + "Copying input data at %p to ensure minimum alignment of %zu bytes", + audio_in, min_align); + + buffer_info->ext_data = av_memdup (audio_in, in_size); + frame->data[0] = buffer_info->ext_data; + + // Todo: could probably avoid the buffer_info helper struct allocation + // in this case (and above too) + gst_buffer_unmap (buffer, &buffer_info->map); + gst_buffer_unref (buffer); + buffer_info->buffer = NULL; + } + frame->extended_data = frame->data; frame->linesize[0] = in_size; frame->nb_samples = nsamples = in_size / info->bpf;