From a6f17e1f6a53f8bb016acfbcd55b61cbe220f5c8 Mon Sep 17 00:00:00 2001
From: Arnesh Banerjee <linkrinku13@gmail.com>
Date: Tue, 4 Aug 2026 19:49:11 +0530
Subject: [PATCH] videoio(ffmpeg): use avcodec_get_supported_config for
 framerates on FFmpeg 9

AVCodec::supported_framerates was deprecated in FFmpeg 7.1 and removed in
FFmpeg 9, so direct field access no longer builds against FFmpeg 9.

Read the supported frame rate list through avcodec_get_supported_config()
when building against libavcodec 61.13.100 or newer. That call returns the
same list plus its entry count, so the loop iterates by count instead of the
old sentinel terminator. Older FFmpeg keeps the previous field access.
---
 modules/videoio/src/cap_ffmpeg_impl.hpp | 34 +++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp
index 3dd42ecfd1fc..883690584a6e 100644
--- a/modules/videoio/src/cap_ffmpeg_impl.hpp
+++ b/modules/videoio/src/cap_ffmpeg_impl.hpp
@@ -2629,6 +2629,39 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc,
     c->time_base.den = frame_rate;
     c->time_base.num = frame_rate_base;
     /* adjust time base for supported framerates */
+    // AVCodec::supported_framerates was deprecated in FFmpeg 7.1 and removed in
+    // FFmpeg 9. avcodec_get_supported_config() returns the same list together
+    // with its entry count, so use it when available.
+#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(61, 13, 100)
+    const AVRational *supported_framerates = NULL;
+    int num_supported_framerates = 0;
+    if (codec)
+        avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_FRAME_RATE, 0,
+                                     (const void **)&supported_framerates, &num_supported_framerates);
+    if (supported_framerates && num_supported_framerates > 0){
+        AVRational req = {frame_rate, frame_rate_base};
+        const AVRational *best=NULL;
+        AVRational best_error= {INT_MAX, 1};
+        for(int i = 0; i < num_supported_framerates; i++){
+            const AVRational *p = &supported_framerates[i];
+            AVRational error= av_sub_q(req, *p);
+            if(error.num <0) error.num *= -1;
+            if(av_cmp_q(error, best_error) < 0){
+                best_error= error;
+                best= p;
+            }
+        }
+        if (best == NULL)
+        {
+#ifdef CV_FFMPEG_CODECPAR
+            avcodec_free_context(&c);
+#endif
+            return NULL;
+        }
+        c->time_base.den= best->num;
+        c->time_base.num= best->den;
+    }
+#else
     if(codec && codec->supported_framerates){
         const AVRational *p= codec->supported_framerates;
         AVRational req = {frame_rate, frame_rate_base};
@@ -2652,6 +2685,7 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc,
         c->time_base.den= best->num;
         c->time_base.num= best->den;
     }
+#endif
 
     c->gop_size = 12; /* emit one intra frame every twelve frames at most */
     c->pix_fmt = pixel_format;
