mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-09-27 00:30:20 +00:00
opencv: Backport videoio fixes for ffmpeg 9
oe-core upgraded ffmpeg 8.1.2 -> 9.0, which removed the AVCodec::pix_fmts and AVCodec::supported_framerates fields (deprecated since FFmpeg 7.1 / libavcodec 61.13.100). opencv's videoio ffmpeg backend still reads both of them directly in cap_ffmpeg_hw.hpp and cap_ffmpeg_impl.hpp, so it does not build against ffmpeg 9. Backport the merged upstream series from opencv/opencv#29533, which reads those lists through avcodec_get_supported_config() when building against libavcodec 61.13.100 or newer and keeps the old field access otherwise. The series was merged on 2026-08-11, after the 4.14.0 tag (2026-07-17), so it is not part of the release we build. Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
From 700cd32ffd59ed3c6f6aec1919867653d8b125ea Mon Sep 17 00:00:00 2001
|
||||
From: Aadhu23 <aadhavansalthivel5@gmail.com>
|
||||
Date: Thu, 16 Jul 2026 09:21:37 +0000
|
||||
Subject: [PATCH 1/3] videoio: support FFmpeg after AVCodec::pix_fmts removal
|
||||
|
||||
Upstream-Status: Backport [https://github.com/opencv/opencv/pull/29533]
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
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 <linkrinku13@gmail.com>
|
||||
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.
|
||||
Upstream-Status: Backport [https://github.com/opencv/opencv/pull/29533]
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
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 <alexander.smorkalov@opencv.ai>
|
||||
Date: Tue, 11 Aug 2026 13:01:55 +0300
|
||||
Subject: [PATCH 3/3] Code review fixes.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/opencv/opencv/pull/29533]
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
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){
|
||||
@@ -34,6 +34,7 @@ SRC_URI = "git://github.com/opencv/opencv.git;name=opencv;branch=4.x;protocol=ht
|
||||
file://download.patch \
|
||||
file://0001-Make-ts-module-external.patch \
|
||||
file://0008-Do-not-embed-build-directory-in-binaries.patch \
|
||||
file://29533.patch \
|
||||
"
|
||||
SRC_URI:append:riscv64 = " file://0001-Use-Os-to-compile-tinyxml2.cpp.patch;patchdir=contrib"
|
||||
SRC_URI:append:aarch64 = " git://gitlab.arm.com/kleidi/kleidicv;branch=main;destsuffix=${BB_GIT_DEFAULT_DESTSUFFIX}/3rdparty/kleidicv;name=kleidicv;protocol=https"
|
||||
|
||||
Reference in New Issue
Block a user