From 700cd32ffd59ed3c6f6aec1919867653d8b125ea Mon Sep 17 00:00:00 2001 From: Aadhu23 Date: Thu, 16 Jul 2026 09:21:37 +0000 Subject: [PATCH 1/3] 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 83ed22ca2800267050a4a9a94afab605c990c0e0 Mon Sep 17 00:00:00 2001 From: Arnesh Banerjee Date: Tue, 4 Aug 2026 19:49:11 +0530 Subject: [PATCH 2/3] 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 a7fb1eda9a54..d5b950392c94 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -2627,6 +2627,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}; @@ -2650,6 +2683,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; From c0166c617d765ac707dde6b9acd8cfcd49751049 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 11 Aug 2026 13:01:55 +0300 Subject: [PATCH 3/3] Code review fixes. --- modules/videoio/src/cap_ffmpeg_hw.hpp | 16 ++++---- modules/videoio/src/cap_ffmpeg_impl.hpp | 51 ++++++++++++------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/modules/videoio/src/cap_ffmpeg_hw.hpp b/modules/videoio/src/cap_ffmpeg_hw.hpp index bb5e4c108819..6c456881122a 100644 --- a/modules/videoio/src/cap_ffmpeg_hw.hpp +++ b/modules/videoio/src/cap_ffmpeg_hw.hpp @@ -757,7 +757,7 @@ 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 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; @@ -770,15 +770,15 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor (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; + 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) { diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index d5b950392c94..fc4479e07c5f 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -2627,37 +2627,36 @@ 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 (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) - { + if (best == NULL) + { #ifdef CV_FFMPEG_CODECPAR - avcodec_free_context(&c); + avcodec_free_context(&c); #endif - return NULL; + return NULL; + } + c->time_base.den = best->num; + c->time_base.num = best->den; } - c->time_base.den= best->num; - c->time_base.num= best->den; } #else if(codec && codec->supported_framerates){