https://github.com/opencv/opencv/pull/29533
https://github.com/opencv/opencv/issues/29655

videoio: fix build with FFmpeg 9 after AVCodec::pix_fmts/supported_framerates
removal. FFmpeg 7.1 deprecated AVCodec's direct pix_fmts/supported_framerates
fields in favor of avcodec_get_supported_config(), and FFmpeg 9 removed the
old fields outright - opencv-5.0.0 still used them directly, so it fails to
build against media-video/ffmpeg-9.0.2 with:

  error: 'AVCodec' {aka 'struct AVCodec'} has no member named 'pix_fmts'
  error: 'const AVCodec' {aka 'const struct AVCodec'} has no member named
         'supported_framerates'

Verbatim upstream fix, merged to the opencv 4.x branch via the PR above but
not yet backported to 5.x (checked: still absent from the 5.x branch tip as
of this writing). Applies cleanly (0 fuzz, only line-number offsets) to the
5.0.0 tarball since this file hasn't otherwise changed between the branches.

diff --git a/modules/videoio/src/cap_ffmpeg_hw.hpp b/modules/videoio/src/cap_ffmpeg_hw.hpp
index 65045a2bc79e..6c456881122a 100644
--- a/modules/videoio/src/cap_ffmpeg_hw.hpp
+++ b/modules/videoio/src/cap_ffmpeg_hw.hpp
@@ -757,6 +757,30 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor
 #endif
             if (hw_type == AV_HWDEVICE_TYPE_CUDA) // CUDA encoders don't support avcodec_get_hw_config()
                 hw_native_fmt = AV_PIX_FMT_CUDA;
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(61, 13, 100)
+            if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE) {
+                const AVPixelFormat *pix_fmts = NULL;
+                int num_pix_fmts = 0;
+
+                int ret = avcodec_get_supported_config(
+                    NULL,
+                    c,
+                    AV_CODEC_CONFIG_PIX_FORMAT,
+                    0,
+                    (const void **)&pix_fmts,
+                    &num_pix_fmts);
+
+                if (ret >= 0 && pix_fmts && num_pix_fmts > 0) {
+                        for (int i = 0; i < num_pix_fmts; i++) {
+                            if (pix_fmts[i] == hw_native_fmt) {
+                                *hw_pix_fmt = hw_native_fmt;
+                                if (hw_check_codec(c, hw_type, disabled_codecs))
+                                    return c;
+                            }
+                        }
+                    }
+            }
+#else
             if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE && c->pix_fmts) {
                 for (int i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
                     if (c->pix_fmts[i] == hw_native_fmt) {
@@ -766,6 +790,7 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor
                     }
                 }
             }
+#endif
             for (int i = 0;; i++) {
                 const AVCodecHWConfig *hw_config = avcodec_get_hw_config(c, i);
                 if (!hw_config)
diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp
index a7fb1eda9a54..fc4479e07c5f 100644
--- a/modules/videoio/src/cap_ffmpeg_impl.hpp
+++ b/modules/videoio/src/cap_ffmpeg_impl.hpp
@@ -2627,6 +2627,38 @@ 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 */
+#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(61, 13, 100)
+    if (codec){
+        const AVRational *supported_framerates = NULL;
+        int num_supported_framerates = 0;
+        int ret = avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_FRAME_RATE, 0,
+                                               (const void **)&supported_framerates, &num_supported_framerates);
+
+        if (ret >= 0 && 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};
@@ -2650,6 +2682,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;
