This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit bdbb580d9c7b4979fa6c0b3819296dc70635713a Author: Ivan Grigorev <[email protected]> AuthorDate: Wed Jun 10 17:42:43 2026 +0200 Commit: michaelni <[email protected]> CommitDate: Sun Jun 14 15:34:43 2026 +0000 swresample/tests: add resample realloc regression test Add a regression test exercising the swr_convert(N) -> swr_convert(2N) edge case: the second call reuses the internal preout buffer at full capacity, with no trailing slack from swri_realloc_audio()'s amortized doubling. internal_sample_fmt is forced to S16P to reach the int16 SIMD resample path, where ff_resample_common_int16_sse2 overruns its destination by 2 bytes on the last iteration. Without a resampler fix this test fails under valgrind/ASAN with a heap-buffer-overflow (Invalid write of size 4, 2 bytes past the end). Signed-off-by: Ivan Grigorev <[email protected]> --- libswresample/Makefile | 3 +- libswresample/tests/swresample_resample_realloc.c | 120 +++++++++++++++++++++ tests/fate/libswresample.mak | 7 ++ ...ffmpeg-error-rate-fail => swr-resample-realloc} | 0 4 files changed, 129 insertions(+), 1 deletion(-) diff --git a/libswresample/Makefile b/libswresample/Makefile index 8b9a0fe6f5..12fbfc35c1 100644 --- a/libswresample/Makefile +++ b/libswresample/Makefile @@ -24,4 +24,5 @@ SHLIBOBJS += log2_tab.o # Windows resource file SHLIBOBJS-$(HAVE_GNU_WINDRES) += swresampleres.o -TESTPROGS = swresample +TESTPROGS = swresample \ + swresample_resample_realloc \ diff --git a/libswresample/tests/swresample_resample_realloc.c b/libswresample/tests/swresample_resample_realloc.c new file mode 100644 index 0000000000..a72194a7f8 --- /dev/null +++ b/libswresample/tests/swresample_resample_realloc.c @@ -0,0 +1,120 @@ +/* + * Exercise the swr_convert(N) -> swr_convert(2N) edge case where the + * second call reuses the internal preout buffer at full capacity, with + * no trailing slack from swri_realloc_audio()'s amortized doubling. + * Forces internal_sample_fmt=S16P to reach the int16 SIMD resample path. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include "libavutil/channel_layout.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/samplefmt.h" +#include "libswresample/swresample.h" + +int main(void) +{ + const int IN_RATE = 48000; + const int OUT_RATE = 16000; + /* First call asks for N out frames, second call asks for 2N. */ + const int N1_OUT = 160; + const int N2_OUT = 320; + const int N1_IN = N1_OUT * IN_RATE / OUT_RATE; /* 480 */ + const int N2_IN = N2_OUT * IN_RATE / OUT_RATE; /* 960 */ + + SwrContext *swr = swr_alloc(); + AVChannelLayout mono = AV_CHANNEL_LAYOUT_MONO; + int ret = 0; + + if (!swr) { + fprintf(stderr, "swr_alloc failed\n"); + return 1; + } + + av_opt_set_chlayout (swr, "in_chlayout", &mono, 0); + av_opt_set_chlayout (swr, "out_chlayout", &mono, 0); + av_opt_set_int (swr, "in_sample_rate", IN_RATE, 0); + av_opt_set_int (swr, "out_sample_rate", OUT_RATE, 0); + av_opt_set_sample_fmt (swr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); + av_opt_set_sample_fmt (swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + /* Force the int16 SIMD resample path. */ + av_opt_set_sample_fmt (swr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0); + + if ((ret = swr_init(swr)) < 0) { + fprintf(stderr, "swr_init failed: %d\n", ret); + ret = 1; + goto end; + } + + { + int16_t *input = av_calloc(N2_IN, sizeof(int16_t)); + int16_t *out = av_calloc(N2_OUT, sizeof(int16_t)); + const uint8_t *in_planes[1]; + uint8_t *out_planes[1]; + int i, n; + + if (!input || !out) { + fprintf(stderr, "alloc failed\n"); + av_free(input); + av_free(out); + ret = 1; + goto end; + } + + /* Non-zero samples so the SIMD inner loop produces real data. */ + for (i = 0; i < N2_IN; ++i) + input[i] = (int16_t)((i * 7) & 0x3fff); + + /* Call #1: out_count = N. swri_realloc_audio() doubles count and + * grows s->preout to capacity 2N (e.g. 640 bytes for N=160). */ + in_planes[0] = (const uint8_t *)input; + out_planes[0] = (uint8_t *)out; + n = swr_convert(swr, out_planes, N1_OUT, in_planes, N1_IN); + if (n < 0) { + fprintf(stderr, "swr_convert call#1 failed: %d\n", n); + av_free(input); + av_free(out); + ret = 1; + goto end; + } + + /* Call #2: out_count = 2N. a->count == 2N, so swri_realloc_audio() + * skips realloc and reuses the existing buffer at full capacity. */ + in_planes[0] = (const uint8_t *)input; + out_planes[0] = (uint8_t *)out; + n = swr_convert(swr, out_planes, N2_OUT, in_planes, N2_IN); + if (n < 0) { + fprintf(stderr, "swr_convert call#2 failed: %d\n", n); + av_free(input); + av_free(out); + ret = 1; + goto end; + } + + av_free(input); + av_free(out); + } + +end: + swr_free(&swr); + return ret; +} diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index 5317d4148d..25073923b5 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -1105,5 +1105,12 @@ fate-swr-custom-rematrix: CMP = oneline fate-swr-custom-rematrix: REF = 2a14a44deb4ae26e3b474ddbfbc048f8 FATE_SWR += $(FATE_SWR_CUSTOM_REMATRIX-yes) + +FATE_SWR_REALLOC-$(CONFIG_SWRESAMPLE) += fate-swr-resample-realloc +fate-swr-resample-realloc: libswresample/tests/swresample_resample_realloc$(EXESUF) +fate-swr-resample-realloc: CMD = run libswresample/tests/swresample_resample_realloc$(EXESUF) + +FATE_SWR += $(FATE_SWR_REALLOC-yes) + FATE_FFMPEG += $(FATE_SWR) fate-swr: $(FATE_SWR) diff --git a/tests/ref/fate/ffmpeg-error-rate-fail b/tests/ref/fate/swr-resample-realloc similarity index 100% copy from tests/ref/fate/ffmpeg-error-rate-fail copy to tests/ref/fate/swr-resample-realloc _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
