summaryrefslogtreecommitdiff
path: root/gui-apps/wf-recorder/files/wf-recorder-0.6.0-ffmpeg-9.patch
blob: b7efb3773efb579bdd44fbd3d6f11b4f3949cc9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
From 0c20d4c611c7d310f40d7341066686bd1a224164 Mon Sep 17 00:00:00 2001
From: Ravi Arnan <raviarnankeren@gmail.com>
Date: Sat, 22 Aug 2026 14:38:31 +0800
Subject: [PATCH] frame-writer: use avcodec_get_supported_config for codec
 formats

libavcodec 63 removes AVCodec's pix_fmts, sample_fmts and ch_layouts,
which 62 had deprecated in favour of avcodec_get_supported_config(), so
building against ffmpeg 9 fails with "no member named 'pix_fmts'" and
the same for the other two.

Read each of them through a helper that calls
avcodec_get_supported_config() from libavcodec 62 onwards and the array
below that. The returned lists carry the same terminators the arrays
did, and a NULL result still means the codec does not restrict the
value, so the call sites keep the loops and the NULL checks they had.

Fixes #350

Upstream-Status: pending, https://github.com/ammen99/wf-recorder/pull/351
(carried by Hedronfire from 2026-11-01 for FFmpeg 9; drop once merged)
---
 src/frame-writer.cpp | 81 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 65 insertions(+), 16 deletions(-)

diff --git a/src/frame-writer.cpp b/src/frame-writer.cpp
index 34d16d6..3d4c375 100644
--- a/src/frame-writer.cpp
+++ b/src/frame-writer.cpp
@@ -13,6 +13,34 @@
 
 #define HAVE_CH_LAYOUT (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100))
 
+// The AVCodec format arrays were deprecated in favour of
+// avcodec_get_supported_config() in libavcodec 62 and removed in 63
+#define HAVE_CODEC_SUPPORTED_CONFIG (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(62, 0, 100))
+
+#if HAVE_CODEC_SUPPORTED_CONFIG
+/* The list is terminated the same way the removed AVCodec arrays were, and a
+ * NULL result still means the codec does not restrict the value, so callers can
+ * treat this exactly as they treated the arrays. */
+template<class T>
+static const T *get_codec_config(const AVCodec *codec, enum AVCodecConfig config)
+{
+    const void *configs = NULL;
+    if (avcodec_get_supported_config(NULL, codec, config, 0, &configs, NULL) < 0)
+        return NULL;
+
+    return static_cast<const T*> (configs);
+}
+#endif
+
+static const enum AVPixelFormat *get_codec_pix_fmts(const AVCodec *codec)
+{
+#if HAVE_CODEC_SUPPORTED_CONFIG
+    return get_codec_config<enum AVPixelFormat> (codec, AV_CODEC_CONFIG_PIX_FORMAT);
+#else
+    return codec->pix_fmts;
+#endif
+}
+
 static const AVRational US_RATIONAL{1,1000000} ;
 
 // av_register_all was deprecated in 58.9.100, removed in 59.0.100
@@ -190,23 +218,24 @@ AVPixelFormat FrameWriter::handle_buffersink_pix_fmt(const AVCodec *codec)
         return lookup_pixel_format(params.pix_fmt);
 
     auto in_fmt = get_input_format();
+    const enum AVPixelFormat *pix_fmts = get_codec_pix_fmts(codec);
 
     /* For codecs such as rawvideo no supported formats are listed */
-    if (!codec->pix_fmts)
+    if (!pix_fmts)
         return in_fmt;
 
     /* If the codec supports getting the appropriate RGB format
      * directly, we want to use it since we don't have to convert data */
-    if (is_fmt_supported(in_fmt, codec->pix_fmts))
+    if (is_fmt_supported(in_fmt, pix_fmts))
         return in_fmt;
 
     /* Choose the format supported by the codec which best approximates the
      * input fmt. */
     AVPixelFormat best_format = AV_PIX_FMT_NONE;
