Submitted By: Joe Locash Date: 2026-08-05 Initial Package Version: 4.13.0 Origin: Upstream: https://github.com/opencv/opencv/pull/29533 https://github.com/opencv/opencv/pull/29662 Upstream Status: Pending Description: Fixes building with ffmpeg-9 From 7551012b4e1c854c1dc36483c893f90b1c236977 Mon Sep 17 00:00:00 2001 From: Aadhu23 Date: Thu, 16 Jul 2026 09:21:37 +0000 Subject: [PATCH] videoio: support FFmpeg after AVCodec::pix_fmts removal --- modules/videoio/src/cap_ffmpeg_hw.hpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/videoio/src/cap_ffmpeg_hw.hpp b/modules/videoio/src/cap_ffmpeg_hw.hpp index 65045a2bc79e..bb5e4c108819 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_VERSION_INT >= 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) From a6f17e1f6a53f8bb016acfbcd55b61cbe220f5c8 Mon Sep 17 00:00:00 2001 From: Arnesh Banerjee 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;