diff --git a/retroarch-ffmpeg9.patch b/retroarch-ffmpeg9.patch deleted file mode 100644 index f82f70d..0000000 --- a/retroarch-ffmpeg9.patch +++ /dev/null @@ -1,207 +0,0 @@ -From f5b422d5a81f0b4d263e2f52c8419ea9ce7467f6 Mon Sep 17 00:00:00 2001 -From: LibretroAdmin -Date: Mon, 10 Aug 2026 21:42:29 +0000 -Subject: [PATCH] ffmpeg: support FFmpeg 9 (lavc 63), version-gated back to - existing floor - -MSYS2 updated mingw-w64-ffmpeg to 9.0, which removes the deprecated -AVCodec.sample_fmts / AVCodec.supported_samplerates arrays and breaks -the MSYS2 CI build in record_ffmpeg.c. - -record_ffmpeg: add accessors that use avcodec_get_supported_config() -where available (lavc >= 61.13.100, FFmpeg 7.1+) and fall back to the -legacy AVCodec struct members on older versions. NULL now means -unrestricted instead of being dereferenced, hardening both paths. - -camera/ffmpeg: version-gate const-ness of the AVInputFormat/AVCodec -pointers; lavf 59 (FFmpeg 5.0) made that API const-correct, lavf 58 -(FFmpeg 4.x, the driver's minimum) warns on const pointers. - -Verified: compile matrix with production flags against FFmpeg 3.4.13, -4.4.5, 5.1.6, 6.1.2, 7.1.1, 8.1.2 and 9.0 all clean; full configure + -make against FFmpeg 9.0 builds and links; resolver logic runtime-tested -under ASan/UBSan against FFmpeg 9.0 (new path) and 6.1.2 (legacy path) -with identical results and no sanitizer findings. ---- - camera/drivers/ffmpeg.c | 17 +++++++- - record/drivers/record_ffmpeg.c | 71 +++++++++++++++++++++++++++++----- - 2 files changed, 76 insertions(+), 12 deletions(-) - -diff --git a/camera/drivers/ffmpeg.c b/camera/drivers/ffmpeg.c -index 2c0e68adade4..f12f55690465 100644 ---- a/camera/drivers/ffmpeg.c -+++ b/camera/drivers/ffmpeg.c -@@ -58,13 +58,26 @@ extern "C" { - #define FFMPEG_CAMERA_DEFAULT_BACKEND "lavfi" - #endif - -+/* lavf 59 (FFmpeg 5.0) made the demuxer/codec discovery API const-correct: -+ * av_find_input_format() returns const AVInputFormat*, avformat_open_input() -+ * accepts one, and av_find_best_stream() takes const AVCodec**. Older -+ * versions use mutable pointers throughout, so a single const-qualified -+ * declaration cannot satisfy both. */ -+#if LIBAVFORMAT_VERSION_MAJOR >= 59 -+typedef const AVInputFormat ffmpeg_camera_input_format_t; -+typedef const AVCodec ffmpeg_camera_codec_t; -+#else -+typedef AVInputFormat ffmpeg_camera_input_format_t; -+typedef AVCodec ffmpeg_camera_codec_t; -+#endif -+ - typedef struct ffmpeg_camera - { - sthread_t *poll_thread; - AVFormatContext *format_context; - AVCodecContext *decoder_context; -- const AVCodec *decoder; -- const AVInputFormat *input_format; /* owned by ffmpeg, don't free it */ -+ ffmpeg_camera_codec_t *decoder; /* owned by ffmpeg, don't free it */ -+ ffmpeg_camera_input_format_t *input_format; /* owned by ffmpeg, don't free it */ - AVDictionary *options; - AVPacket *packet; - AVFrame *camera_frame; -diff --git a/record/drivers/record_ffmpeg.c b/record/drivers/record_ffmpeg.c -index fc801af0b34e..5f72f2b87241 100644 ---- a/record/drivers/record_ffmpeg.c -+++ b/record/drivers/record_ffmpeg.c -@@ -79,6 +79,15 @@ extern "C" { - #define FFMPEG8 (LIBAVCODEC_VERSION_MAJOR >= 62) - #endif - -+/* avcodec_get_supported_config() was added in lavc 61.13.100 (FFmpeg 7.1) -+ * and the AVCodec.sample_fmts / AVCodec.supported_samplerates arrays it -+ * replaces were deprecated at the same time, then removed entirely in -+ * lavc 63 (FFmpeg 9). Use the new API as soon as it is available so a -+ * single codepath covers FFmpeg 7.1 through 9+, and keep the old struct -+ * members for FFmpeg 7.0 and older. */ -+#define HAVE_AVCODEC_GET_SUPPORTED_CONFIG \ -+ (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)) -+ - #ifndef AV_INPUT_BUFFER_MIN_SIZE - #define AV_INPUT_BUFFER_MIN_SIZE 16384 - #endif -@@ -216,11 +225,48 @@ typedef struct ffmpeg - - AVFormatContext *ctx; - -+/* Returns the encoder's list of supported sample formats, terminated by -+ * AV_SAMPLE_FMT_NONE, or NULL if the encoder does not restrict sample -+ * formats (or the list could not be queried). */ -+static const enum AVSampleFormat *ffmpeg_codec_sample_formats( -+ const AVCodec *codec) -+{ -+#if HAVE_AVCODEC_GET_SUPPORTED_CONFIG -+ const void *fmts = NULL; -+ if (avcodec_get_supported_config(NULL, codec, -+ AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, &fmts, NULL) < 0) -+ return NULL; -+ return (const enum AVSampleFormat*)fmts; -+#else -+ return codec->sample_fmts; -+#endif -+} -+ -+/* Returns the encoder's list of supported sample rates, terminated by 0, -+ * or NULL if the encoder does not restrict sample rates (or the list -+ * could not be queried). */ -+static const int *ffmpeg_codec_supported_samplerates(const AVCodec *codec) -+{ -+#if HAVE_AVCODEC_GET_SUPPORTED_CONFIG -+ const void *rates = NULL; -+ if (avcodec_get_supported_config(NULL, codec, -+ AV_CODEC_CONFIG_SAMPLE_RATE, 0, &rates, NULL) < 0) -+ return NULL; -+ return (const int*)rates; -+#else -+ return codec->supported_samplerates; -+#endif -+} -+ - static bool ffmpeg_codec_has_sample_format(enum AVSampleFormat fmt, - const enum AVSampleFormat *fmts) - { - unsigned i; - -+ /* A NULL list means the encoder does not restrict sample formats. */ -+ if (!fmts) -+ return true; -+ - for (i = 0; fmts[i] != AV_SAMPLE_FMT_NONE; i++) - if (fmt == fmts[i]) - return true; -@@ -230,30 +276,32 @@ static bool ffmpeg_codec_has_sample_format(enum AVSampleFormat fmt, - static void ffmpeg_audio_resolve_format(struct ff_audio_info *audio, - const AVCodec *codec) - { -+ const enum AVSampleFormat *sample_fmts = ffmpeg_codec_sample_formats(codec); -+ - audio->codec->sample_fmt = AV_SAMPLE_FMT_NONE; - -- if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_FLTP, codec->sample_fmts)) -+ if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_FLTP, sample_fmts)) - { - audio->codec->sample_fmt = AV_SAMPLE_FMT_FLTP; - audio->use_float = true; - audio->is_planar = true; - RARCH_LOG("[FFmpeg] Using sample format FLTP.\n"); - } -- else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_FLT, codec->sample_fmts)) -+ else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_FLT, sample_fmts)) - { - audio->codec->sample_fmt = AV_SAMPLE_FMT_FLT; - audio->use_float = true; - audio->is_planar = false; - RARCH_LOG("[FFmpeg] Using sample format FLT.\n"); - } -- else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_S16P, codec->sample_fmts)) -+ else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_S16P, sample_fmts)) - { - audio->codec->sample_fmt = AV_SAMPLE_FMT_S16P; - audio->use_float = false; - audio->is_planar = true; - RARCH_LOG("[FFmpeg] Using sample format S16P.\n"); - } -- else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_S16, codec->sample_fmts)) -+ else if (ffmpeg_codec_has_sample_format(AV_SAMPLE_FMT_S16, sample_fmts)) - { - audio->codec->sample_fmt = AV_SAMPLE_FMT_S16; - audio->use_float = false; -@@ -268,21 +316,24 @@ static void ffmpeg_audio_resolve_sample_rate(ffmpeg_t *handle, - { - struct ff_config_param *params = &handle->config; - struct record_params *param = &handle->params; -+ const int *supported_samplerates = ffmpeg_codec_supported_samplerates(codec); - -- /* We'll have to force resampling to some supported sampling rate. */ -- if (codec->supported_samplerates && !params->sample_rate) -+ /* We'll have to force resampling to some supported sampling rate. -+ * A NULL list means the encoder accepts any sample rate, in which -+ * case the input rate is kept as-is. */ -+ if (supported_samplerates && !params->sample_rate) - { - unsigned i; - int input_rate = (int)param->samplerate; - - /* Favor closest sampling rate, but always prefer ratio > 1.0. */ -- int best_rate = codec->supported_samplerates[0]; -+ int best_rate = supported_samplerates[0]; - int best_diff = best_rate - input_rate; - -- for (i = 1; codec->supported_samplerates[i]; i++) -+ for (i = 1; supported_samplerates[i]; i++) - { - bool better_rate = false; -- int diff = codec->supported_samplerates[i] - input_rate; -+ int diff = supported_samplerates[i] - input_rate; - - if (best_diff < 0) - better_rate = (diff > best_diff); -@@ -291,7 +342,7 @@ static void ffmpeg_audio_resolve_sample_rate(ffmpeg_t *handle, - - if (better_rate) - { -- best_rate = codec->supported_samplerates[i]; -+ best_rate = supported_samplerates[i]; - best_diff = diff; - } - } diff --git a/retroarch.spec b/retroarch.spec index cca7a32..14543ee 100644 --- a/retroarch.spec +++ b/retroarch.spec @@ -126,10 +126,6 @@ Patch: 0003_use_system_zstd.patch # https://github.com/libretro/RetroArch/pull/17563 Patch: https://github.com/libretro/RetroArch/pull/17563.patch#/0002-Support-for-newer-glslang-versions-without-SPIRV-and-HLSL-libraries.patch -# Support FFmpeg 9 -# https://github.com/libretro/RetroArch/issues/19351 -Patch: https://github.com/libretro/RetroArch/commit/f5b422d5a81f0b4d263e2f52c8419ea9ce7467f6.patch#/retroarch-ffmpeg9.patch - BuildRequires: desktop-file-utils BuildRequires: gcc-c++ >= 7 BuildRequires: git-core