-    for (int i = 0; codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+    for (int i = 0; pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
         int loss = 0;
         best_format = av_find_best_pix_fmt_of_2(best_format,
-            codec->pix_fmts[i], in_fmt, false, &loss);
+            pix_fmts[i], in_fmt, false, &loss);
     }
     return best_format;
 }
@@ -513,20 +542,39 @@ void FrameWriter::init_video_stream()
 }
 
 #ifdef HAVE_AUDIO
+static const enum AVSampleFormat *get_codec_sample_fmts(const AVCodec *codec)
+{
+#if HAVE_CODEC_SUPPORTED_CONFIG
+    return get_codec_config<enum AVSampleFormat> (codec, AV_CODEC_CONFIG_SAMPLE_FORMAT);
+#else
+    return codec->sample_fmts;
+#endif
+}
+
 #if HAVE_CH_LAYOUT
+static const AVChannelLayout *get_codec_ch_layouts(const AVCodec *codec)
+{
+#if HAVE_CODEC_SUPPORTED_CONFIG
+    return get_codec_config<AVChannelLayout> (codec, AV_CODEC_CONFIG_CHANNEL_LAYOUT);
+#else
+    return codec->ch_layouts;
+#endif
+}
+
 static uint64_t get_codec_channel_layout(const AVCodec *codec)
 {
     int i = 0;
-    if (!codec->ch_layouts)
+    const AVChannelLayout *ch_layouts = get_codec_ch_layouts(codec);
+    if (!ch_layouts)
         return AV_CH_LAYOUT_STEREO;
     while (1) {
-        if (!av_channel_layout_check(&codec->ch_layouts[i]))
+        if (!av_channel_layout_check(&ch_layouts[i]))
             break;
-        if (codec->ch_layouts[i].u.mask == AV_CH_LAYOUT_STEREO)
-            return codec->ch_layouts[i].u.mask;
+        if (ch_layouts[i].u.mask == AV_CH_LAYOUT_STEREO)
+            return ch_layouts[i].u.mask;
         i++;
     }
-    return codec->ch_layouts[0].u.mask;
+    return ch_layouts[0].u.mask;
 }
 #else
 static uint64_t get_codec_channel_layout(const AVCodec *codec)
@@ -548,20 +596,21 @@ static uint64_t get_codec_channel_layout(const AVCodec *codec)
 static enum AVSampleFormat get_codec_auto_sample_fmt(const AVCodec *codec)
 {
     int i = 0;
-    if (!codec->sample_fmts)
+    const enum AVSampleFormat *sample_fmts = get_codec_sample_fmts(codec);
+    if (!sample_fmts)
         return av_get_sample_fmt(FALLBACK_AUDIO_SAMPLE_FMT);
     while (1) {
-        if (codec->sample_fmts[i] == -1)
+        if (sample_fmts[i] == -1)
             break;
-        if (av_get_bytes_per_sample(codec->sample_fmts[i]) >= 2)
-            return codec->sample_fmts[i];
+        if (av_get_bytes_per_sample(sample_fmts[i]) >= 2)
+            return sample_fmts[i];
         i++;
     }
-    return codec->sample_fmts[0];
+    return sample_fmts[0];
 }
 
 bool check_fmt_available(const AVCodec *codec, AVSampleFormat fmt){
-    for (const enum AVSampleFormat *sample_ptr = codec -> sample_fmts; *sample_ptr != -1; sample_ptr++)
+    for (const enum AVSampleFormat *sample_ptr = get_codec_sample_fmts(codec); *sample_ptr != -1; sample_ptr++)
     {
         if (*sample_ptr == fmt)
         {
@@ -578,7 +627,7 @@ static enum AVSampleFormat convert_codec_sample_fmt(const AVCodec *codec, std::s
     {
         std::cerr << "Failed to find the given sample format: " << requested_fmt << std::endl;
         std::exit(-1);
-    } else if (!codec->sample_fmts || check_fmt_available(codec, converted_fmt))
+    } else if (!get_codec_sample_fmts(codec) || check_fmt_available(codec, converted_fmt))
     {
         std::cerr << "Using sample format " << av_get_sample_fmt_name(converted_fmt) << " for audio codec " << codec->name << std::endl;
         return converted_fmt;