File ffmpeg-dlopen-openh264.patch of Package ffmpeg-7
355
1
From 4739b0c97b3378bdaf737171777fe9a71a53eff1 Mon Sep 17 00:00:00 2001
2
From: Neal Gompa <ngompa@fedoraproject.org>
3
Date: Wed, 12 Oct 2022 09:41:27 -0400
4
Subject: [PATCH] avcodec/openh264: Add the ability to dlopen() OpenH264
5
6
We can't directly depend on OpenH264, but we can weakly link to it
7
and gracefully expose the capability.
8
9
Co-authored-by: Andreas Schneider <asn@cryptomilk.org>
10
Co-authored-by: Neal Gompa <ngompa@fedoraproject.org>
11
12
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
13
Signed-off-by: Neal Gompa <ngompa@fedoraproject.org>
14
---
15
configure | 3
16
libavcodec/Makefile | 1
17
libavcodec/libopenh264.c | 5 +
18
libavcodec/libopenh264_dlopen.c | 147 ++++++++++++++++++++++++++++++++++++++++
19
libavcodec/libopenh264_dlopen.h | 58 +++++++++++++++
20
libavcodec/libopenh264dec.c | 8 ++
21
libavcodec/libopenh264enc.c | 8 ++
22
7 files changed, 230 insertions(+)
23
create mode 100644 libavcodec/libopenh264_dlopen.c
24
create mode 100644 libavcodec/libopenh264_dlopen.h
25
26
Index: ffmpeg-7.1/configure
27
===================================================================
28
--- ffmpeg-7.1.orig/configure
29
+++ ffmpeg-7.1/configure
30
31
--enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
32
--enable-libopencv enable video filtering via libopencv [no]
33
--enable-libopenh264 enable H.264 encoding via OpenH264 [no]
34
+ --enable-libopenh264-dlopen enable H.264 encoding via dlopen()'ed OpenH264 [no]
35
--enable-libopenjpeg enable JPEG 2000 encoding via OpenJPEG [no]
36
--enable-libopenmpt enable decoding tracked files via libopenmpt [no]
37
--enable-libopenvino enable OpenVINO as a DNN module backend
38
39
libmysofa
40
libopencv
41
libopenh264
42
+ libopenh264_dlopen
43
libopenjpeg
44
libopenmpt
45
libopenvino
46
47
require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } ||
48
require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; }
49
enabled libopenh264 && require_pkg_config libopenh264 "openh264 >= 1.3.0" wels/codec_api.h WelsGetCodecVersion
50
+enabled libopenh264_dlopen && enable libopenh264 && add_cppflags "-I$(dirname $(readlink -f "$0"))/ffdlopenhdrs/include -DCONFIG_LIBOPENH264_DLOPEN=1"
51
enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version ||
52
{ require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } }
53
enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
54
Index: ffmpeg-7.1/libavcodec/Makefile
55
===================================================================
56
--- ffmpeg-7.1.orig/libavcodec/Makefile
57
+++ ffmpeg-7.1/libavcodec/Makefile
58
59
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
60
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
61
OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o
62
+OBJS-$(CONFIG_LIBOPENH264_DLOPEN) += libopenh264_dlopen.o
63
OBJS-$(CONFIG_LIBOPENH264_DECODER) += libopenh264dec.o libopenh264.o
64
OBJS-$(CONFIG_LIBOPENH264_ENCODER) += libopenh264enc.o libopenh264.o
65
OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o
66
Index: ffmpeg-7.1/libavcodec/libopenh264.c
67
===================================================================
68
--- ffmpeg-7.1.orig/libavcodec/libopenh264.c
69
+++ ffmpeg-7.1/libavcodec/libopenh264.c
70
71
*/
72
73
#include <string.h>
74
+
75
+#ifdef CONFIG_LIBOPENH264_DLOPEN
76
+#include "libopenh264_dlopen.h"
77
+#else
78
#include <wels/codec_api.h>
79
#include <wels/codec_ver.h>
80
+#endif
81
82
#include "libavutil/error.h"
83
#include "libavutil/log.h"
84
Index: ffmpeg-7.1/libavcodec/libopenh264_dlopen.c
85
===================================================================
86
--- /dev/null
87
+++ ffmpeg-7.1/libavcodec/libopenh264_dlopen.c
88
89
+/*
90
+ * OpenH264 dlopen code
91
+ *
92
+ * Copyright (C) 2022 Andreas Schneider <asn@cryptomilk.org>
93
+ *
94
+ * This file is part of FFmpeg.
95
+ *
96
+ * FFmpeg is free software; you can redistribute it and/or
97
+ * modify it under the terms of the GNU Lesser General Public
98
+ * License as published by the Free Software Foundation; either
99
+ * version 2.1 of the License, or (at your option) any later version.
100
+ *
101
+ * FFmpeg is distributed in the hope that it will be useful,
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
104
+ * Lesser General Public License for more details.
105
+ *
106
+ * You should have received a copy of the GNU Lesser General Public
107
+ * License along with FFmpeg; if not, write to the Free Software
108
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
109
+ */
110
+
111
+#include <dlfcn.h>
112
+
113
+#include "libopenh264_dlopen.h"
114
+
115
+/*
116
+ * The symbol binding makes sure we do not run into strict aliasing issues which
117
+ * can lead into segfaults.
118
+ */
119
+typedef int (*__oh264_WelsCreateSVCEncoder)(ISVCEncoder **);
120
+typedef void (*__oh264_WelsDestroySVCEncoder)(ISVCEncoder *);
121
+typedef int (*__oh264_WelsGetDecoderCapability)(SDecoderCapability *);
122
+typedef long (*__oh264_WelsCreateDecoder)(ISVCDecoder **);
123
+typedef void (*__oh264_WelsDestroyDecoder)(ISVCDecoder *);
124
+typedef OpenH264Version (*__oh264_WelsGetCodecVersion)(void);
125
+typedef void (*__oh264_WelsGetCodecVersionEx)(OpenH264Version *);
126
+
127
+#define OH264_SYMBOL_ENTRY(i) \
128
+ union { \
129
+ __oh264_##i f; \
130
+ void *obj; \
131
+ } _oh264_##i
132
+
133
+struct oh264_symbols {
134
+ OH264_SYMBOL_ENTRY(WelsCreateSVCEncoder);
135
+ OH264_SYMBOL_ENTRY(WelsDestroySVCEncoder);
136
+ OH264_SYMBOL_ENTRY(WelsGetDecoderCapability);
137
+ OH264_SYMBOL_ENTRY(WelsCreateDecoder);
138
+ OH264_SYMBOL_ENTRY(WelsDestroyDecoder);
139
+ OH264_SYMBOL_ENTRY(WelsGetCodecVersion);
140
+ OH264_SYMBOL_ENTRY(WelsGetCodecVersionEx);
141
+};
142
+
143
+/* Symbols are bound by loadLibOpenH264() */
144
+static struct oh264_symbols openh264_symbols;
145
+
146
+int oh264_WelsCreateSVCEncoder(ISVCEncoder **ppEncoder) {
147
+ return openh264_symbols._oh264_WelsCreateSVCEncoder.f(ppEncoder);
148
+}
149
+
150
+void oh264_WelsDestroySVCEncoder(ISVCEncoder *pEncoder) {
151
+ return openh264_symbols._oh264_WelsDestroySVCEncoder.f(pEncoder);
152
+}
153
+
154
+int oh264_WelsGetDecoderCapability(SDecoderCapability *pDecCapability) {
155
+ return openh264_symbols._oh264_WelsGetDecoderCapability.f(pDecCapability);
156
+}
157
+
158
+long oh264_WelsCreateDecoder(ISVCDecoder **ppDecoder) {
159
+ return openh264_symbols._oh264_WelsCreateDecoder.f(ppDecoder);
160
+}
161
+
162
+void oh264_WelsDestroyDecoder(ISVCDecoder *pDecoder) {
163
+ return openh264_symbols._oh264_WelsDestroyDecoder.f(pDecoder);
164
+}
165
+
166
+OpenH264Version oh264_WelsGetCodecVersion(void) {
167
+ return openh264_symbols._oh264_WelsGetCodecVersion.f();
168
+}
169
+
170
+void oh264_WelsGetCodecVersionEx(OpenH264Version *pVersion) {
171
+ openh264_symbols._oh264_WelsGetCodecVersionEx.f(pVersion);
172
+}
173
+
174
+static void *_oh264_bind_symbol(AVCodecContext *avctx,
175
+ void *handle,
176
+ const char *sym_name) {
177
+ void *sym = NULL;
178
+
179
+ sym = dlsym(handle, sym_name);
180
+ if (sym == NULL) {
181
+ const char *err = dlerror();
182
+ av_log(avctx,
183
+ AV_LOG_WARNING,
184
+ "%s: Failed to bind %s\n",
185
+ err,
186
+ sym_name);
187
+ return NULL;
188
+ }
189
+
190
+ return sym;
191
+}
192
+
193
+#define oh264_bind_symbol(avctx, handle, sym_name) \
194
+ if (openh264_symbols._oh264_##sym_name.obj == NULL) { \
195
+ openh264_symbols._oh264_##sym_name.obj = _oh264_bind_symbol(avctx, handle, #sym_name); \
196
+ if (openh264_symbols._oh264_##sym_name.obj == NULL) { \
197
+ return 1; \
198
+ } \
199
+ }
200
+
201
+int loadLibOpenH264(AVCodecContext *avctx) {
202
+ static bool initialized = false;
203
+ void *libopenh264 = NULL;
204
+ const char *err = NULL;
205
+
206
+ if (initialized) {
207
+ return 0;
208
+ }
209
+
210
+#define OPENH264_LIB "libopenh264.so.7"
211
+ libopenh264 = dlopen(OPENH264_LIB, RTLD_LAZY);
212
+ err = dlerror();
213
+ if (err != NULL) {
214
+ av_log(avctx, AV_LOG_WARNING,
215
+ "%s: %s is missing, openh264 support will be disabled\n", err,
216
+ OPENH264_LIB);
217
+
218
+ if (libopenh264 != NULL) {
219
+ dlclose(libopenh264);
220
+ }
221
+ return 1;
222
+ }
223
+
224
+ oh264_bind_symbol(avctx, libopenh264, WelsCreateSVCEncoder);
225
+ oh264_bind_symbol(avctx, libopenh264, WelsDestroySVCEncoder);
226
+ oh264_bind_symbol(avctx, libopenh264, WelsGetDecoderCapability);
227
+ oh264_bind_symbol(avctx, libopenh264, WelsCreateDecoder);
228
+ oh264_bind_symbol(avctx, libopenh264, WelsDestroyDecoder);
229
+ oh264_bind_symbol(avctx, libopenh264, WelsGetCodecVersion);
230
+ oh264_bind_symbol(avctx, libopenh264, WelsGetCodecVersionEx);
231
+
232
+ initialized = true;
233
+
234
+ return 0;
235
+}
236
Index: ffmpeg-7.1/libavcodec/libopenh264_dlopen.h
237
===================================================================
238
--- /dev/null
239
+++ ffmpeg-7.1/libavcodec/libopenh264_dlopen.h
240
241
+/*
242
+ * OpenH264 dlopen code
243
+ *
244
+ * Copyright (C) 2022 Andreas Schneider <asn@cryptomilk.org>
245
+ *
246
+ * This file is part of FFmpeg.
247
+ *
248
+ * FFmpeg is free software; you can redistribute it and/or
249
+ * modify it under the terms of the GNU Lesser General Public
250
+ * License as published by the Free Software Foundation; either
251
+ * version 2.1 of the License, or (at your option) any later version.
252
+ *
253
+ * FFmpeg is distributed in the hope that it will be useful,
254
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
255
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
256
+ * Lesser General Public License for more details.
257
+ *
258
+ * You should have received a copy of the GNU Lesser General Public
259
+ * License along with FFmpeg; if not, write to the Free Software
260
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
261
+ */
262
+
263
+#ifndef HAVE_LIBOPENH264_DLOPEN_H
264
+#define HAVE_LIBOPENH264_DLOPEN_H
265
+
266
+#ifdef CONFIG_LIBOPENH264_DLOPEN
267
+
268
+#include <wels/codec_api.h>
269
+#include <wels/codec_ver.h>
270
+
271
+#include "avcodec.h"
272
+
273
+int oh264_WelsCreateSVCEncoder(ISVCEncoder **ppEncoder);
274
+#define WelsCreateSVCEncoder oh264_WelsCreateSVCEncoder
275
+
276
+void oh264_WelsDestroySVCEncoder(ISVCEncoder *pEncoder);
277
+#define WelsDestroySVCEncoder oh264_WelsDestroySVCEncoder
278
+
279
+int oh264_WelsGetDecoderCapability(SDecoderCapability *pDecCapability);
280
+#define WelsGetDecoderCapability oh264_WelsGetDecoderCapability
281
+
282
+long oh264_WelsCreateDecoder(ISVCDecoder **ppDecoder);
283
+#define WelsCreateDecoder oh264_WelsCreateDecoder
284
+
285
+void oh264_WelsDestroyDecoder(ISVCDecoder *pDecoder);
286
+#define WelsDestroyDecoder oh264_WelsDestroyDecoder
287
+
288
+OpenH264Version oh264_WelsGetCodecVersion(void);
289
+#define WelsGetCodecVersion oh264_WelsGetCodecVersion
290
+
291
+void oh264_WelsGetCodecVersionEx(OpenH264Version *pVersion);
292
+#define WelsGetCodecVersionEx oh264_WelsGetCodecVersionEx
293
+
294
+int loadLibOpenH264(AVCodecContext *avctx);
295
+
296
+#endif /* CONFIG_LIBOPENH264_DLOPEN */
297
+
298
+#endif /* HAVE_LIBOPENH264_DLOPEN_H */
299
Index: ffmpeg-7.1/libavcodec/libopenh264dec.c
300
===================================================================
301
--- ffmpeg-7.1.orig/libavcodec/libopenh264dec.c
302
+++ ffmpeg-7.1/libavcodec/libopenh264dec.c
303
304
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
305
*/
306
307
+#ifdef CONFIG_LIBOPENH264_DLOPEN
308
+#include "libopenh264_dlopen.h"
309
+#else
310
#include <wels/codec_api.h>
311
#include <wels/codec_ver.h>
312
+#endif
313
314
#include "libavutil/common.h"
315
#include "libavutil/fifo.h"
316
317
int log_level;
318
WelsTraceCallback callback_function;
319
320
+#ifdef CONFIG_LIBOPENH264_DLOPEN
321
+ if (loadLibOpenH264(avctx))
322
+ return AVERROR_DECODER_NOT_FOUND;
323
+#endif
324
if (WelsCreateDecoder(&s->decoder)) {
325
av_log(avctx, AV_LOG_ERROR, "Unable to create decoder\n");
326
return AVERROR_UNKNOWN;
327
Index: ffmpeg-7.1/libavcodec/libopenh264enc.c
328
===================================================================
329
--- ffmpeg-7.1.orig/libavcodec/libopenh264enc.c
330
+++ ffmpeg-7.1/libavcodec/libopenh264enc.c
331
332
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
333
*/
334
335
+#ifdef CONFIG_LIBOPENH264_DLOPEN
336
+#include "libopenh264_dlopen.h"
337
+#else
338
#include <wels/codec_api.h>
339
#include <wels/codec_ver.h>
340
+#endif
341
342
#include "libavutil/attributes.h"
343
#include "libavutil/common.h"
344
345
WelsTraceCallback callback_function;
346
AVCPBProperties *props;
347
348
+#ifdef CONFIG_LIBOPENH264_DLOPEN
349
+ if (loadLibOpenH264(avctx))
350
+ return AVERROR_ENCODER_NOT_FOUND;
351
+#endif
352
if (WelsCreateSVCEncoder(&s->encoder)) {
353
av_log(avctx, AV_LOG_ERROR, "Unable to create encoder\n");
354
return AVERROR_UNKNOWN;
355